You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/08/01 03:20:22 UTC

svn commit: r681578 [1/2] - in /directory/apacheds/branches/bigbang: core-constants/src/main/java/org/apache/directory/server/constants/ core/src/main/java/org/apache/directory/server/core/authn/ core/src/main/java/org/apache/directory/server/core/part...

Author: elecharny
Date: Thu Jul 31 18:20:21 2008
New Revision: 681578

URL: http://svn.apache.org/viewvc?rev=681578&view=rev
Log:
One step further in the JNDI removal :
o Fixed PLAIN, CRAM-MD5 SASL mechanims
o Fixed Simple authentication
o Added a mechanism to handle transition between anonymous/authenticated users
o Fixed bugs in the way operation are executed if the user is anonymous
o Added more AttributeType constants

Kerberos is not working yet
GSSAPI and DIGEST-MD5 mechanisms are not working either

Some more JNDI code has to be replaced.

Added:
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslServer.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/CramMd5CallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/CramMd5MechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/DigestMd5CallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/DigestMd5MechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/gssapi/
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/gssapi/GssapiCallbackHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/GssapiCallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/gssapi/GssapiMechanismHandler.java
      - copied, changed from r681116, directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/GssapiMechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java
    directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/store/ContextOperation.java
Removed:
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/CramMd5CallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/CramMd5MechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/DigestMd5CallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/DigestMd5MechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/GssapiCallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/GssapiMechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/PlainMechanismHandler.java
Modified:
    directory/apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/ApacheSchemaConstants.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AnonymousAuthenticator.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/LdapPrincipal.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
    directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/JndiPrincipalStoreImpl.java
    directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/MultiBaseSearch.java
    directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/SingleBaseSearch.java
    directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/operations/GetPrincipal.java
    directory/apacheds/branches/bigbang/protocol-dns/src/main/java/org/apache/directory/server/dns/store/jndi/MultiBaseSearch.java
    directory/apacheds/branches/bigbang/protocol-newldap/pom.xml
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/LdapRequestHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/MechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SimpleMechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java
    directory/apacheds/branches/bigbang/protocol-newldap/src/test/java/org/apache/directory/server/newldap/LdapServerSettingsTest.java
    directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/catalog/GetCatalog.java
    directory/apacheds/branches/bigbang/server-integ/src/main/java/org/apache/directory/server/integ/LdapServerFactory.java
    directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/DITUtilitiesSP.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SimpleBindITest.java

Modified: directory/apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/ApacheSchemaConstants.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/ApacheSchemaConstants.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/ApacheSchemaConstants.java (original)
+++ directory/apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/ApacheSchemaConstants.java Thu Jul 31 18:20:21 2008
@@ -117,17 +117,24 @@
     String ENTRY_DELETED_OID                        = "1.3.6.1.4.1.18060.0.4.1.2.31";
 
     // SchemaModifiersName
-    String SCHEMA_MODIFIERS_NAME_AT         = "schemaModifiersName";
-    String SCHEMA_MODIFIERS_NAME_AT_OID     = "";
+    String SCHEMA_MODIFIERS_NAME_AT                 = "schemaModifiersName";
+    String SCHEMA_MODIFIERS_NAME_AT_OID             = "";
     
     // SchemaModifyTimestamp
-    String SCHEMA_MODIFY_TIMESTAMP_AT = "schemaModifyTimestamp";
-    String SCHEMA_MODIFY_TIMESTAMP_AT_OID = "";
+    String SCHEMA_MODIFY_TIMESTAMP_AT               = "schemaModifyTimestamp";
+    String SCHEMA_MODIFY_TIMESTAMP_AT_OID           = "";
     
     // SubschemaSubentryName
-    String SUBSCHEMA_SUBENTRY_NAME_AT = "subschemaSubentryName";
-    String SUBSCHEMA_SUBENTRY_NAME_AT_OID = "";
+    String SUBSCHEMA_SUBENTRY_NAME_AT               = "subschemaSubentryName";
+    String SUBSCHEMA_SUBENTRY_NAME_AT_OID           = "";
     
+    // CatalogEntryName
+    String APACHE_CATALOGUE_ENTRY_NAME_AT           = "apacheCatalogEntryName";
+    String APACHE_CATALOGUE_ENTRY_NAME_AT_OID       = "1.3.6.1.4.1.18060.0.4.1.2.17";
+    
+    String APACHE_CATALOGUE_ENTRY_BASE_DN_AT        = "apacheCatalogEntryBaseDn";
+    String APACHE_CATALOGUE_ENTRY_BASE_DN_AT_OID    = "1.3.6.1.4.1.18060.0.4.1.2.18";
+
     // WindowsFilePath
     String WINDOWS_FILE_AT                          = "windowsFilePath";
     String WINDOWS_FILE_AT_OID                      = "1.3.6.1.4.1.18060.0.4.1.2.19";

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AnonymousAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AnonymousAuthenticator.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AnonymousAuthenticator.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AnonymousAuthenticator.java Thu Jul 31 18:20:21 2008
@@ -50,7 +50,9 @@
      */
     public LdapPrincipal authenticate( BindOperationContext opContext ) throws NamingException
     {
-        if ( getDirectoryService().isAllowAnonymousAccess() )
+        // We only allow Anonymous binds if the sservice allows them _or_
+        // if the user wants to bind on the rootDSE
+        if ( getDirectoryService().isAllowAnonymousAccess() || opContext.getDn().isEmpty() )
         {
             return LdapPrincipal.ANONYMOUS;
         }

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java Thu Jul 31 18:20:21 2008
@@ -38,6 +38,7 @@
 import org.apache.directory.server.core.interceptor.NextInterceptor;
 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
+import org.apache.directory.server.core.interceptor.context.CompareOperationContext;
 import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
 import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
 import org.apache.directory.server.core.interceptor.context.GetMatchedNameOperationContext;
@@ -54,9 +55,11 @@
 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
 import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
 import org.apache.directory.shared.ldap.exception.LdapAuthenticationException;
+import org.apache.directory.shared.ldap.exception.LdapNoPermissionException;
 import org.apache.directory.shared.ldap.exception.LdapOperationNotSupportedException;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.StringTools;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -349,6 +352,20 @@
     }
 
 
