All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cristalise.lookup.ldap.LDAPLookup Maven / Gradle / Ivy

There is a newer version: 5.7.1
Show newest version
/**
 * This file is part of the CRISTAL-iSE LDAP lookup plugin.
 * Copyright (c) 2001-2016 The CRISTAL Consortium. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * http://www.fsf.org/licensing/licenses/lgpl.html
 */
/*
 * 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.Stack;
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 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, mRoleTypeRoot, 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; mRoleTypeRoot = "cn=role,"+props.mLocalPath; } /** * 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); } private void migrateOldRoles() { //search the mDomainPath tree uniqueMember=userDN //filter = objectclass=cristalrole AND uniqueMember=userDN String oldAgentPath = "cn=agent,"+mDomainTypeRoot; LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); searchCons.setBatchSize(0); searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); searchCons.setMaxResults(0); String[] attr = { LDAPConnection.ALL_USER_ATTRS }; try { LDAPSearchResults res = mLDAPAuth.getAuthObject().search(oldAgentPath, LDAPConnection.SCOPE_SUB, "(objectclass=cristalrole)", attr, false, searchCons); Stack toDelete = new Stack(); while (res.hasMore()) { LDAPEntry role = res.next(); toDelete.push(role); String choppedRole = role.getDN().substring(0, role.getDN().lastIndexOf(oldAgentPath)); if (choppedRole.length() == 0) continue; String[] roleComponents = choppedRole.split(","); String[] rolePathStr = new String[roleComponents.length]; for (int i=0; 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 '"+uuid+"'"); } catch (LDAPException ex) { if (ex.getResultCode() == LDAPException.NO_SUCH_OBJECT) throw new ObjectNotFoundException("Entity '"+uuid+"' does not exist"); Logger.error(ex); throw new ObjectNotFoundException("Error getting entity class for '"+uuid+"'"); } } /** 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(mRoleTypeRoot))), 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("Item found outside entity tree"); } else { throw new ObjectNotFoundException("Unrecognised LDAP entry. Not a cristal entry '"+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 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 '"+agentName+"'. No userId specified"); String agentPass = agentPath.getPassword(); if (agentPass != null && agentPass.length() > 0) try { if (!agentPass.matches("^\\{[a-zA-Z0-5]*\\}")) agentPass = LDAPLookupUtils.generateUserPassword(agentPass); attrs.add(new LDAPAttribute("userPassword", agentPass)); } catch (NoSuchAlgorithmException ex) { throw new ObjectCannotBeUpdated("Cryptographic libraries for password hashing not found."); } else attrs.add(new LDAPAttribute("userPassword", "{sha}!")); } 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("Cannot create Role '"+rolePath.getName()+"' because it exists"); } 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("Cannot create Role '"+rolePath.getName()+"'- LDAPException:"+ 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 '"+role.getName()+"'"); } } @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 '"+agent.getAgentName()+"' did not have role '"+role.getName()+"'"); } @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(mRoleTypeRoot,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 '"+role.getName()+"' 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(mRoleTypeRoot,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 '"+agentName+"' was not an Agent"); } @Override public RolePath getRolePath(String roleName) throws ObjectNotFoundException { // empty rolename gives the core role if (roleName.length() == 0) return new RolePath(); if (roleName.contains("/")) { // absolute path RolePath absPath = new RolePath(); absPath.setPath(roleName); if (absPath.exists()) { LDAPEntry entry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(absPath)); try { absPath.setHasJobList(LDAPLookupUtils.getFirstAttributeValue(entry, "jobList").equals("TRUE")); } catch (Exception e) { Logger.error(e); throw new ObjectNotFoundException("Could not find role "+roleName); } return absPath; } } // else search for named role LDAPSearchConstraints searchCons = new LDAPSearchConstraints(); searchCons.setBatchSize(0); searchCons.setDereference(LDAPSearchConstraints.DEREF_NEVER ); String filter = "(&(objectclass=cristalrole)(cn="+roleName+"))"; Iterator res = search(mRoleTypeRoot,LDAPConnection.SCOPE_SUB,filter,searchCons); if (!res.hasNext()) throw new ObjectNotFoundException("Role '"+roleName+"' not found"); Path result = res.next(); if (result instanceof RolePath) return (RolePath)result; else throw new ObjectNotFoundException("Entry '"+roleName+"' 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 '"+role.getName()+"' 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 { if (!newPassword.matches("^\\{[a-zA-Z0-5]*\\}")) newPassword = LDAPLookupUtils.generateUserPassword(newPassword); 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", newPassword); } @Override public String getAgentName(AgentPath agentPath) throws ObjectNotFoundException { LDAPEntry agentEntry = LDAPLookupUtils.getEntry(mLDAPAuth.getAuthObject(), getFullDN(agentPath)); return LDAPLookupUtils.getFirstAttributeValue(agentEntry,"uid"); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy