Purpose:
This document is a sample on how to resolve http://www.ja-sig.org/issues/browse/CAS-664.
Environment:
Server: Fedora 10 + CAS 3.3.1 + Tomcat 5.5.27 + OpenLDAP 2.4.12 + Cyrus SASL 2.1.22
Client: Fedora 10 + Firefox 3 (in the same computor with Server)
Realm: dell-d830
Config OpenLDAP DIGEST-MD5
1. Edit /etc/slapd.conf, add the following:
password-hash {CLEARTEXT} sasl-realm dell-d830 authz-regexp uid=(\[^,\]*),cn=dell-d830,cn=digest-md5,cn=auth ldap:///o=langhua,c=cn??sub?(uid=$1)
2. /etc/init.d/ldap restart
3. Add a user to OpenLDAP
uid=test,ou=beijing,o=langhua,c=cn
userPassword is 111111
Config SASL DIGEST-MD5
1. Add a user to SASL
saslpasswd2 \-c test Password: 111111 Again (for verification): 111111
2. Test SASL DIGEST-MD5
Open a console and run:
sasl2-sample-server Console output: trying 2, 1, 6 trying 10, 1, 6 bind: Address already in use
Open another console and run:
sasl2-sample-client \-m DIGEST-MD5 localhost Console output: receiving capability list... recv: {53} PLAIN CRAM-MD5 ANONYMOUS LOGIN NTLM GSSAPI DIGEST-MD5 PLAIN CRAM-MD5 ANONYMOUS LOGIN NTLM GSSAPI DIGEST-MD5 send: {10} DIGEST-MD5 send: {1} N recv: {114} nonce="i7iU89Jmqj2S8BmExkXbkTwV8TaMdOrh1T803Q2UHw4=",realm="dell-d830",qop="auth",charset=utf-8,algorithm=md5-sess please enter an authentication id: please enter an authorization id: test Password: 111111 send: {231} username="test",realm="dell-d830",nonce="i7iU89Jmqj2S8BmExkXbkTwV8TaMdOrh1T803Q2UHw4=",cnonce="h3prPJs4mCG0XAUJNiEhlISg0BjgS2UcRenpY6S3IuI=",nc=00000001,qop=auth,digest-uri="rcmd/localhost",response=e8f55dabc929152361c6cdcbb0d22532 recv: {40} rspauth=44285575e382f452e158665a2727a493 send: {0} successful authentication closing connection
DIGEST-MD5 is ok.
Config CAS
1. Create /cas-server-support-ldap/src/main/java/org/jasig/cas/adaptors/ldap/BindLdapDigestMd5AuthenticationHandler.java
BindLdapDigestMd5AuthenticationHandler.java
/* * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license * distributed with this file and available online at * http://www.ja-sig.org/products/cas/overview/license/ */ package org.jasig.cas.adaptors.ldap; import org.jasig.cas.authentication.handler.AuthenticationException; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; import org.inspektr.common.ioc.annotation.IsIn; import javax.naming.directory.DirContext; import javax.naming.directory.SearchControls; /** * Handler to do LDAP bind. * * @author Scott Battaglia * @version $Revision: 44152 $ $Date: 2008-08-13 15:18:57 -0400 (Wed, 13 Aug * 2008) $ * @since 3.0.3 */ public class BindLdapDigestMd5AuthenticationHandler extends AbstractLdapDigestMd5AuthenticationHandler { /** The default maximum number of results to return. */ private static final int DEFAULT_MAX_NUMBER_OF_RESULTS = 1000; /** The default timeout. */ private static final int DEFAULT_TIMEOUT = 1000; /** The search base to find the user under. */ private String searchBase; /** The scope. */ @IsIn( { SearchControls.OBJECT_SCOPE, SearchControls.ONELEVEL_SCOPE, SearchControls.SUBTREE_SCOPE }) private int scope = SearchControls.SUBTREE_SCOPE; /** The maximum number of results to return. */ private int maxNumberResults = DEFAULT_MAX_NUMBER_OF_RESULTS; /** The amount of time to wait. */ private int timeout = DEFAULT_TIMEOUT; /** Boolean of whether multiple accounts are allowed. */ private boolean allowMultipleAccounts; protected final boolean authenticateUsernamePasswordInternal( final UsernamePasswordCredentials credentials) throws AuthenticationException { DirContext context; context = this.getContextSource().getDirContext( credentials.getUsername(), credentials.getPassword()); if (context == null) { return false; } return true; } protected String composeCompleteDnToCheck(final String dn, final UsernamePasswordCredentials credentials) { return dn; } private final SearchControls getSearchControls() { final SearchControls constraints = new SearchControls(); constraints.setSearchScope(this.scope); constraints.setReturningAttributes(new String[0]); constraints.setTimeLimit(this.timeout); constraints.setCountLimit(this.maxNumberResults); return constraints; } /** * Method to return whether multiple accounts are allowed. * * @return true if multiple accounts are allowed, false otherwise. */ protected boolean isAllowMultipleAccounts() { return this.allowMultipleAccounts; } /** * Method to return the max number of results allowed. * * @return the maximum number of results. */ protected int getMaxNumberResults() { return this.maxNumberResults; } /** * Method to return the scope. * * @return the scope */ protected int getScope() { return this.scope; } /** * Method to return the search base. * * @return the search base. */ protected String getSearchBase() { return this.searchBase; } /** * Method to return the timeout. * * @return the timeout. */ protected int getTimeout() { return this.timeout; } public final void setScope(final int scope) { this.scope = scope; } /** * @param allowMultipleAccounts * The allowMultipleAccounts to set. */ public void setAllowMultipleAccounts(final boolean allowMultipleAccounts) { this.allowMultipleAccounts = allowMultipleAccounts; } /** * @param maxNumberResults * The maxNumberResults to set. */ public final void setMaxNumberResults(final int maxNumberResults) { this.maxNumberResults = maxNumberResults; } /** * @param searchBase * The searchBase to set. */ public final void setSearchBase(final String searchBase) { this.searchBase = searchBase; } /** * @param timeout * The timeout to set. */ public final void setTimeout(final int timeout) { this.timeout = timeout; } }
2. Create /cas-server-support-ldap/src/main/java/org/jasig/cas/adaptors/ldap/AbstractLdapDigestMd5AuthenticationHandler.java
AbstractLdapDigestMd5AuthenticationHandler.java
/* * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license * distributed with this file and available online at * http://www.ja-sig.org/products/cas/overview/license/ */ package org.jasig.cas.adaptors.ldap; import org.jasig.cas.adaptors.ldap.util.AuthenticatedLdapDigestMd5ContextSource; import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; import org.inspektr.common.ioc.annotation.NotNull; import org.springframework.beans.factory.InitializingBean; import org.springframework.ldap.core.LdapTemplate; import org.springframework.util.Assert; /** * Abstract class to handle common LDAP functionality. * * @author Scott Battaglia * @version $Revision: 42776 $ $Date: 2008-01-04 09:15:42 -0500 (Fri, 04 Jan 2008) $ * @since 3.0.3 */ public abstract class AbstractLdapDigestMd5AuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler implements InitializingBean { /** LdapTemplate to execute ldap queries. */ @NotNull private LdapTemplate ldapTemplate; /** Instance of ContextSource */ @NotNull private AuthenticatedLdapDigestMd5ContextSource contextSource; /** The filter path to the uid of the user. */ @NotNull private String filter; /** Whether the LdapTemplate should ignore partial results. */ private boolean ignorePartialResultException = false; /** * Method to set the datasource and generate a JdbcTemplate. * * @param contextSource the datasource to use. */ public final void setContextSource(final AuthenticatedLdapDigestMd5ContextSource contextSource) { this.contextSource = contextSource; this.ldapTemplate = new LdapTemplate(contextSource); } public final void setIgnorePartialResultException(final boolean ignorePartialResultException) { this.ignorePartialResultException = ignorePartialResultException; } /** * Method to return the LdapTemplate * * @return a fully created LdapTemplate. */ protected final LdapTemplate getLdapTemplate() { return this.ldapTemplate; } protected final AuthenticatedLdapDigestMd5ContextSource getContextSource() { return this.contextSource; } protected final String getFilter() { return this.filter; } public final void afterPropertiesSet() throws Exception { Assert.isTrue(this.filter.contains("%u"), "filter must contain %u"); this.ldapTemplate.setIgnorePartialResultException(this.ignorePartialResultException); } /** * @param filter The filter to set. */ public final void setFilter(final String filter) { this.filter = filter; } }
3. Create /cas-server-support-ldap/src/main/java/org/jasig/cas/adaptors/ldap/util/AbstractLdapDigestMd5AuthenticationHandler.java
AbstractLdapDigestMd5AuthenticationHandler.java
/* * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license * distributed with this file and available online at * http://www.ja-sig.org/products/cas/overview/license/ */ package org.jasig.cas.adaptors.ldap.util; import org.springframework.ldap.core.support.LdapContextSource; import javax.naming.Context; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import java.util.Enumeration; import java.util.Hashtable; public class AuthenticatedLdapDigestMd5ContextSource extends LdapContextSource { private DirContext context; public Hashtable<String, String> environment; public DirContext getDirContext(final String principal, final String credentials) { environment = (Hashtable) getAnonymousEnv().clone(); String authenMethod = environment.get(Context.SECURITY_AUTHENTICATION); if (authenMethod == null) { environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5"); } String providerUrl = environment.get(Context.PROVIDER_URL); if (providerUrl == null) { environment.put(Context.PROVIDER_URL, assembleProviderUrlString(getUrls())); } Enumeration keys = environment.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); System.setProperty(key, environment.get(key)); } environment.put(Context.SECURITY_PRINCIPAL, principal); environment.put(Context.SECURITY_CREDENTIALS, credentials); try { // Create the initial directory context context = new InitialDirContext(environment); } catch (Exception e) { System.err.println("Authentication failed: " + e); context = null; } return context; } }
4. Build a new cas-server-support-ldap-3.3.1.jar and deploy it in CAS
5. Config deployerConfigContext.xml
Fill the new methods into the deployerConfigContext.xml.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- | deployerConfigContext.xml centralizes into one file some of the declarative configuration that | all CAS deployers will need to modify. | | This file declares some of the Spring-managed JavaBeans that make up a CAS deployment. | The beans declared in this file are instantiated at context initialization time by the Spring | ContextLoaderListener declared in web.xml. It finds this file because this | file is among those declared in the context parameter "contextConfigLocation". | | By far the most common change you will need to make in this file is to change the last bean | declaration to replace the default SimpleTestUsernamePasswordAuthenticationHandler with | one implementing your approach for authenticating usernames and passwords. +--> <beans> <!-- | This bean declares our AuthenticationManager. The CentralAuthenticationService service bean | declared in applicationContext.xml picks up this AuthenticationManager by reference to its id, | "authenticationManager". Most deployers will be able to use the default AuthenticationManager | implementation and so do not need to change the class of this bean. We include the whole | AuthenticationManager here in the userConfigContext.xml so that you can see the things you will | need to change in context. +--> <bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl"> <!-- | This is the List of CredentialToPrincipalResolvers that identify what Principal is trying to authenticate. | The AuthenticationManagerImpl considers them in order, finding a CredentialToPrincipalResolver which | supports the presented credentials. | | AuthenticationManagerImpl uses these resolvers for two purposes. First, it uses them to identify the Principal | attempting to authenticate to CAS /login . In the default configuration, it is the DefaultCredentialsToPrincipalResolver | that fills this role. If you are using some other kind of credentials than UsernamePasswordCredentials, you will need to replace | DefaultCredentialsToPrincipalResolver with a CredentialsToPrincipalResolver that supports the credentials you are | using. | | Second, AuthenticationManagerImpl uses these resolvers to identify a service requesting a proxy granting ticket. | In the default configuration, it is the HttpBasedServiceCredentialsToPrincipalResolver that serves this purpose. | You will need to change this list if you are identifying services by something more or other than their callback URL. +--> <property name="credentialsToPrincipalResolvers"> <list> <!-- | UsernamePasswordCredentialsToPrincipalResolver supports the UsernamePasswordCredentials that we use for /login | by default and produces SimplePrincipal instances conveying the username from the credentials. | | If you've changed your LoginFormAction to use credentials other than UsernamePasswordCredentials then you will also | need to change this bean declaration (or add additional declarations) to declare a CredentialsToPrincipalResolver that supports the | Credentials you are using. +--> <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" /> <!-- | HttpBasedServiceCredentialsToPrincipalResolver supports HttpBasedCredentials. It supports the CAS 2.0 approach of | authenticating services by SSL callback, extracting the callback URL from the Credentials and representing it as a | SimpleService identified by that callback URL. | | If you are representing services by something more or other than an HTTPS URL whereat they are able to | receive a proxy callback, you will need to change this bean declaration (or add additional declarations). +--> <bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" /> </list> </property> <!-- | Whereas CredentialsToPrincipalResolvers identify who it is some Credentials might authenticate, | AuthenticationHandlers actually authenticate credentials. Here we declare the AuthenticationHandlers that | authenticate the Principals that the CredentialsToPrincipalResolvers identified. CAS will try these handlers in turn | until it finds one that both supports the Credentials presented and succeeds in authenticating. +--> <property name="authenticationHandlers"> <list> <!-- | This is the authentication handler that authenticates services by means of callback via SSL, thereby validating | a server side SSL certificate. +--> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" /> <!-- | This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS | into production. The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials | where the username equals the password. You will need to replace this with an AuthenticationHandler that implements your | local authentication strategy. You might accomplish this by coding a new such handler and declaring | edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules. +--> <bean class="org.jasig.cas.adaptors.ldap.BindLdapDigestMd5AuthenticationHandler"> <property name="filter" value="uid:caseExactmatch:=%u" /> <property name="searchBase" value="o=langhua,c=cn" /> <property name="contextSource" ref="contextSource" /> </bean> </list> </property> </bean> <bean id="contextSource" class="org.jasig.cas.adaptors.ldap.util.AuthenticatedLdapDigestMd5ContextSource"> <property name="anonymousReadOnly" value="true" /> <property name="pooled" value="true" /> <property name="urls"> <list> <value>ldap://localhost:389/</value> </list> </property> <property name="baseEnvironmentProperties"> <map> </map> </property> </bean> <!-- This bean defines the security roles for the Services Management application. Simple deployments can use the in-memory version. More robust deployments will want to use another option, such as the Jdbc version. The name of this should remain "userDetailsService" in order for Acegi to find it. To use this, you should add an entry similar to the following between the two value tags: battags=notused,ROLE_ADMIN where battags is the username you want to grant access to. You can put one entry per line. --> <bean id="userDetailsService" class="org.springframework.security.userdetails.memory.InMemoryDaoImpl"> <property name="userMap"> <value> </value> </property> </bean> <!-- Bean that defines the attributes that a service may return. This example uses the Stub/Mock version. A real implementation may go against a database or LDAP server. The id should remain "attributeRepository" though. --> <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"> <property name="backingMap"> <map> <entry key="uid" value="uid" /> <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> <entry key="groupMembership" value="groupMembership" /> </map> </property> </bean> <!-- Sample, in-memory data store for the ServiceRegistry. A real implementation would probably want to replace this with the JPA-backed ServiceRegistry DAO The name of this bean should remain "serviceRegistryDao". --> <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl" /> </beans>
6. Restart CAS
Login CAS
Visit http://localhost:8080/cas/login, enter test/111111 to login. This should be successful. Here is a piece of ldap log to show the ldap login procedure:
Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: slap_listener_activate(7): Feb 8 03:48:47 localhost slapd[11389]: >>> slap_listener(ldap:///) Feb 8 03:48:47 localhost slapd[11389]: daemon: listen=7, new connection on 12 Feb 8 03:48:47 localhost slapd[11389]: daemon: added 12r (active) listener=(nil) Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: 12r Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: daemon: read active on 12 Feb 8 03:48:47 localhost slapd[11389]: connection_get(12) Feb 8 03:48:47 localhost slapd[11389]: connection_get(12): got connid=0 Feb 8 03:48:47 localhost slapd[11389]: connection_read(12): checking for input on id=0 Feb 8 03:48:47 localhost slapd[11389]: conn=0 op=0 do_bind Feb 8 03:48:47 localhost slapd[11389]: >>> dnPrettyNormal: <> Feb 8 03:48:47 localhost slapd[11389]: <<< dnPrettyNormal: <>, <> Feb 8 03:48:47 localhost slapd[11389]: do_bind: dn () SASL mech DIGEST-MD5 Feb 8 03:48:47 localhost slapd[11389]: ==> sasl_bind: dn="" mech=DIGEST-MD5 datalen=0 Feb 8 03:48:47 localhost slapd[11389]: SASL [conn=0] Debug: DIGEST-MD5 server step 1 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_sasl: err=14 len=182 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_response: msgid=1 tag=97 err=14 Feb 8 03:48:47 localhost slapd[11389]: <== slap_sasl_bind: rc=14 Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: 12r Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: daemon: read active on 12 Feb 8 03:48:47 localhost slapd[11389]: connection_get(12) Feb 8 03:48:47 localhost slapd[11389]: connection_get(12): got connid=0 Feb 8 03:48:47 localhost slapd[11389]: connection_read(12): checking for input on id=0 Feb 8 03:48:47 localhost slapd[11389]: conn=0 op=1 do_bind Feb 8 03:48:47 localhost slapd[11389]: >>> dnPrettyNormal: <> Feb 8 03:48:47 localhost slapd[11389]: <<< dnPrettyNormal: <>, <> Feb 8 03:48:47 localhost slapd[11389]: do_bind: dn () SASL mech DIGEST-MD5 Feb 8 03:48:47 localhost slapd[11389]: ==> sasl_bind: dn="" mech=<continuing> datalen=255 Feb 8 03:48:47 localhost slapd[11389]: SASL [conn=0] Debug: DIGEST-MD5 server step 2 Feb 8 03:48:47 localhost slapd[11389]: SASL Canonicalize [conn=0]: authcid="test1" Feb 8 03:48:47 localhost slapd[11389]: slap_sasl_getdn: conn 0 id=test1 [len=5] Feb 8 03:48:47 localhost slapd[11389]: slap_sasl_getdn: u:id converted to uid=test1,cn=dell-d830,cn=DIGEST-MD5,cn=auth Feb 8 03:48:47 localhost slapd[11389]: >>> dnNormalize: <uid=test1,cn=dell-d830,cn=DIGEST-MD5,cn=auth> Feb 8 03:48:47 localhost slapd[11389]: <<< dnNormalize: <uid=test1,cn=dell-d830,cn=digest-md5,cn=auth> Feb 8 03:48:47 localhost slapd[11389]: ==>slap_sasl2dn: converting SASL name uid=test1,cn=dell-d830,cn=digest-md5,cn=auth to a DN Feb 8 03:48:47 localhost slapd[11389]: [rw] authid: "uid=test1,cn=dell-d830,cn=digest-md5,cn=auth" -> "ldap:///o=langhua,c=cn??sub?(uid=test1)" Feb 8 03:48:47 localhost slapd[11389]: slap_parseURI: parsing ldap:///o=langhua,c=cn??sub?(uid=test1) Feb 8 03:48:47 localhost slapd[11389]: str2filter "(uid=test1)" Feb 8 03:48:47 localhost slapd[11389]: begin get_filter Feb 8 03:48:47 localhost slapd[11389]: EQUALITY Feb 8 03:48:47 localhost slapd[11389]: end get_filter 0 Feb 8 03:48:47 localhost slapd[11389]: >>> dnNormalize: <o=langhua,c=cn> Feb 8 03:48:47 localhost slapd[11389]: <<< dnNormalize: <o=langhua,c=cn> Feb 8 03:48:47 localhost slapd[11389]: slap_sasl2dn: performing internal search (base=o=langhua,c=cn, scope=2) Feb 8 03:48:47 localhost slapd[11389]: => bdb_search Feb 8 03:48:47 localhost slapd[11389]: bdb_dn2entry("o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: => bdb_dn2id("o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: <= bdb_dn2id: got id=0x1 Feb 8 03:48:47 localhost slapd[11389]: entry_decode: "o=langhua,c=cn" Feb 8 03:48:47 localhost slapd[11389]: <= entry_decode(o=langhua,c=cn) Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access to "o=langhua,c=cn" "entry" requested Feb 8 03:48:47 localhost slapd[11389]: => slap_access_allowed: backend default auth access granted to "(anonymous)" Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access granted by read(=rscxd) Feb 8 03:48:47 localhost slapd[11389]: search_candidates: base="o=langhua,c=cn" (0x00000001) scope=2 Feb 8 03:48:47 localhost slapd[11389]: => bdb_dn2idl("o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: => bdb_filter_candidates Feb 8 03:48:47 localhost slapd[11389]: #011AND Feb 8 03:48:47 localhost slapd[11389]: => bdb_list_candidates 0xa0 Feb 8 03:48:47 localhost slapd[11389]: => bdb_filter_candidates Feb 8 03:48:47 localhost slapd[11389]: #011OR Feb 8 03:48:47 localhost slapd[11389]: => bdb_list_candidates 0xa1 Feb 8 03:48:47 localhost slapd[11389]: => bdb_filter_candidates Feb 8 03:48:47 localhost slapd[11389]: #011EQUALITY Feb 8 03:48:47 localhost slapd[11389]: => bdb_equality_candidates (objectClass) Feb 8 03:48:47 localhost slapd[11389]: => key_read Feb 8 03:48:47 localhost slapd[11389]: bdb_idl_fetch_key: [b49d1940] Feb 8 03:48:47 localhost slapd[11389]: <= bdb_index_read: failed (-30989) Feb 8 03:48:47 localhost slapd[11389]: <= bdb_equality_candidates: id=0, first=0, last=0 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_filter_candidates: id=0 first=0 last=0 Feb 8 03:48:47 localhost slapd[11389]: => bdb_filter_candidates Feb 8 03:48:47 localhost slapd[11389]: #011EQUALITY Feb 8 03:48:47 localhost slapd[11389]: => bdb_equality_candidates (uid) Feb 8 03:48:47 localhost slapd[11389]: => key_read Feb 8 03:48:47 localhost slapd[11389]: bdb_idl_fetch_key: [36e55cac] Feb 8 03:48:47 localhost slapd[11389]: <= bdb_index_read 1 candidates Feb 8 03:48:47 localhost slapd[11389]: <= bdb_equality_candidates: id=1, first=79, last=79 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_filter_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_list_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_filter_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_list_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: <= bdb_filter_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: bdb_search_candidates: id=1 first=79 last=79 Feb 8 03:48:47 localhost slapd[11389]: entry_decode: "uid=test1,ou=beijing,o=langhua,c=cn" Feb 8 03:48:47 localhost slapd[11389]: <= entry_decode(uid=test1,ou=beijing,o=langhua,c=cn) Feb 8 03:48:47 localhost slapd[11389]: => bdb_dn2id("ou=beijing,o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: <= bdb_dn2id: got id=0x3 Feb 8 03:48:47 localhost slapd[11389]: => bdb_dn2id("uid=test1,ou=beijing,o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: <= bdb_dn2id: got id=0x4f Feb 8 03:48:47 localhost slapd[11389]: => test_filter Feb 8 03:48:47 localhost slapd[11389]: EQUALITY Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access to "uid=test1,ou=beijing,o=langhua,c=cn" "uid" requested Feb 8 03:48:47 localhost slapd[11389]: => slap_access_allowed: backend default auth access granted to "(anonymous)" Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access granted by read(=rscxd) Feb 8 03:48:47 localhost slapd[11389]: <= test_filter 6 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_result: conn=0 op=1 p=3 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_result: err=0 matched="" text="" Feb 8 03:48:47 localhost slapd[11389]: <==slap_sasl2dn: Converted SASL name to uid=test1,ou=beijing,o=langhua,c=cn Feb 8 03:48:47 localhost slapd[11389]: slap_sasl_getdn: dn:id converted to uid=test1,ou=beijing,o=langhua,c=cn Feb 8 03:48:47 localhost slapd[11389]: SASL Canonicalize [conn=0]: slapAuthcDN="uid=test1,ou=beijing,o=langhua,c=cn" Feb 8 03:48:47 localhost slapd[11389]: => bdb_search Feb 8 03:48:47 localhost slapd[11389]: bdb_dn2entry("uid=test1,ou=beijing,o=langhua,c=cn") Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access to "uid=test1,ou=beijing,o=langhua,c=cn" "entry" requested Feb 8 03:48:47 localhost slapd[11389]: => slap_access_allowed: backend default auth access granted to "(anonymous)" Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access granted by read(=rscxd) Feb 8 03:48:47 localhost slapd[11389]: base_candidates: base: "uid=test1,ou=beijing,o=langhua,c=cn" (0x0000004f) Feb 8 03:48:47 localhost slapd[11389]: => test_filter Feb 8 03:48:47 localhost slapd[11389]: PRESENT Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access to "uid=test1,ou=beijing,o=langhua,c=cn" "objectClass" requested Feb 8 03:48:47 localhost slapd[11389]: => slap_access_allowed: backend default auth access granted to "(anonymous)" Feb 8 03:48:47 localhost slapd[11389]: => access_allowed: auth access granted by read(=rscxd) Feb 8 03:48:47 localhost slapd[11389]: <= test_filter 6 Feb 8 03:48:47 localhost slapd[11389]: slap_ap_lookup: str2ad(cmusaslsecretDIGEST-MD5): attribute type undefined Feb 8 03:48:47 localhost slapd[11389]: send_ldap_result: conn=0 op=1 p=3 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_result: err=0 matched="" text="" Feb 8 03:48:47 localhost slapd[11389]: SASL Canonicalize [conn=0]: authzid="test1" Feb 8 03:48:47 localhost slapd[11389]: SASL proxy authorize [conn=0]: authcid="test1@dell-d830" authzid="test1@dell-d830" Feb 8 03:48:47 localhost slapd[11389]: SASL Authorize [conn=0]: proxy authorization allowed authzDN="" Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on 1 descriptor Feb 8 03:48:47 localhost slapd[11389]: daemon: activity on: Feb 8 03:48:47 localhost slapd[11389]: Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=7 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: daemon: epoll: listen=8 active_threads=0 tvp=zero Feb 8 03:48:47 localhost slapd[11389]: send_ldap_sasl: err=0 len=40 Feb 8 03:48:47 localhost slapd[11389]: do_bind: SASL/DIGEST-MD5 bind: dn="uid=test1,ou=beijing,o=langhua,c=cn" sasl_ssf=0 Feb 8 03:48:47 localhost slapd[11389]: send_ldap_response: msgid=2 tag=97 err=0 Feb 8 03:48:47 localhost slapd[11389]: <== slap_sasl_bind: rc=0
That's it. Good luck!
Shi Yusen/Beijing Langhua Ltd.
http://www.langhua.cn/