+    public boolean compare( NextInterceptor next, CompareOperationContext opContext ) throws Exception
+    {
+        if ( IS_DEBUG )
+        {
+            LOG.debug( "Operation Context: {}", opContext );
+        }
+
+        checkAuthenticated( opContext );
+        boolean result = next.compare( opContext );
+        invalidateAuthenticatorCaches( opContext.getDn() );
+        return result;
+    }
+
+
     public void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext opContext )
             throws Exception
     {
@@ -389,7 +406,7 @@
 
 
     /**
-     * Check if the curretn operation has a valid PrincipalDN or not.
+     * Check if the current operation has a valid PrincipalDN or not.
      *
      * @param opContext the OperationContext for this operation
      * @param operation the operation type
@@ -397,10 +414,11 @@
      */
     private void checkAuthenticated( OperationContext operation ) throws Exception
     {
-        if ( operation.getSession() == null || operation.getSession().getEffectivePrincipal() == null )
+        if ( operation.getSession().isAnonymous() && !directoryService.isAllowAnonymousAccess() 
+            && !operation.getDn().isEmpty() )
         {
             LOG.error( "Attempted operation {} by unauthenticated caller.", operation.getName() );
-            throw new IllegalStateException( "Attempted operation by unauthenticated caller." );
+            throw new LdapNoPermissionException( "Attempted operation by unauthenticated caller." );
         }
     }
 
@@ -458,13 +476,16 @@
             {
                 // perform the authentication
                 LdapPrincipal principal = authenticator.authenticate( opContext );
-
-                // authentication was successful
-                CoreSession session = new DefaultCoreSession( principal, directoryService );
-                opContext.setSession( session );
+                
+                LdapPrincipal clonedPrincipal = (LdapPrincipal)(principal.clone());
 
                 // remove creds so there is no security risk
                 opContext.setCredentials( null );
+                clonedPrincipal.setUserPassword( StringTools.EMPTY_BYTES );
+
+                // authentication was successful
+                CoreSession session = new DefaultCoreSession( clonedPrincipal, directoryService );
+                opContext.setSession( session );
 
                 return;
             }

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/LdapPrincipal.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/LdapPrincipal.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/LdapPrincipal.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authn/LdapPrincipal.java Thu Jul 31 18:20:21 2008
@@ -35,7 +35,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public final class LdapPrincipal implements Principal, Serializable
+public final class LdapPrincipal implements Principal, Serializable, Cloneable
 {
     private static final long serialVersionUID = 3906650782395676720L;
 
@@ -158,4 +158,21 @@
         this.userPassword = new byte[ userPassword.length ];
         System.arraycopy( userPassword, 0, this.userPassword, 0, userPassword.length );
     }
+    
+    
+    /**
+     * Clone the object. This is done so that we don't store the 
+     * password in a LdapPrincipal more than necessary.
+     */
+    public Object clone() throws CloneNotSupportedException
+    {
+        LdapPrincipal clone = (LdapPrincipal)super.clone();
+        
+        if ( userPassword != null )
+        {
+            clone.setUserPassword( userPassword );
+        }
+        
+        return clone;
+    }
 }

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java Thu Jul 31 18:20:21 2008
@@ -904,7 +904,13 @@
             boolean isObjectScope = searchCtls.getSearchScope() == SearchControls.OBJECT_SCOPE;
             
             // test for (objectClass=*)
-            boolean isSearchAll = ( ( PresenceNode ) filter ).getAttribute().equals( SchemaConstants.OBJECT_CLASS_AT_OID );
+            boolean isSearchAll = false;
+            
+            // We have to be careful, as we may have a filter which is not a PresenceFilter
+            if ( filter instanceof PresenceNode )
+            {
+                isSearchAll = ( ( PresenceNode ) filter ).getAttribute().equals( SchemaConstants.OBJECT_CLASS_AT_OID );
+            }
 
             /*
              * if basedn is "", filter is "(objectclass=*)" and scope is object
@@ -1002,6 +1008,7 @@
                 return new BaseEntryFilteringCursor( new SingletonCursor<ServerEntry>( serverEntry ), opContext );
             }
 
+            // TODO : handle searches based on the RootDSE
             throw new LdapNameNotFoundException();
         }
 

Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/JndiPrincipalStoreImpl.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/JndiPrincipalStoreImpl.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/JndiPrincipalStoreImpl.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/JndiPrincipalStoreImpl.java Thu Jul 31 18:20:21 2008
@@ -92,6 +92,6 @@
         }
 
         // search only the configured entry baseDN
-        return new SingleBaseSearch( searchBaseDn, directoryService );
+        return new SingleBaseSearch( catalogBaseDn, searchBaseDn, directoryService );
     }
 }

Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/MultiBaseSearch.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/MultiBaseSearch.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/MultiBaseSearch.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/MultiBaseSearch.java Thu Jul 31 18:20:21 2008
@@ -24,12 +24,10 @@
 import java.util.Map;
 
 import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
 import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.core.DirectoryService;
-import org.apache.directory.server.core.jndi.ServerLdapContext;
 import org.apache.directory.server.kerberos.shared.store.operations.AddPrincipal;
 import org.apache.directory.server.kerberos.shared.store.operations.ChangePassword;
 import org.apache.directory.server.kerberos.shared.store.operations.DeletePrincipal;
@@ -39,7 +37,6 @@
 import org.apache.directory.server.protocol.shared.catalog.Catalog;
 import org.apache.directory.server.protocol.shared.catalog.GetCatalog;
 import org.apache.directory.server.protocol.shared.store.ContextOperation;
-import org.apache.directory.shared.ldap.name.LdapDN;
 
 
 /**
@@ -63,9 +60,7 @@
         this.directoryService = directoryService;
         try
         {
-            CoreSession session = directoryService.getSession();
-            DirContext ctx = new ServerLdapContext( directoryService, session, new LdapDN( catalogBaseDn ) );
-            catalog = new KerberosCatalog( ( Map ) execute( ctx, new GetCatalog() ) );
+            catalog = new KerberosCatalog( ( Map ) execute( directoryService.getSession(), new GetCatalog() ) );
         }
         catch ( Exception e )
         {
@@ -79,7 +74,7 @@
     {
         try
         {
-            return ( String ) execute( getDirContext( entry.getRealmName() ), new AddPrincipal( entry ) );
+            return ( String ) execute( directoryService.getSession(), new AddPrincipal( entry ) );
         }
         catch ( NamingException ne )
         {
@@ -92,7 +87,7 @@
     {
         try
         {
-            return ( String ) execute( getDirContext( principal.getRealm() ), new DeletePrincipal( principal ) );
+            return ( String ) execute( directoryService.getSession(), new DeletePrincipal( principal ) );
         }
         catch ( NamingException ne )
         {
@@ -106,7 +101,7 @@
     {
         try
         {
-            return ( PrincipalStoreEntry[] ) execute( getDirContext( realm ), new GetAllPrincipals() );
+            return ( PrincipalStoreEntry[] ) execute( directoryService.getSession(), new GetAllPrincipals() );
         }
         catch ( NamingException ne )
         {
@@ -120,7 +115,7 @@
     {
         try
         {
-            return ( PrincipalStoreEntry ) execute( getDirContext( principal.getRealm() ), new GetPrincipal( principal ) );
+            return ( PrincipalStoreEntry ) execute( directoryService.getSession(), new GetPrincipal( principal ) );
         }
         catch ( NamingException ne )
         {
@@ -134,7 +129,7 @@
     {
         try
         {
-            return ( String ) execute( getDirContext( principal.getRealm() ), new ChangePassword( principal, newPassword ) );
+            return ( String ) execute( directoryService.getSession(), new ChangePassword( principal, newPassword ) );
         }
         catch ( NamingException ne )
         {
@@ -144,15 +139,8 @@
     }
 
 
-    private Object execute( DirContext ctx, ContextOperation operation ) throws Exception
+    private Object execute( CoreSession session, ContextOperation operation ) throws Exception
     {
-        return operation.execute( ctx, null );
-    }
-
-    
-    private DirContext getDirContext( String name ) throws Exception
-    {
-        CoreSession session = directoryService.getSession();
-        return new ServerLdapContext( directoryService, session, new LdapDN( catalog.getBaseDn( name ) ) );
+        return operation.execute( session, null );
     }
 }

Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/SingleBaseSearch.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/SingleBaseSearch.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/SingleBaseSearch.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/SingleBaseSearch.java Thu Jul 31 18:20:21 2008
@@ -22,40 +22,37 @@
 
 import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.core.DirectoryService;
-import org.apache.directory.server.core.jndi.ServerLdapContext;
 import org.apache.directory.server.kerberos.shared.store.operations.AddPrincipal;
 import org.apache.directory.server.kerberos.shared.store.operations.ChangePassword;
 import org.apache.directory.server.kerberos.shared.store.operations.DeletePrincipal;
 import org.apache.directory.server.kerberos.shared.store.operations.GetAllPrincipals;
 import org.apache.directory.server.kerberos.shared.store.operations.GetPrincipal;
 import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
-import org.apache.directory.shared.ldap.name.LdapDN;
 
-import javax.naming.directory.DirContext;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
 
 /**
- * A JNDI-backed search strategy implementation.  This search strategy searches a
- * single base DN for Kerberos principals.
+ * A JNDI-backed search strategy implementation. This search strategy searches 
+ * for Kerberos principals.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
 class SingleBaseSearch implements PrincipalStore
 {
-    private final DirContext ctx;
+    private final CoreSession session;
 
 
-    SingleBaseSearch( String searchBaseDn, DirectoryService directoryService )
+    SingleBaseSearch( DirectoryService directoryService )
     {
         try
         {
-            CoreSession session = directoryService.getSession();
-            ctx = new ServerLdapContext( directoryService, session, new LdapDN( searchBaseDn ) );
-        } catch ( Exception e )
+            session = directoryService.getSession();
+        } 
+        catch ( Exception e )
         {
-            throw new ServiceConfigurationException("Can't get context at" + searchBaseDn, e);
+            throw new ServiceConfigurationException("Can't get a session", e);
         }
 
     }
@@ -63,30 +60,30 @@
 
     public String addPrincipal( PrincipalStoreEntry entry ) throws Exception
     {
-        return ( String ) new AddPrincipal( entry ).execute( ctx, null );
+        return ( String ) new AddPrincipal( entry ).execute( session, null );
     }
 
 
     public String deletePrincipal( KerberosPrincipal principal ) throws Exception
     {
-        return ( String ) new DeletePrincipal( principal ).execute( ctx, null );
+        return ( String ) new DeletePrincipal( principal ).execute( session, null );
     }
 
 
     public PrincipalStoreEntry[] getAllPrincipals( String realm ) throws Exception
     {
-        return ( PrincipalStoreEntry[] ) new GetAllPrincipals().execute( ctx, null );
+        return ( PrincipalStoreEntry[] ) new GetAllPrincipals().execute( session, null );
     }
 
 
     public PrincipalStoreEntry getPrincipal( KerberosPrincipal principal ) throws Exception
     {
-        return ( PrincipalStoreEntry ) new GetPrincipal( principal ).execute( ctx, null );
+        return ( PrincipalStoreEntry ) new GetPrincipal( principal ).execute( session, null );
     }
 
 
     public String changePassword( KerberosPrincipal principal, String newPassword ) throws Exception
     {
-        return ( String ) new ChangePassword( principal, newPassword ).execute( ctx, null );
+        return ( String ) new ChangePassword( principal, newPassword ).execute( session, null );
     }
 }

Modified: directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/operations/GetPrincipal.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/operations/GetPrincipal.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/operations/GetPrincipal.java (original)
+++ directory/apacheds/branches/bigbang/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/store/operations/GetPrincipal.java Thu Jul 31 18:20:21 2008
@@ -22,7 +22,9 @@
 
 import java.io.IOException;
 import java.text.ParseException;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import javax.naming.Name;
 import javax.naming.NamingEnumeration;
@@ -34,6 +36,10 @@
 import javax.naming.directory.SearchResult;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
@@ -42,8 +48,13 @@
 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntryModifier;
 import org.apache.directory.server.protocol.shared.store.ContextOperation;
+import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.message.AttributeImpl;
 import org.apache.directory.shared.ldap.message.AttributesImpl;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.schema.AttributeTypeOptions;
 
 
 /**
@@ -75,7 +86,7 @@
      * Note that the base is a relative path from the existing context.
      * It is not a DN.
      */
