private static void updateAdminConnectorConfiguration( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter) throws NamingException { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes(new String[] {"ds-cfg-listen-port", "objectclass"}); String filter = "(objectclass=ds-cfg-administration-connector)"; LdapName jndiName = new LdapName("cn=config"); NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls); try { Integer adminConnectorPort = null; // we should have a single administration connector while (listeners.hasMore()) { SearchResult sr = listeners.next(); String port = getFirstValue(sr, "ds-cfg-listen-port"); adminConnectorPort = new Integer(port); } // Even if we have a single port, use an array to be consistent with // other protocols. ArrayList<Integer> adminPorts = new ArrayList<Integer>(); ArrayList<Boolean> adminEnabled = new ArrayList<Boolean>(); if (adminConnectorPort != null) { adminPorts.add(adminConnectorPort); adminEnabled.add(Boolean.TRUE); } desc.serverProperties.put(ServerProperty.ADMIN_PORT, adminPorts); desc.serverProperties.put(ServerProperty.ADMIN_ENABLED, adminEnabled); } finally { listeners.close(); } }
private static void updateLdapConfiguration( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter) throws NamingException { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes( new String[] { "ds-cfg-enabled", "ds-cfg-listen-address", "ds-cfg-listen-port", "ds-cfg-use-ssl", "ds-cfg-allow-start-tls", "objectclass" }); String filter = "(objectclass=ds-cfg-ldap-connection-handler)"; LdapName jndiName = new LdapName("cn=config"); NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls); try { ArrayList<Integer> ldapPorts = new ArrayList<Integer>(); ArrayList<Integer> ldapsPorts = new ArrayList<Integer>(); ArrayList<Boolean> ldapEnabled = new ArrayList<Boolean>(); ArrayList<Boolean> ldapsEnabled = new ArrayList<Boolean>(); ArrayList<Boolean> startTLSEnabled = new ArrayList<Boolean>(); desc.serverProperties.put(ServerProperty.LDAP_PORT, ldapPorts); desc.serverProperties.put(ServerProperty.LDAPS_PORT, ldapsPorts); desc.serverProperties.put(ServerProperty.LDAP_ENABLED, ldapEnabled); desc.serverProperties.put(ServerProperty.LDAPS_ENABLED, ldapsEnabled); desc.serverProperties.put(ServerProperty.STARTTLS_ENABLED, startTLSEnabled); while (listeners.hasMore()) { SearchResult sr = listeners.next(); String port = getFirstValue(sr, "ds-cfg-listen-port"); boolean isSecure = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-use-ssl")); boolean enabled = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-enabled")); if (isSecure) { ldapsPorts.add(new Integer(port)); ldapsEnabled.add(enabled); } else { ldapPorts.add(new Integer(port)); ldapEnabled.add(enabled); enabled = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-allow-start-tls")); startTLSEnabled.add(enabled); } } } finally { listeners.close(); } }
/** * Updates the instance key public-key certificate value of this context from the local truststore * of the instance bound by this context. Any current value of the certificate is overwritten. The * intent of this method is to retrieve the instance-key public-key certificate when this context * is bound to an instance, and cache it for later use in registering the instance into ADS. * * @param desc The map to update with the instance key-pair public-key certificate. * @param ctx The bound server instance. * @throws NamingException if unable to retrieve certificate from bound instance. */ private static void updatePublicKeyCertificate( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter filter) throws NamingException { /* TODO: this DN is declared in some core constants file. Create a constants file for the installer and import it into the core. */ final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore"; final LdapName dn = new LdapName(dnStr); for (int i = 0; i < 2; ++i) { /* If the entry does not exist in the instance's truststore backend, add it (which induces the CryptoManager to create the public-key certificate attribute), then repeat the search. */ try { final SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.OBJECT_SCOPE); final String attrIDs[] = {"ds-cfg-public-key-certificate;binary"}; searchControls.setReturningAttributes(attrIDs); final SearchResult certEntry = ctx.search(dn, "(objectclass=ds-cfg-instance-key)", searchControls).next(); final Attribute certAttr = certEntry.getAttributes().get(attrIDs[0]); if (null != certAttr) { /* attribute ds-cfg-public-key-certificate is a MUST in the schema */ desc.serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE, certAttr.get()); } break; } catch (NameNotFoundException x) { if (0 == i) { /* Poke CryptoManager to initialize truststore. Note the special attribute in the request. */ final Attributes attrs = new BasicAttributes(); final Attribute oc = new BasicAttribute("objectclass"); oc.add("top"); oc.add("ds-cfg-self-signed-cert-request"); attrs.put(oc); ctx.createSubcontext(dn, attrs).close(); } else { throw x; } } } }
/** * Returns the values of the ds-base-dn-entry count attributes for the given backend monitor entry * using the provided InitialLdapContext. * * @param ctx the InitialLdapContext to use to update the configuration. * @param backendID the id of the backend. * @return the values of the ds-base-dn-entry count attribute. * @throws NamingException if there was an error. */ private static Set<String> getBaseDNEntryCount(InitialLdapContext ctx, String backendID) throws NamingException { LinkedHashSet<String> v = new LinkedHashSet<String>(); SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE); ctls.setReturningAttributes(new String[] {"ds-base-dn-entry-count"}); String filter = "(ds-backend-id=" + backendID + ")"; LdapName jndiName = new LdapName("cn=monitor"); NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls); try { while (listeners.hasMore()) { SearchResult sr = listeners.next(); v.addAll(getValues(sr, "ds-base-dn-entry-count")); } } finally { listeners.close(); } return v; }
private static void updateMiscellaneous( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter) throws NamingException { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.OBJECT_SCOPE); ctls.setReturningAttributes(new String[] {"ds-sync-generation-id"}); String filter = "(|(objectclass=*)(objectclass=ldapsubentry))"; LdapName jndiName = new LdapName("cn=schema"); NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls); try { while (listeners.hasMore()) { SearchResult sr = listeners.next(); desc.serverProperties.put( ServerProperty.SCHEMA_GENERATION_ID, getFirstValue(sr, "ds-sync-generation-id")); } } finally { listeners.close(); } }
/** * Cleans up the contents of the ads truststore. * * @param ctx the bound instance. * @throws NamingException in case an error occurs while updating the instance's ads-truststore * via LDAP. */ public static void cleanAdsTrustStore(InitialLdapContext ctx) throws NamingException { try { SearchControls sc = new SearchControls(); sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); sc.setReturningAttributes(new String[] {SchemaConstants.NO_ATTRIBUTES}); NamingEnumeration<SearchResult> ne = ctx.search(TRUSTSTORE_DN, "(objectclass=ds-cfg-instance-key)", sc); ArrayList<String> dnsToDelete = new ArrayList<String>(); try { while (ne.hasMore()) { SearchResult sr = ne.next(); dnsToDelete.add(sr.getName() + "," + TRUSTSTORE_DN); } } finally { ne.close(); } for (String dn : dnsToDelete) { ctx.destroySubcontext(dn); } } catch (NameNotFoundException nnfe) { // Ignore LOG.log(Level.WARNING, "Error cleaning truststore: " + nnfe, nnfe); } }
/** * Initialize this <code>LoginModule</code>. * * @param subject the <code>Subject</code> to be authenticated. * @param callbackHandler a <code>CallbackHandler</code> to acquire the username and password. * @param sharedState shared <code>LoginModule</code> state. * @param options options specified in the login <code>Configuration</code> for this particular * <code>LoginModule</code>. */ public void initialize( Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; ldapEnvironment = new Hashtable(9); ldapEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // Add any JNDI properties to the environment Set keys = options.keySet(); String key; for (Iterator i = keys.iterator(); i.hasNext(); ) { key = (String) i.next(); if (key.indexOf(".") > -1) { ldapEnvironment.put(key, options.get(key)); } } // initialize any configured options userProvider = (String) options.get(USER_PROVIDER); if (userProvider != null) { ldapEnvironment.put(Context.PROVIDER_URL, userProvider); } authcIdentity = (String) options.get(AUTHC_IDENTITY); if (authcIdentity != null && (authcIdentity.indexOf(USERNAME_TOKEN) != -1)) { identityMatcher = USERNAME_PATTERN.matcher(authcIdentity); } userFilter = (String) options.get(USER_FILTER); if (userFilter != null) { if (userFilter.indexOf(USERNAME_TOKEN) != -1) { filterMatcher = USERNAME_PATTERN.matcher(userFilter); } constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setReturningAttributes(new String[0]); // return no attrs constraints.setReturningObjFlag(true); // to get the full DN } authzIdentity = (String) options.get(AUTHZ_IDENTITY); if (authzIdentity != null && authzIdentity.startsWith("{") && authzIdentity.endsWith("}")) { if (constraints != null) { authzIdentityAttr = authzIdentity.substring(1, authzIdentity.length() - 1); constraints.setReturningAttributes(new String[] {authzIdentityAttr}); } authzIdentity = null; // set later, from the specified attribute } // determine mode if (authcIdentity != null) { if (userFilter != null) { authFirst = true; // authentication-first mode } else { authOnly = true; // authentication-only mode } } if ("false".equalsIgnoreCase((String) options.get("useSSL"))) { useSSL = false; ldapEnvironment.remove(Context.SECURITY_PROTOCOL); } else { ldapEnvironment.put(Context.SECURITY_PROTOCOL, "ssl"); } tryFirstPass = "******".equalsIgnoreCase((String) options.get("tryFirstPass")); useFirstPass = "******".equalsIgnoreCase((String) options.get("useFirstPass")); storePass = "******".equalsIgnoreCase((String) options.get("storePass")); clearPass = "******".equalsIgnoreCase((String) options.get("clearPass")); debug = "true".equalsIgnoreCase((String) options.get("debug")); if (debug) { if (authFirst) { System.out.println( "\t\t[LdapLoginModule] " + "authentication-first mode; " + (useSSL ? "SSL enabled" : "SSL disabled")); } else if (authOnly) { System.out.println( "\t\t[LdapLoginModule] " + "authentication-only mode; " + (useSSL ? "SSL enabled" : "SSL disabled")); } else { System.out.println( "\t\t[LdapLoginModule] " + "search-first mode; " + (useSSL ? "SSL enabled" : "SSL disabled")); } } }
private static void updateReplication( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter) throws NamingException { boolean replicationEnabled = false; SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.OBJECT_SCOPE); ctls.setReturningAttributes(new String[] {"ds-cfg-enabled"}); String filter = "(objectclass=ds-cfg-synchronization-provider)"; LdapName jndiName = new LdapName("cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config"); NamingEnumeration<SearchResult> syncProviders = null; try { syncProviders = ctx.search(jndiName, filter, ctls); while (syncProviders.hasMore()) { SearchResult sr = syncProviders.next(); if ("true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-enabled"))) { replicationEnabled = true; } } } catch (NameNotFoundException nse) { /* ignore */ } finally { if (syncProviders != null) { syncProviders.close(); } } desc.serverProperties.put( ServerProperty.IS_REPLICATION_ENABLED, replicationEnabled ? Boolean.TRUE : Boolean.FALSE); Set<String> allReplicationServers = new LinkedHashSet<String>(); if (cacheFilter.searchBaseDNInformation()) { ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes( new String[] {"ds-cfg-base-dn", "ds-cfg-replication-server", "ds-cfg-server-id"}); filter = "(objectclass=ds-cfg-replication-domain)"; jndiName = new LdapName("cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config"); syncProviders = null; try { syncProviders = ctx.search(jndiName, filter, ctls); while (syncProviders.hasMore()) { SearchResult sr = syncProviders.next(); int id = Integer.parseInt(getFirstValue(sr, "ds-cfg-server-id")); Set<String> replicationServers = getValues(sr, "ds-cfg-replication-server"); Set<String> dns = getValues(sr, "ds-cfg-base-dn"); for (String dn : dns) { for (ReplicaDescriptor replica : desc.getReplicas()) { if (areDnsEqual(replica.getSuffix().getDN(), dn)) { replica.setReplicationId(id); // Keep the values of the replication servers in lower case // to make use of Sets as String simpler. LinkedHashSet<String> repServers = new LinkedHashSet<String>(); for (String s : replicationServers) { repServers.add(s.toLowerCase()); } replica.setReplicationServers(repServers); allReplicationServers.addAll(repServers); } } } } } catch (NameNotFoundException nse) { /* ignore */ } finally { if (syncProviders != null) { syncProviders.close(); } } } ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes( new String[] { "ds-cfg-replication-port", "ds-cfg-replication-server", "ds-cfg-replication-server-id" }); filter = "(objectclass=ds-cfg-replication-server)"; jndiName = new LdapName("cn=Multimaster " + "Synchronization,cn=Synchronization Providers,cn=config"); desc.serverProperties.put(ServerProperty.IS_REPLICATION_SERVER, Boolean.FALSE); NamingEnumeration<SearchResult> entries = null; try { entries = ctx.search(jndiName, filter, ctls); while (entries.hasMore()) { SearchResult sr = entries.next(); desc.serverProperties.put(ServerProperty.IS_REPLICATION_SERVER, Boolean.TRUE); String v = getFirstValue(sr, "ds-cfg-replication-port"); desc.serverProperties.put(ServerProperty.REPLICATION_SERVER_PORT, Integer.parseInt(v)); v = getFirstValue(sr, "ds-cfg-replication-server-id"); desc.serverProperties.put(ServerProperty.REPLICATION_SERVER_ID, Integer.parseInt(v)); Set<String> values = getValues(sr, "ds-cfg-replication-server"); // Keep the values of the replication servers in lower case // to make use of Sets as String simpler. LinkedHashSet<String> repServers = new LinkedHashSet<String>(); for (String s : values) { repServers.add(s.toLowerCase()); } allReplicationServers.addAll(repServers); desc.serverProperties.put( ServerProperty.EXTERNAL_REPLICATION_SERVERS, allReplicationServers); } } catch (NameNotFoundException nse) { /* ignore */ } finally { if (entries != null) { entries.close(); } } boolean replicationSecure = false; if (replicationEnabled) { ctls = new SearchControls(); ctls.setSearchScope(SearchControls.OBJECT_SCOPE); ctls.setReturningAttributes(new String[] {"ds-cfg-ssl-encryption"}); filter = "(objectclass=ds-cfg-crypto-manager)"; jndiName = new LdapName("cn=Crypto Manager,cn=config"); entries = ctx.search(jndiName, filter, ctls); try { while (entries.hasMore()) { SearchResult sr = entries.next(); String v = getFirstValue(sr, "ds-cfg-ssl-encryption"); replicationSecure = "true".equalsIgnoreCase(v); } } finally { entries.close(); } } desc.serverProperties.put( ServerProperty.IS_REPLICATION_SECURE, replicationSecure ? Boolean.TRUE : Boolean.FALSE); }
private static void updateReplicas( ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter) throws NamingException { if (!cacheFilter.searchBaseDNInformation()) { return; } SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes(new String[] {"ds-cfg-base-dn", "ds-cfg-backend-id"}); String filter = "(objectclass=ds-cfg-backend)"; LdapName jndiName = new LdapName("cn=config"); NamingEnumeration<SearchResult> databases = ctx.search(jndiName, filter, ctls); try { while (databases.hasMore()) { SearchResult sr = databases.next(); String id = getFirstValue(sr, "ds-cfg-backend-id"); if (!isConfigBackend(id) || isSchemaBackend(id)) { Set<String> baseDns = getValues(sr, "ds-cfg-base-dn"); Set<String> entries; if (cacheFilter.searchMonitoringInformation()) { entries = getBaseDNEntryCount(ctx, id); } else { entries = new HashSet<String>(); } Set<ReplicaDescriptor> replicas = desc.getReplicas(); for (String baseDn : baseDns) { boolean addReplica = cacheFilter.searchAllBaseDNs(); if (!addReplica) { for (String dn : cacheFilter.getBaseDNsToSearch()) { addReplica = Utils.areDnsEqual(dn, baseDn); if (addReplica) { break; } } } if (addReplica) { SuffixDescriptor suffix = new SuffixDescriptor(); suffix.setDN(baseDn); ReplicaDescriptor replica = new ReplicaDescriptor(); replica.setServer(desc); replica.setBackendName(id); replicas.add(replica); HashSet<ReplicaDescriptor> r = new HashSet<ReplicaDescriptor>(); r.add(replica); suffix.setReplicas(r); replica.setSuffix(suffix); int nEntries = -1; for (String s : entries) { int index = s.indexOf(" "); if (index != -1) { String dn = s.substring(index + 1); if (Utils.areDnsEqual(baseDn, dn)) { try { nEntries = Integer.parseInt(s.substring(0, index)); } catch (Throwable t) { /* Ignore */ } break; } } } replica.setEntries(nEntries); } } desc.setReplicas(replicas); } } } finally { databases.close(); } }