/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: IdUtils.java,v 1.34 2009/11/20 23:52:54 ww203982 Exp $ * * Portions Copyrighted 2011-2015 ForgeRock AS. * Portions Copyrighted 2014 Nomura Research Institute, Ltd */ package com.sun.identity.idm; import java.security.AccessController; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import com.iplanet.am.sdk.AMConstants; import com.iplanet.am.sdk.AMDirectoryAccessFactory; import com.iplanet.am.sdk.AMException; import com.iplanet.am.sdk.AMObject; import com.iplanet.am.sdk.AMOrganization; import com.iplanet.am.sdk.AMStoreConnection; import com.iplanet.am.sdk.common.IDirectoryServices; import com.iplanet.am.util.SystemProperties; import com.iplanet.sso.SSOException; import com.iplanet.sso.SSOToken; import com.sun.identity.authentication.service.AuthD; import com.sun.identity.common.CaseInsensitiveHashMap; import com.sun.identity.common.DNUtils; import com.sun.identity.security.AdminTokenAction; import com.sun.identity.shared.Constants; import com.sun.identity.shared.debug.Debug; import com.sun.identity.sm.DNMapper; import com.sun.identity.sm.OrgConfigViaAMSDK; import com.sun.identity.sm.OrganizationConfigManager; import com.sun.identity.sm.SMSEntry; import com.sun.identity.sm.SMSException; import com.sun.identity.sm.ServiceConfig; import com.sun.identity.sm.ServiceConfigManager; import com.sun.identity.sm.ServiceManager; import org.forgerock.openam.ldap.LDAPUtils; import org.forgerock.opendj.ldap.DN; /** * The class defines some static utilities used by other components like policy * and auth * * @supported.api */ public final class IdUtils { private static Debug debug = AMIdentityRepository.debug; private static Map mapSupportedTypes = new CaseInsensitiveHashMap(10); public static Set supportedTypes = new HashSet(); private static Map mapTypesToServiceNames = new CaseInsensitiveHashMap(); protected static Map typesCanBeMemberOf = new CaseInsensitiveHashMap(); protected static Map typesCanHaveMembers = new CaseInsensitiveHashMap(); protected static Map typesCanAddMembers = new CaseInsensitiveHashMap(); // Static map to cache "orgIdentifier" and organization DN private static Map orgIdentifierToOrgName = Collections.synchronizedMap( new CaseInsensitiveHashMap()); private static Map orgStatusCache = Collections.synchronizedMap( new CaseInsensitiveHashMap()); // ServiceConfigManager for sunidentityrepository service private static String notificationId; private static ServiceConfigManager serviceConfigManager; // User naming attribute for AMSDK private static String USER_NAMING_ATTR; // Organization naming attribute for AMSDK private static String ORG_NAMING_ATTR; // SMS Root Suffix private static String ROOT_SUFFIX; // DN pointing to the services node private static String SERVICES_SUFFIX; // Special Users private static Set specialUsers = new HashSet(); static { initialize(); } protected static void initialize() { if (ServiceManager.isConfigMigratedTo70()) { // IdRepo service schema exists. Read the supported // entities from there try { SSOToken adminToken = (SSOToken) AccessController .doPrivileged(AdminTokenAction.getInstance()); serviceConfigManager = new ServiceConfigManager(adminToken, IdConstants.REPO_SERVICE, "1.0"); ServiceConfig ss = serviceConfigManager.getGlobalConfig(null); Set typeSchemaNames = ss.getSubConfigNames("*", IdConstants.SUPPORTED_TYPES); if (typeSchemaNames == null || typeSchemaNames.isEmpty()) { loadDefaultTypes(); } else { Iterator it = typeSchemaNames.iterator(); while (it.hasNext()) { String typeSchema = (String) it.next(); IdType idType = new IdType(typeSchema); supportedTypes.add(idType); mapSupportedTypes.put(idType.getName(), idType); ServiceConfig tsc = ss.getSubConfig(typeSchema); Map attributes = tsc.getAttributes(); Set serviceNameSet = (Set) attributes .get(IdConstants.SERVICE_NAME); Set canBeMembersOf = (Set) attributes .get(IdConstants.ATTR_MEMBER_OF); Set canHaveMembers = (Set) attributes .get(IdConstants.ATTR_HAVE_MEMBERS); Set canAddMembers = (Set) attributes .get(IdConstants.ATTR_ADD_MEMBERS); if (serviceNameSet != null && !serviceNameSet.isEmpty()) { mapTypesToServiceNames.put(typeSchema, (String) serviceNameSet.iterator().next()); } if (canBeMembersOf != null && !canBeMembersOf.isEmpty()) { Set memberOfSet = getMemberSet(canBeMembersOf); typesCanBeMemberOf.put(typeSchema, memberOfSet); } if (canHaveMembers != null && !canHaveMembers.isEmpty()) { Set memberSet = getMemberSet(canHaveMembers); typesCanHaveMembers.put(typeSchema, memberSet); } if (canAddMembers != null && !canAddMembers.isEmpty()) { Set memberSet = getMemberSet(canAddMembers); typesCanAddMembers.put(typeSchema, memberSet); } } } } catch (SMSException e) { String installTime = SystemProperties.get( Constants.SYS_PROPERTY_INSTALL_TIME, "false"); if (!installTime.equals("true")) { debug.error( "IdUtils.initialize: Loading default types.", e); } loadDefaultTypes(); } catch (SSOException ssoe) { debug.error("dUtils.initialize: Loading default types", ssoe); loadDefaultTypes(); } } else { loadDefaultTypes(); } // Register for SMS notifications to root realm if (notificationId == null) { try { SSOToken adminToken = (SSOToken) AccessController .doPrivileged(AdminTokenAction.getInstance()); if (serviceConfigManager == null) { serviceConfigManager = new ServiceConfigManager(adminToken, IdConstants.REPO_SERVICE, "1.0"); } notificationId = serviceConfigManager.addListener( new IdUtilsListener()); } catch (SMSException e) { String installTime = SystemProperties.get( Constants.SYS_PROPERTY_INSTALL_TIME, "false"); if (!installTime.equals("true")) { debug.error( "IdUtils.initialize: Register notification", e); } } catch (SSOException ssoe) { String installTime = SystemProperties.get( Constants.SYS_PROPERTY_INSTALL_TIME, "false"); if (!installTime.equals("true")) { debug.error( "IdUtils.initialize: Register notification", ssoe); } } } } /** * @supported.api * Returns a handle of the Identity object based on * the SSO Token passed in (AMIdentity object of the user * who is authenticated). * * @param token Single sign on token of user. * @return Identity object. * @throws IdRepoException if there are repository related error conditions. * @throws SSOException if user's single sign on token is invalid. */ public static AMIdentity getIdentity(SSOToken token) throws IdRepoException, SSOException { String principal = token.getProperty(Constants.UNIVERSAL_IDENTIFIER); if (principal == null) { // This could happen during co-existence with AM 6.x // and SSOToken created by AM 6.x server. In this case // the principal name would be the DN principal = token.getPrincipal().getName(); } return (getIdentity(token, principal)); } /** * @supported.api * * Returns a string which uniquely represents this identity object. * * @param id * AMIdentity object whose string represenation is * needed. * @return universal identifier of id. */ public static String getUniversalId(AMIdentity id) { return id.getUniversalId(); } /** * @supported.api * * Returns an AMIdentity object, if provided with a string * identifier for the object. * * @param token SSOToken of the administrator * @param univId String represenation of the identity. * @return Identity object * @throws IdRepoException if the identifier provided is wrong. */ public static AMIdentity getIdentity(SSOToken token, String univId) throws IdRepoException { return (getIdentity(token, univId, null)); } /** * Returns an AMIdentity object, given the * DN of an authenticated identity, realm name and identity type. * This interface is mainly for authentication component to get * back the identity of the user. * * @param token SSOToken of the administrator * @param amsdkdn DN of the authenticated user * @param realm realm name where the user was authenticated * @return Identity object or null * @throws IdRepoException if the underly components throws * exception while obtaining the identity object */ public static AMIdentity getIdentity(SSOToken token, String amsdkdn, String realm) throws IdRepoException { if (amsdkdn == null || !LDAPUtils.isDN(amsdkdn)) { Object[] args = { amsdkdn }; throw (new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.ILLEGAL_UNIVERSAL_IDENTIFIER, args)); } DN amsdkdnObject = LDAPUtils.newDN(amsdkdn); // Try constructing the identity object if (amsdkdn.toLowerCase().startsWith("id=")) { try { return (new AMIdentity(amsdkdnObject, token)); } catch (IdRepoException ide) { // this could be a AMSDK DN. Follow the AMSDK rules if (debug.messageEnabled()) { debug.message("IdUtils:getIdentity(token, " + amsdkdn + ") got exception: " + ide.getMessage() + "\n\tContinuing with AMSDK DN check"); } } } // Check for Special Users initializeSpecialUsers(); if (specialUsers.contains(DNUtils.normalizeDN(amsdkdn))) { return new AMIdentity(amsdkdnObject, token, LDAPUtils.rdnValueFromDn( amsdkdnObject), IdType.USER, ROOT_SUFFIX); } // Since "amsdkdn" is not a UUID, check if realm has AMSDK configured // This change is to avoid the issue of IdUtils always checking the // users in AMSDK as IdUtils does not check if AMSDK is configured in // any of the realms. try { if (!ServiceManager.isAMSDKEnabled() || ((realm != null) && !OrgConfigViaAMSDK.isAMSDKConfigured(realm)) || (!ServiceManager.isAMSDKConfigured())) { // Not configured for AMSDK, return return (null); } } catch (SMSException smse) { // Ignore the exception and continue } // Initialize root realm suffix, org and user naming attributes initializeForGetIdentity(); // Determine if the amsdkdn is valid. Obtain name & type String name = null; IdType type = null; try { // Since we would using AMSDK, get AMDirectoryManager preload // all the attributes and check if it exists IDirectoryServices dsServices = AMDirectoryAccessFactory.getDirectoryServices(); // Preload/cache all the attributes assuming it is a user // Mainly for performance reasons, since getObjectType would // force multiple another directory lookup try { if (amsdkdn.startsWith(USER_NAMING_ATTR)) { dsServices.getAttributes(token, amsdkdn, AMObject.USER); } } catch (Exception e) { // Ignore the exception and continue since this for cache } // Getting object type would use the cached attributes int sdkType = dsServices.getObjectType(token, amsdkdn); // Convert the sdkType to IdRepo type type = getType(AMStoreConnection.getObjectName(sdkType)); name = AMConstants.CONTAINER_DEFAULT_TEMPLATE_ROLE; if (!type.equals(IdType.REALM)) { name = LDAPUtils.rdnValueFromDn(amsdkdnObject); } } catch (AMException ame) { // Debug the message and return null if (debug.messageEnabled()) { debug.message("IdUtils.getIdentity: Unable to resolve " + "AMSDK DN: " + amsdkdn, ame); } return (null); } catch (SSOException ssoe) { // Debug the message and return null if (debug.messageEnabled()) { debug.message("IdUtils.getIdentity: Unable to resolve " + "AMSDK DN. Got SSOException", ssoe); } return (null); } // Need to determine realm for amsdkdn String srealm = ROOT_SUFFIX; if (!amsdkdn.equals(ROOT_SUFFIX) && !amsdkdn.equals(SERVICES_SUFFIX)) { // Need to get the object type and walk up the tree int index = amsdkdn.indexOf(ORG_NAMING_ATTR); if (index == 0) { srealm = OrgConfigViaAMSDK.getRealmForAMSDK(amsdkdn, realm); } else if (index > 0) { srealm = OrgConfigViaAMSDK.getRealmForAMSDK( amsdkdn.substring(index), realm); } if (debug.messageEnabled()) { debug.message("IdUtils.getIdentity:: amsdkdn=" + amsdkdn + " maps to realm=" + srealm); } } else if (amsdkdn.equals(SERVICES_SUFFIX)) { // Since amsdkdn points to services node, // it should be reset to root suffix amsdkdn = ROOT_SUFFIX; } return (new AMIdentity(amsdkdnObject, token, name, type, srealm)); } /** * Returns the name of service which defines the profile information for * this type. Returns null, if nothing is defined. * * @param type IdType whose service name is needed. * @return Name of the service. */ public static String getServiceName(IdType type) { return (String) mapTypesToServiceNames.get(type.getName()); } /** * Returns corresponding IdType object given a type. * * @param type of object to return. * @return Idtype of type. * @throws IdRepoException if there are no corresponding types. */ public static IdType getType(String type) throws IdRepoException { if (type.equalsIgnoreCase("managedrole")) { type = "role"; } else if (type.equalsIgnoreCase("organization") || type.equalsIgnoreCase("organizationalunit")) { type = "realm"; } IdType returnType = (IdType) mapSupportedTypes.get(type); if (returnType == null) { Object args[] = { type }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NOT_SUPPORTED_TYPE, args); } return returnType; } /** * Returns the matching DN from the AM SDK for this entry. This utility is * required by auth. * * @param id AMIdentity object. * @return DN of the object, as represented in the datastore. */ public static String getDN(AMIdentity id) { if (id.getDN() != null) { return id.getDN(); } else { return id.getUniversalId(); } } /** * Returns an organization which maps to the identifier used by application * * @param orgIdentifier Organization identifier * @return Organization mapping to that identifier. */ public static String getOrganization(SSOToken token, String orgIdentifier) throws IdRepoException, SSOException { // Check in cache first String id = null; if ((id = (String) orgIdentifierToOrgName.get(orgIdentifier)) != null) { return (id); } // Compute the organization name if (debug.messageEnabled()) { debug.message("IdUtils:getOrganization Input orgname: " + orgIdentifier); } if (orgIdentifier == null || orgIdentifier.length() == 0 || orgIdentifier.equals("/")) { // Return base DN id = DNMapper.orgNameToDN("/"); } else if (orgIdentifier.startsWith("/")) { // If orgIdentifier is in "/" format covert to DN and return id = DNMapper.orgNameToDN(orgIdentifier); try { new OrganizationConfigManager(token, orgIdentifier); } catch (SMSException e) { debug.message("IdUtils.getOrganization Exception in getting org name from SMS", e); Object[] args = { orgIdentifier }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } } else if (LDAPUtils.isDN(orgIdentifier)) { id = orgIdentifier; try { // Search for realms with orgIdentifier name OrganizationConfigManager ocm = new OrganizationConfigManager(token, orgIdentifier); } catch (SMSException smse) { // debug message here. if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization Exception in " + "getting org name from SMS", smse); } Object[] args = { orgIdentifier }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } } else if (ServiceManager.isCoexistenceMode()) { // Return the org DN as determined by AMStoreConnection if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization: getting from AMSDK"); } try { AMStoreConnection amsc = new AMStoreConnection(token); id = amsc.getOrganizationDN(orgIdentifier, null); } catch (AMException ame) { if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization Exception in " + "getting org name from AMSDK", ame); } throw convertAMException(ame); } } else { // Get the realm name from SMS if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization: getting from " + "SMS realms"); } try { boolean foundOrg = false; ServiceManager sm = new ServiceManager(token); // First search for realms with orgIdentifier name OrganizationConfigManager ocm = sm .getOrganizationConfigManager("/"); Set subOrgNames = ocm.getSubOrganizationNames(orgIdentifier, true); if (subOrgNames != null && !subOrgNames.isEmpty()) { if (subOrgNames.size() == 1) { id = DNMapper.orgNameToDN((String) subOrgNames .iterator().next()); foundOrg = true; } else { for (Iterator items = subOrgNames.iterator(); items.hasNext();) { // check for orgIdentifier String subRealmName = (String) items.next(); StringTokenizer st = new StringTokenizer( subRealmName, "/"); // Need to handle the scenario where multiple // sub-realm with the same name should not be // allowed while (st.hasMoreTokens()) { if (st.nextToken().equalsIgnoreCase( orgIdentifier)) { if (!foundOrg) { id = DNMapper.orgNameToDN(subRealmName); foundOrg = true; } else { Object[] args = {orgIdentifier}; throw new IdRepoException(IdRepoBundle .BUNDLE_NAME, IdRepoErrorCode.MULTIPLE_MAPPINGS_FOUND, args); } } } } } } // Check if organization name has been determined if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization: getting from " + "SMS realms aliases"); } // perform organization alias search Set vals = new HashSet(); vals.add(orgIdentifier); Set orgAliases = sm.searchOrganizationNames( IdConstants.REPO_SERVICE, IdConstants.ORGANIZATION_ALIAS_ATTR, vals); if (!foundOrg && ((orgAliases == null) || orgAliases.isEmpty())) { if (debug.warningEnabled()) { debug.warning("IdUtils.getOrganization Unable" + " to find Org name for: " + orgIdentifier); } Object[] args = {orgIdentifier}; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } else if ((orgAliases != null) && (orgAliases.size() > 0) && (foundOrg || orgAliases.size() > 1)) { // Multiple realms should not have the same alias if (debug.warningEnabled()) { debug.warning("IdUtils.getOrganization Multiple " + " matching Orgs found for: " + orgIdentifier); } Object[] args = {orgIdentifier}; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.MULTIPLE_MAPPINGS_FOUND, args); } if (!foundOrg) { String tmpS = (String) orgAliases.iterator().next(); id = DNMapper.orgNameToDN(tmpS); } } catch (SMSException smse) { // debug message here. if (debug.messageEnabled()) { debug.message("IdUtils.getOrganization Exception in " + "getting org name from SMS", smse); } Object[] args = { orgIdentifier }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } } if (debug.messageEnabled()) { debug.message("IdUtils:getOrganization Search for OrgIdentifier:" + orgIdentifier + " returning realm DN: " + id); } // Add to cache and return id orgIdentifierToOrgName.put(orgIdentifier, id); return id; } /** * Clears the cache containing orgIdentifiers to organization names */ protected static void clearOrganizationNamesCache() { orgIdentifierToOrgName.clear(); orgStatusCache.clear(); if (debug.messageEnabled()) { debug.message("IdUtils.clearOrganizationNamesCache called"); } } /** * Returs true or false, depending on if this organization is enabled or * not. The organization string passed to this method should be an * identifier returned from the method * IdUtils.getOrganization . In the default mode, where * relams are enabled but backward comaptibility is required, this checks * for organization status in the AM enabled Sun DS. Otherwise, it checks * for organization status from the realms tree. * * @param token token SSOToken a valid SSOToken. * @param org name of the organization of interest. * @return true if org is active; * otherwise false * @throws IdRepoException if there are repository related error conditions. * @throws SSOException If user's single sign on token is invalid. */ public static boolean isOrganizationActive(SSOToken token, String org) throws IdRepoException, SSOException { // Check the cache if (orgStatusCache.containsKey(org)) { return (((Boolean) orgStatusCache.get(org)).booleanValue()); } boolean isActive = true; // Need to initialize ServiceManager by creating the constructor if (!ServiceManager.isCoexistenceMode()) { // Pick it up from the realms tree. try { OrganizationConfigManager ocm = new OrganizationConfigManager( token, org); if (ocm == null) { Object[] args = { org }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } Map attributes = ocm.getAttributes(IdConstants.REPO_SERVICE); Set vals = (Set) attributes .get(IdConstants.ORGANIZATION_STATUS_ATTR); if (vals == null || vals.isEmpty()) { isActive = true; } else { String stringActive = (String) vals.iterator().next(); isActive = stringActive.equalsIgnoreCase("Active"); } } catch (SMSException smse) { Object args[] = { org }; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.NO_MAPPING_FOUND, args); } } else if (ServiceManager.isAMSDKEnabled()) { // Return the org DN as determined by AMStoreConnection. try { AMStoreConnection amsc = new AMStoreConnection(token); AMOrganization orgObj = amsc.getOrganization(org); isActive = orgObj.isActivated(); } catch (AMException ame) { throw convertAMException(ame); } } // Add to cache orgStatusCache.put(org, isActive); return isActive; } private static void initializeForGetIdentity() { // Initialize root realm, if not already initalized if (ROOT_SUFFIX == null) { ROOT_SUFFIX = SMSEntry.getRootSuffix(); StringBuilder sb = new StringBuilder(100); sb.append(SMSEntry.SERVICES_RDN) .append(SMSEntry.COMMA).append(ROOT_SUFFIX); SERVICES_SUFFIX = DNUtils.normalizeDN(sb.toString()); } // Initialize organization and user naming attributes if ((ORG_NAMING_ATTR == null) || (USER_NAMING_ATTR == null)) { try { ORG_NAMING_ATTR = AMStoreConnection.getNamingAttribute( AMObject.ORGANIZATION).toLowerCase() + "="; USER_NAMING_ATTR = AMStoreConnection.getNamingAttribute( AMObject.USER).toLowerCase() + "="; } catch (AMException ame) { if (debug.warningEnabled()) { debug.warning("IdUtils: unable to get naming " + "attribute for org/user. Using \"o\"/\"uid\""); } ORG_NAMING_ATTR = "o="; USER_NAMING_ATTR = "uid="; } } } private static void initializeSpecialUsers() { // Populate special users if (specialUsers.isEmpty()) { String susers = SystemProperties.get( Constants.AUTHENTICATION_SPECIAL_USERS, ""); StringTokenizer st = new StringTokenizer( susers, "|"); while (st.hasMoreTokens()) { specialUsers.add(DNUtils.normalizeDN(st.nextToken())); } susers = SystemProperties.get( "com.sun.identity.authentication.super.user", ""); specialUsers.add(DNUtils.normalizeDN(susers)); } } /** * Returns an IdRepoException based on an AMException * * @param ame * @return IdRepoException based on ame. */ public static IdRepoException convertAMException(AMException ame) { Object[] args = ame.getMessageArgs(); String eCode = ame.getErrorCode(); IdRepoException ide = null; if (args == null) { ide = new IdRepoException("amProfile", eCode, null); } else { ide = new IdRepoException("amProfile", ame.getErrorCode(), args); } ide.setLDAPErrorCode(ame.getLDAPErrorCode()); return ide; } private static void loadDefaultTypes() { supportedTypes.add(IdType.REALM); supportedTypes.add(IdType.AGENT); supportedTypes.add(IdType.USER); supportedTypes.add(IdType.ROLE); supportedTypes.add(IdType.GROUP); supportedTypes.add(IdType.FILTEREDROLE); mapSupportedTypes.put(IdType.REALM.getName(), IdType.REALM); mapSupportedTypes.put(IdType.USER.getName(), IdType.USER); mapSupportedTypes.put(IdType.ROLE.getName(), IdType.ROLE); mapSupportedTypes.put(IdType.FILTEREDROLE.getName(), IdType.FILTEREDROLE); mapSupportedTypes.put(IdType.AGENT.getName(), IdType.AGENT); mapSupportedTypes.put(IdType.GROUP.getName(), IdType.GROUP); Set memberSet = new HashSet(); memberSet.add(IdType.ROLE); memberSet.add(IdType.GROUP); memberSet.add(IdType.FILTEREDROLE); typesCanBeMemberOf.put(IdType.USER.getName(), memberSet); Set memberShipSet = new HashSet(); memberShipSet.add(IdType.USER); typesCanHaveMembers.put(IdType.ROLE.getName(), memberShipSet); typesCanHaveMembers.put(IdType.GROUP.getName(), memberShipSet); typesCanHaveMembers.put(IdType.FILTEREDROLE.getName(), memberShipSet); typesCanAddMembers.put(IdType.GROUP.getName(), memberShipSet); typesCanAddMembers.put(IdType.ROLE.getName(), memberShipSet); } private static Set getMemberSet(Set members) { Set memberSet = new HashSet(members.size() * 2); for (Iterator iter = members.iterator(); iter.hasNext();) { String currType = (String) iter.next(); memberSet.add(new IdType(currType)); } return memberSet; } /** * Returns the user name extracted from the uuid * if the orgName supplied in the parameter is * not same realm name in uuid then IdRepoException * is thrown * * @param uuid uuid of the user * @param orgName the org user is trying to login to * @return user name * @throws IdRepoException */ public static String getIdentityName(String uuid, String orgName) throws IdRepoException { String username = uuid; // Check uuid if ((uuid != null) && uuid.toLowerCase().startsWith("id=")) { // Could be universal id, get the identity object AMIdentity id = new AMIdentity(null, uuid); username = id.getName(); // Check the realm names String realm = DNUtils.normalizeDN(id.getRealm()); if (!DNUtils.normalizeDN(orgName).equals(realm)) { Object[] args = {uuid, orgName}; throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.REALM_NAME_NOT_MATCH_AUTHENTICATION_REALM, args); } } return (username); } /** * Gets the AMIdentity of a user with username equal to uName that exists in realm * * @param uName username of the user to get. * @param realm realm the user belongs to. * @return The AMIdentity of user with username equal to uName. */ public static AMIdentity getIdentity(String uName, String realm) { AMIdentity theID = null; AMIdentityRepository amIdRepo = getAMIdentityRepository(DNMapper.orgNameToDN(realm)); IdSearchControl idsc = new IdSearchControl(); idsc.setRecursive(true); idsc.setAllReturnAttributes(true); // search for the identity Set results = Collections.EMPTY_SET; try { idsc.setMaxResults(0); IdSearchResults searchResults = amIdRepo.searchIdentities(IdType.USER, uName, idsc); if (searchResults != null) { results = searchResults.getSearchResults(); } if (results == null || results.size() != 1) { throw new IdRepoException("IdUtils" + ".getIdentity : " + "More than one user found"); } theID = results.iterator().next(); } catch (IdRepoException e) { debug.warning("Error searching for user identity"); } catch (SSOException e) { debug.warning("User's ssoToken has expired"); } return theID; } /** * Returns AMIdentityRepostiory handle for an organization. * * @param orgDN the organization name. * @return AMIdentityRepostiory object */ public static AMIdentityRepository getAMIdentityRepository(String orgDN) { return AuthD.getAuth().getAMIdentityRepository(orgDN); } // SMS service listener to reinitialize if IdRepo service changes static class IdUtilsListener implements com.sun.identity.sm.ServiceListener { public void schemaChanged(String serviceName, String version) { initialize(); } public void globalConfigChanged(String serviceName, String version, String groupName, String serviceComponent, int type) { initialize(); clearOrganizationNamesCache(); } public void organizationConfigChanged(String serviceName, String version, String orgName, String groupName, String serviceComponent, int type) { clearOrganizationNamesCache(); } } }