-    public Object execute( DirContext ctx, Name base )
+    public Object execute( CoreSession session, LdapDN base )
     {
         if ( principal == null )
         {
@@ -83,39 +94,52 @@
         }
 
         String[] attrIDs =
-            {   KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, 
+            {   
+                KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, 
                 KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, 
                 KerberosAttribute.KRB5_KEY_AT,
                 KerberosAttribute.APACHE_SAM_TYPE_AT, 
                 KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT,
                 KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT, 
-                KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT };
+                KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT 
+            };
 
-        Attributes matchAttrs = new AttributesImpl( true );
-        matchAttrs.put( new AttributeImpl( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principal.getName() ) );
+        Set<AttributeTypeOptions> matchAttrs = new HashSet<AttributeTypeOptions>();
+        AttributeTypeRegistry atRegistry = session.getDirectoryService().getRegistries().getAttributeTypeRegistry();
+        AttributeTypeOptions krb5PrincipalAT = null;
+        
+        try
+        {
+            krb5PrincipalAT = new AttributeTypeOptions( atRegistry.lookup( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ) );
+        }
+        catch ( NamingException ne )
+        {
+            return null;
+        }
+        
+        matchAttrs.add( krb5PrincipalAT );
 
         PrincipalStoreEntry entry = null;
 
         try
         {
-            NamingEnumeration<SearchResult> answer = ctx.search( "", matchAttrs, attrIDs );
+            EntryFilteringCursor cursor = session.list( LdapDN.EMPTY_LDAPDN, AliasDerefMode.DEREF_ALWAYS, matchAttrs );
 
-            if ( answer.hasMore() )
+            cursor.beforeFirst();
+            
+            if ( cursor.next() )
             {
-                SearchResult result = answer.next();
-
-                Attributes attrs = result.getAttributes();
-
-                if ( attrs == null )
+                ClonedServerEntry result = cursor.get();
+                
+                if ( !result.containsAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ) )
                 {
                     return null;
                 }
-
-                String distinguishedName = result.getName();
-                entry = getEntry( distinguishedName, attrs );
+                
+                entry = getEntry( result );
             }
         }
-        catch ( NamingException e )
+        catch ( Exception e )
         {
             return null;
         }
@@ -132,33 +156,33 @@
      * @return the entry for the principal
      * @throws NamingException if there are any access problems
      */
-    private PrincipalStoreEntry getEntry( String distinguishedName, Attributes attrs ) throws NamingException
+    private PrincipalStoreEntry getEntry( ServerEntry entry ) throws NamingException
     {
         PrincipalStoreEntryModifier modifier = new PrincipalStoreEntryModifier();
 
-        modifier.setDistinguishedName( distinguishedName );
+        modifier.setDistinguishedName( entry.getDn().getUpName() );
 
-        String principal = ( String ) attrs.get( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ).get();
+        String principal = entry.get( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ).getString();
         modifier.setPrincipal( new KerberosPrincipal( principal ) );
 
-        String keyVersionNumber = ( String ) attrs.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get();
+        String keyVersionNumber = entry.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).getString();
         modifier.setKeyVersionNumber( Integer.parseInt( keyVersionNumber ) );
 
