/*
* 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: OrganizationConfigManager.java,v 1.31 2010/01/20 17:01:36 veiming Exp $
*
* Portions Copyrighted 2011-2016 ForgeRock AS.
*/
package com.sun.identity.sm;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import org.forgerock.openam.ldap.LDAPUtils;
import org.forgerock.opendj.ldap.DN;
import com.iplanet.am.util.SystemProperties;
import com.iplanet.sso.SSOException;
import com.iplanet.sso.SSOToken;
import com.iplanet.ums.IUMSConstants;
import com.sun.identity.authentication.util.ISAuthConstants;
import com.sun.identity.common.CaseInsensitiveHashSet;
import com.sun.identity.delegation.DelegationException;
import com.sun.identity.delegation.DelegationUtils;
import com.sun.identity.idm.IdConstants;
import com.sun.identity.idm.IdRepoException;
import com.sun.identity.idm.plugins.internal.AgentsRepo;
import com.sun.identity.shared.Constants;
/**
* The class <code>OrganizationConfigManager</code> provides interfaces to
* manage an organization's configuration data. It provides interfaces to create
* and delete organizations, service attributes for organizations and service
* configuration parameters.
* <p>
* The organization configuration can be managed in a hierarchical manner, and a
* forward slash "/" will be used to separate the name hierarchy. Hence the root
* of the organization hierarchy will be represented by a single forward slash
* "/", and sub-organizations will be separated by "/". For example "/a/b/c"
* would represent a "c" sub-organization within "b" which would be a
* sub-organization of "a".
*
* @supported.all.api
*/
public class OrganizationConfigManager {
// Instance variables
private SSOToken token;
private String orgName;
private String orgDN;
private OrgConfigViaAMSDK amsdk;
private OrganizationConfigManagerImpl orgConfigImpl;
static String orgNamingAttrInLegacyMode;
static Pattern baseDNpattern = Pattern.compile(SMSEntry.getRootSuffix());
protected static final String SERVICES_NODE = SMSEntry.SERVICES_RDN
+ SMSEntry.COMMA + SMSEntry.getRootSuffix();
// set the special characters which are not in realm names.
static String specialCharsString = "*|(|)|!|/|=";
private static String SEPERATOR = "|";
private String CONF_ENABLED =
"sun-idrepo-amSDK-config-copyconfig-enabled";
private boolean copyOrgInitialized;
private boolean copyOrgEnabled;
private String amSDKOrgDN;
// sunOrganizationAlias in org DIT.
public static final String SUNORG_ALIAS = "sunOrganizationAliases";
// associatedDomain in org DIT.
private String SUNDNS_ALIAS = "sunDNSAliases";
// sunPreferredDomain in org DIT.
private String SUNPREF_DOMAIN = "sunPreferredDomain";
// inetDomainStatus in org DIT.
private String SUNORG_STATUS = "sunOrganizationStatus";
private static final String SMS_INVALID_SSO_TOKEN = "sms-INVALID_SSO_TOKEN";
static {
initializeFlags();
}
/**
* Constructor to obtain an instance of
* <code>OrganizationConfigManager
* </code> for an organization by providing
* an authenticated identity of the user. The organization name would be "/"
* seperated to represent organization hierarchy.
*
* @param token
* single sign on token of authenticated user identity.
* @param orgName
* name of the organization. The value of <code>null
* </code> or
* "/" would represent the root organization.
*
* @throws SMSException
* if an error has occurred while getting the instance of
* <code>OrganizationConfigManager
* </code>.
*/
public OrganizationConfigManager(SSOToken token, String orgName)
throws SMSException {
// Copy instance variables
this.token = token;
this.orgName = orgName;
// Instantiate and validate
validateConfigImpl();
orgDN = orgConfigImpl.getOrgDN();
try {
if (migratedTo70 && !registeredForConfigNotifications) {
ServiceConfigManager scmr = new ServiceConfigManager(
ServiceManager.REALM_SERVICE, token);
scmr.addListener(new OrganizationConfigManagerListener());
registeredForConfigNotifications = true;
}
} catch (SMSException s) {
String installTime = SystemProperties.get(
Constants.SYS_PROPERTY_INSTALL_TIME, "false");
if (!installTime.equals("true")) {
SMSEntry.debug.warning("OrganizationConfigManager: "
+ "constructor. Unable to "
+ "construct ServiceConfigManager for idRepoService ", s);
}
throw s;
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager:Constructor", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
if (coexistMode) {
amsdk = new OrgConfigViaAMSDK(token, DNMapper
.realmNameToAMSDKName(orgDN), orgDN);
if (orgNamingAttrInLegacyMode == null) {
orgNamingAttrInLegacyMode = getNamingAttrForOrg();
}
}
}
/**
* Returns the fully qualified name of the
* organization from the root
*
* @return the name of the organization
*/
public String getOrganizationName() {
return (orgName);
}
/**
* Returns the services configured for the organization.
*
* @return service names configured for the organization.
* @throws SMSException
* if there is an error accessing the data store to read the
* configured services.
*
* @deprecated This method has been deprecated, use <code>
* getAssignedServices()</code>
* instead.
*/
public Set getConfiguredServices() throws SMSException {
return (getAssignedServices());
}
/**
* Returns a set of service schemas to be used for
* creation of an organization. The service schemas contain a list of
* attributes and their schema, and will be provided as
* <code>ServiceSchema</code>.
*
* @return Set of <code>ServiceSchema</code> to be used for creation of an
* organization.
* @throws SMSException
* if there is an error accessing the data store to read the
* service schemas.
*/
public Set getServiceSchemas() throws SMSException {
// Loop through the services and determine the
// organization creation schemas
Set serviceSchemaSet = null;
try {
Set serviceNames = getServiceNames(token);
serviceSchemaSet = new HashSet(serviceNames.size() * 2);
for (Iterator names = serviceNames.iterator(); names.hasNext();) {
ServiceSchemaManager ssm = new ServiceSchemaManager(
(String) names.next(), token);
ServiceSchema ss = ssm.getOrganizationCreationSchema();
if (ss != null) {
serviceSchemaSet.add(ss);
}
}
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager:getServiceSchemas"
+ " unable to get service schema", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN), ssoe,
SMS_INVALID_SSO_TOKEN));
}
return (serviceSchemaSet);
}
/**
* Creates a sub-organization under the current
* organization and sets the specified attributes. The sub-organization
* created can be only one level below the current organization. For
* multiple levels this method must be called recursively with the
* corresponding <code>OrganizationConfigManager
* </code>. The organization
* name must not have forward slash ("/"). For eg., the actual organization
* name 'iplanet' cannot be 'iplan/et' because we are using '/' as the
* seperator here. The attributes for the organization can be <code>
* null</code>;
* else would contain service name as the key and another <code>Map</code>
* as the value that would contain the key-values pair for the services.
*
* @param subOrgName
* the name of the sub-organization.
* @param attributes
* Map of attributes for the organization per service. The
* parameter Map attributes contains another Map as its value,
* which then has attribute names and values. The way it is
* arranged is: Map::attributes --> Key: String::ServiceName
* Value: Map::svcAttributes Map::svcAttributes --> Key:
* String::AttributeName Value: Set::AttributeValues
*
* @return organization config manager of the newly created
* sub-organization.
* @throws SMSException
* if creation of sub-organization failed, or if creation of
* sub-organization is attempted when configuration is not
* migrated to realms.
*/
public OrganizationConfigManager createSubOrganization(String subOrgName,
Map attributes) throws SMSException {
validateConfigImpl();
/*
* Since the "Map attributes" can contain more than one service name,
* creation of the sub organization is be achieved in 2 steps. i) create
* the sub-organization without the attributes ii) for the service names
* in the Map call setAttributes(...)
*/
boolean orgExists = false;
String subOrgDN = normalizeDN(subOrgName, orgDN);
try {
// Check if realm exists, this throws SMSException
// if realm does not exist
// This is to avoid duplicate creation of realms.
new OrganizationConfigManager(token, subOrgDN);
SMSEntry.debug.error("OrganizationConfigManager::"
+ "createSubOrganization() " + "Realm Already Exists.. "
+ subOrgDN);
orgExists = true;
} catch (SMSException smse) {
try {
orgExists = !getRealmByAlias(subOrgName).isEmpty();
} catch (SSOException e) {
SMSEntry.debug.error("OrganizationConfigManager::" +
"createSubOrganization:", e);
}
if (!orgExists) {
SMSEntry.debug.message("OrganizationConfigManager::createSubOrganization() New Realm, creating realm: {} - {}", subOrgName, smse);
}
}
Object args[] = { subOrgName };
if (orgExists) {
throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
"sms-organization_already_exists1",
args));
}
StringTokenizer st =
new StringTokenizer(specialCharsString, SEPERATOR);
while (st.hasMoreTokens()) {
String obj = (String) st.nextToken();
if (subOrgName.indexOf(obj) > -1) {
SMSEntry.debug.error("OrganizationConfigManager::"+
"createSubOrganization() : Invalid realm name: "+
subOrgName);
SMSEntry.debug.error("OrganizationConfigManager::"+
"createSubOrganization() : Detected invalid chars: "+obj);
Object args1[] = {subOrgName};
throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
SMSEntry.bundle.getString("sms-invalid-org-name"),args1));
}
}
validateOrgName(subOrgName);
// If in legacy mode or (realm mode and copy org enabled)
// Create the AMSDK organization first
if ((coexistMode) || (realmEnabled && isCopyOrgEnabled())) {
amsdk.createSubOrganization(subOrgName);
}
if ((realmEnabled || subOrgDN.toLowerCase().startsWith(
SMSEntry.SUN_INTERNAL_REALM_PREFIX))
&& getSubOrganizationNames(subOrgName, false).isEmpty()) {
CreateServiceConfig.createOrganization(token, subOrgDN);
}
// Update the attributes
// If in coexistMode and serviceName is idRepoService
// the following call sets the attributes to AMSDK organization also.
OrganizationConfigManager ocm = getSubOrgConfigManager(subOrgName);
if ((attributes != null) && (!attributes.isEmpty())) {
for (Iterator svcNames = attributes.keySet().iterator(); svcNames
.hasNext();) {
String serviceName = (String) svcNames.next();
Map svcAttributes = (Map) attributes.get(serviceName);
if ((svcAttributes != null) && (!svcAttributes.isEmpty())) {
ocm.setAttributes(serviceName, svcAttributes);
}
}
}
if (realmEnabled) {
AgentsRepo agentsRepo = new AgentsRepo();
HashMap config = new HashMap(1);
HashSet realmName = new HashSet(1);
realmName.add(subOrgDN);
config.put("agentsRepoRealmName", realmName);
try {
agentsRepo.initialize(config);
agentsRepo.createAgentGroupConfig(token);
} catch (IdRepoException ide) {
SMSEntry.debug.error("OrganizationConfigManager::"+
"createSubOrganization:", ide);
}
}
// If in realm mode and not in legacy mode, default services needs
// to be added.
if (realmEnabled && !coexistMode) {
loadDefaultServices(token, ocm);
}
// If in realm mode and copy org enabled, default services needs
// to be registered for the newly created org/suborg and the
// amSDKOrgName/OpenAM Organization is updated with the
// new suborg dn.
if (realmEnabled && isCopyOrgEnabled()) {
registerSvcsForOrg(subOrgName, subOrgDN);
OrganizationConfigManager subOrg =
getSubOrgConfigManager(subOrgName);
ServiceConfig s =
subOrg.getServiceConfig(ServiceManager.REALM_SERVICE);
if (s != null) {
try {
Iterator items = s.getSubConfigNames().iterator();
while (items.hasNext()) {
ServiceConfig subConfig =
s.getSubConfig((String) items.next());
if (subConfig.getSchemaID().equalsIgnoreCase(
IdConstants.AMSDK_PLUGIN_NAME)) {
Map amsdkConfig = new HashMap();
Set vals = new HashSet();
vals.add(orgNamingAttrInLegacyMode +
SMSEntry.EQUALS +
subOrgName + SMSEntry.COMMA + amSDKOrgDN);
amsdkConfig.put("amSDKOrgName", vals);
subConfig.setAttributes(amsdkConfig);
}
break;
}
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager::"+
"createSubOrganization:", ssoe);
throw (new SMSException(SMSEntry.bundle.getString(
SMS_INVALID_SSO_TOKEN), SMS_INVALID_SSO_TOKEN));
}
}
}
if (realmEnabled) {
try {
if (coexistMode) {
DelegationUtils.createRealmPrivileges(token, orgName);
} else {
OrganizationConfigManager parentOrg =
getParentOrgConfigManager();
DelegationUtils.copyRealmPrivilegesFromParent(
token, parentOrg, ocm);
}
} catch (SSOException ssoe) {
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("Creating delegation permissions for: " +
orgName + " failed", ssoe);
}
} catch (SMSException smse) {
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("Creating delegation permissions for: " +
orgName + " failed", smse);
}
} catch (DelegationException de) {
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("Creating delegation permissions for: " +
orgName + " failed", de);
}
}
}
// Return the newly created organization config manager
return (ocm);
}
private Set getRealmByAlias(String subOrgName) throws SSOException, SMSException {
ServiceManager serviceManager = new ServiceManager(token);
return serviceManager.searchOrganizationNames(
IdConstants.REPO_SERVICE,
IdConstants.ORGANIZATION_ALIAS_ATTR, Collections.singleton(subOrgName));
}
private void validateOrgName(final String subOrgName) throws SMSException {
String realm = DNMapper.orgNameToRealmName(subOrgName);
int idx = realm.lastIndexOf('/');
if (idx > -1 && idx < realm.length() - 1) {
realm = realm.substring(idx+1);
}
if (InvalidRealmNameManager.getInvalidRealmNames().contains(realm)) {
SMSEntry.debug.error("OrganizationConfigManager::createSubOrganization() : Invalid realm name: " +
subOrgName + " - clashes with REST endpoint");
throw new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
SMSEntry.bundle.getString("sms-invalid-org-name"), new Object[]{ subOrgName });
}
}
/**
* Returns the names of all sub-organizations.
*
* @return set of names of all sub-organizations.
* @throws SMSException
* if there is an error accessing the data store to read the
* sub-organization names.
*/
public Set getSubOrganizationNames() throws SMSException {
try {
return (getSubOrganizationNames("*", false));
} catch (SMSException s) {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "getSubOrganizationNames() Unable to "
+ "get sub organization names ", s);
throw s;
}
}
/**
* Returns the names of all peer-organizations.
*
* @return set of names of all peer-organizations.
* @throws SMSException
* if there is an error accessing the data store to read the
* peer-organization names.
*/
public Set getPeerOrganizationNames() throws SMSException {
Set getPeerSet = Collections.EMPTY_SET;
if (realmEnabled) {
try {
OrganizationConfigManager ocmParent =
getParentOrgConfigManager();
getPeerSet = ocmParent.getSubOrganizationNames();
} catch (SMSException s) {
if (SMSEntry.debug.warningEnabled()) {
SMSEntry.debug.warning("OrganizationConfigManager: "
+ "getPeerOrganizationNames() Unable to "
+ "get Peer organization names ", s);
}
throw s;
}
}
return (getPeerSet);
}
/**
* Returns names of sub-organizations matching the
* given pattern. If the parameter <code>recursive</code> is set to
* <code>true</code>, search will be performed for the entire sub-tree.
* The pattern can contain "*" as the wildcard to represent zero or more
* characters.
*
* @param pattern
* pattern that will be used for searching, where "*" will be the
* wildcard.
* @param recursive
* if set to <code>true</code> the entire sub-tree will be
* searched for the organization names.
* @return names of sub-organizations matching the pattern.
* @throws SMSException
* if there is an error accessing the data store to read the
* sub-organization names.
*/
public Set getSubOrganizationNames(String pattern, boolean recursive)
throws SMSException {
validateConfigImpl();
try {
if (realmEnabled) {
return (orgConfigImpl.getSubOrganizationNames(token, pattern,
recursive));
} else {
// Must be in coexistence mode
return (amsdk.getSubOrganizationNames(pattern, recursive));
}
} catch (SMSException s) {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "getSubOrganizationNames(String pattern, "
+ "boolean recursive) Unable to get sub organization "
+ "names for filter: " + pattern, s);
throw s;
}
}
/**
* Deletes the given sub-organization. If the
* parameter <code>recursive</code> is set to <code>true</code>, then
* the suborganization and the sub-tree will be deleted.
*
* If the parameter <code>recursive</code> is set to <code>false</code>
* then the sub-organization shall be deleted provided it is the leaf node.
* If there are entries beneath the sub-organization and if the parameter
* <code>recursive</code> is set to <code>false</code>, then an
* exception is thrown that this sub-organization cannot be deleted.
*
* @param subOrgName
* sub-organization name to be deleted.
* @param recursive
* if set to <code>true</code> the entire sub-tree will be
* deleted.
* @throws SMSException
* if the sub-organization name cannot be found, or if there are
* entries beneath the sub-organization and if the parameter
* <code>recursive</code> is set to <code>false</code>.
*/
public void deleteSubOrganization(String subOrgName, boolean recursive)
throws SMSException {
validateConfigImpl();
// Should not delete the root realm, should throw exception if
// attempted.
String subOrgDN = normalizeDN(subOrgName, orgDN);
if (subOrgDN.equals(SMSEntry.SLASH_STR) ||
subOrgDN.equalsIgnoreCase(SMSEntry.getRootSuffix()) ||
subOrgDN.equalsIgnoreCase(SERVICES_NODE)) {
Object parms[] = { orgName };
SMSEntry.debug.error(
"OrganizationConfigManager: deleteSubOrganization(" +
"Root realm "+orgName + " cannot be deleted. ");
throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
"sms-cannot_delete_rootsuffix",parms));
}
// Delete the sub-organization
OrganizationConfigManager subRlmConfigMgr =
getSubOrgConfigManager(subOrgName);
//set the filter "*" to be passed for the search.
Set subRlmSet =
subRlmConfigMgr.getSubOrganizationNames("*", true);
if (realmEnabled) {
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
subOrgDN);
if (cEntry.isDirty()) {
cEntry.refresh();
}
SMSEntry entry = cEntry.getClonedSMSEntry();
if (!recursive) {
// Check if there are sub organization entries
// and if exist
// throw exception that this sub organization cannot be
// deleted.
if ((subRlmSet !=null) && (!subRlmSet.isEmpty())) {
throw (new SMSException(SMSEntry.bundle
.getString("sms-entries-exists"),
"sms-entries-exists"));
}
}
// Obtain the SMSEntry for the suborg and
// sub tree and delete it.
entry.delete(token);
cEntry.refresh(entry);
} catch (SSOException ssoe) {
SMSEntry.debug.error(
"OrganizationConfigManager: deleteSubOrganization(" +
"String subOrgName, boolean recursive) Unable to " +
"delete sub organization ", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in legacy mode or (realm mode and copy org enabled)
// delete the corresponding organization.
if ((coexistMode) || (realmEnabled && isCopyOrgEnabled())) {
String amsdkName = DNMapper.realmNameToAMSDKName(subOrgDN);
if (!SMSEntry.getRootSuffix().equalsIgnoreCase(
SMSEntry.getAMSdkBaseDN())) {
String convOrg = subOrgName;
if (subOrgName.startsWith("/")) {
convOrg = DNMapper.convertToDN(subOrgName).toString();
}
amsdkName = convOrg + SMSEntry.COMMA + amSDKOrgDN;
}
amsdk.deleteSubOrganization(amsdkName);
}
}
/**
* Returns the <code>OrganizationConfigManager</code>
* for the given organization name.
*
* @param subOrgName
* the name of the organization.
* @return the configuration manager for the given organization.
*
* @throws SMSException
* if the organization name cannot be found or user doesn't have
* access to that organization.
*/
public OrganizationConfigManager getSubOrgConfigManager(String subOrgName)
throws SMSException {
validateConfigImpl();
// Normalize sub organization name
return (new OrganizationConfigManager(token, normalizeDN(subOrgName,
orgDN)));
}
/**
* Returns the organization creation attributes for
* the service.
*
* @param serviceName
* name of the service.
* @return map of organization creation attribute values for service
* @throws SMSException
* if there is an error accessing the data store to read the
* attributes of the service.
*/
public Map getAttributes(String serviceName) throws SMSException {
validateConfigImpl();
if (serviceName == null) {
return (Collections.EMPTY_MAP);
}
Map attrValues = null;
// Attributes can be obtained only if DIT is migrated to AM 7.0
if (migratedTo70) {
// Lowercase the service name
serviceName = serviceName.toLowerCase();
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
orgDN);
if (cEntry.isDirty() || (coexistMode) ||
(realmEnabled && isCopyOrgEnabled())) {
// Since AMSDK org notifications will not be
// obtained, the entry must be read again
cEntry.refresh();
}
SMSEntry entry = cEntry.getSMSEntry();
Map map = SMSUtils.getAttrsFromEntry(entry);
if ((map != null) && (!map.isEmpty())) {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String name = (String) itr.next();
if ((name.toLowerCase()).startsWith(serviceName)) {
Set values = (Set) map.get(name);
// Remove the serviceName and '-' and return only
// the attribute name,value.
String key;
if (!serviceName.isEmpty()) {
key = name.substring(serviceName.length() + 1);
} else {
key = name;
}
if (attrValues == null) {
attrValues = new HashMap();
}
attrValues.put(key, values);
}
}
}
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "getAttributes(String serviceName) Unable to "
+ "get Attributes", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in coexistMode and serviceName is idRepoService
// get attributes from AMSDK organization
if ((coexistMode || (realmEnabled && isCopyOrgEnabled()))
&& serviceName
.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE)) {
Map amsdkMap = amsdk.getAttributes();
Map mergesdkMap = new HashMap(2);
if (amsdkMap != null && !amsdkMap.isEmpty()) {
Set mergeValues = new HashSet(2);
Iterator itr = amsdkMap.keySet().iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
if (key.equalsIgnoreCase(SUNDNS_ALIAS) ||
key.equalsIgnoreCase(SUNPREF_DOMAIN) ||
key.equalsIgnoreCase(SUNORG_ALIAS)) {
buildSet(key, amsdkMap, mergeValues);
}
}
mergesdkMap.put(SUNORG_ALIAS, mergeValues);
mergesdkMap.put(SUNORG_STATUS,
(Set) amsdkMap.get(SUNORG_STATUS));
}
if (attrValues == null) {
attrValues = mergesdkMap;
} else {
attrValues.putAll(mergesdkMap);
}
}
return ((attrValues == null) ? Collections.EMPTY_MAP : attrValues);
}
/**
* Builds and returns the appropriate Set for the attributes to be
* merged from org and realm if the system is
* in intrusive mode (Both org DIT and realm DIT are present).
* This happens when the Copy Config flag is enabled.
*/
private Set buildSet(String attrName, Map attributes, Set resultSet) {
Set vals = (Set) attributes.get(attrName);
if ((vals != null) && !vals.isEmpty()) {
resultSet.addAll(vals);
}
return (resultSet);
}
/**
* Adds organization attributes for the service. If
* the attribute already exists, the values will be appended to it, provided
* it is a multi-valued attribute. It will throw exception if we try to add
* a value to an attribute which has the same value already.
*
* @param serviceName
* name of the service.
* @param attrName
* name of the attribute.
* @param values
* values for the attribute.
* @throws SMSException
* if we try to add a value to an attribute which has the same
* value already.
*/
public void addAttributeValues(String serviceName, String attrName,
Set values) throws SMSException {
validateConfigImpl();
if (serviceName == null || attrName == null) {
return;
}
if (migratedTo70) {
// Lowercase the servicename
serviceName = serviceName.toLowerCase();
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
orgDN);
if (cEntry.isDirty()) {
cEntry.refresh();
}
SMSEntry e = cEntry.getClonedSMSEntry();
ServiceSchemaManager ssm = new ServiceSchemaManager(
serviceName, token);
ServiceSchema ss = ssm.getOrganizationCreationSchema();
if (ss == null) {
throw (new SMSException(SMSEntry.bundle
.getString("sms-SMSSchema_service_notfound"),
"sms-SMSSchema_service_notfound"));
}
Map map = new HashMap(2);
Set newValues = new HashSet(values);
Map allAttributes = ss.getAttributeDefaults();
Set existingValues = (Set)allAttributes.get(attrName);
if ((existingValues != null) && !existingValues.isEmpty()) {
newValues.addAll(existingValues);
}
map.put(attrName, newValues);
ss.validateAttributes(map);
SMSUtils.addAttribute(e, serviceName + "-" + attrName,
values, ss.getSearchableAttributeNames());
e.save(token);
cEntry.refresh(e);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable "
+ "to add Attribute Values", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in coexistMode and serviceName is idRepoService
// add the attributes to AMSDK organization
if (coexistMode
&& serviceName
.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE)) {
amsdk.addAttributeValues(attrName, values);
}
}
/**
* Sets/Creates organization attributes for the
* service. If the attributes already exists, the given attribute values
* will replace them.
*
* @param serviceName
* name of the service.
* @param attributes
* attribute-values pairs.
* @throws SMSException
* if the serviceName cannot be found.
*/
public void setAttributes(String serviceName, Map attributes)
throws SMSException {
validateConfigImpl();
if (serviceName == null) {
return;
}
if (migratedTo70) {
// Lowercase the serviceName
serviceName = serviceName.toLowerCase();
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
orgDN);
if (cEntry.isDirty()) {
cEntry.refresh();
}
SMSEntry e = cEntry.getClonedSMSEntry();
if ((attributes != null) && (!attributes.isEmpty())) {
// Validate the attributes
ServiceSchemaManager ssm = new ServiceSchemaManager(
serviceName, token);
ServiceSchema ss = ssm.getOrganizationCreationSchema();
ss.validateAttributes(attributes);
// Normalize the attributes with service name
Map attrsMap = new HashMap();
Iterator itr = attributes.keySet().iterator();
while (itr.hasNext()) {
String name = (String) itr.next();
Set values = (Set) attributes.get(name);
/*
* To make the attributes qualified by service name we
* prefix the attribute names with the service name.
*/
attrsMap.put(serviceName + "-" + name, values);
}
// Look for old attrs. in the storage and add them too.
Map oldAttrs = getAttributes(serviceName);
Iterator it = oldAttrs.keySet().iterator();
while (it.hasNext()) {
String skey = (String) it.next();
if (!attributes.containsKey(skey))
attrsMap.put(serviceName + "-" + skey, oldAttrs
.get(skey));
}
// Set the attributes in SMSEntry
SMSUtils.setAttributeValuePairs(e, attrsMap, ss
.getSearchableAttributeNames());
String dataStore = SMSEntry.getDataStore(token);
// Add these OCs only for SunOne DS. Do not add the
// OCs for Active Directory.
// Will get WILL_NOT_PERFORM in AD.
if ((dataStore != null) && !dataStore.equals(
SMSEntry.DATASTORE_ACTIVE_DIR)
) {
// This is for storing organization attributes
// in top/default realm node. eg.,ou=services,o=isp
if (e.getDN().equalsIgnoreCase(SERVICES_NODE)) {
String[] ocVals = e
.getAttributeValues(SMSEntry.ATTR_OBJECTCLASS);
boolean exists = false;
for (int ic = 0; ocVals != null
&& ic < ocVals.length; ic++)
{
if (ocVals[ic].startsWith(
SMSEntry.OC_SERVICE_COMP)) {
// OC needs to be added outside the for loop
// else will throw concurrent mod exception
exists = true;
break;
}
}
if (!exists) {
e.addAttribute(SMSEntry.ATTR_OBJECTCLASS,
SMSEntry.OC_SERVICE_COMP);
}
} else if (e.getDN().startsWith(
SMSEntry.ORGANIZATION_RDN + SMSEntry.EQUALS)) {
// This is for storing organization attributes in
// organizations created via sdk through realm
// console.
String[] vals = e
.getAttributeValues(SMSEntry.ATTR_OBJECTCLASS);
boolean rsvcExists = false;
for (int n = 0; vals != null && n < vals.length;
n++) {
if (vals[n].equalsIgnoreCase(
SMSEntry.OC_REALM_SERVICE))
{
// OC needs to be added outside the for loop
// else will throw concurrent mod exception
rsvcExists = true;
break;
}
}
if (!rsvcExists) {
e.addAttribute(SMSEntry.ATTR_OBJECTCLASS,
SMSEntry.OC_REALM_SERVICE);
}
}
}
// Save in backend data store and refresh the cache
e.save(token);
cEntry.refresh(e);
}
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable "
+ "to set Attributes", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in coexistMode and serviceName is idRepoService
// set the attributes to AMSDK organization
if ((coexistMode || (realmEnabled && isCopyOrgEnabled()))
&& serviceName
.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE)) {
amsdk.setAttributes(attributes);
}
}
/**
* Removes the given organization creation attribute
* for the service.
*
* @param serviceName
* name of service.
* @param attrName
* name of attribute.
* @throws SMSException
* if the organization attribute for the service to be removed
* cannot be found, or if the service name cannot be found.
*/
public void removeAttribute(String serviceName, String attrName)
throws SMSException {
validateConfigImpl();
if (serviceName == null || attrName == null) {
return;
}
if (migratedTo70) {
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
orgDN);
if (cEntry.isDirty()) {
cEntry.refresh();
}
SMSEntry e = cEntry.getClonedSMSEntry();
SMSUtils.removeAttribute(e, serviceName.toLowerCase() + "-"
+ attrName);
e.save(token);
cEntry.refresh(e);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable "
+ "to remove Attribute", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in coexistMode and serviceName is idRepoService
// remove the attributes to AMSDK organization
if (coexistMode
&& serviceName
.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE)) {
amsdk.removeAttribute(attrName);
}
}
/**
* Removes the given organization creation attribute
* values for the service.
*
* @param serviceName
* name of service.
* @param attrName
* name of attribute.
* @param values
* attribute values to be removed.
* @throws SMSException
* if the organization attribute for the service to be removed
* cannot be found, or if the service name cannot be found, or
* if the value cannot be removed.
*/
public void removeAttributeValues(String serviceName, String attrName,
Set values) throws SMSException {
validateConfigImpl();
if (serviceName == null || attrName == null) {
return;
}
if (migratedTo70) {
try {
CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token,
orgDN);
if (cEntry.isDirty()) {
cEntry.refresh();
}
SMSEntry e = cEntry.getClonedSMSEntry();
ServiceSchemaManager ssm = new ServiceSchemaManager(
serviceName, token);
ServiceSchema ss = ssm.getOrganizationCreationSchema();
Map map = new HashMap(2);
map.put(attrName, values);
ss.validateAttributes(map);
SMSUtils.removeAttributeValues(e, serviceName.toLowerCase()
+ "-" + attrName, values, ss
.getSearchableAttributeNames());
e.save(token);
cEntry.refresh(e);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable "
+ "to remove Attribute Values", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
// If in coexistMode and serviceName is idRepoService
// remove the attributes to AMSDK organization
if (coexistMode
&& serviceName
.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE)) {
amsdk.removeAttributeValues(attrName, values);
}
}
/**
* Returns the service configuration object for the
* given service name.
*
* @param serviceName
* name of a service.
* @return service configuration object for the service.
* @throws SMSException
* if there is an error accessing the data store to read the
* service configuration, or if the service name cannot be
* found.
*/
public ServiceConfig getServiceConfig(String serviceName)
throws SMSException {
try {
ServiceConfigManager scmgr = new ServiceConfigManager(serviceName,
token);
ServiceConfig scg = scmgr.getOrganizationConfig(orgName, null);
return (scg);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable to "
+ "get Service Config", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
ServiceSchema getServiceSchema(String serviceName) throws SMSException {
try {
return new ServiceSchemaManager(serviceName, token).getOrganizationSchema();
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable to get Service Schema", ssoe);
throw new SMSException(SMSEntry.bundle.getString(SMS_INVALID_SSO_TOKEN), SMS_INVALID_SSO_TOKEN);
}
}
/**
* Adds a service configuration object for the given
* service name for this organization. If the service has been already added
* a <code>SMSException</code> will be thrown.
*
* @param serviceName
* name of the service.
* @param attributes
* service configuration attributes.
* @return service configuration object.
* @throws SMSException
* if the service configuration has been added already.
*/
public ServiceConfig addServiceConfig(String serviceName, Map attributes)
throws SMSException {
try {
ServiceConfigManagerImpl scmi = ServiceConfigManagerImpl
.getInstance(token, serviceName,
ServiceManager.getVersion(serviceName));
ServiceConfigImpl sci = scmi.getOrganizationConfig(token, orgName,
null);
if (sci == null || sci.isNewEntry()) {
ServiceConfigManager scm = new ServiceConfigManager(
serviceName, token);
return (scm.createOrganizationConfig(orgName, attributes));
} else {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "ServiceConfig already exists: " + sci.getDN());
throw (new SMSException(SMSEntry.bundle
.getString("sms-service_already_exists1")));
}
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable to "
+ "add Service Config", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
/**
* Removes the service configuration object for the
* given service name for this organization.
*
* @param serviceName
* name of the service.
* @throws SMSException
* if the service name cannot be found, or not added to the
* organization.
*/
public void removeServiceConfig(String serviceName) throws SMSException {
try {
ServiceConfigManager scm = new ServiceConfigManager(serviceName,
token);
scm.deleteOrganizationConfig(orgName);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: Unable to "
+ "delete Service Config", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
/**
* Registers for changes to organization's
* configuration. The object will be called when configuration for this
* organization is changed.
*
* @param listener
* callback object that will be invoked when organization
* configuration has changed
* @return an ID of the registered listener.
*/
public String addListener(ServiceListener listener) {
return (orgConfigImpl.addListener(listener));
}
/**
* Removes the listener from the organization for the
* given listener ID. The ID was issued when the listener was registered.
*
* @param listenerID
* the listener ID issued when the listener was registered
*/
public void removeListener(String listenerID) {
orgConfigImpl.removeListener(listenerID);
}
/**
* Returns normalized DN for realm model
*/
private static String normalizeDN(String subOrgName, String orgDN) {
// Return orgDN if subOrgName is either null or empty
if (subOrgName == null || subOrgName.length() == 0) {
return (orgDN);
}
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager."
+ "normalizeDN()-subOrgName " + subOrgName);
}
String subOrgDN = null;
if (LDAPUtils.isDN(subOrgName) && (!subOrgName.startsWith("///"))) {
int ndx = subOrgName.lastIndexOf(DNMapper.serviceDN);
if (ndx == -1) {
// Check for baseDN
ndx = subOrgName.lastIndexOf(SMSEntry.getRootSuffix());
}
if (ndx > 0) {
subOrgName = subOrgName.substring(0, ndx - 1);
}
subOrgDN = DNMapper.normalizeDN(subOrgName) + orgDN;
} else if (subOrgName.indexOf('/') != -1) {
String tmp = DNMapper.convertToDN(subOrgName).toString();
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager."
+ "normalizeDN()-slashConvertedString: " + tmp);
}
if (tmp != null && tmp.length() > 0) {
if (tmp.charAt(tmp.length() - 1) == ',') {
subOrgDN = tmp + DNMapper.serviceDN;
} else {
int dx = tmp.indexOf(SMSEntry.COMMA);
if (dx >= 0) {
subOrgDN = tmp + SMSEntry.COMMA + DNMapper.serviceDN;
} else {
subOrgDN = tmp + SMSEntry.COMMA + orgDN;
}
}
} else {
subOrgDN = orgDN;
}
} else if (subOrgName.startsWith(SMSEntry.SUN_INTERNAL_REALM_NAME)) {
subOrgDN = SMSEntry.ORG_PLACEHOLDER_RDN + subOrgName
+ SMSEntry.COMMA + DNMapper.serviceDN;
} else {
if (coexistMode) {
subOrgDN = orgNamingAttrInLegacyMode + SMSEntry.EQUALS
+ subOrgName + SMSEntry.COMMA
+ DNMapper.realmNameToAMSDKName(orgDN);
} else {
subOrgDN = SMSEntry.ORG_PLACEHOLDER_RDN + subOrgName
+ SMSEntry.COMMA + orgDN;
}
}
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager::"
+ "normalizeDN() suborgdn " + subOrgDN);
}
return (subOrgDN);
}
/**
* Returns all service names configured for AM
*/
static Set getServiceNames(SSOToken token) throws SMSException,
SSOException {
// Get the service names from ServiceManager
CachedSubEntries cse = CachedSubEntries.getInstance(token,
DNMapper.serviceDN);
return (cse.getSubEntries(token));
}
/**
* Returns a set of service names that can be assigned
* to a realm. This set excludes name of services that are already assigned
* to the realm and services that are required for the existence of a realm.
*
* @return a set of service names that can be assigned to a realm.
* @throws SMSException
* if there is an error accessing the data store to read the
* service configuration
*/
public Set getAssignableServices() throws SMSException {
// Get all service names, and remove the assigned services
// Set containing service names that has organization schema
Set orgSchemaServiceNames = new HashSet();
try {
for (Iterator names = getServiceNames(token).iterator(); names
.hasNext();) {
String serviceName = (String) names.next();
ServiceSchemaManagerImpl ssmi = ServiceSchemaManagerImpl
.getInstance(token, serviceName,
ServiceManager.getVersion(serviceName));
if (ssmi.getSchema(SchemaType.ORGANIZATION) != null) {
// Need to check if the user has permission
// to add/assign the service
StringBuilder d = new StringBuilder(100);
// Need to construct
// "ou=default,ou=organizationconfig,ou=1.0,ou="
d.append(SMSEntry.PLACEHOLDER_RDN).append(SMSEntry.EQUALS)
.append(SMSUtils.DEFAULT).append(SMSEntry.COMMA)
.append(CreateServiceConfig.ORG_CONFIG_NODE)
.append(SMSEntry.PLACEHOLDER_RDN).append(
SMSEntry.EQUALS).append("1.0").append(
SMSEntry.COMMA).append(
SMSEntry.PLACEHOLDER_RDN).append(
SMSEntry.EQUALS);
// Append service name, and org name
d.append(serviceName);
if (!orgDN.equalsIgnoreCase(DNMapper.serviceDN)) {
d.append(SMSEntry.COMMA).append(SMSEntry.SERVICES_RDN);
}
d.append(SMSEntry.COMMA).append(orgDN);
try {
// The function will throw exception if
// user does not have permissions
SMSEntry.getDelegationPermission(token, d.toString(),
SMSEntry.modifyActionSet);
orgSchemaServiceNames.add(serviceName);
} catch (SMSException smse) {
if (smse.getExceptionCode() !=
SMSException.STATUS_NO_PERMISSION)
{
throw (smse);
}
}
}
}
// Need to remove mandatory services
// %%% TODO. Need to have SMS Service with this information
// orgSchemaServiceNames.removeAll(getMandatoryServices());
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager."
+ "getAssignableServices(): SSOException", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
// Remove assigned services
HashSet answer = new HashSet(orgSchemaServiceNames);
answer.removeAll(getAssignedServices());
return (answer);
}
/**
* Returns a set of service names that are assigned to
* a realm.
*
* @return a set of service names that are assigned to a realm.
* @throws SMSException
* if there is an error accessing the data store to read the
* service configuration
*/
public Set<String> getAssignedServices() throws SMSException {
return (getAssignedServices(true));
}
/**
* Returns a set of service names that are assigned to a realm.
*
* @param includeMandatory
* <code>true</code> to include mandatory service names.
* @return a set of service names that are assigned to a realm.
* @throws SMSException
* if there is an error accessing the data store to read the
* service configuration
*/
public Set<String> getAssignedServices(boolean includeMandatory)
throws SMSException {
validateConfigImpl();
Set<String> assignedServices = Collections.EMPTY_SET;
if (coexistMode) {
// Get assigned services from OrgConfigViaAMSDK
assignedServices = amsdk.getAssignedServices();
} else {
// Get assigned service names from OrganizationConfigManagerImpl
assignedServices = orgConfigImpl.getAssignedServices(token);
}
if (!includeMandatory) {
// Get services assigned by default
Set ds = ServiceManager.requiredServices();
assignedServices.removeAll(ds);
}
return (assignedServices);
}
/**
* Assigns the given service to the orgnization with
* the respective attributes. If the service has been already added a <code>
* SMSException</code>
* will be thrown.
*
* @param serviceName
* name of the service
* @param attributes
* service configuration attributes
* @throws SMSException
* if the service configuration has been added already.
*/
public void assignService(String serviceName, Map attributes)
throws SMSException {
addServiceConfig(serviceName, attributes);
}
/**
* Returns attributes configured for the service.
*
* @param serviceName
* name of the service
* @return a map of attributes for the service
* @throws SMSException
* if there is an error accessing the data store to read the
* service configuration, or if the service name cannot be
* found.
*/
public Map getServiceAttributes(String serviceName) throws SMSException {
ServiceConfig scg = getServiceConfig(serviceName);
if (scg == null) {
Object args[] = { serviceName };
SMSEntry.debug.error(
"OrganizationConfigManager.getServiceAttributes() Unable " +
"to get service attributes. ");
throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
"sms-no-organization-schema",
args));
}
return (scg.getAttributes());
}
/**
* Unassigns the service from the organization.
*
* @param serviceName
* name of the service
* @throws SMSException
* if the service name cannot be found or assigned, or if the
* service is a mandatory service.
*/
public void unassignService(String serviceName) throws SMSException {
// if (coexistMode) {
// amsdk.unassignService(serviceName);
// } else {
removeServiceConfig(serviceName);
// }
}
/**
* Sets the attributes related to provided service.
* The assumption is that the service is already assigned to the
* organization. The attributes for the service are validated against the
* service schema.
*
* @param serviceName
* name of the service
* @param attributes
* attributes of the service
* @throws SMSException
* if the service name cannot be found or not assigned to the
* organization.
*/
public void modifyService(String serviceName, Map attributes)
throws SMSException {
try {
getServiceConfig(serviceName).setAttributes(attributes);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager.modifyService "
+ "SSOException in modify service ", ssoe);
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
public String getNamingAttrForOrg() {
return OrgConfigViaAMSDK.getNamingAttrForOrg();
}
/**
* Returns the <code>OrganizationConfigManager</code>
* of the parent for the given organization name.
*
* @return the configuration manager of the parent for the given
* organization.
* @throws SMSException
* if user doesn't have access to that organization.
*/
public OrganizationConfigManager getParentOrgConfigManager()
throws SMSException {
OrganizationConfigManager ocm = null;
String parentDN = null;
if (LDAPUtils.isDN(orgDN)) {
if (orgDN.equalsIgnoreCase(DNMapper.serviceDN)) {
return (this);
}
parentDN = DN.valueOf(orgDN).parent().toString();
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager."
+ "getParentOrgConfigManager() parentDN : " + parentDN);
}
if (parentDN != null && parentDN.length() > 0) {
ocm = new OrganizationConfigManager(token, parentDN);
}
}
return ocm;
}
/**
* Loads default services to a newly created realm
*/
public static void loadDefaultServices(SSOToken token,
OrganizationConfigManager ocm) throws SMSException {
// Check if DIT has been migrated to 7.0
if (!migratedTo70) {
return;
}
Set defaultServices = ServiceManager.servicesAssignedByDefault();
// Load the default services automatically
OrganizationConfigManager parentOrg = ocm.getParentOrgConfigManager();
if (defaultServices == null) {
// There are no services to be loaded
return;
}
Set assignedServices = new CaseInsensitiveHashSet(
parentOrg.getAssignedServices());
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager"
+ "::loadDefaultServices " + "assignedServices : "
+ assignedServices);
}
boolean doAuthServiceLater = false;
boolean doAuthHttpBasicLater = false;
String serviceName = null;
// Copy service configuration
Iterator items = defaultServices.iterator();
while (items.hasNext() || doAuthHttpBasicLater || doAuthServiceLater) {
if (items.hasNext()) {
serviceName = (String) items.next();
if (serviceName.equals(ISAuthConstants.AUTH_SERVICE_NAME)) {
doAuthServiceLater = true;
continue;
} else if (serviceName.equals(
ISAuthConstants.AUTH_HTTP_BASIC_SERVICE_NAME)) {
doAuthHttpBasicLater = true;
continue;
}
} else if (doAuthHttpBasicLater) {
serviceName = ISAuthConstants.AUTH_HTTP_BASIC_SERVICE_NAME;
doAuthHttpBasicLater = false;
} else if (doAuthServiceLater) {
serviceName = ISAuthConstants.AUTH_SERVICE_NAME;
doAuthServiceLater = false;
}
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager" +
"::loadDefaultServices:ServiceName " + serviceName);
}
try {
ServiceConfig sc = parentOrg.getServiceConfig(serviceName);
ServiceSchema ss = parentOrg.getServiceSchema(serviceName);
Map attrs = null;
if (sc != null && assignedServices.contains(serviceName)) {
attrs = sc.getAttributesWithoutDefaults();
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug
.message("OrganizationConfigManager"
+ "::loadDefaultServices "
+ "Copying service from parent: "
+ serviceName);
}
ServiceConfig scn = ocm
.addServiceConfig(serviceName, attrs);
// Copy sub-configurations, if any
copySubConfig(sc, scn, ss);
}
} catch (SSOException ssoe) {
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message(
"OrganizationConfigManager.loadDefaultServices " +
"SSOException in loading default services ",
ssoe);
}
throw (new SMSException(SMSEntry.bundle
.getString(SMS_INVALID_SSO_TOKEN),
SMS_INVALID_SSO_TOKEN));
}
}
}
/**
* Registers default services to newly created suborganizations.
*/
private void registerSvcsForOrg(String subOrgName, String subOrgDN)
{
try {
Set defaultServices =
ServiceManager.servicesAssignedByDefault();
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager::"+
"registerSvcsForOrg. "+
"defaultServices : " + defaultServices);
}
// Register the default services to the newly created orgs,so
// they will be marked with the OC sunRegisteredServiceName.
if (defaultServices != null) {
Set assignedServices = amsdk.getAssignedServices();
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager::" +
"registerSvcsForOrg:assignedServices: " +
assignedServices);
}
Iterator items = defaultServices.iterator();
String serviceName = null;
if (SMSEntry.getRootSuffix().equalsIgnoreCase(
SMSEntry.getAMSdkBaseDN())) {
amsdk = new OrgConfigViaAMSDK(token,
orgNamingAttrInLegacyMode + SMSEntry.EQUALS +
subOrgName + SMSEntry.COMMA +
DNMapper.realmNameToAMSDKName(orgDN), subOrgDN);
} else {
amsdk = new OrgConfigViaAMSDK(token,
orgNamingAttrInLegacyMode + SMSEntry.EQUALS +
subOrgName + SMSEntry.COMMA + amSDKOrgDN, subOrgDN);
}
while (items.hasNext()) {
serviceName = (String) items.next();
if (assignedServices.contains(serviceName)) {
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message(
"OrganizationConfigManager::"+
"registerSvcsForOrg:ServiceName : " +
serviceName);
}
amsdk.assignService(serviceName);
}
}
}
} catch (SMSException smse) {
// Unable to load default services
if (SMSEntry.debug.warningEnabled()) {
SMSEntry.debug.warning("OrganizationConfigManager::" +
"registerSvcsForOrg. " +
"SMSException in registering services: ", smse);
}
}
}
/**
* Copies service configurations recursively from source to destination
*/
static void copySubConfig(ServiceConfig from, ServiceConfig to, ServiceSchema serviceSchema)
throws SMSException, SSOException {
Set subConfigNames = from.getSubConfigNames();
for (Iterator items = subConfigNames.iterator(); items.hasNext();) {
String subConfigName = (String) items.next();
ServiceConfig scf = from.getSubConfig(subConfigName);
ServiceSchema subSchema = serviceSchema.getSubSchema(scf.getSchemaID());
if (subSchema.isRealmCloneable()) {
to.addSubConfig(subConfigName, scf.getSchemaID(), scf.getPriority(), scf.getAttributesWithoutDefaults());
ServiceConfig sct = to.getSubConfig(subConfigName);
copySubConfig(scf, sct, subSchema);
}
}
}
/**
* Determines whether an organization ought to be created for each
* realm in realm only mode of installation based on the boolean flag
* in amSDK plugin.
* This requirement is for portal customers.
*/
protected boolean isCopyOrgEnabled() {
if (copyOrgInitialized) {
return (copyOrgEnabled);
}
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager: "+
"in isCopyOrgEnabled() ");
}
// Check if AMSDK is configured for the realm
try {
ServiceConfig s = getServiceConfig(ServiceManager.REALM_SERVICE);
if (s != null) {
Iterator items = s.getSubConfigNames().iterator();
while (items.hasNext()) {
String name = items.next().toString();
ServiceConfig subConfig = s.getSubConfig(name);
if (subConfig == null) {
SMSEntry.debug.error("OrganizationConfigManager.is" +
"CopyOrgEnabled. SubConfig is NULL: " +
"SC Name: " + name + " For org: " + orgDN);
return (false);
}
if (subConfig.getSchemaID().equalsIgnoreCase(
IdConstants.AMSDK_PLUGIN_NAME)) {
Map configMap = subConfig.getAttributes();
if ((configMap != null) && !configMap.isEmpty()) {
// Get the amsdkOrgName from the amSDKRepo to build
// OrgConfigViaSDK instance.
Set orgs = (Set) configMap.get("amSDKOrgName");
if (orgs != null && !orgs.isEmpty()) {
amSDKOrgDN = (String) orgs.iterator().next();
Set cfgs = (Set) configMap.get(CONF_ENABLED);
if ( (cfgs != null) && (!cfgs.isEmpty()) &&
(cfgs.contains("true")) &&
(amSDKOrgDN !=null) ) {
amsdk = new OrgConfigViaAMSDK(token,
amSDKOrgDN, orgDN);
if (orgNamingAttrInLegacyMode == null) {
orgNamingAttrInLegacyMode =
getNamingAttrForOrg();
}
copyOrgEnabled = true;
}
break;
}
}
}
}
}
} catch (SSOException sse) {
// Use default values i.e., false
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager:" +
"isCopyOrgEnabled() Unable to get service: " +
ServiceManager.REALM_SERVICE, sse);
}
} catch (SMSException e) {
// Use default values i.e., false
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager:" +
"isCopyOrgEnabled() Unable to get service: " +
ServiceManager.REALM_SERVICE, e);
}
}
copyOrgInitialized = true;
if (SMSEntry.debug.messageEnabled()) {
SMSEntry.debug.message("OrganizationConfigManager: "+
"copyOrgEnabled == " + copyOrgEnabled);
}
return (copyOrgEnabled);
}
static void initializeFlags() {
realmEnabled = ServiceManager.isRealmEnabled();
coexistMode = ServiceManager.isCoexistenceMode();
migratedTo70 = ServiceManager.isConfigMigratedTo70();
}
void validateConfigImpl() throws SMSException {
// Instantiate the OrgConfigImpl and cache it
if ((orgConfigImpl == null) || !orgConfigImpl.isValid()) {
try {
orgConfigImpl = OrganizationConfigManagerImpl.getInstance(
token, orgName);
} catch (SSOException ssoe) {
throw (new SMSException(ssoe, SMS_INVALID_SSO_TOKEN));
}
}
}
class OrganizationConfigManagerListener implements ServiceListener {
public void schemaChanged(String serviceName, String version) {
// Call ServiceManager to notify
ServiceManager.schemaChanged();
// If naming service has changed, reload the AM Servers
if (serviceName.equalsIgnoreCase(ServiceManager.PLATFORM_SERVICE)) {
ServiceManager.accessManagerServers = null;
}
}
public void globalConfigChanged(String serviceName, String version,
String groupName, String serviceComponent, int type) {
if (serviceName.equalsIgnoreCase(ServiceManager.REALM_SERVICE)) {
try {
ServiceManager.checkFlags(token);
} catch (SSOException ssoe) {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "globalConfigChanged ", ssoe);
} catch (SMSException smse) {
SMSEntry.debug.error("OrganizationConfigManager: "
+ "globalConfigChanged ", smse);
}
realmEnabled = ServiceManager.isRealmEnabled();
coexistMode = ServiceManager.isCoexistenceMode();
migratedTo70 = ServiceManager.isConfigMigratedTo70();
}
}
public void organizationConfigChanged(String serviceName,
String version, String orgName, String groupName,
String serviceComponent, int type) {
// Reset the cached configuration in OrgConfigViaAMSDK
if (serviceName.equalsIgnoreCase(OrgConfigViaAMSDK.IDREPO_SERVICE))
{
OrgConfigViaAMSDK.attributeMappings = new HashMap();
OrgConfigViaAMSDK.reverseAttributeMappings = new HashMap();
}
}
}
// ******* Static Variables ************
// To determine if notification object has been registered for config
// changes
private static boolean registeredForConfigNotifications;
// Realm & Co-existence modes
private static boolean realmEnabled;
private static boolean coexistMode;
private static boolean migratedTo70;
}