8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: OrganizationConfigManagerImpl.java,v 1.12 2009/07/25 05:11:55 qcheng Exp $
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * Portions Copyrighted 2011-2015 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The class <code>OrganizationConfigManagerImpl</code> provides interfaces to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * read the service's configuration data. It provides access to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>OrganizationConfigImpl</code> which represents a single
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "configuration" in the service. It manages configuration data only for GLOBAL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and ORGANIZATION types.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterclass OrganizationConfigManagerImpl implements SMSObjectListener {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Instance variables
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Pointer to schema changes listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private Map listenerObjects = Collections.synchronizedMap(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Notification search string
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Constructs an instance of <code>OrganizationConfigManagerImpl</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * for the given organization. It requires an user identity that will be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * used to perform read operations. It is assumed that the application
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * calling this constructor should authenticate the user.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private OrganizationConfigManagerImpl(CachedSMSEntry entry,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String orgDN, SSOToken token) throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Register for notifications
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster listenerId = SMSNotificationManager.getInstance()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!orgDN.startsWith(SMSEntry.SERVICES_RDN)) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington DN notifyDN = DN.valueOf(SMSEntry.SERVICES_RDN + "," + orgDN);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington orgNotificationSearchString = notifyDN.toString().toLowerCase();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns organization name as DN
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns a set of service names that are assigned to this realm
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set getAssignedServices(SSOToken token) throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get service names and iterate through them
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster se = CachedSubEntries.getInstance(token, orgDN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster se = CachedSubEntries.getInstance(token, "ou=services,"+orgDN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator names = se.getSubEntries(token).iterator(); names
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // For backward compatibility, get the version from the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // service. no hardcoding to '1.0', even if it improves
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee // performance in OpenAM. Otherwise, it breaks for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // services like iplanetAMProviderConfigService with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // '1.1' as version.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .getInstance(token, serviceName, ServiceManager
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // handle special case for co-existence of OpenSSO and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // AM 7.1. The version for iplanetAMProviderConfigService
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // is "1.1" instead of "1.0" for other services.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster scmi = ServiceConfigManagerImpl.getInstance(token,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster serviceName, ServiceManager.getVersion(serviceName));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceConfigImpl sci = scmi.getOrganizationConfig(token,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("OrganizationConfigManagerImpl.getAssignedServices "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sms-INVALID_SSO_TOKEN"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the names of all suborganizations.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set getSubOrganizationNames(SSOToken token) throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (getSubOrganizationNames(token, "*", false));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the names of suborganizations that match the given pattern.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set getSubOrganizationNames(SSOToken token, String pattern,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster subEntries = CachedSubEntries.getInstance(token, orgDN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (subEntries.searchSubOrgNames(token, pattern, recursive));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("OrganizationConfigManagerImpl: Unable to "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sms-INVALID_SSO_TOKEN"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Registers for changes to organization's configuration. The object will be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * called when configuration for this organization is changed.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param listener
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * callback object that will be invoked when organization
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * configuration has changed
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return an ID of the registered listener.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized String addListener(ServiceListener listener) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Removes the listener from the organization for the given listener ID. The
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * ID was issued when the listener was registered.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param listenerID
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the listener ID issued when the listener was registered
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void removeListener(String listenerID) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((listenerID != null) && listenerObjects.isEmpty()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSNotificationManager.getInstance().removeCallbackHandler(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Implementations for SMSObjectListener
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Ignore, do nothing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void objectChanged(String dn, int type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check for listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrgConfigMgrImpl::entryChanged"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "\norgNotificationSearchString: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // check for service name, version and type
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // From realm tree, orgNotificationSearchString will be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // ou=services,o=hpq,ou=services,dc=iplanet,dc=com
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrgConfigMgrImpl::entryChanged "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + " DN: " + dn + "\norgNotificationSearchString: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if the DN matches with organization name
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((index = dn.indexOf(orgNotificationSearchString)) != -1) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Initialize parameters
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the DN ignoring the organization name
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington DN ndn = DN.valueOf(dn.substring(0, index - 1));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Needs to check if the DN has more realm names
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (size != 0 && "o".equals(LDAPUtils.rdnValue(ndn.rdn()))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // More realm names are present, changes not meant for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // this organization
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "OrgConfigMgrImpl::entryChanged Notification " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "not sent since realms names donot match. \nDN: " +
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Iterator<RDN> rdnIterator = ndn.iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the version, service, group and component name
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington serviceName = LDAPUtils.rdnValue(rdnIterator.next());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington version = LDAPUtils.rdnValue(rdnIterator.next());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington //Skip 1 RDNs
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington groupName = LDAPUtils.rdnValue(rdnIterator.next());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // The subconfig names should be "/" separated and left to right
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington sbr.append('/').append(LDAPUtils.rdnValue(rdnIterator.next()));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Convert changeType from JNDI to com.sun.identity.shared.ldap
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get organization name
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String orgName = dn.substring(index + orgIndex + 1);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "entryChanged() serviceName " + serviceName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.message("OrganizationConfigManagerImpl:"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Send notifications to listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster notifyOrgConfigChange(serviceName, version, orgName, groupName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster void notifyOrgConfigChange(String serviceName, String version,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String orgName, String groupName, String comp, int type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (listenerObjects) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Iterator items = listenerObjects.values().iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceListener sl = (ServiceListener) items.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sl.organizationConfigChanged(serviceName, version, orgName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.eventDebug.error("OrganizationConfigManager" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Impl:notifyOrgConfigChange Error sending notify to" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Clears the listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((listenerId != null) && ((listenerObjects == null) ||
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSNotificationManager.getInstance().removeCallbackHandler(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((smsEntry.isValid() && smsEntry.isDirty()) ||
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If in co-exist mode, SMS will not get updates for org
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // hence have to update the SMSEntry
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if the organization still exists
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("OrganizationConfigManagerImpl::isValid" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If entry is invalid, remove from cache
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // ---------------------------------------------------------
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Static Protected Methods
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // ---------------------------------------------------------
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster protected static OrganizationConfigManagerImpl getInstance(SSOToken token,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String orgName) throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Convert orgName to DN
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If orgDN is the baseDN, append "ou=services" to it
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("OrganizationConfigMgrImpl::getInstance: called: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // check in cache for organization name
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster OrganizationConfigManagerImpl answer = getFromCache(orgDN, token);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((answer != null) && ServiceManager.isRealmEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If in co-exist mode, SMS will not get updates for org
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // hence have to update the cEntry
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Not in cache, construct the object and validate
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (configMgrImpls) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check the cache again, maybe added by another thread
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((answer = getFromCache(orgDN, null)) == null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If in co-exist mode, SMS will not get updates for org
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // hence have to update the cEntry
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Validate the entry
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("OrganizationConfigMgrImpl::getInstance: success: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static OrganizationConfigManagerImpl getFromCache(String cacheName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SSOToken t) throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster OrganizationConfigManagerImpl answer = (OrganizationConfigManagerImpl)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check of OCM is valid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if the user has permissions
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set principals = (Set) userPrincipals.get(cacheName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster !principals.contains(t.getTokenID().toString())) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Principal name not in cache, need to check perm
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static CachedSMSEntry checkAndUpdatePermission(String cacheName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SSOToken t) throws SSOException, SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CachedSMSEntry answer = CachedSMSEntry.getInstance(t, cacheName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set sudoPrincipals = (Set) userPrincipals.get(cacheName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sudoPrincipals = Collections.synchronizedSet(new HashSet(2));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (configMgrImpls) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator items = configMgrImpls.values().iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static Map configMgrImpls = Collections.synchronizedMap(