-        if ( attrs.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ) != null )
+        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ) != null )
         {
-            String val = ( String ) attrs.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ).get();
+            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ).getString();
             modifier.setDisabled( "true".equalsIgnoreCase( val ) );
         }
 
-        if ( attrs.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ) != null )
+        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ) != null )
         {
-            String val = ( String ) attrs.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ).get();
+            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ).getString();
             modifier.setLockedOut( "true".equalsIgnoreCase( val ) );
         }
 
-        if ( attrs.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ) != null )
+        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ) != null )
         {
-            String val = ( String ) attrs.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ).get();
+            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ).getString();
             try
             {
                 modifier.setExpiration( KerberosTime.getTime( val ) );
@@ -171,15 +195,16 @@
             }
         }
 
-        if ( attrs.get( KerberosAttribute.APACHE_SAM_TYPE_AT ) != null )
+        if ( entry.get( KerberosAttribute.APACHE_SAM_TYPE_AT ) != null )
         {
-            String samType = ( String ) attrs.get( KerberosAttribute.APACHE_SAM_TYPE_AT ).get();
+            String samType = entry.get( KerberosAttribute.APACHE_SAM_TYPE_AT ).getString();
             modifier.setSamType( SamType.getTypeByOrdinal( Integer.parseInt( samType ) ) );
         }
 
-        if ( attrs.get( KerberosAttribute.KRB5_KEY_AT ) != null )
+        if ( entry.get( KerberosAttribute.KRB5_KEY_AT ) != null )
         {
-            Attribute krb5key = attrs.get( KerberosAttribute.KRB5_KEY_AT );
+            EntryAttribute krb5key = entry.get( KerberosAttribute.KRB5_KEY_AT );
+            
             try
             {
                 Map<EncryptionType, EncryptionKey> keyMap = modifier.reconstituteKeyMap( krb5key );

Modified: directory/apacheds/branches/bigbang/protocol-dns/src/main/java/org/apache/directory/server/dns/store/jndi/MultiBaseSearch.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-dns/src/main/java/org/apache/directory/server/dns/store/jndi/MultiBaseSearch.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-dns/src/main/java/org/apache/directory/server/dns/store/jndi/MultiBaseSearch.java (original)
+++ directory/apacheds/branches/bigbang/protocol-dns/src/main/java/org/apache/directory/server/dns/store/jndi/MultiBaseSearch.java Thu Jul 31 18:20:21 2008
@@ -66,9 +66,7 @@
         try
         {
             CoreSession session = directoryService.getSession();
-            DirContext ctx = new ServerLdapContext( directoryService, session, new LdapDN( catalogBaseDn ) );
-            //noinspection unchecked
-            catalog = new DnsCatalog( ( Map<String, Object> ) new GetCatalog().execute( ctx, null ) );
+            catalog = new DnsCatalog( ( Map<String, Object> ) new GetCatalog().execute( session, null ) );
         }
         catch ( Exception e )
         {

Modified: directory/apacheds/branches/bigbang/protocol-newldap/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/pom.xml?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/pom.xml (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/pom.xml Thu Jul 31 18:20:21 2008
@@ -42,6 +42,11 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-ldap</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.mina</groupId>
       <artifactId>mina-filter-ssl</artifactId>
     </dependency>

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java Thu Jul 31 18:20:21 2008
@@ -21,6 +21,7 @@
 
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -60,6 +61,11 @@
     
     /** The CoreSession */
     private CoreSession coreSession;
+    
+    /** A reference on the LdapServer instance */
+    private LdapServer ldapServer;
+    
+    
     private Map<Integer, AbandonableRequest> outstandingRequests;
     
     
@@ -69,6 +75,12 @@
     /** The current mechanism used to authenticate the user */
     private String currentMechanism;
     
+    
+    /**
+     * A Map containing Objects used during the SASL negotiation
+     */
+    private Map<String, Object> saslProperties;
+    
  
     /**
      * Creates a new instance of LdapSession associated with the underlying
@@ -82,6 +94,7 @@
         outstandingLock = "OutstandingRequestLock: " + ioSession.toString();
         outstandingRequests = new ConcurrentHashMap<Integer, AbandonableRequest>();
         bindStatus = BindStatus.ANONYMOUS;
+        saslProperties = new HashMap<String, Object>();
     }
     
     
@@ -292,4 +305,56 @@
     {
         return currentMechanism;
     }
+
+
+    /**
+     *  @return The SASL properties
+     */
+    public Map<String, Object> getSaslProperties()
+    {
+        return saslProperties;
+    }
+
+
+    /**
+     * Add a Sasl property and value
+     * 
+     * @param property the property to add
+     * @param value the value for this property
+     */
+    public void putSaslProperties( String property, Object value )
+    {
+        saslProperties.put( property, value );
+    }
+    
+    
+    /**
+     * Remove a property from the SaslProperty map
+     *
+     * @param property the property to remove
+     */
+    public void removeSaslProperty( String property )
+    {
+        saslProperties.remove( property );
+    }
+
+
+    /**
+     *  @return The LdapServer reference
+     */
+    public LdapServer getLdapServer()
+    {
+        return ldapServer;
+    }
+
+
+    /**
+     * Store a reference on the LdapServer intance
+     *
+     * @param ldapServer the LdapServer instance
+     */
+    public void setLdapServer( LdapServer ldapServer )
+    {
+        this.ldapServer = ldapServer;
+    }
 }

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/LdapRequestHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/LdapRequestHandler.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/LdapRequestHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/LdapRequestHandler.java Thu Jul 31 18:20:21 2008
@@ -23,11 +23,9 @@
 import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.newldap.LdapServer;
 import org.apache.directory.server.newldap.LdapSession;
+import org.apache.directory.shared.ldap.message.AbandonRequest;
 import org.apache.directory.shared.ldap.message.BindRequest;
 import org.apache.directory.shared.ldap.message.Request;
-import org.apache.directory.shared.ldap.message.ResultCodeEnum;
-import org.apache.directory.shared.ldap.message.ResultResponse;
-import org.apache.directory.shared.ldap.message.ResultResponseRequest;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.handler.demux.MessageHandler;
 
@@ -100,7 +98,16 @@
             
             coreSession = getLdapServer().getDirectoryService().getSession();
             ldapSession.setCoreSession( coreSession );
+
+            if ( message instanceof AbandonRequest )
+            {
+                return;
+            }
             
+            handle( ldapSession, message );
+            return;
+
+            /*
             if ( coreSession.getDirectoryService().isAllowAnonymousAccess() )
             {
             	// We are not authenticated, and the server allows anonymous access,
@@ -124,6 +131,7 @@
             	// Last case : the AbandonRequest. We just quit.
                 return;
             }
+            */
         }
     }
 

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java Thu Jul 31 18:20:21 2008
@@ -20,20 +20,18 @@
 package org.apache.directory.server.newldap.handlers;
 
 
-import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 
 import javax.naming.Name;
 import javax.security.auth.Subject;
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 
-import org.apache.commons.lang.NotImplementedException;
+import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.ServerEntry;
 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
@@ -43,8 +41,9 @@
 import org.apache.directory.server.newldap.LdapServer;
 import org.apache.directory.server.newldap.LdapSession;
 import org.apache.directory.server.newldap.handlers.bind.MechanismHandler;
+import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
 import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
-import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.exception.LdapAuthenticationException;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.message.BindRequest;
@@ -53,6 +52,7 @@
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.util.StringTools;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -73,7 +73,14 @@
     /** A Hashed Adapter mapping SASL mechanisms to their handlers. */
     private Map<String, MechanismHandler> handlers;
 
-        
+    /** A session created using the server Admin, to be able to get full access to the server */
+    private CoreSession adminSession;
+    
+    
+    /** A lock used to protect the creation of the inner AdminSession */
+    private Object mutex = new Object();
+    
+    
     /**
      * Set the mechanisms handler map.
      * 
@@ -92,8 +99,21 @@
      * @param message The BindRequest received
      * @throws Exception If the authentication cannot be done
      */
-    public void handleSimpleAuth( LdapSession session, BindRequest bindRequest ) throws Exception
+    public void handleSimpleAuth( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
     {
+        // if the user is already bound, we have to unbind him
+        if ( !ldapSession.isAnonymous() )
+        {
+            // We already have a bound session for this user. We have to
+            // abandon it first.
+            ldapSession.getCoreSession().unbind();
+            
+            // Reset the status to Anonymous
+            ldapSession.setAnonymous();
+        }
+
+        // Now, bind the user
+        
         // create a new Bind context, with a null session, as we don't have 
         // any context yet.
         BindOperationContext opContext = new BindOperationContext( null );
@@ -111,20 +131,15 @@
 	        getLdapServer().getDirectoryService().getOperationManager().bind( opContext );
 	        
 	        // As a result, store the created session in the Core Session
-	        session.setCoreSession( opContext.getSession() );
-	        
-	        // Return the successful response
-	        BindResponse response = ( BindResponse ) bindRequest.getResultResponse();
-	        response.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
-	        LdapProtocolUtils.setResponseControls( opContext, response );
+	        ldapSession.setCoreSession( opContext.getSession() );
 	        
-	        // Write it back to the client
-	        if ( ! session.getCoreSession().isAnonymous() )
+	        if ( ! ldapSession.getCoreSession().isAnonymous() )
 	        {
-	            session.setAuthenticated();
+	            ldapSession.setAuthenticated();
 	        }
-	        session.getIoSession().write( response );
-	        LOG.debug( "Returned SUCCESS message: {}.", response );
+	        
+	        // Return the successful response
+	        sendBindSuccess( ldapSession, bindRequest, null );
         }
         catch ( Exception e )
         {
@@ -166,156 +181,337 @@
             }
 
             result.setErrorMessage( msg );
-            session.getIoSession().write( bindRequest.getResultResponse() );
+            ldapSession.getIoSession().write( bindRequest.getResultResponse() );
         }
     }
     
     
     /**
-     * Handle the SASL authentication.
-     *
-     * @param session The associated Session
-     * @param message The BindRequest received
-     * @throws Exception If the authentication cannot be done
+     * Check if the mechanism exists.
      */
