From 254ee6f47eebfc00462c10756a92066e82cc1a96 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 21 Jun 2011 15:46:02 +0200 Subject: Initial commit --- source/com/c2kernel/lookup/AgentPath.java | 152 +++++++ source/com/c2kernel/lookup/DomainPath.java | 153 +++++++ source/com/c2kernel/lookup/EntityPath.java | 172 ++++++++ .../c2kernel/lookup/InvalidAgentPathException.java | 13 + .../lookup/InvalidEntityPathException.java | 13 + source/com/c2kernel/lookup/LDAPLookup.java | 461 +++++++++++++++++++++ source/com/c2kernel/lookup/LDAPLookupUtils.java | 317 ++++++++++++++ source/com/c2kernel/lookup/LDAPPathSet.java | 70 ++++ source/com/c2kernel/lookup/LDAPProperties.java | 38 ++ .../com/c2kernel/lookup/LDAPPropertyManager.java | 118 ++++++ source/com/c2kernel/lookup/LDAPRoleManager.java | 199 +++++++++ .../c2kernel/lookup/LegacyLDAPPropertyManager.java | 70 ++++ source/com/c2kernel/lookup/NextKeyManager.java | 72 ++++ source/com/c2kernel/lookup/Path.java | 301 ++++++++++++++ source/com/c2kernel/lookup/RolePath.java | 117 ++++++ 15 files changed, 2266 insertions(+) create mode 100755 source/com/c2kernel/lookup/AgentPath.java create mode 100755 source/com/c2kernel/lookup/DomainPath.java create mode 100755 source/com/c2kernel/lookup/EntityPath.java create mode 100755 source/com/c2kernel/lookup/InvalidAgentPathException.java create mode 100755 source/com/c2kernel/lookup/InvalidEntityPathException.java create mode 100755 source/com/c2kernel/lookup/LDAPLookup.java create mode 100755 source/com/c2kernel/lookup/LDAPLookupUtils.java create mode 100755 source/com/c2kernel/lookup/LDAPPathSet.java create mode 100755 source/com/c2kernel/lookup/LDAPProperties.java create mode 100755 source/com/c2kernel/lookup/LDAPPropertyManager.java create mode 100755 source/com/c2kernel/lookup/LDAPRoleManager.java create mode 100755 source/com/c2kernel/lookup/LegacyLDAPPropertyManager.java create mode 100755 source/com/c2kernel/lookup/NextKeyManager.java create mode 100755 source/com/c2kernel/lookup/Path.java create mode 100755 source/com/c2kernel/lookup/RolePath.java (limited to 'source/com/c2kernel/lookup') diff --git a/source/com/c2kernel/lookup/AgentPath.java b/source/com/c2kernel/lookup/AgentPath.java new file mode 100755 index 0000000..01c764f --- /dev/null +++ b/source/com/c2kernel/lookup/AgentPath.java @@ -0,0 +1,152 @@ +/************************************************************************** + * EntityPath.java + * + * $Revision: 1.12 $ + * $Date: 2005/10/13 08:15:00 $ + * + * Copyright (C) 2001 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +package com.c2kernel.lookup; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.xerces.impl.dv.util.Base64; + +import com.c2kernel.common.ObjectCannotBeUpdated; +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.process.Gateway; +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; +import com.novell.ldap.LDAPEntry; + + +/** +* Extends Path to enforce SystemKey structure and support int form +* +* @version $Revision: 1.12 $ $Date: 2005/10/13 08:15:00 $ +* @author $Author: abranson $ +**/ +public class AgentPath extends EntityPath +{ + + private String mAgentName=null; + private String mPassword=null; + + public AgentPath(int syskey, String agentName) + throws InvalidAgentPathException,InvalidEntityPathException + { + super(syskey); + if (agentName!=null && agentName.length()>0) + setAgentName(agentName); + else + throw new InvalidAgentPathException(); + } + + public AgentPath(int syskey) + throws InvalidEntityPathException + { + super(syskey); + } + + public AgentPath(EntityPath entity) { + super(); + try { + setSysKey(entity.getSysKey()); + } catch (InvalidEntityPathException ex) { + //won't happen as the entity path was valid + } + } + + public void setAgentName(String agentID) + { + mAgentName = agentID; + } + + public String getAgentName() + { + if (mAgentName==null) + { + try { + LDAPEntry agentEntry = LDAPLookupUtils.getEntry(Gateway.getLDAPLookup().getConnection(), this.getDN() + mLocalPath); + mAgentName = LDAPLookupUtils.getFirstAttributeValue(agentEntry,"uid"); + } catch (ObjectNotFoundException e) { + mAgentName = ""; + } + } + return mAgentName; + } + + public RolePath[] getRoles() + { + return Gateway.getLDAPLookup().getRoleManager().getRoles(this); + } + + public boolean hasRole(RolePath role) { + return Gateway.getLDAPLookup().getRoleManager().hasRole(this, role); + } + + public boolean hasRole(String role) { + try { + return hasRole(Gateway.getLDAPLookup().getRoleManager().getRolePath(role)); + } catch (ObjectNotFoundException ex) { + return false; + } + } + + public void setPassword(String passwd) + { + mPassword = passwd; + } + + public String getPassword() + { + return mPassword; + } + + public String dump() { + return super.dump()+ + "\n agentID="+ + mAgentName; + } + + static String generateUserPassword(String pass, String algo) throws NoSuchAlgorithmException { + MessageDigest sha = MessageDigest.getInstance(algo); + sha.reset(); + sha.update(pass.getBytes()); + byte hash[] = sha.digest(); + StringBuffer digest = new StringBuffer("{").append(algo).append("}"); + digest.append(Base64.encode(hash)); + return digest.toString(); + } + + public LDAPAttributeSet createAttributeSet() throws ObjectCannotBeUpdated + { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass","cristalagent")); + attrs.add(new LDAPAttribute("intsyskey",Integer.toString(mSysKey))); + attrs.add(new LDAPAttribute("cn", getPath()[getPath().length-1])); + if (mIOR != null) + attrs.add(new LDAPAttribute("ior", Gateway.getORB().object_to_string(mIOR))); + + if (mAgentName!=null && mAgentName.length()>0) + attrs.add(new LDAPAttribute("uid",mAgentName)); + else + throw new ObjectCannotBeUpdated("Cannot create agent. No userId specified", ""); + + if (mPassword!=null && mPassword.length()>0) + try { + attrs.add(new LDAPAttribute("userPassword",generateUserPassword(mPassword, "SHA"))); + } catch (NoSuchAlgorithmException ex) { + throw new ObjectCannotBeUpdated("Cryptographic libraries for password hashing not found.", ""); + } + else + throw new ObjectCannotBeUpdated("Cannot create agent. No password given", ""); + + return attrs; + } + +} + diff --git a/source/com/c2kernel/lookup/DomainPath.java b/source/com/c2kernel/lookup/DomainPath.java new file mode 100755 index 0000000..ad314ee --- /dev/null +++ b/source/com/c2kernel/lookup/DomainPath.java @@ -0,0 +1,153 @@ +/************************************************************************** + * DomainPath.java + * + * $Revision: 1.22 $ + * $Date: 2005/10/13 08:15:00 $ + * + * Copyright (C) 2001 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +package com.c2kernel.lookup; + +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.process.Gateway; +import com.c2kernel.utils.Logger; +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; + + +/** +* @version $Revision: 1.22 $ $Date: 2005/10/13 08:15:00 $ +* @author $Author: abranson $ +**/ +public class DomainPath extends Path +{ + private EntityPath target = null; + protected static String mTypeRoot; + +/* Very simple extension to Path. Only copies constructors and defines root */ + + public DomainPath() + { + super(Path.UNKNOWN); + } + + public DomainPath(short type) + { + super(); + mType = type; + } + + public DomainPath(String[] path) + { + super(path, Path.UNKNOWN); + } + + public DomainPath(String path) + { + super(path, Path.UNKNOWN); + } + + public DomainPath(String path, EntityPath entity) throws InvalidEntityPathException + { + super(path, Path.UNKNOWN); + setEntity(entity); + } + + public DomainPath(DomainPath parent, String child) { + super(parent, child); + } + + /* the root of domain paths is /domain + * clearly + */ + public String getRoot() { + return "domain"; + } + + public DomainPath getParent() { + if (mPath.length == 0) + return null; + + String[] parentPath = new String[mPath.length-1]; + System.arraycopy(mPath, 0, parentPath, 0, parentPath.length); + return new DomainPath(parentPath); + } + + public void setEntity(EntityPath newTarget) { + if (newTarget == null) { // clear + target = null; + mType = Path.CONTEXT; + return; + } + + target = newTarget; + mType = Path.ENTITY; + } + + public EntityPath getEntity() throws ObjectNotFoundException { + if (mType == UNKNOWN) { // must decide + checkType(); + } + + if (target == null) + throw new ObjectNotFoundException("Path is a context", ""); + return target; + } + + public short getType() { + if (mType == UNKNOWN) { // must decide + checkType(); + } + return mType; + } + + public void checkType() { + try { + setEntity(Gateway.getLDAPLookup().resolvePath(this)); + } catch (InvalidEntityPathException ex) { + Logger.error(ex); + mType = CONTEXT; + } catch (ObjectNotFoundException ex) { + mType = CONTEXT; + } + + } + + /** + * Retrieves the domkey of the path + * @return the last path component; + */ + public String getName() { + return mPath[mPath.length-1]; + } + + public int getSysKey() { + if (mType == UNKNOWN) { // must decide + checkType(); + } + + if (mType == ENTITY) { + return target.getSysKey(); + } + else return INVALID; + } + + public LDAPAttributeSet createAttributeSet() { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("cn",getName())); + if (getType() == ENTITY) { + String objectclass_values[] = { "alias", "aliasObject" }; + attrs.add(new LDAPAttribute("objectclass",objectclass_values)); + attrs.add(new LDAPAttribute("aliasedObjectName",target.getFullDN())); + } + + else + { + attrs.add(new LDAPAttribute("objectclass","cristalcontext")); + } + return attrs; + } +} + diff --git a/source/com/c2kernel/lookup/EntityPath.java b/source/com/c2kernel/lookup/EntityPath.java new file mode 100755 index 0000000..079f171 --- /dev/null +++ b/source/com/c2kernel/lookup/EntityPath.java @@ -0,0 +1,172 @@ +/************************************************************************** + * EntityPath.java + * + * $Revision: 1.14 $ + * $Date: 2006/03/03 13:52:21 $ + * + * Copyright (C) 2001 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +package com.c2kernel.lookup; + +import java.util.ArrayList; + +import com.c2kernel.common.ObjectCannotBeUpdated; +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.process.Gateway; +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; + + +/** +* Extends Path to enforce SystemKey structure and support int form +* +* @version $Revision: 1.14 $ $Date: 2006/03/03 13:52:21 $ +* @author $Author: abranson $ +**/ +public class EntityPath extends Path +{ + // no of components in a syskey + public static final int elementNo = 3; + // no of digits in a syskey component + public static final int elementLen = 3; + // maximum possible int syskey + public static final int maxSysKey = (int)Math.pow(10, elementNo*elementLen)-1; + protected static String mTypeRoot; + /* + * From syskey int + * Note no EntityPath constructors allow setting of CONTEXT or ENTITY: + * The object decides that for itself from the number of components + */ + + public EntityPath(int syskey) throws InvalidEntityPathException { + super(); + setSysKey(syskey); + } + + /* + */ + public EntityPath() + { + super(); + } + + + /* + */ + public EntityPath(String[] path) throws InvalidEntityPathException + { + super(path, Path.CONTEXT); // dummy - it will get replaced in checkSysPath() + checkSysPath(); + } + + /* + */ + public EntityPath(String path) throws InvalidEntityPathException + { + super(path, Path.CONTEXT); + checkSysPath(); + } + + /* + */ + public EntityPath(EntityPath parent, String child) throws InvalidEntityPathException { + super(parent, child); + checkSysPath(); + } + + // EntityPaths root in /entity + public String getRoot() { + return "entity"; + } + + public EntityPath getEntity() throws ObjectNotFoundException { + return this; + } + + public byte[] getOID() { + if (mSysKey == Path.INVALID) return null; + return String.valueOf(mSysKey).getBytes(); + } + + /*************************************************************************/ + + /** Returns int form of syskey (if possible) + */ + public int getSysKey() { + if (mSysKey == Path.INVALID && mType == Path.ENTITY) + try { + if (mPath.length != elementNo) + throw new InvalidEntityPathException("Incorrect number of components for a system key"); + mSysKey = 0; + for (int i=0; i= '0') && (c <='9')) + mSysKey = mSysKey*10 + c - '0'; + else + throw new InvalidEntityPathException("Component '"+keypart+"' contained a non-numeric char (excluding first char 'd')."); + + } + } + } catch (InvalidEntityPathException ex) { + mSysKey = Path.INVALID; + } + return mSysKey; + } + + /** Sets path from int syskey + */ + public void setSysKey(int sysKey) throws InvalidEntityPathException + { + if (sysKey < 0 || sysKey > maxSysKey) + throw new InvalidEntityPathException("System key "+sysKey+" out of range"); + String stringPath = Integer.toString(sysKey); + ArrayList newKey = new ArrayList(); + for (int i=0; i elementNo) + throw new InvalidEntityPathException("EntityPath cannot have more than "+elementNo+" components: "+toString()); + if (mPath.length == elementNo) + mType = Path.ENTITY; + else + mType = Path.CONTEXT; + } + + public LDAPAttributeSet createAttributeSet() throws ObjectCannotBeUpdated { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass","cristalentity")); + attrs.add(new LDAPAttribute("intsyskey",Integer.toString(mSysKey))); + attrs.add(new LDAPAttribute("cn", getPath()[getPath().length-1])); + if (mIOR != null) + attrs.add(new LDAPAttribute("ior", Gateway.getORB().object_to_string(mIOR))); + return attrs; + } +} + diff --git a/source/com/c2kernel/lookup/InvalidAgentPathException.java b/source/com/c2kernel/lookup/InvalidAgentPathException.java new file mode 100755 index 0000000..be4d952 --- /dev/null +++ b/source/com/c2kernel/lookup/InvalidAgentPathException.java @@ -0,0 +1,13 @@ +package com.c2kernel.lookup; + +public class InvalidAgentPathException extends InvalidEntityPathException { + + public InvalidAgentPathException() { + super(); + } + + public InvalidAgentPathException(String msg) { + super(msg); + } + +} diff --git a/source/com/c2kernel/lookup/InvalidEntityPathException.java b/source/com/c2kernel/lookup/InvalidEntityPathException.java new file mode 100755 index 0000000..27c754d --- /dev/null +++ b/source/com/c2kernel/lookup/InvalidEntityPathException.java @@ -0,0 +1,13 @@ +package com.c2kernel.lookup; + +public class InvalidEntityPathException extends Exception { + + public InvalidEntityPathException() { + super(); + } + + public InvalidEntityPathException(String msg) { + super(msg); + } + +} diff --git a/source/com/c2kernel/lookup/LDAPLookup.java b/source/com/c2kernel/lookup/LDAPLookup.java new file mode 100755 index 0000000..04d99f0 --- /dev/null +++ b/source/com/c2kernel/lookup/LDAPLookup.java @@ -0,0 +1,461 @@ +/* + * Directory Lookup Service * + * author: Florida Estrella +*/ + +package com.c2kernel.lookup; + +import java.util.Enumeration; +import java.util.StringTokenizer; + +import com.c2kernel.common.ObjectAlreadyExistsException; +import com.c2kernel.common.ObjectCannotBeUpdated; +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.entity.TraceableEntity; +import com.c2kernel.entity.agent.ActiveEntity; +import com.c2kernel.entity.proxy.EntityProxyManager; +import com.c2kernel.entity.proxy.ProxyMessage; +import com.c2kernel.process.Gateway; +import com.c2kernel.utils.Logger; +import com.c2kernel.utils.Resource; +import com.novell.ldap.*; + +/** + * 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 + +{ + private LDAPConnection mLDAPConn; + private LDAPProperties mLDAPProps; + private NextKeyManager mNextKeyManager; + private LDAPPropertyManager mPropManager; + private LDAPRoleManager mRoleManager; + + + + /** + * Creates a new LDAPLookup manager with the properties supplied. + * This should be only done by the Gateway during initialisation. + * + * @param props The LDAP properties object that extracts LDAP connection properties from the global c2kprops + */ + public LDAPLookup(LDAPProperties props) throws LDAPException + { + Logger.msg(8,"LDAPLookup - initialising."); + + mLDAPProps = props; + + mLDAPConn = createConnection(mLDAPProps); + + Path.mGlobalPath=props.mGlobalPath; + Path.mRootPath=props.mRootPath; + Path.mLocalPath=props.mLocalPath; + + EntityPath.mTypeRoot = "cn=entity,"+props.mLocalPath; + DomainPath.mTypeRoot = "cn=domain,"+props.mLocalPath; + + mNextKeyManager = new NextKeyManager(this, "cn=last,"+EntityPath.mTypeRoot); + Logger.debug("LDAP.useOldProps="+Gateway.getProperty("LDAP.useOldProps", "false")); + if (Gateway.getProperty("LDAP.useOldProps", "false").equals("true")) { + Logger.debug("Using Kernel 2.1 LDAP Property Format"); + mPropManager = new LegacyLDAPPropertyManager(this); + } + else { + Logger.debug("Using Kernel 2.2 LDAP Property Format"); + mPropManager = new LDAPPropertyManager(this); + } + mRoleManager = new LDAPRoleManager(this, "cn=agent,"+DomainPath.mTypeRoot, EntityPath.mTypeRoot); + + } + + /** + * 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; + } + + /** + * Gets the entity key generator, used to get a unique system key for new entities. + * @return the global NextKeyManager + */ + public NextKeyManager getNextKeyManager() + { + return mNextKeyManager; + } + + /** + * 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; + } + /** + * Gets the role manager, that is used to add and remove roles and agents. + * @return Returns the mRoleManager. + */ + public LDAPRoleManager getRoleManager() { + return mRoleManager; + } + + /** + * Returns the current LDAP connection, and attempts to reconnect if it has been closed. + * @return + */ + protected LDAPConnection getConnection() + { + if (!mLDAPConn.isConnected()) { + Logger.warning("LDAPLookup - lost connection to LDAP server. Attempting to reconnect."); + try { + mLDAPConn = createConnection(mLDAPProps); + } catch (LDAPException ex) { } + } + return mLDAPConn; + } + + /** + * Disconnects the connection with the LDAP server during shutdown + */ + 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; + } + } + + /** + * 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(path.getFullDN()); + } + + /** + * 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(getConnection(),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 InvalidEntityPathException + * @throws ObjectNotFoundException + */ + protected EntityPath resolvePath(DomainPath domPath) + throws InvalidEntityPathException, ObjectNotFoundException { + EntityPath referencedPath = null; + LDAPEntry domEntry = LDAPLookupUtils.getEntry(getConnection(), domPath + .getFullDN(), LDAPSearchConstraints.DEREF_ALWAYS); + String entityKey = LDAPLookupUtils.getFirstAttributeValue(domEntry, + "intsyskey"); + Logger.msg(7, "DomainPath " + domPath + " is a reference to " + + entityKey); + String objClass = LDAPLookupUtils.getFirstAttributeValue(domEntry, + "objectClass"); + if (objClass.equals("cristalagent")) + referencedPath = new AgentPath(Integer.parseInt(entityKey)); + else + referencedPath = new EntityPath(Integer.parseInt(entityKey)); + + return referencedPath; + } + + + public LDAPEntry add(Path path) + throws ObjectCannotBeUpdated, ObjectAlreadyExistsException + { + String root = path.getRoot(); + try { + checkLDAPContext(path); + LDAPAttributeSet attrSet = path.createAttributeSet(); + LDAPEntry newEntry = new LDAPEntry(path.getFullDN(),attrSet); + LDAPLookupUtils.addEntry(getConnection(),newEntry); + if (path instanceof DomainPath) + EntityProxyManager.sendProxyEvent(new ProxyMessage(ProxyMessage.NA, path.toString(), ProxyMessage.ADDED)); + return newEntry; + } 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) + public void delete(Path path) throws ObjectCannotBeUpdated + { + try { + LDAPLookupUtils.delete(getConnection(),path.getDN()+Path.mLocalPath); + } catch (LDAPException ex) { + throw new ObjectCannotBeUpdated(ex.getLDAPErrorMessage(), ""); + } + if (path instanceof DomainPath) { + EntityProxyManager.sendProxyEvent(new ProxyMessage(ProxyMessage.NA, path.toString(), ProxyMessage.DELETED)); + } + } + + //change specs, add boolean alias leaf context + protected void checkLDAPContext(Path path) + throws LDAPException + { + String dn = path.getFullDN(); + if (!LDAPLookupUtils.exists(getConnection(),dn)) + { + String listDN[] = path.getPath(); + String name = "cn="+ path.getRoot() + "," + Path.mLocalPath; + int i=0; + while (i', ';', '/'}; + String escapedStr = new String(name); + + //Backslash is both a Java and an LDAP escape character, so escape it first + escapedStr = escapedStr.replaceAll("\\\\","\\\\"); + + //Positional characters - see RFC 2253 + escapedStr = escapedStr.replaceAll("^#","\\\\#"); + escapedStr = escapedStr.replaceAll("^ | $","\\\\ "); + + for (int i=0;i < META_CHARS.length;i++) { + escapedStr = escapedStr.replaceAll("\\"+META_CHARS[i],"\\\\" + META_CHARS[i]); + } + Logger.msg(6, "LDAP DN "+name+" escaped to "+escapedStr); + return escapedStr; + } + + public static String escapeSearchFilter (String filter) { + //From RFC 2254 + String escapedStr = new String(filter); + + escapedStr = escapedStr.replaceAll("\\\\","\\\\5c"); + //escapedStr = escapedStr.replaceAll("\\*","\\\\2a"); // we need stars for searching + escapedStr = escapedStr.replaceAll("\\(","\\\\28"); + escapedStr = escapedStr.replaceAll("\\)","\\\\29"); + Logger.msg(6, "LDAP Search Filter "+filter+" escaped to "+escapedStr); + return escapedStr; + } +} diff --git a/source/com/c2kernel/lookup/LDAPPathSet.java b/source/com/c2kernel/lookup/LDAPPathSet.java new file mode 100755 index 0000000..9c68c5c --- /dev/null +++ b/source/com/c2kernel/lookup/LDAPPathSet.java @@ -0,0 +1,70 @@ +package com.c2kernel.lookup; + +import java.util.Enumeration; + +import com.c2kernel.process.Gateway; +import com.c2kernel.utils.Logger; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPSearchResults; + +/************************************************************************** + * + * $Revision: 1.6 $ + * $Date: 2005/12/01 14:23:14 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + + + +public class LDAPPathSet implements Enumeration { + LDAPSearchResults results; + LDAPEntry nextEntry; + + public LDAPPathSet() { // empty + results = null; + } + + public LDAPPathSet(LDAPSearchResults results) { + this.results = results; + } + + public boolean hasMoreElements() { + 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; + } + + public Object nextElement() { + if (results == null) return null; + try { + if (nextEntry == null) + nextEntry = results.next(); + Path nextPath = Gateway.getLDAPLookup().nodeToPath(nextEntry); + nextEntry = null; + return nextPath; + } catch (Exception ex) { + Logger.error("Error loading next path"); + Logger.error(ex); + nextEntry = null; + if (hasMoreElements()) { + Logger.error("Skipping to next entry"); + return nextElement(); + } + else + return null; + } + } +} diff --git a/source/com/c2kernel/lookup/LDAPProperties.java b/source/com/c2kernel/lookup/LDAPProperties.java new file mode 100755 index 0000000..e884a54 --- /dev/null +++ b/source/com/c2kernel/lookup/LDAPProperties.java @@ -0,0 +1,38 @@ +/* + * Directory Lookup Service +*/ + +package com.c2kernel.lookup; + +import com.c2kernel.process.Gateway; + +/** + * @version $Revision: 1.16 $ $Date: 2005/10/12 12:51:54 $ + * @author $Author: abranson $ + */ +public class LDAPProperties +{ + public String mGlobalPath = null; //o=cern.ch + public String mRootPath = null; //cn=cristal2 + public String mLocalPath = null; //cn=lab27 + public String mPort = null; + public String mHost = null; + public String mUser = null; + public String mPassword = null; + + public LDAPProperties() + { + mGlobalPath = Gateway.getProperty( "LDAP.GlobalPath" ); + mRootPath = Gateway.getProperty( "LDAP.RootPath" ); + mLocalPath = Gateway.getProperty( "LDAP.LocalPath" ); + mPort = Gateway.getProperty( "LDAP.port" ); + mHost = Gateway.getProperty( "LDAP.host" ); + mUser = Gateway.getProperty( "LDAP.user" ); + mPassword = Gateway.getProperty( "LDAP.password" ); + + mRootPath += "," + mGlobalPath; + mLocalPath += "," + mRootPath; + + } +} + diff --git a/source/com/c2kernel/lookup/LDAPPropertyManager.java b/source/com/c2kernel/lookup/LDAPPropertyManager.java new file mode 100755 index 0000000..4e1883e --- /dev/null +++ b/source/com/c2kernel/lookup/LDAPPropertyManager.java @@ -0,0 +1,118 @@ +package com.c2kernel.lookup; + +import java.util.ArrayList; +import java.util.Enumeration; + +import com.c2kernel.common.ObjectCannotBeUpdated; +import com.c2kernel.common.ObjectNotFoundException; +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 LDAPLookup ldap; + + public LDAPPropertyManager(LDAPLookup ldap) { + super(); + this.ldap = ldap; + } + + /** + * @param thisEntity - EntityPath of the subject entity + * @return + * @throws ObjectNotFoundException + */ + public boolean hasProperties(EntityPath thisEntity) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(ldap.getConnection(), thisEntity.getFullDN()); + return entityEntry.getAttribute("cristalprop") != null; + } + + /** + * @param thisEntity - EntityPath of the subject entity + * @return array of Property + * @throws ObjectNotFoundException + */ + public String[] getPropertyNames(EntityPath thisEntity) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(ldap.getConnection(), thisEntity.getFullDN()); + ArrayList propbag = new ArrayList(); + LDAPAttribute props = entityEntry.getAttribute("cristalprop"); + for (Enumeration e = props.getStringValues(); e.hasMoreElements();) { + String thisProp = (String)e.nextElement(); + propbag.add(thisProp.substring(0, thisProp.indexOf(':'))); + } + + String[] retArr = new String[props.size()]; + return (String[])propbag.toArray(retArr); + } + + /** + * @param thisEntity - EntityPath of the subject entity + * @param propName - the name of the property to retrieve + * @return String the property value + * @throws ObjectNotFoundException + */ + public String getPropertyValue(EntityPath thisEntity, String name) throws ObjectNotFoundException { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(ldap.getConnection(), thisEntity.getFullDN()); + return getPropertyAttr(entityEntry, name); + } + + /** + * @param thisEntity - EntityPath of the subject entity + * @param name - the property name to delete + * @throws ObjectNotFoundException + * @throws ObjectCannotBeUpdated + */ + public void deleteProperty(EntityPath thisEntity, String name) throws ObjectNotFoundException, ObjectCannotBeUpdated { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(ldap.getConnection(), thisEntity.getFullDN()); + String propVal = getPropertyAttr(entityEntry, name); + Logger.msg(6, "LDAPLookupUtils.deleteProperty("+name+") - Deleting property"); + LDAPLookupUtils.removeAttributeValue(ldap.getConnection(), entityEntry, "cristalprop", name+":"+propVal); + } + + /** + * @param thisEntity - EntityPath of the subject entity + * @param prop - the property to store + * @throws ObjectNotFoundException + * @throws ObjectCannotBeUpdated + */ + public void setProperty(EntityPath thisEntity, Property prop) throws ObjectNotFoundException, ObjectCannotBeUpdated { + LDAPEntry entityEntry = LDAPLookupUtils.getEntry(ldap.getConnection(), thisEntity.getFullDN()); + try { + String propVal = getPropertyAttr(entityEntry, prop.getName()); + Logger.msg(6, "LDAPLookupUtils.setProperty("+prop.getName()+") - Removing old value '"+propVal+"'"); + LDAPLookupUtils.removeAttributeValue(ldap.getConnection(), entityEntry, "cristalprop", prop.getName()+":"+propVal); + } 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(ldap.getConnection(), entityEntry, "cristalprop", prop.getName()+":"+prop.getValue()); + } + + private String getPropertyAttr(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+":"; + for (Enumeration e = props.getStringValues(); e.hasMoreElements();) { + String val = (String)e.nextElement(); + if (val.toLowerCase().startsWith(propPrefix.toLowerCase())) + return val.substring(propPrefix.length()); + } + throw new ObjectNotFoundException("Property "+propName+" does not exist", ""); + } + +} diff --git a/source/com/c2kernel/lookup/LDAPRoleManager.java b/source/com/c2kernel/lookup/LDAPRoleManager.java new file mode 100755 index 0000000..a9b6b23 --- /dev/null +++ b/source/com/c2kernel/lookup/LDAPRoleManager.java @@ -0,0 +1,199 @@ +package com.c2kernel.lookup; + +import java.util.ArrayList; +import java.util.Enumeration; + +import com.c2kernel.common.ObjectAlreadyExistsException; +import com.c2kernel.common.ObjectCannotBeUpdated; +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.utils.Logger; +import com.novell.ldap.*; + +/************************************************************************** + * + * $Revision: 1.1 $ + * $Date: 2005/04/26 06:48:12 $ + * + * Copyright (C) 2003 CERN - European Organization for Nuclear Research + * All rights reserved. + **************************************************************************/ + +// public static final String codeRevision = "$Revision: 1.1 $ $Date: 2005/04/26 06:48:12 $ $Author: abranson $"; +public class LDAPRoleManager { + + /** + * + */ + LDAPLookup mLdap; + private String mRolePath; + private String mEntityPath; + + public LDAPRoleManager(LDAPLookup ldap, String rolePath, String entityPath) { + super(); + this.mLdap = ldap; + this.mRolePath = rolePath; + this.mEntityPath = entityPath; + } + + //NOTE: A role must have at LEAST 1 userDN, cannot be empty... + //Creates a cristalRole + //CristalRole is-a specialized CristalContext which contains multi-valued uniqueMember attribute pointing to cristalagents + public RolePath createRole(String roleName, boolean jobList) + throws ObjectAlreadyExistsException, ObjectCannotBeUpdated + { + + // create the role + RolePath rolePath = new RolePath(roleName, jobList); + String roleDN = rolePath.getFullDN(); + LDAPEntry roleNode; + try + { + roleNode = LDAPLookupUtils.getEntry(mLdap.getConnection(), rolePath.getFullDN()); + throw new ObjectAlreadyExistsException(); + } catch (ObjectNotFoundException ex) { } + + //create CristalRole if it does not exist + roleNode = new LDAPEntry(roleDN, rolePath.createAttributeSet()); + try { + LDAPLookupUtils.addEntry(mLdap.getConnection(),roleNode); + } catch (LDAPException e) { + throw new ObjectCannotBeUpdated(e.getLDAPErrorMessage(), ""); + } + return rolePath; + + + } + public void deleteRole(RolePath role) throws ObjectNotFoundException, ObjectCannotBeUpdated { + try { + LDAPLookupUtils.delete(mLdap.getConnection(), role.getFullDN()); + } catch (LDAPException ex) { + throw new ObjectCannotBeUpdated("Could not remove role"); + } + } + + protected void addRole(AgentPath agent, RolePath role) + throws ObjectCannotBeUpdated, ObjectNotFoundException + { + LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLdap.getConnection(), role.getFullDN()); + //add memberDN to uniqueMember if it is not yet a member + if (!LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", agent.getFullDN())) + LDAPLookupUtils.addAttributeValue(mLdap.getConnection(), roleEntry, "uniqueMember", agent.getFullDN()); + else + throw new ObjectCannotBeUpdated("Agent " + agent.getAgentName() + " already has role " + role.getName()); + } + + protected void removeRole(AgentPath agent, RolePath role) + throws ObjectCannotBeUpdated, ObjectNotFoundException + { + LDAPEntry roleEntry = LDAPLookupUtils.getEntry(mLdap.getConnection(), role.getFullDN()); + if (LDAPLookupUtils.existsAttributeValue(roleEntry, "uniqueMember", agent.getFullDN())) + LDAPLookupUtils.removeAttributeValue(mLdap.getConnection(), roleEntry, "uniqueMember", agent.getFullDN()); + else + throw new ObjectCannotBeUpdated("Agent did not have that role"); + } + + protected boolean hasRole(AgentPath agent, RolePath role) { + String filter = "(&(objectclass=cristalrole)(uniqueMember="+agent.getFullDN()+")(cn="+role.getName()+"))"; + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(0); + searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); + Enumeration roles = mLdap.search(mRolePath,LDAPConnection.SCOPE_SUB,filter,searchCons); + return roles.hasMoreElements(); + } + + protected AgentPath[] getAgents(RolePath role) + throws ObjectNotFoundException + { + //get the roleDN entry, and its uniqueMember entry pointing to + LDAPEntry roleEntry; + try { + roleEntry = LDAPLookupUtils.getEntry(mLdap.getConnection(), role.getFullDN()); + } catch (ObjectNotFoundException e) { + throw new ObjectNotFoundException("Role does not exist", ""); + } + + String[] res = LDAPLookupUtils.getAllAttributeValues(roleEntry,"uniqueMember"); + ArrayList agents = new ArrayList(); + for (int i=0; i=0; i--) + dnBuffer.append("cn=").append(mPath[i]).append(","); + dnBuffer.append("cn="+getRoot()+","); + mDN = dnBuffer.toString(); + } + return mDN; + } + + public String getFullDN() { + return getDN()+mLocalPath; + } + + public boolean exists() { + return Gateway.getLDAPLookup().exists(this); + } + + /** Queries the lookup for the IOR + */ + + public org.omg.CORBA.Object getIOR() { + org.omg.CORBA.Object newIOR = null; + if (mIOR==null) { // if not cached try to resolve + LDAPLookup myLookup = Gateway.getLDAPLookup(); + try { + newIOR = myLookup.getIOR(this); + } catch (ObjectNotFoundException ex) { + newIOR = null; + } + setIOR(newIOR); + } + return mIOR; + } + + public String toString() { + return getString(); + } + + public short getType() { + return mType; + } + + public int getSysKey() { + return mSysKey; + } + + public Enumeration getChildren() { + String filter = "objectclass=*"; + LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); + searchCons.setBatchSize(10); + searchCons.setDereference(LDAPSearchConstraints.DEREF_FINDING ); + return Gateway.getLDAPLookup().search(getFullDN(), LDAPConnection.SCOPE_ONE,filter,searchCons); + } + + public Path find(String name) throws ObjectNotFoundException { + Enumeration e = Gateway.getLDAPLookup().search(this, name); + if (e.hasMoreElements()) { + Path thisPath =(Path)e.nextElement(); + if (e.hasMoreElements()) + throw new ObjectNotFoundException("More than one match for "+name, ""); + return thisPath; + } + throw new ObjectNotFoundException("No match for "+name, ""); + } + + public abstract EntityPath getEntity() throws ObjectNotFoundException; + + public abstract LDAPAttributeSet createAttributeSet() throws ObjectCannotBeUpdated; + + public boolean equals( Object path ) + { + return toString().equals(path.toString()); + } + + public int hashCode() { + return toString().hashCode(); + } + + public String dump() { + StringBuffer comp = new StringBuffer("Components: { "); + for (int i=0; i