/** * Validate User * * @param ldapURL provider url - e.g. ldap://dc.compiere.org * @param domain domain name = e.g. compiere.org * @param userName user name - e.g. jjanke * @param password password * @return true if validated with ldap */ public static boolean validate(String ldapURL, String domain, String userName, String password) { Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // ldap://dc.compiere.org env.put(Context.PROVIDER_URL, ldapURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); // [email protected] StringBuffer principal = new StringBuffer(userName).append("@").append(domain); env.put(Context.SECURITY_PRINCIPAL, principal.toString()); env.put(Context.SECURITY_CREDENTIALS, password); // try { // Create the initial context InitialLdapContext ctx = new InitialLdapContext(env, null); // DirContext ctx = new InitialDirContext(env); // Test - Get the attributes Attributes answer = ctx.getAttributes(""); // Print the answer if (false) dump(answer); } catch (AuthenticationException e) { log.info("Error: " + principal + " - " + e.getLocalizedMessage()); return false; } catch (Exception e) { log.log(Level.SEVERE, ldapURL + " - " + principal, e); return false; } log.info("OK: " + principal); return true; } // validate
/** * Seeds the bound instance's local ads-truststore with a set of instance key-pair public key * certificates. The result is the instance will trust any instance posessing the private key * corresponding to one of the public-key certificates. This trust is necessary at least to * initialize replication, which uses the trusted certificate entries in the ads-truststore for * server authentication. * * @param ctx The bound instance. * @param keyEntryMap The set of valid (i.e., not tagged as compromised) instance key-pair * public-key certificate entries in ADS represented as a map from keyID to public-key * certificate (binary). * @throws NamingException in case an error occurs while updating the instance's ads-truststore * via LDAP. */ public static void seedAdsTrustStore(InitialLdapContext ctx, Map<String, byte[]> keyEntryMap) 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 Attribute oc = new BasicAttribute("objectclass"); oc.add("top"); oc.add("ds-cfg-instance-key"); for (Map.Entry<String, byte[]> keyEntry : keyEntryMap.entrySet()) { final BasicAttributes keyAttrs = new BasicAttributes(); keyAttrs.put(oc); final Attribute rdnAttr = new BasicAttribute( ADSContext.ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyEntry.getKey()); keyAttrs.put(rdnAttr); keyAttrs.put( new BasicAttribute( ADSContext.ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE.getAttributeName() + ";binary", keyEntry.getValue())); final LdapName keyDn = new LdapName( (new StringBuilder(rdnAttr.getID())) .append("=") .append(Rdn.escapeValue(rdnAttr.get())) .append(",") .append(TRUSTSTORE_DN) .toString()); try { ctx.createSubcontext(keyDn, keyAttrs).close(); } catch (NameAlreadyBoundException x) { ctx.destroySubcontext(keyDn); ctx.createSubcontext(keyDn, keyAttrs).close(); } } }
/* Return all groups for principal == null or all groups for which principal * is a member * */ private Collection<BwGroup> getGroups( final DirConfigProperties dirProps, final BwPrincipal principal) throws CalFacadeException { LdapConfigProperties props = (LdapConfigProperties) dirProps; InitialLdapContext ctx = null; String member = null; if (principal != null) { if (principal.getKind() == WhoDefs.whoTypeUser) { member = getUserEntryValue(props, principal); } else if (principal.getKind() == WhoDefs.whoTypeGroup) { member = getGroupEntryValue(props, principal); } } try { ctx = createLdapInitContext(props); BasicAttributes matchAttrs = new BasicAttributes(true); if (member != null) { matchAttrs.put(props.getGroupMemberAttr(), member); } String[] idAttr = {props.getGroupIdAttr()}; ArrayList<BwGroup> groups = new ArrayList<BwGroup>(); NamingEnumeration response = ctx.search(props.getGroupContextDn(), matchAttrs, idAttr); while (response.hasMore()) { SearchResult sr = (SearchResult) response.next(); Attributes attrs = sr.getAttributes(); Attribute nmAttr = attrs.get(props.getGroupIdAttr()); if (nmAttr.size() != 1) { throw new CalFacadeException("org.bedework.ldap.groups.multiple.result"); } BwGroup group = new BwGroup(); group.setAccount(nmAttr.get(0).toString()); group.setPrincipalRef(makePrincipalUri(group.getAccount(), WhoDefs.whoTypeGroup)); groups.add(group); } return groups; } catch (Throwable t) { if (debug) { error(t); } throw new CalFacadeException(t); } finally { // Close the context to release the connection if (ctx != null) { closeContext(ctx); } } }
public boolean existsUser(String userId) { InitialLdapContext ctx = null; boolean exists = false; try { ctx = buildInitialLdapContext(); String userContext = this.config.getProperty(USER_CTX); String userFilter = this.config.getProperty(USER_FILTER); String userAttrId = this.config.getProperty(USER_ATTR_ID, "uid"); userFilter = userFilter.replaceAll("\\{0\\}", userId); if (logger.isDebugEnabled()) { logger.debug( "Seaching for user existence with filter " + userFilter + " on context " + userContext); } SearchControls constraints = new SearchControls(); NamingEnumeration<SearchResult> result = ctx.search(userContext, userFilter, constraints); if (result.hasMore()) { SearchResult sr = result.next(); Attribute ldapUserId = sr.getAttributes().get(userAttrId); if (ldapUserId.contains(userId)) { exists = true; } if (logger.isDebugEnabled()) { logger.debug( "Entry in LDAP found and result of matching with given user id is " + exists); } } result.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } return exists; }
public Iterator<OrganizationalEntity> getMembersForGroup(Group group) { InitialLdapContext ctx = null; List<OrganizationalEntity> memebers = new ArrayList<OrganizationalEntity>(); try { ctx = buildInitialLdapContext(); String roleContext = this.config.getProperty(ROLE_CTX); String roleFilter = this.config.getProperty(ROLE_MEMBERS_FILTER, this.config.getProperty(ROLE_FILTER)); String roleAttrId = this.config.getProperty(MEMBER_ATTR_ID, "member"); String entityId = group.getId(); if (Boolean.parseBoolean(this.config.getProperty(IS_ENTITY_ID_DN, "false"))) { entityId = extractUserId(entityId, group); } roleFilter = roleFilter.replaceAll("\\{0\\}", entityId); SearchControls constraints = new SearchControls(); String searchScope = this.config.getProperty(SEARCH_SCOPE); if (searchScope != null) { constraints.setSearchScope(parseSearchScope(searchScope)); } NamingEnumeration<SearchResult> result = ctx.search(roleContext, roleFilter, constraints); while (result.hasMore()) { SearchResult sr = result.next(); Attribute member = sr.getAttributes().get(roleAttrId); for (int i = 0; i < member.size(); i++) { User user = TaskModelProvider.getFactory().newUser(); ((InternalOrganizationalEntity) user).setId(member.get(i).toString()); memebers.add(user); } } result.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } return memebers.iterator(); }
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(); } }
/** * Retrieve the input attributes from the Active Directory for the given search query * * <p>Method getAttributes. * * @param searchBase String * @return List<User> * @throws NamingException */ private final List<User> getAttributes(String searchBase) throws NamingException { LOGGER.info(">> getAttributes()"); NamingEnumeration<SearchResult> results = localInitialLdapContext.search(searchBase, searchFilter, searchctls); List<User> users = new ArrayList<User>(); User user = null; while (results.hasMoreElements()) { user = new User(); SearchResult searchResult = results.next(); Attributes attrs = searchResult.getAttributes(); if (attrs != null && attrs.size() != 0) { Attribute attribute = null; String[] retrieveAttributes = parameters.getRetrieveAttributes(); String[] attributesValues = new String[retrieveAttributes.length]; for (int i = 0; i < retrieveAttributes.length; i++) { attribute = attrs.get(retrieveAttributes[i]); if (attribute != null && attribute.get() != null) { if (!isNullOrEmpty(attribute.get().toString())) { attributesValues[i] = attribute.get().toString(); } } } user.setAttributeValues(attributesValues); } users.add(user); } LOGGER.info("<< getAttributes()"); return users; }
/** * Method used to know if we are connected as administrator in a server with a given * InitialLdapContext. * * @param ctx the context. * @return <CODE>true</CODE> if we are connected and read the configuration and <CODE>false</CODE> * otherwise. */ public static boolean connectedAsAdministrativeUser(InitialLdapContext ctx) { boolean connectedAsAdministrativeUser = false; try { /* * Search for the config to check that it is the directory manager. */ SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.OBJECT_SCOPE); searchControls.setReturningAttributes(new String[] {SchemaConstants.NO_ATTRIBUTES}); NamingEnumeration<SearchResult> sr = ctx.search("cn=config", "objectclass=*", searchControls); try { while (sr.hasMore()) { sr.next(); } } finally { try { sr.close(); } catch (Exception ex) { LOG.log(Level.WARNING, "Unexpected error closing enumeration on cn=Config entry", ex); } } connectedAsAdministrativeUser = true; } catch (NamingException ne) { // Nothing to do. } catch (Throwable t) { throw new IllegalStateException("Unexpected throwable.", t); } return connectedAsAdministrativeUser; }
public boolean hasEmail(Group group) { InitialLdapContext ctx = null; boolean exists = false; try { ctx = buildInitialLdapContext(); String roleContext = this.config.getProperty(ROLE_CTX); String roleFilter = this.config.getProperty(ROLE_FILTER); String roleAttrId = this.config.getProperty(EMAIL_ATTR_ID, "mail"); String entityId = group.getId(); if (Boolean.parseBoolean(this.config.getProperty(IS_ENTITY_ID_DN, "false"))) { entityId = extractUserId(entityId, group); } roleFilter = roleFilter.replaceAll("\\{0\\}", entityId); SearchControls constraints = new SearchControls(); String searchScope = this.config.getProperty(SEARCH_SCOPE); if (searchScope != null) { constraints.setSearchScope(parseSearchScope(searchScope)); } NamingEnumeration<SearchResult> result = ctx.search(roleContext, roleFilter, constraints); if (result.hasMore()) { SearchResult sr = result.next(); Attribute ldapGroupEmail = sr.getAttributes().get(roleAttrId); if (ldapGroupEmail != null && ldapGroupEmail.get() != null) { exists = true; } } result.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } return exists; }
protected void safeClose(InitialLdapContext ic) { if (ic != null) { try { ic.close(); } catch (NamingException e) { } } }
private void closeContext(final InitialLdapContext ctx) { if (ctx != null) { try { ctx.close(); } catch (Throwable t) { } } }
public boolean existsGroup(String groupId) { InitialLdapContext ctx = null; boolean exists = false; try { ctx = buildInitialLdapContext(); String roleContext = this.config.getProperty(ROLE_CTX); String roleFilter = this.config.getProperty(ROLE_FILTER); String roleAttrId = this.config.getProperty(ROLE_ATTR_ID, "cn"); roleFilter = roleFilter.replaceAll("\\{0\\}", groupId); SearchControls constraints = new SearchControls(); String searchScope = this.config.getProperty(SEARCH_SCOPE); if (searchScope != null) { constraints.setSearchScope(parseSearchScope(searchScope)); } NamingEnumeration<SearchResult> result = ctx.search(roleContext, roleFilter, constraints); if (result.hasMore()) { SearchResult sr = result.next(); Attribute ldapUserId = sr.getAttributes().get(roleAttrId); if (ldapUserId.contains(groupId)) { exists = true; } } result.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } return exists; }
/** * Returns the password used in the provided InitialLdapContext. * * @param ctx the context to analyze. * @return the password used in the provided InitialLdapContext. */ public static String getBindPassword(InitialLdapContext ctx) { String bindPwd = null; try { bindPwd = (String) ctx.getEnvironment().get(Context.SECURITY_CREDENTIALS); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of " + ctx, ne); } return bindPwd; }
/** * Returns the LDAP URL used in the provided InitialLdapContext. * * @param ctx the context to analyze. * @return the LDAP URL used in the provided InitialLdapContext. */ public static String getLdapUrl(InitialLdapContext ctx) { String s = null; try { s = (String) ctx.getEnvironment().get(Context.PROVIDER_URL); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of " + ctx, ne); } return s; }
@Override public LdapContext getSystemLdapContext() throws NamingException { try { InitialLdapContext ictx = new InitialLdapContext(); LdapContext ctx = (LdapContext) ictx.lookup(getLdapJndi()); /* Glassfish does not pass through these properties, even though it is aware of them? * Without com.sun.jndi.ldap.LdapCtxFactory, authentication is NOT carried out */ ctx.addToEnvironment(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); ctx.addToEnvironment("java.naming.ldap.attributes.binary", "userPKCS12"); if (logger.isDebugEnabled()) { String providerURL = (String) ctx.getEnvironment().get(Context.PROVIDER_URL); logger.debug("LDAP providerURL=" + providerURL); } return ctx; } catch (Exception ex) { throw new RuntimeException("Failed to lookup " + getLdapJndi(), ex); } }
/** * Tells whether we are using StartTLS in the provided InitialLdapContext. * * @param ctx the context to analyze. * @return <CODE>true</CODE> if we are using StartTLS and <CODE>false</CODE> otherwise. */ public static boolean isStartTLS(InitialLdapContext ctx) { boolean isStartTLS = false; try { isStartTLS = "true".equalsIgnoreCase((String) ctx.getEnvironment().get(STARTTLS_PROPERTY)); } catch (NamingException ne) { // This is really strange. Seems like a bug somewhere. LOG.log(Level.WARNING, "Naming exception getting environment of " + ctx, ne); } return isStartTLS; }
/* Search for a group to ensure it exists * */ private BwGroup findGroup(final DirConfigProperties dirProps, final String groupName) throws CalFacadeException { LdapConfigProperties props = (LdapConfigProperties) dirProps; InitialLdapContext ctx = null; try { ctx = createLdapInitContext(props); BasicAttributes matchAttrs = new BasicAttributes(true); matchAttrs.put(props.getGroupIdAttr(), groupName); String[] idAttr = {props.getGroupIdAttr()}; BwGroup group = null; NamingEnumeration response = ctx.search(props.getGroupContextDn(), matchAttrs, idAttr); while (response.hasMore()) { // SearchResult sr = (SearchResult)response.next(); // Attributes attrs = sr.getAttributes(); if (group != null) { throw new CalFacadeException("org.bedework.ldap.groups.multiple.result"); } group = new BwGroup(); group.setAccount(groupName); group.setPrincipalRef(makePrincipalUri(groupName, WhoDefs.whoTypeGroup)); } return group; } catch (Throwable t) { if (debug) { error(t); } throw new CalFacadeException(t); } finally { // Close the context to release the connection if (ctx != null) { closeContext(ctx); } } }
public static SearchResult searchUnique(String searchFilter, InitialLdapContext ctx) throws IllegalStateException, NamingException { ctx.setRequestControls(null); SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); searchControls.setTimeLimit(1000); NamingEnumeration<?> namingEnum = ctx.search(MessagingServletConfig.ldapBaseDn, searchFilter, searchControls); if (namingEnum.hasMore()) { SearchResult result = (SearchResult) namingEnum.next(); if (namingEnum.hasMore()) { throw new LimitExceededException( "search with filter " + searchFilter + " returned more than 1 result"); } namingEnum.close(); return result; } else { throw new NameNotFoundException("search with filter " + searchFilter + " returned no result"); } }
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(); } }
protected String searchLdap( String context, String filter, String attrId, OrganizationalEntity entity) { InitialLdapContext ctx = null; String result = null; try { ctx = buildInitialLdapContext(); String entityId = entity.getId(); if (Boolean.parseBoolean(this.config.getProperty(IS_ENTITY_ID_DN, "false"))) { entityId = extractUserId(entityId, entity); } filter = filter.replaceAll("\\{0\\}", entityId); SearchControls constraints = new SearchControls(); String searchScope = this.config.getProperty(SEARCH_SCOPE); if (searchScope != null) { constraints.setSearchScope(parseSearchScope(searchScope)); } NamingEnumeration<SearchResult> ldapResult = ctx.search(context, filter, constraints); if (ldapResult.hasMore()) { SearchResult sr = ldapResult.next(); Attribute entry = sr.getAttributes().get(attrId); if (entry != null) { result = (String) entry.get(); } } ldapResult.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } return result; }
/** * 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; } } } }
@Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { String authorizationHeader = getAuthzHeader(request); if (authorizationHeader == null || authorizationHeader.length() == 0) { // Create an empty authentication token since there is no // Authorization header. return createToken("", "", request, response); } if (log.isDebugEnabled()) { log.debug("Attempting to execute login with headers [" + authorizationHeader + "]"); } String[] prinCred = getPrincipalsAndCredentials(authorizationHeader, request); if (prinCred == null || prinCred.length < 2) { // Create an authentication token with an empty password, // since one hasn't been provided in the request. String username = prinCred == null || prinCred.length == 0 ? "" : prinCred[0]; return createToken(username, "", request, response); } String username = prinCred[0]; String password = prinCred[1]; String sf = SF.replace("{0}", username); try { AuthenticationToken at = new UsernamePasswordToken(MessagingServletConfig.ldapUser, MessagingServletConfig.ldapPw); InitialLdapContext ctx = (InitialLdapContext) jlc.getLdapContext(at.getPrincipal(), at.getCredentials()); SearchResult result = searchUnique(sf, ctx); Attributes attrs = result.getAttributes(); username = "******" + attrs.get("cn").get(0) + ",ou=gateways," + MessagingServletConfig.ldapBaseDn; ctx.close(); } catch (IllegalStateException | NamingException e) { e.printStackTrace(); log.warn(username + "not found in directory"); } return createToken(username, password, request, response); }
/** * Clones the provided InitialLdapContext and returns a connection using the same parameters. * * @param ctx the connection to be cloned. * @param timeout the timeout to establish the connection in milliseconds. Use {@code 0} to * express no timeout. * @param trustManager the trust manager to be used to connect. * @param keyManager the key manager to be used to connect. * @return the new InitialLdapContext connected to the server. * @throws NamingException if there was an error creating the new connection. */ public static InitialLdapContext cloneInitialLdapContext( final InitialLdapContext ctx, int timeout, TrustManager trustManager, KeyManager keyManager) throws NamingException { Hashtable<?, ?> env = ctx.getEnvironment(); Control[] ctls = ctx.getConnectControls(); Control[] newCtls = null; if (ctls != null) { newCtls = new Control[ctls.length]; System.arraycopy(ctls, 0, newCtls, 0, ctls.length); } /* Contains the DirContext and the Exception if any */ final Object[] pair = new Object[] {null, null}; final Hashtable<?, ?> fEnv = env; final TrustManager fTrustManager = trustManager; final KeyManager fKeyManager = keyManager; final Control[] fNewCtls = newCtls; Thread t = new Thread( new Runnable() { @Override public void run() { try { if (isSSL(ctx) || isStartTLS(ctx)) { TrustedSocketFactory.setCurrentThreadTrustManager(fTrustManager, fKeyManager); } pair[0] = new InitialLdapContext(fEnv, fNewCtls); } catch (NamingException ne) { pair[1] = ne; } catch (RuntimeException re) { pair[1] = re; } } }); return getInitialLdapContext(t, pair, timeout); }
/** * 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); } }
/** * @param ctx - the context to search from * @param user - the input username * @param credential - the bind credential * @param baseDN - base DN to search the ctx from * @param filter - the search filter string * @return the userDN string for the successful authentication * @throws NamingException */ @SuppressWarnings("rawtypes") protected String bindDNAuthentication( InitialLdapContext ctx, String user, Object credential, String baseDN, String filter) throws NamingException { SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setTimeLimit(searchTimeLimit); String attrList[] = {distinguishedNameAttribute}; constraints.setReturningAttributes(attrList); NamingEnumeration results = null; Object[] filterArgs = {user}; results = ctx.search(baseDN, filter, filterArgs, constraints); if (results.hasMore() == false) { results.close(); throw PicketBoxMessages.MESSAGES.failedToFindBaseContextDN(baseDN); } SearchResult sr = (SearchResult) results.next(); String name = sr.getName(); String userDN = null; Attributes attrs = sr.getAttributes(); if (attrs != null) { Attribute dn = attrs.get(distinguishedNameAttribute); if (dn != null) { userDN = (String) dn.get(); } } if (userDN == null) { if (sr.isRelative() == true) userDN = name + ("".equals(baseDN) ? "" : "," + baseDN); else throw PicketBoxMessages.MESSAGES.unableToFollowReferralForAuth(name); } safeClose(results); results = null; InitialLdapContext userCtx = constructInitialLdapContext(userDN, credential); safeClose(userCtx); return userDN; }
/** * 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(); } }
/* Find members for given group * */ private void getGroupMembers(final DirConfigProperties dirProps, final BwGroup group) throws CalFacadeException { LdapConfigProperties props = (LdapConfigProperties) dirProps; InitialLdapContext ctx = null; try { ctx = createLdapInitContext(props); BasicAttributes matchAttrs = new BasicAttributes(true); matchAttrs.put(props.getGroupIdAttr(), group.getAccount()); String[] memberAttr = {props.getGroupMemberAttr()}; ArrayList<String> mbrs = null; boolean beenHere = false; NamingEnumeration response = ctx.search(props.getGroupContextDn(), matchAttrs, memberAttr); while (response.hasMore()) { SearchResult sr = (SearchResult) response.next(); Attributes attrs = sr.getAttributes(); if (beenHere) { throw new CalFacadeException("org.bedework.ldap.groups.multiple.result"); } beenHere = true; Attribute membersAttr = attrs.get(props.getGroupMemberAttr()); mbrs = new ArrayList<String>(); for (int m = 0; m < membersAttr.size(); m++) { mbrs.add(membersAttr.get(m).toString()); } } // LDAP We need a way to search recursively for groups. /* Search for each user in the group */ String memberContext = props.getGroupMemberContextDn(); String memberSearchAttr = props.getGroupMemberSearchAttr(); String[] idAttr = { props.getGroupMemberUserIdAttr(), props.getGroupMemberGroupIdAttr(), "objectclass" }; for (String mbr : mbrs) { if (memberContext != null) { matchAttrs = new BasicAttributes(true); matchAttrs.put(memberSearchAttr, mbr); response = ctx.search(memberContext, matchAttrs, idAttr); } else { response = ctx.search(memberContext, null, idAttr); } if (response.hasMore()) { SearchResult sr = (SearchResult) response.next(); Attributes attrs = sr.getAttributes(); Attribute ocsAttr = attrs.get("objectclass"); String userOc = props.getUserObjectClass(); String groupOc = props.getGroupObjectClass(); boolean isGroup = false; for (int oci = 0; oci < ocsAttr.size(); oci++) { String oc = ocsAttr.get(oci).toString(); if (userOc.equals(oc)) { break; } if (groupOc.equals(oc)) { isGroup = true; break; } } BwPrincipal p = null; Attribute attr; if (isGroup) { p = BwPrincipal.makeGroupPrincipal(); attr = attrs.get(props.getGroupMemberGroupIdAttr()); } else { p = BwPrincipal.makeUserPrincipal(); attr = attrs.get(props.getGroupMemberUserIdAttr()); } if (attr.size() != 1) { throw new CalFacadeException("org.bedework.ldap.groups.multiple.result"); } p.setAccount(attr.get(0).toString()); p.setPrincipalRef(makePrincipalUri(p.getAccount(), p.getKind())); group.addGroupMember(p); } } } catch (Throwable t) { if (debug) { error(t); } throw new CalFacadeException(t); } finally { // Close the context to release the connection if (ctx != null) { closeContext(ctx); } } /* Recursively fetch members of groups that are members. */ for (BwGroup g : group.getGroups()) { getGroupMembers(props, g); } }
/** * Close the connection. * * @throws Exception */ public void shutdown() throws Exception { if (ldapContext != null) { ldapContext.close(); } }
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); }