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(); } }
/** * This method will test if a user has access to the LDAP, if so it will then check the list of * groups and check for is access * * @param String username as named via a uid in the LDAP * @param String password clear text in LDAP * @return Hashtable authenticate object */ public Hashtable authenticate(String username, String password, String keyfob_id) { Hashtable authHT = new Hashtable(); if (keyfob_id != null) { System.out.println("attempted keyfob value: " + keyfob_id); // we need to bind with our anon bind user username = this.AD_ANON_BIND_UNAME; password = this.AD_ANON_BIND_PWORD; } // assume they will not pass the test boolean authenticated = false; // first check to see if we even need to hit LDAP (not overridden) if (this.LDAP_OVERRIDE) { System.out.println("Override Authentication"); // just check against stored username/password, put in all groups if (username.equals(this.LDAP_OVERRIDE_UNAME) && password.equals(this.LDAP_OVERRIDE_PWORD)) { authenticated = true; // just add then to each group for (String key : groups.keySet()) { // push the name of the group and access to it boolean authHT.put(key, true); // method throws NamingException } } } else { // authenticate agianst creditials server System.err.println("Trying " + this.PROVIDER_TYPE + " authentication by: " + username); try { // build a hash table to pass as a bindable event // Set up environment for creating initial context Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, this.INITIAL_CONTEXT_FACTORY); env.put(Context.SECURITY_AUTHENTICATION, this.SECURITY_AUTHENTICATION); // we take the uid to authenticate, pair it with the username, and append the base location env.put(Context.PROVIDER_URL, this.PROVIDER_URL); if (this.PROVIDER_TYPE.equals("AD")) { env.put(Context.SECURITY_PRINCIPAL, username + "@" + this.AD_DOMAIN); } else if (this.PROVIDER_TYPE.equals("LDAP")) { env.put( Context.SECURITY_PRINCIPAL, "uid=" + username + "," + this.USERS_LOC + this.BASE_DN); } // we don't need to throw errors here because first try/catch finds it env.put(Context.SECURITY_CREDENTIALS, password); // send env assigments to console // enumerateContents(env.elements()); /** now that we have our hash values lets go authenticate */ // first we want to connect to the LDAP Server and create initial context // making sure the user name and password are valid ctx = new InitialDirContext( env); // Throws AuthenticationException if not valid username/password // WE NEVER GO PAST HERE IF AuthenticationException THROWN System.err.println("connection and creditials valid"); /** * we just split the two paths of AD and LDAP authentication because the LDAP way worked and * we are migrating to AD. However we want to be able to easily switch back until the LDAP * service is discontinued. Theoretically both services should be 'searchable' the same way * at some point the LDAP code should be removed or universal code written */ if (this.PROVIDER_TYPE.equals("AD")) { /** AD way, get the group list, if they match add */ SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); // either search by user name or by keyfob id. either way will return a user if one is // found NamingEnumeration results = null; if (keyfob_id != null) { // we don't challenge on keyfob. assumed if you have keyfob you are that user System.out.println("searching for keyfob id: >" + keyfob_id + "<"); results = ctx.search( this.USERS_LOC + this.BASE_DN, "(" + this.ATTRIBUTE_NAME_KEYFOB_ID + "=" + keyfob_id + ")", constraints); authHT.put("keyfob_id", keyfob_id); // pass it back as proof positive we found it } else { results = ctx.search( this.USERS_LOC + this.BASE_DN, "(" + this.ATTRIBUTE_NAME_UNAME + "=" + username + ")", constraints); } while (results != null && results.hasMore()) { SearchResult sr = (SearchResult) results.next(); String dn = sr.getName() + ", " + this.USERS_LOC + this.BASE_DN; Attributes ar = ctx.getAttributes(dn, MY_ATTRS); if (ar == null) { // we need the user to have attributes throw new Exception("Entry " + dn + " has none of the specified attributes\n"); } for (int i = 0; i < MY_ATTRS.length; i++) { Attribute attr = ar.get(MY_ATTRS[i]); if (attr == null) { continue; } System.out.println(MY_ATTRS[i] + ":"); for (Enumeration vals = attr.getAll(); vals.hasMoreElements(); ) { String temp_next_element = vals.nextElement().toString(); // returns generic Object System.out.println("\t" + temp_next_element); // push the attributes to the auth HT if (!(authHT.containsKey(MY_ATTRS[i]))) { // push the name of the group and access to it boolean authHT.put(MY_ATTRS[i], temp_next_element); } // see if this element value matches any of my groups for (String key : groups.keySet()) { if (temp_next_element .toLowerCase() .startsWith("cn=" + groups.get(key).toLowerCase())) { // push the name of the group and access to it boolean authHT.put(key, true); // if user is found in ANY of the predefined groups they are 'authenticated' to // login. // RolemManager.as handles ACL authenticated = true; } } } } } // now for any groups not found, set them to false for (String key : groups.keySet()) { if (!(authHT.containsKey(key))) { // push the name of the group and access to it boolean authHT.put(key, false); } } // end AD WAY } else if (this.PROVIDER_TYPE.equals("LDAP")) { // authenticated only in the sense they are a valid AD user authenticated = true; // now that we have verified they are a valid user, lets see what type of access they have // groups are specified in the config file as "GROUP_<name>" key=value pairs where value // is the LDAP group name // and key is what we are looking for in the scheduling app for (String key : groups.keySet()) { // push the name of the group and access to it boolean authHT.put( key, new Boolean( userInGroup(username, groups.get(key)))); // method throws NamingException } } else { throw new Exception("Provider type not found."); } // Close the context when we're done ctx.close(); } catch (AuthenticationException e) { // binding to LDAP server with provided username/password failed // e.printStackTrace(); System.err.println( "AuthenticationException: " + e.getMessage()); // outputs -> [LDAP: error code 49 - Invalid Credentials] errorStack += e.getMessage() + "\n"; } catch (NamingException e) { // catches invalid DN. Should not be thrown unless changes made to DN // Could also fail from the context of the called method userInGroup System.err.println("NamingException: " + e.getMessage()); // e.printStackTrace(); errorStack += e.getMessage() + "\n"; } catch (Exception e) { e.printStackTrace(); System.err.println("Exception: " + e.getMessage()); errorStack += e.getMessage() + "\n"; } finally { // make sure our connection is closed if relevant if (ctx != null) { try { ctx.close(); } catch (NamingException e) { throw new RuntimeException(e); } } } } // push whether or not it was authenticated authHT.put("authenticated", new Boolean(authenticated)); // spill contents to catalina.out file enumerateContents(authHT.keys()); enumerateContents(authHT.elements()); return (authHT); }