package org.esupportail.cas.server.handlers.ldap; import java.util.Iterator; import java.util.LinkedList; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import org.dom4j.Element; import org.esupportail.cas.server.util.RedundantHandler; /** *

This class implements an LDAP server class.

*

It can authenticate users by:

*
    *
  1. searching into the LDAP directory to guess the user's * DN thanks to its username;
  2. *
  3. binding to the same LDAP directory with the DN found * previously and the password provided by the user.
  4. *
*

It is used by BindLdapHandler.

* * @author Pascal Aubry * @author Jean-Baptiste Daniel */ public final class BindLdapServer extends LdapServer { /** * Constructor. * * @param handlerDebug debugging mode of the handler * @param handler the handler the server will be used by * @param serverElement the XML element that declares the server * @throws Exception Exception */ public BindLdapServer( final Boolean handlerDebug, final RedundantHandler handler, final Element serverElement) throws Exception { super(handlerDebug, handler, serverElement); traceBegin(); traceEnd(); } /** * Try to authenticate a user (by searching and then binding to * the LDAP directory). * * @param username the user's name * @param password the user's password * * @return Server.AUTHENTICATE_SUCCESS, Server.AUTHENTICATE_NOAUTH * or Server.AUTHENTICATE_FAILURE. */ public int authenticate(final String username, final String password) { traceBegin(); // retrieve the handler we are working for BindLdapHandler handler = (BindLdapHandler) getHandler(); // connect as a privileged user DirContext searchContext = connect(handler.getBindDn(), handler.getBindPassword()); if (getConnectError() != CONNECT_SUCCESS) { trace("Could not bind as a privileged user."); if (searchContext != null) { try { trace("Closing LDAP connection..."); searchContext.close(); } catch (NamingException e) { trace("Could not close connection."); } } traceEnd("AUTHENTICATE_FAILURE"); return AUTHENTICATE_FAILURE; } // Initialize search constraints parameters // 1. search scope to OBJECT_SCOPE (0), ONELEVEL_SCOPE (1), or // SUBTREE_SCOPE (2). String scope = handler.getScope(); int scopeValue; if (scope.equals("base")) { scopeValue = 0; } else if (scope.equals("one")) { scopeValue = 1; } else { scopeValue = 2; } // Attributes to return, null -> all; "" -> nothing final String[] returnedAttributes = { "dn" }; // create a new searchControl object with the parameters we have set trace("Creating search constraints..."); SearchControls constraints = new SearchControls( scopeValue, // Maximum number to return, 0 -> no limit 1000, // Number of ms to wait before return, 0 -> infinite 1000, // attributes to return returnedAttributes, // return the object bound to the name false, // deference the link during search false); // search in the LDAP directory constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); try { trace("Searching in the LDAP directory..."); NamingEnumeration results = searchContext.search(handler.getSearchBase(), replaceTokens(handler.getFilter(), username), constraints); // for each result, store the dn in an array LinkedList dnList = new LinkedList(); try { while (results != null && results.hasMore()) { // get the resulting DN from the results SearchResult searchResult = (SearchResult) results.next(); String name= searchResult.getName(); String dnName= name + ',' + handler.getSearchBase(); dnList.add( dnName ); } } catch(javax.naming.PartialResultException pre) { trace("Warning: (" + pre.getClass().getName() + "): " + pre.getMessage()); } trace("Closing LDAP connection..."); searchContext.close(); searchContext = null; // count the number of results if (dnList.size() == 0) { trace("Username not found."); } else { if (!handler.areMultipleAccountsEnabled() && (dnList.size() > 1)) { trace("Multiple accounts are not allowed (use )."); } else { for (Iterator i = dnList.iterator(); i.hasNext();) { String dn = (String) i.next(); // try to bind to the LDAP directory trace("try to bind as DN '" + dn + "'..."); connectAndClose(dn, password); switch (getConnectError()) { case CONNECT_SUCCESS: trace("Bind succeeded."); traceEnd("AUTHENTICATE_SUCCESS"); return AUTHENTICATE_SUCCESS; case CONNECT_NOAUTH: // could not connect, nothing to be done break; default: trace("Bind failed."); traceEnd("AUTHENTICATE_FAILURE"); return AUTHENTICATE_FAILURE; } } } } } catch (Exception e) { trace("Failure (" + e.getClass().getName() + "): " + e.getMessage()); } if (searchContext != null) { try { searchContext.close(); } catch (NamingException e) { trace("Could not close connection."); } } traceEnd("AUTHENTICATE_NOAUTH"); return AUTHENTICATE_NOAUTH; } }