From eb16b04d14b3bea6cd110f21361e049e35a37822 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 7 Oct 2014 09:17:37 +0200 Subject: Repackage to org.cristalise --- pom.xml | 18 +- .../com/c2kernel/lookup/ldap/LDAPAuthManager.java | 99 --- .../com/c2kernel/lookup/ldap/LDAPClientReader.java | 45 -- .../c2kernel/lookup/ldap/LDAPClusterStorage.java | 151 ----- .../java/com/c2kernel/lookup/ldap/LDAPLookup.java | 753 --------------------- .../com/c2kernel/lookup/ldap/LDAPLookupUtils.java | 365 ---------- .../java/com/c2kernel/lookup/ldap/LDAPPathSet.java | 81 --- .../com/c2kernel/lookup/ldap/LDAPProperties.java | 188 ----- .../c2kernel/lookup/ldap/LDAPPropertyManager.java | 141 ---- .../com/c2kernel/persistency/LDAPClientReader.java | 15 - .../c2kernel/persistency/LDAPClusterStorage.java | 14 - .../cristalise/lookup/ldap/LDAPAuthManager.java | 100 +++ .../cristalise/lookup/ldap/LDAPClientReader.java | 46 ++ .../cristalise/lookup/ldap/LDAPClusterStorage.java | 152 +++++ .../org/cristalise/lookup/ldap/LDAPLookup.java | 753 +++++++++++++++++++++ .../cristalise/lookup/ldap/LDAPLookupUtils.java | 366 ++++++++++ .../org/cristalise/lookup/ldap/LDAPPathSet.java | 82 +++ .../org/cristalise/lookup/ldap/LDAPProperties.java | 189 ++++++ .../lookup/ldap/LDAPPropertyManager.java | 142 ++++ .../org/cristalise/storage/LDAPClientReader.java | 15 + .../org/cristalise/storage/LDAPClusterStorage.java | 14 + src/main/resources/module.xml | 7 +- 22 files changed, 1871 insertions(+), 1865 deletions(-) delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPAuthManager.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPClientReader.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPClusterStorage.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPLookup.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPLookupUtils.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPPathSet.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPProperties.java delete mode 100644 src/main/java/com/c2kernel/lookup/ldap/LDAPPropertyManager.java delete mode 100644 src/main/java/com/c2kernel/persistency/LDAPClientReader.java delete mode 100644 src/main/java/com/c2kernel/persistency/LDAPClusterStorage.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPAuthManager.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPClientReader.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPClusterStorage.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPLookup.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPLookupUtils.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPPathSet.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPProperties.java create mode 100644 src/main/java/org/cristalise/lookup/ldap/LDAPPropertyManager.java create mode 100644 src/main/java/org/cristalise/storage/LDAPClientReader.java create mode 100644 src/main/java/org/cristalise/storage/LDAPClusterStorage.java diff --git a/pom.xml b/pom.xml index 6853210..d2b42a9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,10 +1,10 @@ 4.0.0 - cristal - cristal-ldap - 1.0-SNAPSHOT - cristal-ldap + org.cristalise + cristalise-ldap + 3.0-SNAPSHOT + cristalise-ldap CRISTAL Module UTF-8 @@ -21,7 +21,7 @@ src/main/resources - com/c2kernel/lookup/ldap/resources + org/cristalise/lookup/ldap/resources module.xml @@ -81,8 +81,8 @@ - cristal - cristal-kernel + org.cristalise + cristalise-kernel 3.0-SNAPSHOT @@ -94,8 +94,8 @@ - cristal - cristal-kernel + org.cristalise + cristalise-kernel com.novell.ldap diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPAuthManager.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPAuthManager.java deleted file mode 100644 index 5e6d5ad..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPAuthManager.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.c2kernel.lookup.ldap; - -import com.c2kernel.common.InvalidDataException; -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.process.Gateway; -import com.c2kernel.process.auth.Authenticator; -import com.c2kernel.utils.Logger; -import com.novell.ldap.LDAPConnection; -import com.novell.ldap.LDAPException; - -public class LDAPAuthManager implements Authenticator { - - protected LDAPConnection mLDAPConn; - protected LDAPProperties ldapProps; - - - @Override - public boolean authenticate(String agentName, - String password, String resource) throws InvalidDataException, ObjectNotFoundException { - - ldapProps = new LDAPProperties(Gateway.getProperties()); - - if (ldapProps.mHost!=null && ldapProps.mPort!= null && ldapProps.mLocalPath!=null ) - { - try { // anonymously bind to LDAP and find the agent entry for the username - ldapProps.mUser = ""; - ldapProps.mPassword = ""; - mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); - LDAPLookup anonLookup = new LDAPLookup(); - anonLookup.initPaths(ldapProps); - anonLookup.open(this); - String agentDN = anonLookup.getFullDN(anonLookup.getAgentPath(agentName)); - - //found agentDN, try to log in with it - ldapProps.mUser = agentDN; - ldapProps.mPassword = password; - mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); - return true; - } catch (LDAPException e) { - return false; - } - } - else - { - throw new InvalidDataException("Cannot log in. Some connection properties are not set."); - } - - } - - @Override - public boolean authenticate(String resource) throws InvalidDataException, ObjectNotFoundException { - ldapProps = new LDAPProperties(Gateway.getProperties()); - - if (ldapProps.mUser == null || ldapProps.mUser.length()==0 || - ldapProps.mPassword == null || ldapProps.mPassword.length()==0) - throw new InvalidDataException("LDAP root user properties not found in config."); - try { - mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); - return true; - } catch (LDAPException e) { - return false; - } - } - - /* (non-Javadoc) - * @see com.c2kernel.process.auth.Authenticator#getAuthObject() - */ - @Override - public LDAPConnection getAuthObject() { - - if (mLDAPConn==null || !mLDAPConn.isConnected()) { - Logger.warning("LDAPAuthManager - lost connection to LDAP server. Attempting to reconnect."); - try { - mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); - } catch (LDAPException ex) { } - } - return mLDAPConn; - } - - @Override - public void disconnect() { - Logger.msg(1, "LDAP Lookup: Shutting down LDAP connection."); - if (mLDAPConn != null) { - try { - mLDAPConn.disconnect(); - } catch (LDAPException e) { - Logger.error(e); - } - mLDAPConn = null; - } - - } - - public LDAPAuthManager() { - // TODO Auto-generated constructor stub - } - - -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPClientReader.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPClientReader.java deleted file mode 100644 index 70bf126..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPClientReader.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.c2kernel.lookup.ldap; - -import com.c2kernel.common.PersistencyException; -import com.c2kernel.entity.C2KLocalObject; -import com.c2kernel.lookup.ItemPath; - -/** Allows clients to directly load properties and collections from the LDAP -* so no CORBA calls need to be made during normal browsing -*/ - -public class LDAPClientReader extends LDAPClusterStorage { - // return all readwrite support as readonly - @Override - public short queryClusterSupport(String clusterType) { - return (short)(super.queryClusterSupport(clusterType) & READ); - } - - - /** - * @see com.c2kernel.persistency.ClusterStorage#delete(Integer, String) - */ - @Override - public void delete(ItemPath itemPath, String path) - throws PersistencyException { - throw new PersistencyException("Writing not supported in ClientReader"); - } - - /** - * @see com.c2kernel.persistency.ClusterStorage#getName() - */ - @Override - public String getName() { - return "LDAP Client Cluster Reader"; - } - - /** - * @see com.c2kernel.persistency.ClusterStorage#put(Integer, String, C2KLocalObject) - */ - - public void put(ItemPath itemPath, String path, C2KLocalObject obj) - throws PersistencyException { - throw new PersistencyException("Writing not supported in ClientReader"); - } - -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPClusterStorage.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPClusterStorage.java deleted file mode 100644 index a264fcc..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPClusterStorage.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.c2kernel.lookup.ldap; -import java.util.ArrayList; -import java.util.StringTokenizer; - -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.common.PersistencyException; -import com.c2kernel.entity.C2KLocalObject; -import com.c2kernel.lookup.ItemPath; -import com.c2kernel.lookup.Lookup; -import com.c2kernel.persistency.ClusterStorage; -import com.c2kernel.process.Gateway; -import com.c2kernel.process.auth.Authenticator; -import com.c2kernel.property.Property; -import com.c2kernel.utils.Logger; - -public class LDAPClusterStorage extends ClusterStorage { - LDAPPropertyManager ldapStore; - - @Override - public void open(Authenticator auth) throws PersistencyException { - Lookup lookup = Gateway.getLookup(); - if (lookup instanceof LDAPLookup) - ldapStore = ((LDAPLookup)lookup).getPropManager(); - else - throw new PersistencyException("Cannot use LDAP cluster storage without LDAP Lookup"); - - } - - @Override - public void close() throws PersistencyException { - } - - // introspection - @Override - public short queryClusterSupport(String clusterType) { - if (clusterType.equals(PROPERTY)) - return READWRITE; - else - return NONE; - } - - @Override - public String getName() { - return "LDAP Cluster Storage"; - } - - @Override - public String getId() { - return "LDAP"; - } - - // retrieve object by path - @Override - public C2KLocalObject get(ItemPath thisItem, String path) throws PersistencyException { - Logger.msg(6, "LDAPClusterStorage.get() - "+thisItem+"/"+path); - StringTokenizer tok = new StringTokenizer(path, "/"); - int pathLength = tok.countTokens(); - if (pathLength != 2) - throw new PersistencyException("Path length was invalid: "+path); - String type = tok.nextToken(); - - String objName = tok.nextToken(); - C2KLocalObject newObj; - - if (type.equals(PROPERTY)) { - try { - Property newProperty = ldapStore.getProperty(thisItem, objName); - newObj = newProperty; - } catch (ObjectNotFoundException ex) { - throw new PersistencyException("Property "+objName+" not found in "+thisItem); - } - - } - else - throw new PersistencyException("Cluster type "+type+" not supported."); - - return newObj; - } - // store object by path - @Override - public void put(ItemPath thisItem, C2KLocalObject obj) throws PersistencyException { - Logger.msg(6, "LDAPClusterStorage.put() - "+thisItem+"/"+ClusterStorage.getPath(obj)); - - String type = obj.getClusterType(); - - if (type.equals(PROPERTY)) { - try { - ldapStore.setProperty(thisItem, (Property)obj); - } catch (Exception e1) { - Logger.error(e1); - throw new PersistencyException("LDAPClusterStorage - could not write property"); - } - } - else - throw new PersistencyException("Cluster type "+type+" not supported."); - - } - // delete cluster - @Override - public void delete(ItemPath thisItem, String path) throws PersistencyException { - StringTokenizer tok = new StringTokenizer(path, "/"); - int pathLength = tok.countTokens(); - if (pathLength != 2) - throw new PersistencyException("Path length was invalid: "+path); - String type = tok.nextToken(); - - if (type.equals(PROPERTY)) { - try { - ldapStore.deleteProperty(thisItem, tok.nextToken()); - } catch (Exception e1) { - Logger.error(e1); - throw new PersistencyException("LDAPClusterStorage - could not delete property"); - } - } - else - throw new PersistencyException("Cluster type "+type+" not supported."); - - } - - /* navigation */ - - // directory listing - @Override - public String[] getClusterContents(ItemPath thisItem, String path) throws PersistencyException { - Logger.msg(6, "LDAPClusterStorage.getClusterContents() - "+thisItem+"/"+path); - StringTokenizer tok = new StringTokenizer(path, "/"); - int pathLength = tok.countTokens(); - if (pathLength > 1) - return new String[0]; - - String type = getClusterType(path); - - try { - if (type.equals(PROPERTY)) - return ldapStore.getPropertyNames(thisItem); - else - if (type.equals("")) { // root query - String[] allClusters = new String[0]; - ArrayList clusterList = new ArrayList(); - if (ldapStore.hasProperties(thisItem)) - clusterList.add(PROPERTY); - allClusters = clusterList.toArray(allClusters); - return allClusters; - } - else - throw new PersistencyException("Cluster type "+type+" not supported."); - } catch (ObjectNotFoundException e) { - throw new PersistencyException("Item "+thisItem+" does not exist"); - } - } -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPLookup.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPLookup.java deleted file mode 100644 index cb4395c..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPLookup.java +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Directory Lookup Service * - * author: Florida Estrella -*/ - -package com.c2kernel.lookup.ldap; - -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.StringTokenizer; - -import org.omg.CORBA.Object; - -import com.c2kernel.common.ObjectAlreadyExistsException; -import com.c2kernel.common.ObjectCannotBeUpdated; -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.entity.proxy.ProxyMessage; -import com.c2kernel.lookup.AgentPath; -import com.c2kernel.lookup.DomainPath; -import com.c2kernel.lookup.InvalidItemPathException; -import com.c2kernel.lookup.ItemPath; -import com.c2kernel.lookup.LookupManager; -import com.c2kernel.lookup.Path; -import com.c2kernel.lookup.RolePath; -import com.c2kernel.process.Gateway; -import com.c2kernel.process.auth.Authenticator; -import com.c2kernel.property.Property; -import com.c2kernel.property.PropertyDescription; -import com.c2kernel.property.PropertyDescriptionList; -import com.c2kernel.utils.Logger; -import com.novell.ldap.LDAPAttribute; -import com.novell.ldap.LDAPAttributeSet; -import com.novell.ldap.LDAPConnection; -import com.novell.ldap.LDAPEntry; -import com.novell.ldap.LDAPException; -import com.novell.ldap.LDAPSearchConstraints; -import com.novell.ldap.LDAPSearchResults; - -/** - * The LDAPLookup object, statically accessible through the Gateway, manages - * the LDAP connection for the cristal process. It provides: - *
    - *
  • Authentication - returning an AgentProxy object if a user has logged in - *
  • System key generation - through the NextKeyManager - *
  • Agent and Role lookup/modification - through the RoleManager - *
  • - * @version $Revision: 1.113 $ $Date: 2006/03/03 13:52:21 $ - * @author $Author: abranson $ - */ - -public class LDAPLookup implements LookupManager{ - - protected LDAPAuthManager mLDAPAuth; - protected LDAPPropertyManager mPropManager; - protected LDAPProperties ldapProps; - - private String mGlobalPath, mRootPath, mLocalPath, mRolePath, mItemTypeRoot, mDomainTypeRoot; - - /** - * - */ - public LDAPLookup() { - super(); - } - - /** - * Initializes the DN paths from the Root, global and local paths supplied by the LDAP properties. - * @param props - */ - protected void initPaths(LDAPProperties props){ - - Logger.msg(8,"LDAPLookup.initPaths(): - initialising with LDAPProperties"); - ldapProps = props; - - mGlobalPath=props.mGlobalPath; - mRootPath=props.mRootPath; - mLocalPath=props.mLocalPath; - - mItemTypeRoot = "cn=entity,"+props.mLocalPath; - mDomainTypeRoot = "cn=domain,"+props.mLocalPath; - mRolePath = "cn=agent,"+mDomainTypeRoot; - } - - /** - * Initializes the LDAPLookup manager with the Gateway properties. - * This should be only done by the Gateway during initialisation. - * - * @param auth A LDAPAuthManager authenticator - */ - @Override - public void open(Authenticator auth) { - if (ldapProps == null) - initPaths(new LDAPProperties(Gateway.getProperties())); - - mLDAPAuth = (LDAPAuthManager)auth; - mPropManager = new LDAPPropertyManager(this, mLDAPAuth); - } - - /** - * Gets the property manager, that is used to read and write cristal properties to the LDAP store. - * @return Returns the global LDAPPropertyManager. - */ - public LDAPPropertyManager getPropManager() { - return mPropManager; - } - - /** - * Disconnects the connection with the LDAP server during shutdown - */ - @Override - public void close() { - Logger.msg(1, "LDAP Lookup: Shutting down LDAP connection."); - if (mLDAPAuth != null) { - mLDAPAuth.disconnect(); - mLDAPAuth = null; - } - } - - /** - * Attempts to resolve the CORBA object for a Path, either directly or through an alias. - * @param path the path to resolve - * @return the CORBA object - * @throws ObjectNotFoundException When the path does not exist - */ - public org.omg.CORBA.Object getIOR(Path path) - throws ObjectNotFoundException - { - return resolveObject(getFullDN(path)); - } - - /** - * Attempts to resolve the CORBA object from the IOR attribute of a DN, either directly or through an alias - * @param dn The String dn - * @throws ObjectNotFoundException when the dn or aliased dn does not exist - */ - private org.omg.CORBA.Object resolveObject(String dn) - throws ObjectNotFoundException - { - Logger.msg(8,"LDAPLookup.resolveObject("+dn+")"); - LDAPEntry anEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(),dn,LDAPSearchConstraints.DEREF_NEVER); - if (anEntry != null) - { - String iorString; - try { - iorString = LDAPLookupUtils.getFirstAttributeValue(anEntry, "ior"); - org.omg.CORBA.Object ior=Gateway.getORB().string_to_object(iorString); - if (ior!=null) - return ior; - else - throw new ObjectNotFoundException("LDAPLookup.resolveObject() - " + dn + " has no IOR"); - } catch (ObjectNotFoundException ex) { - return resolveObject(LDAPLookupUtils.getFirstAttributeValue(anEntry,"aliasedObjectName")); - } - } - else - throw new ObjectNotFoundException("LDAPLookup.resolveObject() LDAP node " + dn + " is not in LDAP or has no IOR."); - } - - /** - * - * @param domPath - * @return - * @throws InvalidItemPathException - * @throws ObjectNotFoundException - */ - @Override - public ItemPath resolvePath(DomainPath domPath) - throws InvalidItemPathException, ObjectNotFoundException { - - LDAPEntry domEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), - getFullDN(domPath), LDAPSearchConstraints.DEREF_ALWAYS); - String entityKey = LDAPLookupUtils.getFirstAttributeValue(domEntry, - "cn"); - Logger.msg(7, "DomainPath " + domPath + " is a reference to " - + entityKey); - String objClass = LDAPLookupUtils.getFirstAttributeValue(domEntry, - "objectClass"); - ItemPath referencedPath = new ItemPath(entityKey); - if (objClass.equals("cristalagent")) - return new AgentPath(referencedPath); - - return referencedPath; - } - - - @Override - public void add(Path path) - throws ObjectCannotBeUpdated, ObjectAlreadyExistsException - { - try { - checkLDAPContext(path); - LDAPAttributeSet attrSet = createAttributeSet(path); - LDAPEntry newEntry = new LDAPEntry(getFullDN(path),attrSet); - LDAPLookupUtils.addEntry(mLDAPAuth.getAuthObject(),newEntry); - if (path instanceof DomainPath) - Gateway.getProxyServer().sendProxyEvent(new ProxyMessage(null, path.toString(), ProxyMessage.ADDED)); - } catch (LDAPException ex) { - if (ex.getResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) - throw new ObjectAlreadyExistsException(ex.getLDAPErrorMessage()); - else - throw new ObjectCannotBeUpdated(ex.getLDAPErrorMessage()); - } - } - - //deletes a node - //throws LDAPexception if node cannot be deleted (eg node is not a leaf) - @Override - public void delete(Path path) throws ObjectCannotBeUpdated - { - try { - LDAPLookupUtils.delete(mLDAPAuth.getAuthObject(),getDN(path)+mLocalPath); - } catch (LDAPException ex) { - throw new ObjectCannotBeUpdated(ex.getLDAPErrorMessage()); - } - if (path instanceof DomainPath) { - Gateway.getProxyServer().sendProxyEvent(new ProxyMessage(null, path.toString(), ProxyMessage.DELETED)); - } - } - - //change specs, add boolean alias leaf context - protected void checkLDAPContext(Path path) - { - String dn = getFullDN(path); - if (!LDAPLookupUtils.exists(mLDAPAuth.getAuthObject(),dn)) - { - String listDN[] = path.getPath(); - String name = "cn="+ path.getRoot() + "," + mLocalPath; - int i=0; - while (i params = new ArrayList(); - for (PropertyDescription propDesc: props.list) { - if (propDesc.getIsClassIdentifier()) - params.add(propDesc.getProperty()); - } - return search(start, params.toArray(new Property[params.size()])); - } - - protected LDAPPathSet search(String startDN, int scope, String filter, LDAPSearchConstraints searchCons) - { - Logger.msg(8,"Searching for "+filter+" in "+startDN); - searchCons.setMaxResults(0); - String[] attr = { LDAPConnection.ALL_USER_ATTRS }; - try - { - LDAPSearchResults res = mLDAPAuth.getAuthObject().search(startDN, scope, - filter,attr,false,searchCons); - return new LDAPPathSet(res, this); - } - catch (LDAPException ex) - { - Logger.error("LDAPException::LDAPLookup::search() " + ex.toString()); - return new LDAPPathSet(this); - } - } - //typically search for (any filter combination) - public LDAPPathSet search(String startDN,String filter) - { - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER); - return search(startDN,LDAPConnection.SCOPE_SUB,filter,searchCons); - } - - @Override - public LDAPPathSet searchAliases(ItemPath entity) { - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER); - return search(getFullDN(new DomainPath()), LDAPConnection.SCOPE_SUB, "(&(objectClass=aliasObject)(aliasedObjectName="+ - LDAPLookupUtils.escapeDN(getFullDN(entity))+"))", searchCons); - } - - @Override - public boolean exists(Path path) { - return LDAPLookupUtils.exists(mLDAPAuth.getAuthObject(), getFullDN(path)); - } - - @Override - public ItemPath getItemPath(String uuid) throws ObjectNotFoundException, InvalidItemPathException { - String[] attr = { LDAPConnection.ALL_USER_ATTRS }; - try { - ItemPath item = new ItemPath(uuid); - LDAPEntry anEntry=mLDAPAuth.getAuthObject().read(getDN(item)+mLocalPath,attr); - String type = LDAPLookupUtils.getFirstAttributeValue(anEntry, "objectClass"); - if (type.equals("cristalentity")) - return item; - else if (type.equals("cristalagent")) - return new AgentPath(item); - else - throw new ObjectNotFoundException("Not an entity"); - - } catch (LDAPException ex) { - if (ex.getResultCode() == LDAPException.NO_SUCH_OBJECT) - throw new ObjectNotFoundException("Entity does not exist"); - Logger.error(ex); - throw new ObjectNotFoundException("Error getting entity class"); - } - } - - /** converts an LDAPentry to a Path object - * Note that the search producing the entry should have retrieved the attrs - * 'ior' and 'uniquemember' - * @throws ObjectNotFoundException - * @throws ObjectNotFoundException - * @throws - */ - protected Path nodeToPath(LDAPEntry entry) throws InvalidItemPathException, ObjectNotFoundException - { - String dn = entry.getDN(); - ItemPath entityKey; - org.omg.CORBA.Object ior; - - // extract syskey - try { - String entityKeyStr = LDAPLookupUtils.getFirstAttributeValue(entry, "cn"); - entityKey = new ItemPath(entityKeyStr); - } catch (ObjectNotFoundException ex) { - entityKey = null; - } catch (InvalidItemPathException ex) { - entityKey = null; - } - - // extract IOR - try { - String stringIOR = LDAPLookupUtils.getFirstAttributeValue(entry,"ior"); - ior = Gateway.getORB().string_to_object(stringIOR); - } catch (ObjectNotFoundException ex) { - ior = null; - } - - /* Find the right path class */ - Path thisPath; - if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalagent")) - { //cristalagent - String agentID = LDAPLookupUtils.getFirstAttributeValue(entry,"uid"); - thisPath = new AgentPath(entityKey, agentID); - } - else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalrole")) - { //cristalrole - thisPath = new RolePath(getPathComponents(dn.substring(0, dn.lastIndexOf(mDomainTypeRoot))), - LDAPLookupUtils.getFirstAttributeValue(entry, "jobList").equals("TRUE")); - } - else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","aliasObject") || - (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalcontext") && dn.endsWith(mDomainTypeRoot))) - { - DomainPath domainPath = new DomainPath(); - domainPath.setPath(getPathComponents(dn.substring(0, dn.lastIndexOf(mDomainTypeRoot)))); - thisPath = domainPath; - } - else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalentity") || - (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalcontext") && dn.endsWith(mItemTypeRoot))) - { - if(dn.endsWith(mItemTypeRoot)) { - if (entityKey == null) throw new InvalidItemPathException(entry.getDN()+" was not a valid itemPath"); - thisPath = entityKey; - } - else - throw new ObjectNotFoundException("Entity found outside entity tree"); - } - else - { - throw new ObjectNotFoundException("Unrecognised LDAP entry. Not a cristal entry"); - } - - //set IOR if we have one - if (ior!=null) thisPath.setIOR(ior); - return thisPath; - } - - public String getDN(Path path) { - StringBuffer dnBuffer = new StringBuffer(); - String[] pathComp = path.getPath(); - for (int i=pathComp.length-1; i>=0; i--) - dnBuffer.append("cn=").append(LDAPLookupUtils.escapeDN(pathComp[i])).append(","); - dnBuffer.append("cn="+path.getRoot()+","); - return dnBuffer.toString(); - } - - public String getFullDN(Path path) { - return getDN(path)+mLocalPath; - } - - public String[] getPathComponents(String dnFragment) { - ArrayList newPath = new ArrayList(); - StringTokenizer tok = new StringTokenizer(dnFragment, ","); - String[] path = new String[tok.countTokens()]; - while (tok.hasMoreTokens()) { - String nextPath = tok.nextToken(); - if (nextPath.indexOf("cn=") == 0) - newPath.add(0, LDAPLookupUtils.unescapeDN(nextPath.substring(3))); - else - break; - } - return newPath.toArray(path); - } - - @Override - public Object resolve(Path path) throws ObjectNotFoundException { - return resolveObject(getFullDN(path)); - } - - @Override - public Iterator getChildren(Path path) { - String filter = "objectclass=*"; - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(10); - searchCons.setDereference(LDAPSearchConstraints.DEREF_FINDING ); - return search(getFullDN(path), LDAPConnection.SCOPE_ONE,filter,searchCons); - } - - protected LDAPAttributeSet createAttributeSet(Path path) throws ObjectCannotBeUpdated { - LDAPAttributeSet attrs = new LDAPAttributeSet(); - - if (path instanceof RolePath) { - RolePath rolePath = (RolePath)path; - attrs.add(new LDAPAttribute("objectclass","cristalrole")); - String jobListString = rolePath.hasJobList()?"TRUE":"FALSE"; - attrs.add(new LDAPAttribute("jobList",jobListString)); - attrs.add(new LDAPAttribute("cn", rolePath.getName())); - } - else if (path instanceof DomainPath) { - DomainPath domPath = (DomainPath)path; - attrs.add(new LDAPAttribute("cn",domPath.getName())); - try { - attrs.add(new LDAPAttribute("aliasedObjectName",getFullDN(domPath.getItemPath()))); - String objectclass_values[] = { "alias", "aliasObject" }; - attrs.add(new LDAPAttribute("objectclass",objectclass_values)); - } catch (ObjectNotFoundException e) { // no entity - is a context - attrs.add(new LDAPAttribute("objectclass","cristalcontext")); - } - } - - else if (path instanceof ItemPath) { - ItemPath itemPath = (ItemPath)path; - attrs.add(new LDAPAttribute("cn", itemPath.getUUID().toString())); - if (itemPath.getIOR() != null) - attrs.add(new LDAPAttribute("ior", Gateway.getORB().object_to_string(itemPath.getIOR()))); - - if (path instanceof AgentPath) { - AgentPath agentPath = (AgentPath)path; - attrs.add(new LDAPAttribute("objectclass","cristalagent")); - - String agentName = agentPath.getAgentName(); - if (agentName != null && agentName.length() > 0) - attrs.add(new LDAPAttribute("uid", agentName)); - else - throw new ObjectCannotBeUpdated("Cannot create agent. No userId specified"); - - String agentPass = agentPath.getPassword(); - if (agentPass != null && agentPass.length() > 0) - try { - attrs.add(new LDAPAttribute("userPassword", AgentPath.generateUserPassword(agentPass, "SHA"))); - } catch (NoSuchAlgorithmException ex) { - throw new ObjectCannotBeUpdated("Cryptographic libraries for password hashing not found."); - } - else - throw new ObjectCannotBeUpdated("Cannot create agent. No password given"); - } - else { - attrs.add(new LDAPAttribute("objectclass","cristalentity")); - } - } - - return attrs; - - } - - //Creates a cristalRole - //CristalRole is-a specialized CristalContext which contains multi-valued uniqueMember attribute pointing to cristalagents - @Override - public RolePath createRole(RolePath rolePath) - throws ObjectAlreadyExistsException, ObjectCannotBeUpdated - { - - // create the role - String roleDN = getFullDN(rolePath); - LDAPEntry roleNode; - try - { - roleNode = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(rolePath)); - throw new ObjectAlreadyExistsException(); - } catch (ObjectNotFoundException ex) { } - - //create CristalRole if it does not exist - roleNode = new LDAPEntry(roleDN, createAttributeSet(rolePath)); - try { - LDAPLookupUtils.addEntry(mLDAPAuth.getAuthObject(),roleNode); - } catch (LDAPException e) { - throw new ObjectCannotBeUpdated(e.getLDAPErrorMessage()); - } - return rolePath; - - - } - public void deleteRole(RolePath role) throws ObjectNotFoundException, ObjectCannotBeUpdated { - try { - LDAPLookupUtils.delete(mLDAPAuth.getAuthObject(), getFullDN(role)); - } catch (LDAPException ex) { - throw new ObjectCannotBeUpdated("Could not remove role"); - } - } - - @Override - public void addRole(AgentPath agent, RolePath role) - throws ObjectCannotBeUpdated, ObjectNotFoundException - { - LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); - //add memberDN to uniqueMember if it is not yet a member - if (!LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", getFullDN(agent))) - LDAPLookupUtils.addAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "uniqueMember", getFullDN(agent)); - else - throw new ObjectCannotBeUpdated("Agent " + agent.getAgentName() + " already has role " + role.getName()); - } - - @Override - public void removeRole(AgentPath agent, RolePath role) - throws ObjectCannotBeUpdated, ObjectNotFoundException - { - LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); - if (LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", getFullDN(agent))) - LDAPLookupUtils.removeAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "uniqueMember", getFullDN(agent)); - else - throw new ObjectCannotBeUpdated("Agent did not have that role"); - } - - @Override - public boolean hasRole(AgentPath agent, RolePath role) { - String filter = "(&(objectclass=cristalrole)(uniqueMember="+getFullDN(agent)+")(cn="+role.getName()+"))"; - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); - return search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons).hasNext(); - } - - @Override - public AgentPath[] getAgents(RolePath role) - throws ObjectNotFoundException - { - //get the roleDN entry, and its uniqueMember entry pointing to - LDAPEntry roleEntry; - try { - roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); - } catch (ObjectNotFoundException e) { - throw new ObjectNotFoundException("Role does not exist"); - } - - String[] res = LDAPLookupUtils.getAllAttributeValues(roleEntry,"uniqueMember"); - ArrayList agents = new ArrayList(); - for (String userDN : res) { - try { - LDAPEntry userEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), userDN); - AgentPath path = (AgentPath)nodeToPath(userEntry); - agents.add(path); - } catch (ObjectNotFoundException ex) { - Logger.error("Agent "+userDN+" does not exist"); - } catch (InvalidItemPathException ex) { - Logger.error("Agent "+userDN+" is not a valid entity"); - } - } - AgentPath[] usersList = new AgentPath[0]; - usersList = agents.toArray(usersList); - return usersList; - } - - //returns the role/s of a user - @Override - public RolePath[] getRoles(AgentPath agentPath) - { - //search the mDomainPath tree uniqueMember=userDN - //filter = objectclass=cristalrole AND uniqueMember=userDN - String filter = "(&(objectclass=cristalrole)(uniqueMember="+getFullDN(agentPath)+"))"; - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); - Iterator roles = search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons); - ArrayList roleList = new ArrayList(); - - while(roles.hasNext()) - { - RolePath path = (RolePath) roles.next(); - roleList.add(path); - } - RolePath[] roleArr = new RolePath[roleList.size()]; - roleArr = roleList.toArray(roleArr); - return roleArr; - } - - /** - * Utility for looking up a login name - * - * @param ld - * @param agentName - * @param baseDN - * @return - * @throws ObjectNotFoundException - */ - @Override - public AgentPath getAgentPath(String agentName) throws ObjectNotFoundException - { - //search to get the userDN equivalent of the userID - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); - String filter = "(&(objectclass=cristalagent)(uid="+agentName+"))"; - Iterator res = search(mItemTypeRoot,LDAPConnection.SCOPE_SUB,filter,searchCons); - if (!res.hasNext()) - throw new ObjectNotFoundException("Agent not found: "+agentName); - Path result = res.next(); - if (result instanceof AgentPath) - return (AgentPath)result; - else - throw new ObjectNotFoundException("Entry was not an Agent"); - } - - @Override - public RolePath getRolePath(String roleName) throws ObjectNotFoundException - { - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); - String filter = "(&(objectclass=cristalrole)(cn="+roleName+"))"; - Iterator res = search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons); - if (!res.hasNext()) - throw new ObjectNotFoundException("Role not found"); - Path result = res.next(); - if (result instanceof RolePath) - return (RolePath)result; - else - throw new ObjectNotFoundException("Entry was not a Role"); - } - - @Override - public void setHasJobList(RolePath role, boolean hasJobList) throws ObjectNotFoundException, ObjectCannotBeUpdated { - // get entry - LDAPEntry roleEntry; - try { - roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); - } catch (ObjectNotFoundException e) { - throw new ObjectNotFoundException("Role does not exist"); - } - // set attribute - LDAPLookupUtils.setAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "jobList", hasJobList?"TRUE":"FALSE"); - } - - @Override - public void setAgentPassword(AgentPath agent, String newPassword) throws ObjectNotFoundException, ObjectCannotBeUpdated, NoSuchAlgorithmException { - String encPasswd = AgentPath.generateUserPassword(newPassword, "SHA"); - LDAPEntry agentEntry; - try { - agentEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(agent)); - } catch (ObjectNotFoundException e) { - throw new ObjectNotFoundException("Agent "+agent.getAgentName()+" does not exist"); - } - LDAPLookupUtils.setAttributeValue(mLDAPAuth.getAuthObject(), agentEntry, "userPassword", encPasswd); - - } - - @Override - public String getAgentName(AgentPath agentPath) - throws ObjectNotFoundException { - LDAPEntry agentEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(agentPath)); - return LDAPLookupUtils.getFirstAttributeValue(agentEntry,"uid"); - } - -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPLookupUtils.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPLookupUtils.java deleted file mode 100644 index ad41e7a..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPLookupUtils.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Lookup helper class. - */ - -package com.c2kernel.lookup.ldap; - -//import netscape.ldap.*; -//import netscape.ldap.util.*; -import com.c2kernel.common.ObjectAlreadyExistsException; -import com.c2kernel.common.ObjectCannotBeUpdated; -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.utils.Logger; -import com.novell.ldap.LDAPAttribute; -import com.novell.ldap.LDAPAttributeSet; -import com.novell.ldap.LDAPConnection; -import com.novell.ldap.LDAPDN; -import com.novell.ldap.LDAPEntry; -import com.novell.ldap.LDAPException; -import com.novell.ldap.LDAPModification; -import com.novell.ldap.LDAPSearchConstraints; -import com.novell.ldap.LDAPSearchResults; - -/** - * @version $Revision: 1.74 $ $Date: 2006/03/03 13:52:21 $ - * @author $Author: abranson $ - */ - -final public class LDAPLookupUtils -{ - static final char[] META_CHARS = {'+', '=', '"', ',', '<', '>', ';', '/'}; - static final String[] META_ESCAPED = {"2B", "3D", "22", "2C", "3C", "3E", "3B", "2F"}; - static public LDAPEntry getEntry(LDAPConnection ld, String dn,int dereference) - throws ObjectNotFoundException - { - try { - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setBatchSize(0); - searchCons.setDereference(dereference); - LDAPEntry thisEntry = ld.read(dn,searchCons); - if (thisEntry != null) return thisEntry; - } catch (LDAPException ex) { - throw new ObjectNotFoundException("LDAP Exception for dn:"+dn+": \n"+ex.getMessage()); - } - throw new ObjectNotFoundException(dn+" does not exist"); - - } - - - /** - * Utility method to connect to an LDAP server - * @param lp LDAP properties to connect with - * @return a novell LDAPConnection object - * @throws LDAPException when the connection was unsuccessful - */ - public static LDAPConnection createConnection(LDAPProperties lp) throws LDAPException { - LDAPConnection ld = new LDAPConnection(); - - Logger.msg(3, "LDAPLookup - connecting to " + lp.mHost); - ld.connect(lp.mHost, Integer.valueOf(lp.mPort).intValue()); - - Logger.msg(3, "LDAPLookup - authenticating user:" + lp.mUser); - ld.bind( LDAPConnection.LDAP_V3, lp.mUser, - String.valueOf(lp.mPassword).getBytes()); - - Logger.msg(3, "LDAPLookup - authentication successful"); - LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); - searchCons.setMaxResults(0); - ld.setConstraints(searchCons); - - return ld; - } - - //Given a DN, return an LDAP Entry - static public LDAPEntry getEntry(LDAPConnection ld, String dn) - throws ObjectNotFoundException - { - return getEntry(ld, dn, LDAPSearchConstraints.DEREF_NEVER); - } - - static public String getFirstAttributeValue(LDAPEntry anEntry, String attribute) throws ObjectNotFoundException - { - LDAPAttribute attr = anEntry.getAttribute(attribute); - if (attr==null) - throw new ObjectNotFoundException("No attributes named '"+attribute+"'"); - return (String)attr.getStringValues().nextElement(); - } - - static public String[] getAllAttributeValues(LDAPEntry anEntry, String attribute) throws ObjectNotFoundException - { - LDAPAttribute attr = anEntry.getAttribute(attribute); - if (attr!=null) - return attr.getStringValueArray(); - - throw new ObjectNotFoundException("No attributes named '"+attribute+"'"); - - } - - static public boolean existsAttributeValue(LDAPEntry anEntry, String attribute, String value) - { - LDAPAttribute attr = anEntry.getAttribute(attribute); - if (attr!=null) - { - String[] attrValues = new String[attr.size()]; - attrValues = attr.getStringValueArray(); - for (int i=0;i { - LDAPSearchResults results; - LDAPEntry nextEntry; - LDAPLookup ldap; - - public LDAPPathSet(LDAPLookup ldap) { // empty - this.ldap = ldap; - results = null; - } - - public LDAPPathSet(LDAPSearchResults results, LDAPLookup ldap) { - this.ldap = ldap; - this.results = results; - } - - @Override - public boolean hasNext() { - if (results == null) return false; - if (nextEntry != null) return true; - if (results.hasMore()) - try { - nextEntry = results.next(); - return true; - } catch (LDAPException ex) { - if (ex.getResultCode()!=32) {// no results - Logger.error(ex); - Logger.error("Error loading LDAP result set: "+ex.getMessage()); - } - } - return false; - } - - @Override - public Path next() { - if (results == null) return null; - try { - if (nextEntry == null) - nextEntry = results.next(); - Path nextPath = ldap.nodeToPath(nextEntry); - nextEntry = null; - return nextPath; - } catch (Exception ex) { - Logger.error("Error loading next path"); - Logger.error(ex); - nextEntry = null; - if (hasNext()) { - Logger.error("Skipping to next entry"); - return next(); - } - else - return null; - } - } - - @Override - public void remove() { - // do nothing - - } -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPProperties.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPProperties.java deleted file mode 100644 index 289b206..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPProperties.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.c2kernel.lookup.ldap; - -/** - * Directory Lookup Service - * - * This represent - * - */ - -import javax.xml.bind.DatatypeConverter; - -import com.c2kernel.utils.ObjectProperties; - -/** - * example: - * - *
    - * # LDAP Lookup config
    - * # use the ApacheDS 2.0.0 M15 available using the port 10389
    - * LDAP.GlobalPath=dc=cristalosgiglobal
    - * LDAP.RootPath=cn=cristalosgiroot
    - * LDAP.LocalPath=cn=cristalosgilocal
    - * LDAP.port=10389
    - * LDAP.host=localhost
    - * LDAP.user=uid=admin,ou=system
    - * LDAP.password=xxxxxx
    - * or
    - * LDAP.password64=xxxxxx
    - * 
    - * - * @version $Revision: 1.16 $ $Date: 2005/10/12 12:51:54 $ - * @author $Author: abranson $ - * @author ogattaz - */ -public class LDAPProperties { - - private static final String BAD_PASSWORD_MESSAGE = "bad base64 password value"; - - public static final String LDAP_PROP_GPATH = "LDAP.GlobalPath"; - public static final String LDAP_PROP_HOST = "LDAP.host"; - public static final String LDAP_PROP_LPATH = "LDAP.LocalPath"; - public static final String LDAP_PROP_PASS = "LDAP.password"; - public static final String LDAP_PROP_PASS64 = "LDAP.password64"; - public static final String LDAP_PROP_PORT = "LDAP.port"; - public static final String LDAP_PROP_RPATH = "LDAP.RootPath"; - public static final String LDAP_PROP_USER = "LDAP.user"; - - public String mGlobalPath = null; // o=cern.ch - public String mHost = null; - public String mLocalPath = null; // cn=lab27 - public String mPassword = null; - public Integer mPort = null; - public String mRootPath = null; // cn=cristal2 - public String mUser = null; - - /** - * @param aObjectProps - * an ObjectProperties instance comming from clc file for exemple - */ - public LDAPProperties(final ObjectProperties aObjectProps) { - - if (aObjectProps != null) { - - mGlobalPath = aObjectProps.getProperty(LDAP_PROP_GPATH); - - mRootPath = aObjectProps.getProperty(LDAP_PROP_RPATH); - if (mRootPath != null) { - mRootPath += "," + mGlobalPath; - } - - mLocalPath = aObjectProps.getProperty(LDAP_PROP_LPATH); - if (mLocalPath != null) { - mLocalPath += "," + mRootPath; - } - - mPort = aObjectProps.getInt(LDAP_PROP_PORT, 389); - mHost = aObjectProps.getProperty(LDAP_PROP_HOST); - mUser = aObjectProps.getProperty(LDAP_PROP_USER); - mPassword = aObjectProps.getProperty(LDAP_PROP_PASS); - - // if raw password not available, try to find base64 one - if (mPassword == null) { - mPassword = aObjectProps.getProperty(LDAP_PROP_PASS64); - // if base64 password available - if (mPassword != null) { - mPassword = translateBase64OPassword(mPassword); - } - } - } - } - - /** - * @param aPropertyName - * the name of the property associated to the member - * @param aMemberValue - * the value to check - * @return true if valid - * @throws IllegalArgumentException - * if not valid - */ - private boolean checkMemberValidity(final String aPropertyName, - final String aMemberValue) throws IllegalArgumentException { - - if (isMemberValueValid(aMemberValue)) - return true; - - throw new IllegalArgumentException(String.format( - "The LDAP property [%s] is not valid. The member value=[%s]", - aPropertyName, aMemberValue)); - } - - /** - * @param aValue - * the value to be checked - * @return true if not null and not empty - */ - private boolean checkPasswordValidity(final String aPasswordValue) - throws IllegalArgumentException { - - if (checkMemberValidity(LDAP_PROP_PASS, aPasswordValue)) { - - if (aPasswordValue.contains(BAD_PASSWORD_MESSAGE)) { - throw new IllegalArgumentException( - String.format( - "The LDAP property [%s] is not valid. The member value=[%s]", - LDAP_PROP_PASS, aPasswordValue)); - } - } - return true; - } - - /** - * @return true is valid - * @throws IllegalArgumentException - * if one of the members is not valid (null or empty) - */ - public boolean checkValidity() throws IllegalArgumentException { - - return checkMemberValidity(LDAP_PROP_GPATH, mGlobalPath) - && checkMemberValidity(LDAP_PROP_RPATH, mRootPath) - && checkMemberValidity(LDAP_PROP_LPATH, mLocalPath) - && checkMemberValidity(LDAP_PROP_HOST, mHost) - && checkMemberValidity(LDAP_PROP_USER, mUser) - && checkPasswordValidity(mPassword); - } - - /** - * @param aValue - * the value to be checked - * @return true if not null and not empty - */ - private boolean isMemberValueValid(final String aValue) { - - return (aValue != null && !aValue.isEmpty()); - } - - /** - * @return true if the password is not null, not empty and is decoded id the - * passed property is a password64 one - */ - public boolean isPasswordValid() { - try { - return checkPasswordValidity(mPassword); - } catch (IllegalArgumentException ex) { - return false; - } - } - - /** - * @param aBase6Password - * the encoded password - * @return the decodded password or a dummy phrase which cause an explicit - * error when it will be used during the connection - */ - private String translateBase64OPassword(final String aBase6Password) { - - try { - // DatatypeConverter tool class available since java 1.5. - // Throws IllegalArgumentException if value not conform - return new String( - DatatypeConverter.parseBase64Binary(aBase6Password)); - - } catch (IllegalArgumentException ex) { - return String.format("#### %s [%s] ####", BAD_PASSWORD_MESSAGE, - aBase6Password); - } - } -} diff --git a/src/main/java/com/c2kernel/lookup/ldap/LDAPPropertyManager.java b/src/main/java/com/c2kernel/lookup/ldap/LDAPPropertyManager.java deleted file mode 100644 index 48e0a8e..0000000 --- a/src/main/java/com/c2kernel/lookup/ldap/LDAPPropertyManager.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.c2kernel.lookup.ldap; - -import java.util.ArrayList; -import java.util.Enumeration; - -import com.c2kernel.common.ObjectCannotBeUpdated; -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.lookup.ItemPath; -import com.c2kernel.property.Property; -import com.c2kernel.utils.Logger; -import com.novell.ldap.LDAPAttribute; -import com.novell.ldap.LDAPEntry; - -/************************************************************************** - * - * $Revision: 1.3 $ - * $Date: 2006/03/03 13:52:21 $ - * - * Copyright (C) 2003 CERN - European Organization for Nuclear Research - * All rights reserved. - **************************************************************************/ - -public class LDAPPropertyManager { - /** - * - */ - protected final LDAPLookup ldap; - protected final LDAPAuthManager auth; - - public LDAPPropertyManager(LDAPLookup ldap, LDAPAuthManager auth) { - super(); - this.ldap = ldap; - this.auth = auth; - } - - /** - * @param thisItem - EntityPath of the subject entity - * @return - * @throws ObjectNotFoundException - */ - public boolean hasProperties(ItemPath thisItem) throws ObjectNotFoundException { - LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); - return entityEntry.getAttribute("cristalprop") != null; - } - - /** - * @param thisItem - EntityPath of the subject entity - * @return array of Property - * @throws ObjectNotFoundException - */ - public String[] getPropertyNames(ItemPath thisItem) throws ObjectNotFoundException { - LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); - ArrayList propbag = new ArrayList(); - LDAPAttribute props = entityEntry.getAttribute("cristalprop"); - for (Enumeration e = props.getStringValues(); e.hasMoreElements();) { - String thisProp = (String)e.nextElement(); - String thisName = thisProp.substring(0, thisProp.indexOf(':')); - if (thisName.startsWith("!") && thisName.length()>1) thisName = thisName.substring(1); - propbag.add(thisName); - } - - String[] retArr = new String[props.size()]; - return propbag.toArray(retArr); - } - - /** - * @param thisItem - EntityPath of the subject entity - * @param propName - the name of the property to retrieve - * @return The Property object - * @throws ObjectNotFoundException - */ - public Property getProperty(ItemPath thisItem, String name) throws ObjectNotFoundException { - LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); - return getProperty(entityEntry, name); - } - - /** - * @param thisItem - EntityPath of the subject entity - * @param name - the property name to delete - * @throws ObjectNotFoundException - * @throws ObjectCannotBeUpdated - */ - public void deleteProperty(ItemPath thisItem, String name) throws ObjectNotFoundException, ObjectCannotBeUpdated { - LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); - Property prop = getProperty(entityEntry, name); - Logger.msg(6, "LDAPLookupUtils.deleteProperty("+name+") - Deleting property"); - LDAPLookupUtils.removeAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(prop)); - } - - private static String getPropertyAttrValue(Property prop) { - return (prop.isMutable()?"":"!")+prop.getName()+":"+prop.getValue(); - } - - /** - * @param thisItem - EntityPath of the subject entity - * @param prop - the property to store - * @throws ObjectNotFoundException - * @throws ObjectCannotBeUpdated - */ - public void setProperty(ItemPath thisItem, Property prop) throws ObjectNotFoundException, ObjectCannotBeUpdated { - LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); - try { - Property oldProp = getProperty(entityEntry, prop.getName()); - Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - Removing old value '"+oldProp.getValue()+"'"); - LDAPLookupUtils.removeAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(oldProp)); - } catch (ObjectNotFoundException ex) { - Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - creating new property."); - } - Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - setting to '"+prop.getValue()+"'"); - LDAPLookupUtils.addAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(prop)); - } - - public static Property getProperty(LDAPEntry myEntry, String propName) throws ObjectNotFoundException { - // delete existing props - LDAPAttribute props = myEntry.getAttribute("cristalprop"); - if (props == null) - throw new ObjectNotFoundException("Property "+propName+" does not exist"); - String propPrefix = propName+":"; - String roPropPrefix = "!"+propPrefix; - String val = null, name = null; boolean mutable = false; - for (Enumeration e = props.getStringValues(); name==null && e.hasMoreElements();) { - String attrVal = (String)e.nextElement(); - if (attrVal.toLowerCase().startsWith(propPrefix.toLowerCase())) { - name = attrVal.substring(0, propPrefix.length()-1); - val = attrVal.substring(propPrefix.length()); - mutable = true; break; - } - - if (attrVal.toLowerCase().startsWith(roPropPrefix.toLowerCase())) { - name = attrVal.substring(1, roPropPrefix.length()-1); - val = attrVal.substring(roPropPrefix.length()); - mutable = false; break; - } - } - if (name == null) - throw new ObjectNotFoundException("Property "+propName+" does not exist"); - Logger.msg(6, "Loaded "+(mutable?"":"Non-")+"Mutable Property: "+name+"="+val); - return new Property(name, val, mutable); - } - -} diff --git a/src/main/java/com/c2kernel/persistency/LDAPClientReader.java b/src/main/java/com/c2kernel/persistency/LDAPClientReader.java deleted file mode 100644 index 4458ac6..0000000 --- a/src/main/java/com/c2kernel/persistency/LDAPClientReader.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.c2kernel.persistency; - -/** - * Provided for easier loading (may be referenced without package in ClusterStorage property) - * - * @author abranson - * - */ -public class LDAPClientReader extends com.c2kernel.lookup.ldap.LDAPClientReader { - - public LDAPClientReader() { - super(); - } - -} diff --git a/src/main/java/com/c2kernel/persistency/LDAPClusterStorage.java b/src/main/java/com/c2kernel/persistency/LDAPClusterStorage.java deleted file mode 100644 index 005c6e8..0000000 --- a/src/main/java/com/c2kernel/persistency/LDAPClusterStorage.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.c2kernel.persistency; - -/** - * Provided for easier loading (may be referenced without package in ClusterStorage property) - * - * @author abranson - * - */ -public class LDAPClusterStorage extends com.c2kernel.lookup.ldap.LDAPClusterStorage { - - public LDAPClusterStorage() { - super(); - } -} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPAuthManager.java b/src/main/java/org/cristalise/lookup/ldap/LDAPAuthManager.java new file mode 100644 index 0000000..0dfa010 --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPAuthManager.java @@ -0,0 +1,100 @@ +package org.cristalise.lookup.ldap; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.process.Gateway; +import org.cristalise.kernel.process.auth.Authenticator; +import org.cristalise.kernel.utils.Logger; + +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPException; + +public class LDAPAuthManager implements Authenticator { + + protected LDAPConnection mLDAPConn; + protected LDAPProperties ldapProps; + + + @Override + public boolean authenticate(String agentName, + String password, String resource) throws InvalidDataException, ObjectNotFoundException { + + ldapProps = new LDAPProperties(Gateway.getProperties()); + + if (ldapProps.mHost!=null && ldapProps.mPort!= null && ldapProps.mLocalPath!=null ) + { + try { // anonymously bind to LDAP and find the agent entry for the username + ldapProps.mUser = ""; + ldapProps.mPassword = ""; + mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); + LDAPLookup anonLookup = new LDAPLookup(); + anonLookup.initPaths(ldapProps); + anonLookup.open(this); + String agentDN = anonLookup.getFullDN(anonLookup.getAgentPath(agentName)); + + //found agentDN, try to log in with it + ldapProps.mUser = agentDN; + ldapProps.mPassword = password; + mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); + return true; + } catch (LDAPException e) { + return false; + } + } + else + { + throw new InvalidDataException("Cannot log in. Some connection properties are not set."); + } + + } + + @Override + public boolean authenticate(String resource) throws InvalidDataException, ObjectNotFoundException { + ldapProps = new LDAPProperties(Gateway.getProperties()); + + if (ldapProps.mUser == null || ldapProps.mUser.length()==0 || + ldapProps.mPassword == null || ldapProps.mPassword.length()==0) + throw new InvalidDataException("LDAP root user properties not found in config."); + try { + mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); + return true; + } catch (LDAPException e) { + return false; + } + } + + /* (non-Javadoc) + * @see org.cristalise.kernel.process.auth.Authenticator#getAuthObject() + */ + @Override + public LDAPConnection getAuthObject() { + + if (mLDAPConn==null || !mLDAPConn.isConnected()) { + Logger.warning("LDAPAuthManager - lost connection to LDAP server. Attempting to reconnect."); + try { + mLDAPConn = LDAPLookupUtils.createConnection(ldapProps); + } catch (LDAPException ex) { } + } + return mLDAPConn; + } + + @Override + public void disconnect() { + Logger.msg(1, "LDAP Lookup: Shutting down LDAP connection."); + if (mLDAPConn != null) { + try { + mLDAPConn.disconnect(); + } catch (LDAPException e) { + Logger.error(e); + } + mLDAPConn = null; + } + + } + + public LDAPAuthManager() { + // TODO Auto-generated constructor stub + } + + +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPClientReader.java b/src/main/java/org/cristalise/lookup/ldap/LDAPClientReader.java new file mode 100644 index 0000000..fd62699 --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPClientReader.java @@ -0,0 +1,46 @@ +package org.cristalise.lookup.ldap; + +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.C2KLocalObject; +import org.cristalise.kernel.lookup.ItemPath; + + +/** Allows clients to directly load properties and collections from the LDAP +* so no CORBA calls need to be made during normal browsing +*/ + +public class LDAPClientReader extends LDAPClusterStorage { + // return all readwrite support as readonly + @Override + public short queryClusterSupport(String clusterType) { + return (short)(super.queryClusterSupport(clusterType) & READ); + } + + + /** + * @see org.cristalise.kernel.persistency.ClusterStorage#delete(Integer, String) + */ + @Override + public void delete(ItemPath itemPath, String path) + throws PersistencyException { + throw new PersistencyException("Writing not supported in ClientReader"); + } + + /** + * @see org.cristalise.kernel.persistency.ClusterStorage#getName() + */ + @Override + public String getName() { + return "LDAP Client Cluster Reader"; + } + + /** + * @see org.cristalise.kernel.persistency.ClusterStorage#put(Integer, String, C2KLocalObject) + */ + + public void put(ItemPath itemPath, String path, C2KLocalObject obj) + throws PersistencyException { + throw new PersistencyException("Writing not supported in ClientReader"); + } + +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPClusterStorage.java b/src/main/java/org/cristalise/lookup/ldap/LDAPClusterStorage.java new file mode 100644 index 0000000..7132116 --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPClusterStorage.java @@ -0,0 +1,152 @@ +package org.cristalise.lookup.ldap; +import java.util.ArrayList; +import java.util.StringTokenizer; + +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.C2KLocalObject; +import org.cristalise.kernel.lookup.ItemPath; +import org.cristalise.kernel.lookup.Lookup; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.process.Gateway; +import org.cristalise.kernel.process.auth.Authenticator; +import org.cristalise.kernel.property.Property; +import org.cristalise.kernel.utils.Logger; + + +public class LDAPClusterStorage extends ClusterStorage { + LDAPPropertyManager ldapStore; + + @Override + public void open(Authenticator auth) throws PersistencyException { + Lookup lookup = Gateway.getLookup(); + if (lookup instanceof LDAPLookup) + ldapStore = ((LDAPLookup)lookup).getPropManager(); + else + throw new PersistencyException("Cannot use LDAP cluster storage without LDAP Lookup"); + + } + + @Override + public void close() throws PersistencyException { + } + + // introspection + @Override + public short queryClusterSupport(String clusterType) { + if (clusterType.equals(PROPERTY)) + return READWRITE; + else + return NONE; + } + + @Override + public String getName() { + return "LDAP Cluster Storage"; + } + + @Override + public String getId() { + return "LDAP"; + } + + // retrieve object by path + @Override + public C2KLocalObject get(ItemPath thisItem, String path) throws PersistencyException { + Logger.msg(6, "LDAPClusterStorage.get() - "+thisItem+"/"+path); + StringTokenizer tok = new StringTokenizer(path, "/"); + int pathLength = tok.countTokens(); + if (pathLength != 2) + throw new PersistencyException("Path length was invalid: "+path); + String type = tok.nextToken(); + + String objName = tok.nextToken(); + C2KLocalObject newObj; + + if (type.equals(PROPERTY)) { + try { + Property newProperty = ldapStore.getProperty(thisItem, objName); + newObj = newProperty; + } catch (ObjectNotFoundException ex) { + throw new PersistencyException("Property "+objName+" not found in "+thisItem); + } + + } + else + throw new PersistencyException("Cluster type "+type+" not supported."); + + return newObj; + } + // store object by path + @Override + public void put(ItemPath thisItem, C2KLocalObject obj) throws PersistencyException { + Logger.msg(6, "LDAPClusterStorage.put() - "+thisItem+"/"+ClusterStorage.getPath(obj)); + + String type = obj.getClusterType(); + + if (type.equals(PROPERTY)) { + try { + ldapStore.setProperty(thisItem, (Property)obj); + } catch (Exception e1) { + Logger.error(e1); + throw new PersistencyException("LDAPClusterStorage - could not write property"); + } + } + else + throw new PersistencyException("Cluster type "+type+" not supported."); + + } + // delete cluster + @Override + public void delete(ItemPath thisItem, String path) throws PersistencyException { + StringTokenizer tok = new StringTokenizer(path, "/"); + int pathLength = tok.countTokens(); + if (pathLength != 2) + throw new PersistencyException("Path length was invalid: "+path); + String type = tok.nextToken(); + + if (type.equals(PROPERTY)) { + try { + ldapStore.deleteProperty(thisItem, tok.nextToken()); + } catch (Exception e1) { + Logger.error(e1); + throw new PersistencyException("LDAPClusterStorage - could not delete property"); + } + } + else + throw new PersistencyException("Cluster type "+type+" not supported."); + + } + + /* navigation */ + + // directory listing + @Override + public String[] getClusterContents(ItemPath thisItem, String path) throws PersistencyException { + Logger.msg(6, "LDAPClusterStorage.getClusterContents() - "+thisItem+"/"+path); + StringTokenizer tok = new StringTokenizer(path, "/"); + int pathLength = tok.countTokens(); + if (pathLength > 1) + return new String[0]; + + String type = getClusterType(path); + + try { + if (type.equals(PROPERTY)) + return ldapStore.getPropertyNames(thisItem); + else + if (type.equals("")) { // root query + String[] allClusters = new String[0]; + ArrayList clusterList = new ArrayList(); + if (ldapStore.hasProperties(thisItem)) + clusterList.add(PROPERTY); + allClusters = clusterList.toArray(allClusters); + return allClusters; + } + else + throw new PersistencyException("Cluster type "+type+" not supported."); + } catch (ObjectNotFoundException e) { + throw new PersistencyException("Item "+thisItem+" does not exist"); + } + } +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPLookup.java b/src/main/java/org/cristalise/lookup/ldap/LDAPLookup.java new file mode 100644 index 0000000..d954783 --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPLookup.java @@ -0,0 +1,753 @@ +/* + * Directory Lookup Service * + * author: Florida Estrella +*/ + +package org.cristalise.lookup.ldap; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.StringTokenizer; + +import org.cristalise.kernel.common.ObjectAlreadyExistsException; +import org.cristalise.kernel.common.ObjectCannotBeUpdated; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.entity.proxy.ProxyMessage; +import org.cristalise.kernel.lookup.AgentPath; +import org.cristalise.kernel.lookup.DomainPath; +import org.cristalise.kernel.lookup.InvalidItemPathException; +import org.cristalise.kernel.lookup.ItemPath; +import org.cristalise.kernel.lookup.LookupManager; +import org.cristalise.kernel.lookup.Path; +import org.cristalise.kernel.lookup.RolePath; +import org.cristalise.kernel.process.Gateway; +import org.cristalise.kernel.process.auth.Authenticator; +import org.cristalise.kernel.property.Property; +import org.cristalise.kernel.property.PropertyDescription; +import org.cristalise.kernel.property.PropertyDescriptionList; +import org.cristalise.kernel.utils.Logger; +import org.omg.CORBA.Object; + +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPSearchConstraints; +import com.novell.ldap.LDAPSearchResults; + +/** + * The LDAPLookup object, statically accessible through the Gateway, manages + * the LDAP connection for the cristal process. It provides: + *
      + *
    • Authentication - returning an AgentProxy object if a user has logged in + *
    • System key generation - through the NextKeyManager + *
    • Agent and Role lookup/modification - through the RoleManager + *
    • + * @version $Revision: 1.113 $ $Date: 2006/03/03 13:52:21 $ + * @author $Author: abranson $ + */ + +public class LDAPLookup implements LookupManager{ + + protected LDAPAuthManager mLDAPAuth; + protected LDAPPropertyManager mPropManager; + protected LDAPProperties ldapProps; + + private String mGlobalPath, mRootPath, mLocalPath, mRolePath, mItemTypeRoot, mDomainTypeRoot; + + /** + * + */ + public LDAPLookup() { + super(); + } + + /** + * Initializes the DN paths from the Root, global and local paths supplied by the LDAP properties. + * @param props + */ + protected void initPaths(LDAPProperties props){ + + Logger.msg(8,"LDAPLookup.initPaths(): - initialising with LDAPProperties"); + ldapProps = props; + + mGlobalPath=props.mGlobalPath; + mRootPath=props.mRootPath; + mLocalPath=props.mLocalPath; + + mItemTypeRoot = "cn=entity,"+props.mLocalPath; + mDomainTypeRoot = "cn=domain,"+props.mLocalPath; + mRolePath = "cn=agent,"+mDomainTypeRoot; + } + + /** + * Initializes the LDAPLookup manager with the Gateway properties. + * This should be only done by the Gateway during initialisation. + * + * @param auth A LDAPAuthManager authenticator + */ + @Override + public void open(Authenticator auth) { + if (ldapProps == null) + initPaths(new LDAPProperties(Gateway.getProperties())); + + mLDAPAuth = (LDAPAuthManager)auth; + mPropManager = new LDAPPropertyManager(this, mLDAPAuth); + } + + /** + * Gets the property manager, that is used to read and write cristal properties to the LDAP store. + * @return Returns the global LDAPPropertyManager. + */ + public LDAPPropertyManager getPropManager() { + return mPropManager; + } + + /** + * Disconnects the connection with the LDAP server during shutdown + */ + @Override + public void close() { + Logger.msg(1, "LDAP Lookup: Shutting down LDAP connection."); + if (mLDAPAuth != null) { + mLDAPAuth.disconnect(); + mLDAPAuth = null; + } + } + + /** + * Attempts to resolve the CORBA object for a Path, either directly or through an alias. + * @param path the path to resolve + * @return the CORBA object + * @throws ObjectNotFoundException When the path does not exist + */ + public org.omg.CORBA.Object getIOR(Path path) + throws ObjectNotFoundException + { + return resolveObject(getFullDN(path)); + } + + /** + * Attempts to resolve the CORBA object from the IOR attribute of a DN, either directly or through an alias + * @param dn The String dn + * @throws ObjectNotFoundException when the dn or aliased dn does not exist + */ + private org.omg.CORBA.Object resolveObject(String dn) + throws ObjectNotFoundException + { + Logger.msg(8,"LDAPLookup.resolveObject("+dn+")"); + LDAPEntry anEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(),dn,LDAPSearchConstraints.DEREF_NEVER); + if (anEntry != null) + { + String iorString; + try { + iorString = LDAPLookupUtils.getFirstAttributeValue(anEntry, "ior"); + org.omg.CORBA.Object ior=Gateway.getORB().string_to_object(iorString); + if (ior!=null) + return ior; + else + throw new ObjectNotFoundException("LDAPLookup.resolveObject() - " + dn + " has no IOR"); + } catch (ObjectNotFoundException ex) { + return resolveObject(LDAPLookupUtils.getFirstAttributeValue(anEntry,"aliasedObjectName")); + } + } + else + throw new ObjectNotFoundException("LDAPLookup.resolveObject() LDAP node " + dn + " is not in LDAP or has no IOR."); + } + + /** + * + * @param domPath + * @return + * @throws InvalidItemPathException + * @throws ObjectNotFoundException + */ + @Override + public ItemPath resolvePath(DomainPath domPath) + throws InvalidItemPathException, ObjectNotFoundException { + + LDAPEntry domEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), + getFullDN(domPath), LDAPSearchConstraints.DEREF_ALWAYS); + String entityKey = LDAPLookupUtils.getFirstAttributeValue(domEntry, + "cn"); + Logger.msg(7, "DomainPath " + domPath + " is a reference to " + + entityKey); + String objClass = LDAPLookupUtils.getFirstAttributeValue(domEntry, + "objectClass"); + ItemPath referencedPath = new ItemPath(entityKey); + if (objClass.equals("cristalagent")) + return new AgentPath(referencedPath); + + return referencedPath; + } + + + @Override + public void add(Path path) + throws ObjectCannotBeUpdated, ObjectAlreadyExistsException + { + try { + checkLDAPContext(path); + LDAPAttributeSet attrSet = createAttributeSet(path); + LDAPEntry newEntry = new LDAPEntry(getFullDN(path),attrSet); + LDAPLookupUtils.addEntry(mLDAPAuth.getAuthObject(),newEntry); + if (path instanceof DomainPath) + Gateway.getProxyServer().sendProxyEvent(new ProxyMessage(null, path.toString(), ProxyMessage.ADDED)); + } catch (LDAPException ex) { + if (ex.getResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) + throw new ObjectAlreadyExistsException(ex.getLDAPErrorMessage()); + else + throw new ObjectCannotBeUpdated(ex.getLDAPErrorMessage()); + } + } + + //deletes a node + //throws LDAPexception if node cannot be deleted (eg node is not a leaf) + @Override + public void delete(Path path) throws ObjectCannotBeUpdated + { + try { + LDAPLookupUtils.delete(mLDAPAuth.getAuthObject(),getDN(path)+mLocalPath); + } catch (LDAPException ex) { + throw new ObjectCannotBeUpdated(ex.getLDAPErrorMessage()); + } + if (path instanceof DomainPath) { + Gateway.getProxyServer().sendProxyEvent(new ProxyMessage(null, path.toString(), ProxyMessage.DELETED)); + } + } + + //change specs, add boolean alias leaf context + protected void checkLDAPContext(Path path) + { + String dn = getFullDN(path); + if (!LDAPLookupUtils.exists(mLDAPAuth.getAuthObject(),dn)) + { + String listDN[] = path.getPath(); + String name = "cn="+ path.getRoot() + "," + mLocalPath; + int i=0; + while (i params = new ArrayList(); + for (PropertyDescription propDesc: props.list) { + if (propDesc.getIsClassIdentifier()) + params.add(propDesc.getProperty()); + } + return search(start, params.toArray(new Property[params.size()])); + } + + protected LDAPPathSet search(String startDN, int scope, String filter, LDAPSearchConstraints searchCons) + { + Logger.msg(8,"Searching for "+filter+" in "+startDN); + searchCons.setMaxResults(0); + String[] attr = { LDAPConnection.ALL_USER_ATTRS }; + try + { + LDAPSearchResults res = mLDAPAuth.getAuthObject().search(startDN, scope, + filter,attr,false,searchCons); + return new LDAPPathSet(res, this); + } + catch (LDAPException ex) + { + Logger.error("LDAPException::LDAPLookup::search() " + ex.toString()); + return new LDAPPathSet(this); + } + } + //typically search for (any filter combination) + public LDAPPathSet search(String startDN,String filter) + { + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER); + return search(startDN,LDAPConnection.SCOPE_SUB,filter,searchCons); + } + + @Override + public LDAPPathSet searchAliases(ItemPath entity) { + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER); + return search(getFullDN(new DomainPath()), LDAPConnection.SCOPE_SUB, "(&(objectClass=aliasObject)(aliasedObjectName="+ + LDAPLookupUtils.escapeDN(getFullDN(entity))+"))", searchCons); + } + + @Override + public boolean exists(Path path) { + return LDAPLookupUtils.exists(mLDAPAuth.getAuthObject(), getFullDN(path)); + } + + @Override + public ItemPath getItemPath(String uuid) throws ObjectNotFoundException, InvalidItemPathException { + String[] attr = { LDAPConnection.ALL_USER_ATTRS }; + try { + ItemPath item = new ItemPath(uuid); + LDAPEntry anEntry=mLDAPAuth.getAuthObject().read(getDN(item)+mLocalPath,attr); + String type = LDAPLookupUtils.getFirstAttributeValue(anEntry, "objectClass"); + if (type.equals("cristalentity")) + return item; + else if (type.equals("cristalagent")) + return new AgentPath(item); + else + throw new ObjectNotFoundException("Not an entity"); + + } catch (LDAPException ex) { + if (ex.getResultCode() == LDAPException.NO_SUCH_OBJECT) + throw new ObjectNotFoundException("Entity does not exist"); + Logger.error(ex); + throw new ObjectNotFoundException("Error getting entity class"); + } + } + + /** converts an LDAPentry to a Path object + * Note that the search producing the entry should have retrieved the attrs + * 'ior' and 'uniquemember' + * @throws ObjectNotFoundException + * @throws ObjectNotFoundException + * @throws + */ + protected Path nodeToPath(LDAPEntry entry) throws InvalidItemPathException, ObjectNotFoundException + { + String dn = entry.getDN(); + ItemPath entityKey; + org.omg.CORBA.Object ior; + + // extract syskey + try { + String entityKeyStr = LDAPLookupUtils.getFirstAttributeValue(entry, "cn"); + entityKey = new ItemPath(entityKeyStr); + } catch (ObjectNotFoundException ex) { + entityKey = null; + } catch (InvalidItemPathException ex) { + entityKey = null; + } + + // extract IOR + try { + String stringIOR = LDAPLookupUtils.getFirstAttributeValue(entry,"ior"); + ior = Gateway.getORB().string_to_object(stringIOR); + } catch (ObjectNotFoundException ex) { + ior = null; + } + + /* Find the right path class */ + Path thisPath; + if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalagent")) + { //cristalagent + String agentID = LDAPLookupUtils.getFirstAttributeValue(entry,"uid"); + thisPath = new AgentPath(entityKey, agentID); + } + else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalrole")) + { //cristalrole + thisPath = new RolePath(getPathComponents(dn.substring(0, dn.lastIndexOf(mDomainTypeRoot))), + LDAPLookupUtils.getFirstAttributeValue(entry, "jobList").equals("TRUE")); + } + else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","aliasObject") || + (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalcontext") && dn.endsWith(mDomainTypeRoot))) + { + DomainPath domainPath = new DomainPath(); + domainPath.setPath(getPathComponents(dn.substring(0, dn.lastIndexOf(mDomainTypeRoot)))); + thisPath = domainPath; + } + else if (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalentity") || + (LDAPLookupUtils.existsAttributeValue(entry,"objectclass","cristalcontext") && dn.endsWith(mItemTypeRoot))) + { + if(dn.endsWith(mItemTypeRoot)) { + if (entityKey == null) throw new InvalidItemPathException(entry.getDN()+" was not a valid itemPath"); + thisPath = entityKey; + } + else + throw new ObjectNotFoundException("Entity found outside entity tree"); + } + else + { + throw new ObjectNotFoundException("Unrecognised LDAP entry. Not a cristal entry"); + } + + //set IOR if we have one + if (ior!=null) thisPath.setIOR(ior); + return thisPath; + } + + public String getDN(Path path) { + StringBuffer dnBuffer = new StringBuffer(); + String[] pathComp = path.getPath(); + for (int i=pathComp.length-1; i>=0; i--) + dnBuffer.append("cn=").append(LDAPLookupUtils.escapeDN(pathComp[i])).append(","); + dnBuffer.append("cn="+path.getRoot()+","); + return dnBuffer.toString(); + } + + public String getFullDN(Path path) { + return getDN(path)+mLocalPath; + } + + public String[] getPathComponents(String dnFragment) { + ArrayList newPath = new ArrayList(); + StringTokenizer tok = new StringTokenizer(dnFragment, ","); + String[] path = new String[tok.countTokens()]; + while (tok.hasMoreTokens()) { + String nextPath = tok.nextToken(); + if (nextPath.indexOf("cn=") == 0) + newPath.add(0, LDAPLookupUtils.unescapeDN(nextPath.substring(3))); + else + break; + } + return newPath.toArray(path); + } + + @Override + public Object resolve(Path path) throws ObjectNotFoundException { + return resolveObject(getFullDN(path)); + } + + @Override + public Iterator getChildren(Path path) { + String filter = "objectclass=*"; + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(10); + searchCons.setDereference(LDAPSearchConstraints.DEREF_FINDING ); + return search(getFullDN(path), LDAPConnection.SCOPE_ONE,filter,searchCons); + } + + protected LDAPAttributeSet createAttributeSet(Path path) throws ObjectCannotBeUpdated { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + + if (path instanceof RolePath) { + RolePath rolePath = (RolePath)path; + attrs.add(new LDAPAttribute("objectclass","cristalrole")); + String jobListString = rolePath.hasJobList()?"TRUE":"FALSE"; + attrs.add(new LDAPAttribute("jobList",jobListString)); + attrs.add(new LDAPAttribute("cn", rolePath.getName())); + } + else if (path instanceof DomainPath) { + DomainPath domPath = (DomainPath)path; + attrs.add(new LDAPAttribute("cn",domPath.getName())); + try { + attrs.add(new LDAPAttribute("aliasedObjectName",getFullDN(domPath.getItemPath()))); + String objectclass_values[] = { "alias", "aliasObject" }; + attrs.add(new LDAPAttribute("objectclass",objectclass_values)); + } catch (ObjectNotFoundException e) { // no entity - is a context + attrs.add(new LDAPAttribute("objectclass","cristalcontext")); + } + } + + else if (path instanceof ItemPath) { + ItemPath itemPath = (ItemPath)path; + attrs.add(new LDAPAttribute("cn", itemPath.getUUID().toString())); + if (itemPath.getIOR() != null) + attrs.add(new LDAPAttribute("ior", Gateway.getORB().object_to_string(itemPath.getIOR()))); + + if (path instanceof AgentPath) { + AgentPath agentPath = (AgentPath)path; + attrs.add(new LDAPAttribute("objectclass","cristalagent")); + + String agentName = agentPath.getAgentName(); + if (agentName != null && agentName.length() > 0) + attrs.add(new LDAPAttribute("uid", agentName)); + else + throw new ObjectCannotBeUpdated("Cannot create agent. No userId specified"); + + String agentPass = agentPath.getPassword(); + if (agentPass != null && agentPass.length() > 0) + try { + attrs.add(new LDAPAttribute("userPassword", AgentPath.generateUserPassword(agentPass, "SHA"))); + } catch (NoSuchAlgorithmException ex) { + throw new ObjectCannotBeUpdated("Cryptographic libraries for password hashing not found."); + } + else + throw new ObjectCannotBeUpdated("Cannot create agent. No password given"); + } + else { + attrs.add(new LDAPAttribute("objectclass","cristalentity")); + } + } + + return attrs; + + } + + //Creates a cristalRole + //CristalRole is-a specialized CristalContext which contains multi-valued uniqueMember attribute pointing to cristalagents + @Override + public RolePath createRole(RolePath rolePath) + throws ObjectAlreadyExistsException, ObjectCannotBeUpdated + { + + // create the role + String roleDN = getFullDN(rolePath); + LDAPEntry roleNode; + try + { + roleNode = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(rolePath)); + throw new ObjectAlreadyExistsException(); + } catch (ObjectNotFoundException ex) { } + + //create CristalRole if it does not exist + roleNode = new LDAPEntry(roleDN, createAttributeSet(rolePath)); + try { + LDAPLookupUtils.addEntry(mLDAPAuth.getAuthObject(),roleNode); + } catch (LDAPException e) { + throw new ObjectCannotBeUpdated(e.getLDAPErrorMessage()); + } + return rolePath; + + + } + public void deleteRole(RolePath role) throws ObjectNotFoundException, ObjectCannotBeUpdated { + try { + LDAPLookupUtils.delete(mLDAPAuth.getAuthObject(), getFullDN(role)); + } catch (LDAPException ex) { + throw new ObjectCannotBeUpdated("Could not remove role"); + } + } + + @Override + public void addRole(AgentPath agent, RolePath role) + throws ObjectCannotBeUpdated, ObjectNotFoundException + { + LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); + //add memberDN to uniqueMember if it is not yet a member + if (!LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", getFullDN(agent))) + LDAPLookupUtils.addAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "uniqueMember", getFullDN(agent)); + else + throw new ObjectCannotBeUpdated("Agent " + agent.getAgentName() + " already has role " + role.getName()); + } + + @Override + public void removeRole(AgentPath agent, RolePath role) + throws ObjectCannotBeUpdated, ObjectNotFoundException + { + LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); + if (LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", getFullDN(agent))) + LDAPLookupUtils.removeAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "uniqueMember", getFullDN(agent)); + else + throw new ObjectCannotBeUpdated("Agent did not have that role"); + } + + @Override + public boolean hasRole(AgentPath agent, RolePath role) { + String filter = "(&(objectclass=cristalrole)(uniqueMember="+getFullDN(agent)+")(cn="+role.getName()+"))"; + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); + return search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons).hasNext(); + } + + @Override + public AgentPath[] getAgents(RolePath role) + throws ObjectNotFoundException + { + //get the roleDN entry, and its uniqueMember entry pointing to + LDAPEntry roleEntry; + try { + roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); + } catch (ObjectNotFoundException e) { + throw new ObjectNotFoundException("Role does not exist"); + } + + String[] res = LDAPLookupUtils.getAllAttributeValues(roleEntry,"uniqueMember"); + ArrayList agents = new ArrayList(); + for (String userDN : res) { + try { + LDAPEntry userEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), userDN); + AgentPath path = (AgentPath)nodeToPath(userEntry); + agents.add(path); + } catch (ObjectNotFoundException ex) { + Logger.error("Agent "+userDN+" does not exist"); + } catch (InvalidItemPathException ex) { + Logger.error("Agent "+userDN+" is not a valid entity"); + } + } + AgentPath[] usersList = new AgentPath[0]; + usersList = agents.toArray(usersList); + return usersList; + } + + //returns the role/s of a user + @Override + public RolePath[] getRoles(AgentPath agentPath) + { + //search the mDomainPath tree uniqueMember=userDN + //filter = objectclass=cristalrole AND uniqueMember=userDN + String filter = "(&(objectclass=cristalrole)(uniqueMember="+getFullDN(agentPath)+"))"; + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); + Iterator roles = search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons); + ArrayList roleList = new ArrayList(); + + while(roles.hasNext()) + { + RolePath path = (RolePath) roles.next(); + roleList.add(path); + } + RolePath[] roleArr = new RolePath[roleList.size()]; + roleArr = roleList.toArray(roleArr); + return roleArr; + } + + /** + * Utility for looking up a login name + * + * @param ld + * @param agentName + * @param baseDN + * @return + * @throws ObjectNotFoundException + */ + @Override + public AgentPath getAgentPath(String agentName) throws ObjectNotFoundException + { + //search to get the userDN equivalent of the userID + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); + String filter = "(&(objectclass=cristalagent)(uid="+agentName+"))"; + Iterator res = search(mItemTypeRoot,LDAPConnection.SCOPE_SUB,filter,searchCons); + if (!res.hasNext()) + throw new ObjectNotFoundException("Agent not found: "+agentName); + Path result = res.next(); + if (result instanceof AgentPath) + return (AgentPath)result; + else + throw new ObjectNotFoundException("Entry was not an Agent"); + } + + @Override + public RolePath getRolePath(String roleName) throws ObjectNotFoundException + { + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); + String filter = "(&(objectclass=cristalrole)(cn="+roleName+"))"; + Iterator res = search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons); + if (!res.hasNext()) + throw new ObjectNotFoundException("Role not found"); + Path result = res.next(); + if (result instanceof RolePath) + return (RolePath)result; + else + throw new ObjectNotFoundException("Entry was not a Role"); + } + + @Override + public void setHasJobList(RolePath role, boolean hasJobList) throws ObjectNotFoundException, ObjectCannotBeUpdated { + // get entry + LDAPEntry roleEntry; + try { + roleEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(role)); + } catch (ObjectNotFoundException e) { + throw new ObjectNotFoundException("Role does not exist"); + } + // set attribute + LDAPLookupUtils.setAttributeValue(mLDAPAuth.getAuthObject(), roleEntry, "jobList", hasJobList?"TRUE":"FALSE"); + } + + @Override + public void setAgentPassword(AgentPath agent, String newPassword) throws ObjectNotFoundException, ObjectCannotBeUpdated, NoSuchAlgorithmException { + String encPasswd = AgentPath.generateUserPassword(newPassword, "SHA"); + LDAPEntry agentEntry; + try { + agentEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(agent)); + } catch (ObjectNotFoundException e) { + throw new ObjectNotFoundException("Agent "+agent.getAgentName()+" does not exist"); + } + LDAPLookupUtils.setAttributeValue(mLDAPAuth.getAuthObject(), agentEntry, "userPassword", encPasswd); + + } + + @Override + public String getAgentName(AgentPath agentPath) + throws ObjectNotFoundException { + LDAPEntry agentEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(agentPath)); + return LDAPLookupUtils.getFirstAttributeValue(agentEntry,"uid"); + } + +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPLookupUtils.java b/src/main/java/org/cristalise/lookup/ldap/LDAPLookupUtils.java new file mode 100644 index 0000000..b7b656b --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPLookupUtils.java @@ -0,0 +1,366 @@ +/* + * Lookup helper class. + */ + +package org.cristalise.lookup.ldap; + +//import netscape.ldap.*; +//import netscape.ldap.util.*; +import org.cristalise.kernel.common.ObjectAlreadyExistsException; +import org.cristalise.kernel.common.ObjectCannotBeUpdated; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.utils.Logger; + +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPDN; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPModification; +import com.novell.ldap.LDAPSearchConstraints; +import com.novell.ldap.LDAPSearchResults; + +/** + * @version $Revision: 1.74 $ $Date: 2006/03/03 13:52:21 $ + * @author $Author: abranson $ + */ + +final public class LDAPLookupUtils +{ + static final char[] META_CHARS = {'+', '=', '"', ',', '<', '>', ';', '/'}; + static final String[] META_ESCAPED = {"2B", "3D", "22", "2C", "3C", "3E", "3B", "2F"}; + static public LDAPEntry getEntry(LDAPConnection ld, String dn,int dereference) + throws ObjectNotFoundException + { + try { + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(dereference); + LDAPEntry thisEntry = ld.read(dn,searchCons); + if (thisEntry != null) return thisEntry; + } catch (LDAPException ex) { + throw new ObjectNotFoundException("LDAP Exception for dn:"+dn+": \n"+ex.getMessage()); + } + throw new ObjectNotFoundException(dn+" does not exist"); + + } + + + /** + * Utility method to connect to an LDAP server + * @param lp LDAP properties to connect with + * @return a novell LDAPConnection object + * @throws LDAPException when the connection was unsuccessful + */ + public static LDAPConnection createConnection(LDAPProperties lp) throws LDAPException { + LDAPConnection ld = new LDAPConnection(); + + Logger.msg(3, "LDAPLookup - connecting to " + lp.mHost); + ld.connect(lp.mHost, Integer.valueOf(lp.mPort).intValue()); + + Logger.msg(3, "LDAPLookup - authenticating user:" + lp.mUser); + ld.bind( LDAPConnection.LDAP_V3, lp.mUser, + String.valueOf(lp.mPassword).getBytes()); + + Logger.msg(3, "LDAPLookup - authentication successful"); + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setMaxResults(0); + ld.setConstraints(searchCons); + + return ld; + } + + //Given a DN, return an LDAP Entry + static public LDAPEntry getEntry(LDAPConnection ld, String dn) + throws ObjectNotFoundException + { + return getEntry(ld, dn, LDAPSearchConstraints.DEREF_NEVER); + } + + static public String getFirstAttributeValue(LDAPEntry anEntry, String attribute) throws ObjectNotFoundException + { + LDAPAttribute attr = anEntry.getAttribute(attribute); + if (attr==null) + throw new ObjectNotFoundException("No attributes named '"+attribute+"'"); + return (String)attr.getStringValues().nextElement(); + } + + static public String[] getAllAttributeValues(LDAPEntry anEntry, String attribute) throws ObjectNotFoundException + { + LDAPAttribute attr = anEntry.getAttribute(attribute); + if (attr!=null) + return attr.getStringValueArray(); + + throw new ObjectNotFoundException("No attributes named '"+attribute+"'"); + + } + + static public boolean existsAttributeValue(LDAPEntry anEntry, String attribute, String value) + { + LDAPAttribute attr = anEntry.getAttribute(attribute); + if (attr!=null) + { + String[] attrValues = new String[attr.size()]; + attrValues = attr.getStringValueArray(); + for (int i=0;i { + LDAPSearchResults results; + LDAPEntry nextEntry; + LDAPLookup ldap; + + public LDAPPathSet(LDAPLookup ldap) { // empty + this.ldap = ldap; + results = null; + } + + public LDAPPathSet(LDAPSearchResults results, LDAPLookup ldap) { + this.ldap = ldap; + this.results = results; + } + + @Override + public boolean hasNext() { + if (results == null) return false; + if (nextEntry != null) return true; + if (results.hasMore()) + try { + nextEntry = results.next(); + return true; + } catch (LDAPException ex) { + if (ex.getResultCode()!=32) {// no results + Logger.error(ex); + Logger.error("Error loading LDAP result set: "+ex.getMessage()); + } + } + return false; + } + + @Override + public Path next() { + if (results == null) return null; + try { + if (nextEntry == null) + nextEntry = results.next(); + Path nextPath = ldap.nodeToPath(nextEntry); + nextEntry = null; + return nextPath; + } catch (Exception ex) { + Logger.error("Error loading next path"); + Logger.error(ex); + nextEntry = null; + if (hasNext()) { + Logger.error("Skipping to next entry"); + return next(); + } + else + return null; + } + } + + @Override + public void remove() { + // do nothing + + } +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPProperties.java b/src/main/java/org/cristalise/lookup/ldap/LDAPProperties.java new file mode 100644 index 0000000..b9f5b0f --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPProperties.java @@ -0,0 +1,189 @@ +package org.cristalise.lookup.ldap; + +/** + * Directory Lookup Service + * + * This represent + * + */ + +import javax.xml.bind.DatatypeConverter; + +import org.cristalise.kernel.utils.ObjectProperties; + + +/** + * example: + * + *
      + * # LDAP Lookup config
      + * # use the ApacheDS 2.0.0 M15 available using the port 10389
      + * LDAP.GlobalPath=dc=cristalosgiglobal
      + * LDAP.RootPath=cn=cristalosgiroot
      + * LDAP.LocalPath=cn=cristalosgilocal
      + * LDAP.port=10389
      + * LDAP.host=localhost
      + * LDAP.user=uid=admin,ou=system
      + * LDAP.password=xxxxxx
      + * or
      + * LDAP.password64=xxxxxx
      + * 
      + * + * @version $Revision: 1.16 $ $Date: 2005/10/12 12:51:54 $ + * @author $Author: abranson $ + * @author ogattaz + */ +public class LDAPProperties { + + private static final String BAD_PASSWORD_MESSAGE = "bad base64 password value"; + + public static final String LDAP_PROP_GPATH = "LDAP.GlobalPath"; + public static final String LDAP_PROP_HOST = "LDAP.host"; + public static final String LDAP_PROP_LPATH = "LDAP.LocalPath"; + public static final String LDAP_PROP_PASS = "LDAP.password"; + public static final String LDAP_PROP_PASS64 = "LDAP.password64"; + public static final String LDAP_PROP_PORT = "LDAP.port"; + public static final String LDAP_PROP_RPATH = "LDAP.RootPath"; + public static final String LDAP_PROP_USER = "LDAP.user"; + + public String mGlobalPath = null; // o=cern.ch + public String mHost = null; + public String mLocalPath = null; // cn=lab27 + public String mPassword = null; + public Integer mPort = null; + public String mRootPath = null; // cn=cristal2 + public String mUser = null; + + /** + * @param aObjectProps + * an ObjectProperties instance comming from clc file for exemple + */ + public LDAPProperties(final ObjectProperties aObjectProps) { + + if (aObjectProps != null) { + + mGlobalPath = aObjectProps.getProperty(LDAP_PROP_GPATH); + + mRootPath = aObjectProps.getProperty(LDAP_PROP_RPATH); + if (mRootPath != null) { + mRootPath += "," + mGlobalPath; + } + + mLocalPath = aObjectProps.getProperty(LDAP_PROP_LPATH); + if (mLocalPath != null) { + mLocalPath += "," + mRootPath; + } + + mPort = aObjectProps.getInt(LDAP_PROP_PORT, 389); + mHost = aObjectProps.getProperty(LDAP_PROP_HOST); + mUser = aObjectProps.getProperty(LDAP_PROP_USER); + mPassword = aObjectProps.getProperty(LDAP_PROP_PASS); + + // if raw password not available, try to find base64 one + if (mPassword == null) { + mPassword = aObjectProps.getProperty(LDAP_PROP_PASS64); + // if base64 password available + if (mPassword != null) { + mPassword = translateBase64OPassword(mPassword); + } + } + } + } + + /** + * @param aPropertyName + * the name of the property associated to the member + * @param aMemberValue + * the value to check + * @return true if valid + * @throws IllegalArgumentException + * if not valid + */ + private boolean checkMemberValidity(final String aPropertyName, + final String aMemberValue) throws IllegalArgumentException { + + if (isMemberValueValid(aMemberValue)) + return true; + + throw new IllegalArgumentException(String.format( + "The LDAP property [%s] is not valid. The member value=[%s]", + aPropertyName, aMemberValue)); + } + + /** + * @param aValue + * the value to be checked + * @return true if not null and not empty + */ + private boolean checkPasswordValidity(final String aPasswordValue) + throws IllegalArgumentException { + + if (checkMemberValidity(LDAP_PROP_PASS, aPasswordValue)) { + + if (aPasswordValue.contains(BAD_PASSWORD_MESSAGE)) { + throw new IllegalArgumentException( + String.format( + "The LDAP property [%s] is not valid. The member value=[%s]", + LDAP_PROP_PASS, aPasswordValue)); + } + } + return true; + } + + /** + * @return true is valid + * @throws IllegalArgumentException + * if one of the members is not valid (null or empty) + */ + public boolean checkValidity() throws IllegalArgumentException { + + return checkMemberValidity(LDAP_PROP_GPATH, mGlobalPath) + && checkMemberValidity(LDAP_PROP_RPATH, mRootPath) + && checkMemberValidity(LDAP_PROP_LPATH, mLocalPath) + && checkMemberValidity(LDAP_PROP_HOST, mHost) + && checkMemberValidity(LDAP_PROP_USER, mUser) + && checkPasswordValidity(mPassword); + } + + /** + * @param aValue + * the value to be checked + * @return true if not null and not empty + */ + private boolean isMemberValueValid(final String aValue) { + + return (aValue != null && !aValue.isEmpty()); + } + + /** + * @return true if the password is not null, not empty and is decoded id the + * passed property is a password64 one + */ + public boolean isPasswordValid() { + try { + return checkPasswordValidity(mPassword); + } catch (IllegalArgumentException ex) { + return false; + } + } + + /** + * @param aBase6Password + * the encoded password + * @return the decodded password or a dummy phrase which cause an explicit + * error when it will be used during the connection + */ + private String translateBase64OPassword(final String aBase6Password) { + + try { + // DatatypeConverter tool class available since java 1.5. + // Throws IllegalArgumentException if value not conform + return new String( + DatatypeConverter.parseBase64Binary(aBase6Password)); + + } catch (IllegalArgumentException ex) { + return String.format("#### %s [%s] ####", BAD_PASSWORD_MESSAGE, + aBase6Password); + } + } +} diff --git a/src/main/java/org/cristalise/lookup/ldap/LDAPPropertyManager.java b/src/main/java/org/cristalise/lookup/ldap/LDAPPropertyManager.java new file mode 100644 index 0000000..83d6c6d --- /dev/null +++ b/src/main/java/org/cristalise/lookup/ldap/LDAPPropertyManager.java @@ -0,0 +1,142 @@ +package org.cristalise.lookup.ldap; + +import java.util.ArrayList; +import java.util.Enumeration; + +import org.cristalise.kernel.common.ObjectCannotBeUpdated; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.lookup.ItemPath; +import org.cristalise.kernel.property.Property; +import org.cristalise.kernel.utils.Logger; + +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPEntry; + +/************************************************************************** + * + * $Revision: 1.3 $ + * $Date: 2006/03/03 13:52:21 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +public class LDAPPropertyManager { + /** + * + */ + protected final LDAPLookup ldap; + protected final LDAPAuthManager auth; + + public LDAPPropertyManager(LDAPLookup ldap, LDAPAuthManager auth) { + super(); + this.ldap = ldap; + this.auth = auth; + } + + /** + * @param thisItem - EntityPath of the subject entity + * @return + * @throws ObjectNotFoundException + */ + public boolean hasProperties(ItemPath thisItem) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); + return entityEntry.getAttribute("cristalprop") != null; + } + + /** + * @param thisItem - EntityPath of the subject entity + * @return array of Property + * @throws ObjectNotFoundException + */ + public String[] getPropertyNames(ItemPath thisItem) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); + ArrayList propbag = new ArrayList(); + LDAPAttribute props = entityEntry.getAttribute("cristalprop"); + for (Enumeration e = props.getStringValues(); e.hasMoreElements();) { + String thisProp = (String)e.nextElement(); + String thisName = thisProp.substring(0, thisProp.indexOf(':')); + if (thisName.startsWith("!") && thisName.length()>1) thisName = thisName.substring(1); + propbag.add(thisName); + } + + String[] retArr = new String[props.size()]; + return propbag.toArray(retArr); + } + + /** + * @param thisItem - EntityPath of the subject entity + * @param propName - the name of the property to retrieve + * @return The Property object + * @throws ObjectNotFoundException + */ + public Property getProperty(ItemPath thisItem, String name) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); + return getProperty(entityEntry, name); + } + + /** + * @param thisItem - EntityPath of the subject entity + * @param name - the property name to delete + * @throws ObjectNotFoundException + * @throws ObjectCannotBeUpdated + */ + public void deleteProperty(ItemPath thisItem, String name) throws ObjectNotFoundException, ObjectCannotBeUpdated { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); + Property prop = getProperty(entityEntry, name); + Logger.msg(6, "LDAPLookupUtils.deleteProperty("+name+") - Deleting property"); + LDAPLookupUtils.removeAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(prop)); + } + + private static String getPropertyAttrValue(Property prop) { + return (prop.isMutable()?"":"!")+prop.getName()+":"+prop.getValue(); + } + + /** + * @param thisItem - EntityPath of the subject entity + * @param prop - the property to store + * @throws ObjectNotFoundException + * @throws ObjectCannotBeUpdated + */ + public void setProperty(ItemPath thisItem, Property prop) throws ObjectNotFoundException, ObjectCannotBeUpdated { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(auth.getAuthObject(), ldap.getFullDN(thisItem)); + try { + Property oldProp = getProperty(entityEntry, prop.getName()); + Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - Removing old value '"+oldProp.getValue()+"'"); + LDAPLookupUtils.removeAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(oldProp)); + } catch (ObjectNotFoundException ex) { + Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - creating new property."); + } + Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - setting to '"+prop.getValue()+"'"); + LDAPLookupUtils.addAttributeValue(auth.getAuthObject(), entityEntry, "cristalprop", getPropertyAttrValue(prop)); + } + + public static Property getProperty(LDAPEntry myEntry, String propName) throws ObjectNotFoundException { + // delete existing props + LDAPAttribute props = myEntry.getAttribute("cristalprop"); + if (props == null) + throw new ObjectNotFoundException("Property "+propName+" does not exist"); + String propPrefix = propName+":"; + String roPropPrefix = "!"+propPrefix; + String val = null, name = null; boolean mutable = false; + for (Enumeration e = props.getStringValues(); name==null && e.hasMoreElements();) { + String attrVal = (String)e.nextElement(); + if (attrVal.toLowerCase().startsWith(propPrefix.toLowerCase())) { + name = attrVal.substring(0, propPrefix.length()-1); + val = attrVal.substring(propPrefix.length()); + mutable = true; break; + } + + if (attrVal.toLowerCase().startsWith(roPropPrefix.toLowerCase())) { + name = attrVal.substring(1, roPropPrefix.length()-1); + val = attrVal.substring(roPropPrefix.length()); + mutable = false; break; + } + } + if (name == null) + throw new ObjectNotFoundException("Property "+propName+" does not exist"); + Logger.msg(6, "Loaded "+(mutable?"":"Non-")+"Mutable Property: "+name+"="+val); + return new Property(name, val, mutable); + } + +} diff --git a/src/main/java/org/cristalise/storage/LDAPClientReader.java b/src/main/java/org/cristalise/storage/LDAPClientReader.java new file mode 100644 index 0000000..df37fc4 --- /dev/null +++ b/src/main/java/org/cristalise/storage/LDAPClientReader.java @@ -0,0 +1,15 @@ +package org.cristalise.storage; + +/** + * Provided for easier loading (may be referenced without package in ClusterStorage property) + * + * @author abranson + * + */ +public class LDAPClientReader extends org.cristalise.lookup.ldap.LDAPClientReader { + + public LDAPClientReader() { + super(); + } + +} diff --git a/src/main/java/org/cristalise/storage/LDAPClusterStorage.java b/src/main/java/org/cristalise/storage/LDAPClusterStorage.java new file mode 100644 index 0000000..0b4628e --- /dev/null +++ b/src/main/java/org/cristalise/storage/LDAPClusterStorage.java @@ -0,0 +1,14 @@ +package org.cristalise.storage; + +/** + * Provided for easier loading (may be referenced without package in ClusterStorage property) + * + * @author abranson + * + */ +public class LDAPClusterStorage extends org.cristalise.lookup.ldap.LDAPClusterStorage { + + public LDAPClusterStorage() { + super(); + } +} diff --git a/src/main/resources/module.xml b/src/main/resources/module.xml index 521b145..f1b919b 100644 --- a/src/main/resources/module.xml +++ b/src/main/resources/module.xml @@ -3,9 +3,8 @@ LDAP Lookup, Authenticator and NextKeyManager implementations. ${version} - com/c2kernel/lookup/ldap/resources/ - com.c2kernel.lookup.ldap.LDAPAuthManager - com.c2kernel.lookup.ldap.LDAPLookup - com.c2kernel.lookup.ldap.LDAPNextKeyManager + org/cristalise/lookup/ldap/resources/ + org.cristalise.lookup.ldap.LDAPAuthManager + org.cristalise.lookup.ldap.LDAPLookup \ No newline at end of file -- cgit v1.2.3