-    public void handleSaslAuth( LdapSession session, BindRequest message ) throws Exception
+    private boolean checkMechanism( LdapSession ldapSession, String saslMechanism ) throws Exception
     {
-        Map<String, String> saslProps = new HashMap<String, String>();
-        saslProps.put( Sasl.QOP, ldapServer.getSaslQopString() );
-        saslProps.put( "com.sun.security.sasl.digest.realm", getActiveRealms( ldapServer ) );
-        session.getIoSession().setAttribute( "saslProps", saslProps );
+        // Guard clause:  Reject unsupported SASL mechanisms.
+        if ( ! ldapServer.getSupportedMechanisms().contains( saslMechanism ) )
+        {
+            LOG.error( "Bind error : {} mechanism not supported. Please check the server.xml " + 
+                "configuration file (supportedMechanisms field)", 
+                saslMechanism );
 
-        session.getIoSession().setAttribute( "saslHost", ldapServer.getSaslHost() );
-        session.getIoSession().setAttribute( "baseDn", ldapServer.getSearchBaseDn() );
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+    
+    
+    private void generateSaslChallenge( LdapSession ldapSession, SaslServer ss, BindRequest bindRequest )
+    {
+        LdapResult result = bindRequest.getResultResponse().getLdapResult();
 
-        Set<String> activeMechanisms = ldapServer.getSupportedMechanisms();
+        // SaslServer will throw an exception if the credentials are null.
+        if ( bindRequest.getCredentials() == null )
+        {
+            bindRequest.setCredentials( new byte[0] );
+        }
 
-        if ( activeMechanisms.contains( SupportedSaslMechanisms.GSSAPI ) )
+        try
         {
-            try
+            // Compute the challenge
+            byte[] tokenBytes = ss.evaluateResponse( bindRequest.getCredentials() );
+    
+            if ( ss.isComplete() )
             {
-                Subject saslSubject = getSubject( ldapServer );
-                session.getIoSession().setAttribute( "saslSubject", saslSubject );
+                // This is the end of the C/R exchange
+                if ( tokenBytes != null )
+                {
+                    /*
+                     * There may be a token to return to the client.  We set it here
+                     * so it will be returned in a SUCCESS message, after an LdapContext
+                     * has been initialized for the client.
+                     */
+                    ldapSession.getSaslProperties().put( SaslConstants.SASL_CREDS, tokenBytes );
+                }
+                
+                // Return the successful response
+                sendBindSuccess( ldapSession, bindRequest, tokenBytes );
             }
-            catch ( ServiceConfigurationException sce )
+            else
             {
-                activeMechanisms.remove( "GSSAPI" );
-                LOG.warn( sce.getMessage() );
-            }
+                // The SASL bind must continue, we are sending the computed challenge
+                LOG.info( "Continuation token had length " + tokenBytes.length );
+                
+                // Build the response
+                result.setResultCode( ResultCodeEnum.SASL_BIND_IN_PROGRESS );
+                BindResponse resp = ( BindResponse ) bindRequest.getResultResponse();
+                
+                // Store the challenge
+                resp.setServerSaslCreds( tokenBytes );
+                
+                // Switch to AuthPending
+                ldapSession.setAuthPending();
+                
+                // Store the current mechanism, as the C/R is not finished
+                ldapSession.getSaslProperties().put( SaslConstants.SASL_MECH, bindRequest.getSaslMechanism() );
+                
+                // And write back the response
+                ldapSession.getIoSession().write( resp );
+                LOG.debug( "Returning final authentication data to client to complete context." );
+            }
+        }
+        catch ( SaslException se )
+        {
+            LOG.error( se.getMessage() );
+            result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS );
+            result.setErrorMessage( se.getMessage() );
+            
+            // Reinitialize the state to Anonymous and clear the sasl properties
+            ldapSession.getSaslProperties().clear();
+            ldapSession.setAnonymous();
+            
+            // Write back the error response
+            ldapSession.getIoSession().write( bindRequest.getResultResponse() );
         }
+    }
+    
+    
+    private void sendAuthMethNotSupported( LdapSession ldapSession, BindRequest bindRequest )
+    {
+        // First, reinit the state to Anonymous, and clear the
+        // saslProperty map
+        ldapSession.getSaslProperties().clear();
+        ldapSession.setAnonymous();
+        
+        // And send the response to the client
+        LdapResult bindResult = bindRequest.getResultResponse().getLdapResult();
+        bindResult.setResultCode( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
+        bindResult.setErrorMessage( bindRequest.getSaslMechanism() + " is not a supported mechanism." );
+        
+        // Write back the error
+        ldapSession.getIoSession().write( bindRequest.getResultResponse() );
 
-        BindRequest bindRequest = ( BindRequest ) message;
-
-        // Guard clause:  Reject unsupported SASL mechanisms.
-        if ( ! ldapServer.getSupportedMechanisms().contains( bindRequest.getSaslMechanism() ) )
+        return;
+    }
+    
+    
+    private void sendInvalidCredentials( LdapSession ldapSession, BindRequest bindRequest, SaslException se )
+    {
+        LdapResult result = bindRequest.getResultResponse().getLdapResult();
+        
+        LOG.error( se.getMessage() );
+        result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS );
+        result.setErrorMessage( se.getMessage() );
+        
+        // Reinitialize the state to Anonymous and clear the sasl properties
+        ldapSession.getSaslProperties().clear();
+        ldapSession.setAnonymous();
+        
+        // Write back the error response
+        ldapSession.getIoSession().write( bindRequest.getResultResponse() );
+    }
+    
+    
+    private void sendBindSuccess( LdapSession ldapSession, BindRequest bindRequest, byte[] tokenBytes )
+    {
+        // Return the successful response
+        BindResponse response = ( BindResponse ) bindRequest.getResultResponse();
+        response.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
+        response.setServerSaslCreds( tokenBytes );
+        
+        if ( ! ldapSession.getCoreSession().isAnonymous() )
         {
-            LOG.error( "Bind error : {} mechanism not supported. Please check the server.xml " + 
-                "configuration file (supportedMechanisms field)", 
-                bindRequest.getSaslMechanism() );
-
-            LdapResult bindResult = bindRequest.getResultResponse().getLdapResult();
-            bindResult.setResultCode( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
-            bindResult.setErrorMessage( bindRequest.getSaslMechanism() + " is not a supported mechanism." );
-            session.getIoSession().write( bindRequest.getResultResponse() );
-            return;
+            // If we have not been asked to authenticate as Anonymous, authenticate the user
+            ldapSession.setAuthenticated();
+        }
+        else
+        {
+            // Otherwise, switch back to Anonymous
+            ldapSession.setAnonymous();
         }
+        
+        // Clean the SaslProperties, we don't need them anymore
+        ldapSession.getSaslProperties().clear();
 
-        handleSasl( session, bindRequest );
+        ldapSession.getIoSession().write( response );
+        
+        LOG.debug( "Returned SUCCESS message: {}.", response );
     }
 
     
-    /**
-     * Deal with a SASL bind request
-     * 
-     * @param session The IoSession for this Bind Request
-     * @param bindRequest The BindRequest received
-     * 
-     * @exception Exception if the mechanism cannot handle the authentication
-     */
-    public void handleSasl( LdapSession session, BindRequest bindRequest ) throws Exception
+    private void handleSaslAuthPending( LdapSession ldapSession, BindRequest bindRequest, DirectoryService ds ) throws Exception
     {
-        DirectoryService ds = getLdapServer().getDirectoryService();
-        String sessionMechanism = bindRequest.getSaslMechanism();
-
-        if ( sessionMechanism.equals( SupportedSaslMechanisms.PLAIN ) )
+        // First, check that we have the same mechanism
+        String saslMechanism = bindRequest.getSaslMechanism();
+        
+        if ( !ldapSession.getSaslProperties().get( SaslConstants.SASL_MECH ).equals( saslMechanism ) )
         {
-            // TODO - figure out what to provide for the saslAuthId here
-            session.setCoreSession( ds.getSession( bindRequest.getName(), bindRequest.getCredentials(), 
-                sessionMechanism, null ) );
+            sendAuthMethNotSupported( ldapSession, bindRequest );
+            return;
         }
-        else
+        // We have already received a first BindRequest, and sent back some challenge.
+        // First, check if the mechanism is the same
+        MechanismHandler mechanismHandler = handlers.get( saslMechanism );
+
+        if ( mechanismHandler == null )
         {
-            MechanismHandler mechanismHandler = handlers.get( sessionMechanism );
+            String message = "Handler unavailable for " + saslMechanism;
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
 
-            if ( mechanismHandler == null )
+        SaslServer ss = mechanismHandler.handleMechanism( ldapSession, adminSession, bindRequest );
+        
+        if ( !ss.isComplete() )
+        {
+            /*
+             * SaslServer will throw an exception if the credentials are null.
+             */
+            if ( bindRequest.getCredentials() == null )
             {
-                LOG.error( "Handler unavailable for " + sessionMechanism );
-                throw new IllegalArgumentException( "Handler unavailable for " + sessionMechanism );
+                bindRequest.setCredentials( new byte[0] );
             }
-
-            SaslServer ss = mechanismHandler.handleMechanism( session, bindRequest );
-            LdapResult result = bindRequest.getResultResponse().getLdapResult();
-
-            if ( ! ss.isComplete() )
+            
+            byte[] tokenBytes = ss.evaluateResponse( bindRequest.getCredentials() );
+            
+            if ( ss.isComplete() )
             {
-                try
+                if ( tokenBytes != null )
                 {
                     /*
-                     * SaslServer will throw an exception if the credentials are null.
+                     * There may be a token to return to the client.  We set it here
+                     * so it will be returned in a SUCCESS message, after an LdapContext
+                     * has been initialized for the client.
                      */
-                    if ( bindRequest.getCredentials() == null )
-                    {
-                        bindRequest.setCredentials( new byte[0] );
-                    }
-
-                    byte[] tokenBytes = ss.evaluateResponse( bindRequest.getCredentials() );
-
-                    if ( ss.isComplete() )
-                    {
-                        if ( tokenBytes != null )
-                        {
-                            /*
-                             * There may be a token to return to the client.  We set it here
-                             * so it will be returned in a SUCCESS message, after an LdapContext
-                             * has been initialized for the client.
-                             */
-                            session.getIoSession().setAttribute( "saslCreds", tokenBytes );
-                        }
-
-                        /*
-                         * If we got here, we're ready to try getting a core session.
-                         */
-                        // TODO - figure out what to provide for the saslAuthId here
-                        session.setCoreSession( ds.getSession( bindRequest.getName(), bindRequest.getCredentials(), 
-                            sessionMechanism, null ) );
-                    }
-                    else
-                    {
-                        LOG.info( "Continuation token had length " + tokenBytes.length );
-                        result.setResultCode( ResultCodeEnum.SASL_BIND_IN_PROGRESS );
-                        BindResponse resp = ( BindResponse ) bindRequest.getResultResponse();
-                        resp.setServerSaslCreds( tokenBytes );
-                        session.getIoSession().write( resp );
-                        LOG.debug( "Returning final authentication data to client to complete context." );
-                    }
+                    ldapSession.getSaslProperties().put( SaslConstants.SASL_CREDS, tokenBytes );
                 }
-                catch ( SaslException se )
+                
+                // Create the user's coreSession
+                try
                 {
-                    LOG.error( se.getMessage() );
-                    result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS );
-                    result.setErrorMessage( se.getMessage() );
-                    session.getIoSession().write( bindRequest.getResultResponse() );
+                    ServerEntry userEntry = (ServerEntry)ldapSession.getSaslProperties().get( SaslConstants.SASL_AUTHENT_USER );
+                    
+                    CoreSession userSession = ds.getSession( userEntry.getDn(), userEntry.get( SchemaConstants.USER_PASSWORD_AT ).getBytes(), saslMechanism, null );
+                    
+                    ldapSession.setCoreSession( userSession );
+                    
+                    // Mark the user as authenticated
+                    ldapSession.setAuthenticated();
+                    
+                    // Clean the Sasl Properties so that we don't have the user password
+                    // stored in memory forever
+                    ldapSession.getSaslProperties().clear();
+                    
+                    // And send a Success response
+                    sendBindSuccess( ldapSession, bindRequest, tokenBytes );
+                }
+                catch ( Exception e )
+                {
+                    
                 }
             }
         }
     }
-
+    
     
     /**
+     * Handle the SASL authentication. If the mechanism is known, we are
+     * facing three cases :
+     * <ul>
+     * <li>The user does not has a session yet</li>
+     * <li>The user already has a session</li>
+     * <li>The user has started a SASL negotiation</li>
+     * </lu><br/>
+     * 
+     * In the first case, we initiate a SaslBind session, which will be used all
+     * along the negotiation.<br/>
+     * In the second case, we first have to unbind the user, and initiate a new
+     * SaslBind session.<br/>
+     * In the third case, we have sub cases :
+     * <ul>
+     * <li>The mechanism is not provided : that means the user want to reset the
+     * current negotiation. We move back to an Anonymous state</li>
+     * <li>The mechanism is provided : the user is initializing a new negotiation
+     * with another mechanism. The current SaslBind session is reinitialized</li>
+     * <li></li>
+     * </ul><br/>
+     *
+     * @param session The associated Session
+     * @param message The BindRequest received
+     * @throws Exception If the authentication cannot be done
+     */
+    public void handleSaslAuth( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
+    {
+        String saslMechanism = bindRequest.getSaslMechanism();
+        DirectoryService ds = getLdapServer().getDirectoryService();
+        
+        // Case #2 : the user does have a session. We have to unbind him
+        if ( ldapSession.isAuthenticated() )
+        {
+            // We already have a bound session for this user. We have to
+            // close the previous session first.
+            ldapSession.getCoreSession().unbind();
+            
+            // Reset the status to Anonymous
+            ldapSession.setAnonymous();
+            
+            // Clean the sasl properties
+            ldapSession.getSaslProperties().clear();
+            
+            // Now we can continue as if the client was Anonymous from the beginning
+        }
+
+        // case #1 : The user does not have a session.
+        if ( ldapSession.isAnonymous() )
+        {
+            if ( !StringTools.isEmpty( saslMechanism ) )
+            {
+                // fist check that the mechanism exists
+                if ( !checkMechanism( ldapSession, saslMechanism ) )
+                {
+                    // get out !
+                    sendAuthMethNotSupported( ldapSession, bindRequest );
+
+                    return;
+                }
+
+                // Store the mechanism in the ldap session
+                ldapSession.getSaslProperties().put( SaslConstants.SASL_MECH, saslMechanism );
+                
+                // Get the handler for this mechanism
+                MechanismHandler mechanismHandler = handlers.get( saslMechanism );
+                
+                // Get the SaslServer instance which manage the C/R exchange
+                SaslServer ss = mechanismHandler.handleMechanism( ldapSession, adminSession, bindRequest );
+                
+                // We have to generate a challenge
+                generateSaslChallenge( ldapSession, ss, bindRequest );
+                
+                // And get back
+                return;
+            }
+        }
+        else if ( ldapSession.isAuthPending() )
+        {
+            try
+            {
+                handleSaslAuthPending( ldapSession, bindRequest, ds );
+            }
+            catch ( SaslException se )
+            {
+                sendInvalidCredentials( ldapSession, bindRequest, se );
+            }
+            return;
+        }
+    }
+
+
+    /**
      * Create a list of all the configured realms.
      * 
      * @param ldapServer the LdapServer for which we want to get the realms
-     * @return a list of relms, separated by spaces
+     * @return a list of realms, separated by spaces
      */
     private String getActiveRealms( LdapServer ldapServer )
     {
@@ -388,30 +584,15 @@
 
     private PrincipalStoreEntry findPrincipal( LdapServer ldapServer, GetPrincipal getPrincipal ) throws Exception
     {
-//        if ( ctx == null )
-//        {
-//            try
-//            {
-//                LdapDN adminDN = new LdapDN( ServerDNConstants.ADMIN_SYSTEM_DN );
-//                
-//                adminDN.normalize( 
-//                    ldapServer.getDirectoryService().getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
-//                LdapPrincipal principal = new LdapPrincipal( adminDN, AuthenticationLevel.SIMPLE );
-//
-//                CoreSession adminSession = getLdapServer().getDirectoryService().getAdminSession();
-//                
-//                ctx = new ServerLdapContext( ldapServer.getDirectoryService(), principal, 
-//                    new LdapDN( ldapServer.getSearchBaseDn() ) );
-//            }
-//            catch ( NamingException ne )
-//            {
-//                String message = "Failed to get initial context " + ldapServer.getSearchBaseDn();
-//                throw new ServiceConfigurationException( message, ne );
-//            }
-//        }
-//
-//        return ( PrincipalStoreEntry ) getPrincipal.execute( ctx, null );
-        throw new NotImplementedException();
+        synchronized ( mutex )
+        {
+            if ( adminSession == null )
+            {
+                adminSession = getLdapServer().getDirectoryService().getAdminSession();
+            }
+        }
+
+        return ( PrincipalStoreEntry ) getPrincipal.execute( adminSession, null );
     }    
     
 
@@ -423,7 +604,7 @@
      * @throws Exception If the authentication cannot be handled
      */
     @Override
-    public void handle( LdapSession session, BindRequest bindRequest ) throws Exception
+    public void handle( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
     {
         LOG.debug( "Received: {}", bindRequest );
 
@@ -434,18 +615,27 @@
             LdapResult bindResult = bindRequest.getResultResponse().getLdapResult();
             bindResult.setResultCode( ResultCodeEnum.PROTOCOL_ERROR );
             bindResult.setErrorMessage( "Only LDAP v3 is supported." );
-            session.getIoSession().write( bindRequest.getResultResponse() );
+            ldapSession.getIoSession().write( bindRequest.getResultResponse() );
             return;
         }
 
         // Deal with the two kinds of authentication : Simple and SASL
         if ( bindRequest.isSimple() )
         {
-            handleSimpleAuth( session, bindRequest );
+            handleSimpleAuth( ldapSession, bindRequest );
         }
         else
         {
-            handleSaslAuth( session, bindRequest );
+            synchronized ( mutex )
+            {
+                if ( adminSession == null )
+                {
+                    adminSession = getLdapServer().getDirectoryService().getAdminSession();
+                    ldapSession.setLdapServer( getLdapServer() );
+                }
+            }
+
+            handleSaslAuth( ldapSession, bindRequest );
         }
     }
 }

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java Thu Jul 31 18:20:21 2008
@@ -23,6 +23,7 @@
 import org.apache.directory.server.constants.ServerDNConstants;
 import org.apache.directory.server.core.DirectoryService;
 import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.message.BindRequest;
 import org.apache.directory.shared.ldap.message.LdapResult;
@@ -30,6 +31,7 @@
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.apache.mina.common.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -65,7 +67,12 @@
 
     private String username;
     private String realm;
+    
+    /** A reference on the DirectoryService instance */
     protected final DirectoryService directoryService;
+    
+    /** The associated BindRequest */
+    protected final BindRequest bindRequest;
 
 
     /**
@@ -73,9 +80,10 @@
      *
      * @param directoryService
      */
-    protected AbstractSaslCallbackHandler( DirectoryService directoryService )
+    protected AbstractSaslCallbackHandler( DirectoryService directoryService, BindRequest bindRequest )
     {
         this.directoryService = directoryService;
+        this.bindRequest = bindRequest;
     }
 
 
@@ -110,9 +118,9 @@
      * </ul>
      * @param username The username.
      * @param realm The realm.
-     * @return The password resulting from the lookup.
+     * @return The Password entry attribute resulting from the lookup. It may contain more than one password
      */
-    protected abstract String lookupPassword( String username, String realm );
+    protected abstract EntryAttribute lookupPassword( String username, String realm );
 
 
     /**
@@ -141,8 +149,7 @@
 
             if ( LOG.isDebugEnabled() )
             {
-                LOG.debug( "Processing callback " + ( i + 1 ) + " of " + callbacks.length + ":  "
-                        + callback.getClass().toString() );
+                LOG.debug( "Processing callback {} of {}: {}" + callback.getClass(), ( i + 1 ), callbacks.length );
             }
 
             if ( callback instanceof NameCallback )
@@ -162,11 +169,15 @@
             else if ( callback instanceof PasswordCallback )
             {
                 PasswordCallback passwordCB = ( PasswordCallback ) callback;
-                String userPassword = lookupPassword( getUsername(), getRealm() );
+                EntryAttribute userPassword = lookupPassword( getUsername(), getRealm() );
 
                 if ( userPassword != null )
                 {
-                    passwordCB.setPassword( userPassword.toCharArray() );
+                    // We assume that we have only one password available
+                    byte[] password = (byte[])userPassword.get().get();
+                    
+                    String strPassword = StringTools.utf8ToString( password );
+                    passwordCB.setPassword( strPassword.toCharArray() );
                 }
             }
             else if ( callback instanceof AuthorizeCallback )

Added: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslServer.java?rev=681578&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslServer.java (added)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslServer.java Thu Jul 31 18:20:21 2008
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.newldap.handlers.bind;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.newldap.LdapSession;
+import org.apache.directory.shared.ldap.message.BindRequest;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+
+/**
+ * An abstract class containing common parts for the SaslServer local 
+ * implementation, like the BindRequest;
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractSaslServer implements SaslServer 
+{
+    /** The associated BindRequest */
+    private final BindRequest bindRequest;
+    
+    /** The associated LdapSession instance */
+    private final LdapSession ldapSession;
+    
+    /** The admin session, used to authenticate users against the LDAP server */ 
+    private CoreSession adminSession;
+    
+    
+    public AbstractSaslServer( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest )
+    {
+        this.bindRequest = bindRequest;
+        this.ldapSession = ldapSession;
+        this.adminSession = adminSession;
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     * 
+     * NOT IMPLEMENTED
+     */
+    public byte[] unwrap( byte[] incoming, int offset, int len ) throws SaslException
+    {
+        return StringTools.EMPTY_BYTES;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * NOT IMPLEMENTED
+     */
+    public byte[] wrap( byte[] outgoing, int offset, int len ) throws SaslException
+    {
+        return new byte[0];
+    }
+
+    
+    /**
+     *  @return the associated BindRequest object
+     */
+    public BindRequest getBindRequest()
+    {
+        return bindRequest;
+    }
+
+    
+    /**
+     *  @return the associated ioSession
+     */
+    public LdapSession getLdapSession()
+    {
+        return ldapSession;
+    }
+
+
+    /**
+     *  @return the admin Session
+     */
+    public CoreSession getAdminSession()
+    {
+        return adminSession;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getAuthorizationID()
+    {
+        return "";
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getNegotiatedProperty( String propName )
+    {
+        return "";
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dispose() throws SaslException
+    {
+    }
+}

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/MechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/MechanismHandler.java?rev=681578&r1=681577&r2=681578&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/MechanismHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/MechanismHandler.java Thu Jul 31 18:20:21 2008
@@ -22,6 +22,7 @@
 
 import javax.security.sasl.SaslServer;
 
+import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.newldap.LdapSession;
 import org.apache.directory.shared.ldap.message.BindRequest;
 
@@ -36,12 +37,6 @@
 public interface MechanismHandler
 {
     /**
-     * A key constant ({@value}) for storing the SASL context in the session.
-     */
-    public static final String SASL_CONTEXT = "saslContext";
-
-
-    /**
      * Implementors will use the session and message to determine what kind of
      * {@link SaslServer} to create and what initialization parameters it will require.
      *
@@ -50,5 +45,5 @@
      * @return The {@link SaslServer} to use for the duration of the bound session.
      * @throws Exception
      */
-    public SaslServer handleMechanism( LdapSession session, BindRequest bindRequest ) throws Exception;
+    public SaslServer handleMechanism( LdapSession session, CoreSession adminSession, BindRequest bindRequest ) throws Exception;
 }

Added: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java?rev=681578&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java (added)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java Thu Jul 31 18:20:21 2008
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.server.newldap.handlers.bind;
+
+/**
+ * SASL Constants used to store informations releated to the Challenge/response
+ * exchange during the SASL negociation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SaslConstants
+{
+    /**
+     * A key constant for storing the SASL Server in the session.
+     */
+    public static final String SASL_SERVER = "saslServer";
+    
+    /**
+     * A key constant for storing the SASL host in the session
+     */
+    public static final String SASL_HOST = "host";
+    
+    /**
+     * A key constant used when creating a SaslServer
+     */
+    public static final String LDAP_PROTOCOL = "ldap";
+    
+    
+    /**
+     * A key constant for storing the place where we are to search for user's pasword
+     */
+    public static final String SASL_USER_BASE_DN = "userBaseDn";
+    
+    
+    /**
+     * A key constant for storing the current mechanism
+     */
+    public static final String SASL_MECH = "saslMech";
+    
+    
+    /**
+     * A key constant for storing the authenticated user
+     */
+    public static final String SASL_AUTHENT_USER = "saslAuthentUser";
+    
+    
+    /**
+     * A key constant for storing the evaluated credentials
+     */
+    public static final String SASL_CREDS = "saslCreds";
+}