Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/authn/SimpleAuthenticator.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/authn/SimpleAuthenticator.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/authn/SimpleAuthenticator.java (working copy) @@ -19,6 +19,7 @@ import javax.naming.Context; import javax.naming.NamingException; +import javax.naming.InitialContext; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; @@ -89,9 +90,18 @@ ContextPartitionNexus nexus = getFactoryConfiguration().getPartitionNexus(); Attributes userEntry; - + try { + InitialContext bindCtx; + + bindCtx = nexus.bind( principalDn, creds ); + if (bindCtx != null) + { + bindCtx.close(); + return new LdapPrincipal( principalDn ); + } + userEntry = nexus.lookup( principalDn, new String[] {"userPassword"} ); if ( userEntry == null ) { Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/BaseInterceptor.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/BaseInterceptor.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/BaseInterceptor.java (working copy) @@ -20,10 +20,7 @@ import java.util.Iterator; import java.util.Map; -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; +import javax.naming.*; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; @@ -204,4 +201,9 @@ { next.removeContextPartition( suffix ); } + + public InitialContext bind(NextInterceptor next, Name principalDN, Object credentials) throws NamingException + { + return next.bind(principalDN, credentials); + } } Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/Interceptor.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/Interceptor.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/Interceptor.java (working copy) @@ -23,6 +23,7 @@ import javax.naming.Name; import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.InitialContext; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; @@ -191,4 +192,7 @@ */ void move( NextInterceptor next, Name oldName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException; + + InitialContext bind(NextInterceptor next, Name principalDN, Object credentials) + throws NamingException; } Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/InterceptorChain.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/InterceptorChain.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/InterceptorChain.java (working copy) @@ -24,10 +24,7 @@ import java.util.ListIterator; import java.util.Map; -import javax.naming.ConfigurationException; -import javax.naming.Name; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; +import javax.naming.*; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; @@ -73,6 +70,12 @@ return nexus.getRootDSE(); } + /** Optional method to test credentials (return null if not implemented). */ + public InitialContext bind( NextInterceptor next, Name principalDN, Object credentials ) + throws NamingException + { + return nexus.bind( principalDN, credentials ); + } public Name getMatchedName( NextInterceptor next, Name dn, boolean normalized ) throws NamingException { @@ -816,7 +819,26 @@ } } + public InitialContext bind(Name principalDN, Object credentials) throws NamingException + { + Interceptor head = this.head.configuration.getInterceptor(); + NextInterceptor next = this.head.nextInterceptor; + try + { + return head.bind( next, principalDN, credentials ); + } + catch ( NamingException ne ) + { + throw ne; + } + catch ( Throwable e ) + { + throwInterceptorException( head, e ); + throw new InternalError(); // Should be unreachable + } + } + /** * Represents an internal entry of this chain. */ @@ -1160,6 +1182,25 @@ } } + public InitialContext bind( Name principalDN, Object credentials ) throws NamingException + { + Interceptor interceptor = Entry.this.nextEntry.configuration.getInterceptor(); + + try + { + return interceptor.bind( Entry.this.nextEntry.nextInterceptor, principalDN, credentials ); + } + catch ( NamingException ne ) + { + throw ne; + } + catch ( Throwable e ) + { + throwInterceptorException( interceptor, e ); + throw new InternalError(); // Should be unreachable + } + } + public void addContextPartition( ContextPartitionConfiguration cfg ) throws NamingException { Interceptor interceptor = Entry.this.nextEntry.configuration.getInterceptor(); Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/NextInterceptor.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/NextInterceptor.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/interceptor/NextInterceptor.java (working copy) @@ -23,6 +23,7 @@ import javax.naming.Name; import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.InitialContext; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; @@ -120,4 +121,6 @@ */ void move( Name oldName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException; + + InitialContext bind(Name principalDN, Object credentials) throws NamingException; } Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/jndi/ContextPartitionNexusProxy.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/jndi/ContextPartitionNexusProxy.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/jndi/ContextPartitionNexusProxy.java (working copy) @@ -20,11 +20,7 @@ import java.util.Iterator; import java.util.Map; -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.ServiceUnavailableException; +import javax.naming.*; import javax.naming.event.NamingListener; import javax.naming.event.EventContext; import javax.naming.directory.Attributes; @@ -97,6 +93,24 @@ this.service.sync(); } + public InitialContext bind( Name principalDN, Object credentials ) + throws NamingException + { + ensureStarted(); + InvocationStack stack = InvocationStack.getInstance(); + stack.push( new Invocation( + caller, "bind", + new Object[] { principalDN, credentials } ) ); + try + { + return this.configuration.getInterceptorChain().bind( principalDN, credentials ); + } + finally + { + stack.pop(); + } + } + public void close() throws NamingException { this.service.shutdown(); } Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/AbstractContextPartition.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/AbstractContextPartition.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/AbstractContextPartition.java (working copy) @@ -19,11 +19,7 @@ import java.util.ArrayList; import java.util.List; -import javax.naming.Name; -import javax.naming.NameNotFoundException; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.OperationNotSupportedException; +import javax.naming.*; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; @@ -148,6 +144,22 @@ return cfg; } + /** + * Not implemented by default, but will be for partitions which act as + * proxies to remote directories. + * @param principalDN DN to be used for bind attempt. + * @param credentials Credentials matching principalDN. + * @return Null if not implemented, otherwise return + * context resulting from the bind. + * @throws NamingException Method is implemented but encountered an + * exception when attempting the bind. + */ + public InitialContext bind( Name principalDN, Object credentials ) + throws NamingException + { + return null; + } + public final Name getSuffix( boolean normalized ) throws NamingException { if( normalized ) Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/ContextPartition.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/ContextPartition.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/ContextPartition.java (working copy) @@ -19,10 +19,7 @@ import java.util.Map; -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; +import javax.naming.*; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; @@ -76,8 +73,20 @@ */ void sync() throws NamingException; - /** + * Optional method to test credentials (return null if not implemented). + * @param principalDN DN of principal to be used for bind. + * @param credentials Credentials to be used (usually byte[] but left + * as object to provide handling of future SASL support). + * @return Null if not implemented (ie context is not + * proxying to a remote server), otherwise initial context resulting + * from the bind. + * @throws NamingException Problem encountered during the bind. + */ + InitialContext bind( Name principalDN, Object credentials ) + throws NamingException; + + /** * Gets the distinguished/absolute name of the suffix for all entries * stored within this ContextPartition. * Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/DefaultContextPartitionNexus.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/DefaultContextPartitionNexus.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/DefaultContextPartitionNexus.java (working copy) @@ -26,11 +26,7 @@ import java.util.Map; import java.util.Set; -import javax.naming.ConfigurationException; -import javax.naming.Name; -import javax.naming.NameNotFoundException; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; +import javax.naming.*; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; @@ -318,7 +314,15 @@ } } + public InitialContext bind( Name principalDN, Object credentials) + throws NamingException + { + ContextPartition backend = getBackend( principalDN ); + return backend.bind( principalDN, credentials ); + } + + // ------------------------------------------------------------------------ // ContextPartitionNexus Interface Method Implementations // ------------------------------------------------------------------------ Index: apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/impl/btree/BTreeContextPartition.java =================================================================== --- apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/impl/btree/BTreeContextPartition.java (revision 290323) +++ apacheds/trunk/core/src/main/java/org/apache/ldap/server/partition/impl/btree/BTreeContextPartition.java (working copy) @@ -25,6 +25,7 @@ import javax.naming.Name; import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.InitialContext; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; @@ -477,4 +478,11 @@ * @throws NamingException if there is a failure to read the count */ public abstract int count() throws NamingException; + + /** Stub this method out for persisting partitions. */ + public InitialContext bind( Name principalDN, Object credentials ) + throws NamingException + { + return null; + } }