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 2013/04/25 01:29:49 UTC

svn commit: r1471770 - in /directory/apacheds/trunk: core-shared/src/main/java/org/apache/directory/server/core/shared/ core/src/main/java/org/apache/directory/server/core/ interceptors/authn/src/main/java/org/apache/directory/server/core/authn/ server...

Author: elecharny
Date: Wed Apr 24 23:29:48 2013
New Revision: 1471770

URL: http://svn.apache.org/r1471770
Log:
o Modified the way we initialize the Anonymous session in the DefaultCoreSession constructor to avoid creating a new LdapPrincipal everytime
o The isAnonymous() methods work slightly differently
o Don't erase the credentials when we do a bind as admin with another DN : this is a password reset
o Added two tests for the pwdModify extended request
o Added some missing Javadoc

Modified:
    directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
    directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
    directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java

Modified: directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java?rev=1471770&r1=1471769&r2=1471770&view=diff
==============================================================================
--- directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java (original)
+++ directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/DefaultCoreSession.java Wed Apr 24 23:29:48 2013
@@ -113,7 +113,15 @@ public class DefaultCoreSession implemen
     {
         this.directoryService = directoryService;
         authenticatedPrincipal = principal;
-        anonymousPrincipal = new LdapPrincipal( directoryService.getSchemaManager() );
+
+        if ( principal.getAuthenticationLevel() == AuthenticationLevel.NONE )
+        {
+            anonymousPrincipal = principal;
+        }
+        else
+        {
+            anonymousPrincipal = new LdapPrincipal( directoryService.getSchemaManager() );
+        }
 
         // setup attribute type value
         OBJECT_CLASS_AT = directoryService.getSchemaManager().getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
@@ -814,7 +822,7 @@ public class DefaultCoreSession implemen
         }
         else
         {
-            return getEffectivePrincipal().getDn().isEmpty();
+            return authenticatedPrincipal.getAuthenticationLevel() == AuthenticationLevel.NONE;
         }
     }
 

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=1471770&r1=1471769&r2=1471770&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Wed Apr 24 23:29:48 2013
@@ -951,18 +951,27 @@ public class DefaultDirectoryService imp
     }
 
 
+    /**
+     * Get back an anonymous session
+     */
     public CoreSession getSession()
     {
         return new DefaultCoreSession( new LdapPrincipal( schemaManager ), this );
     }
 
 
+    /** 
+     * Get back a session for a given principal
+     */
     public CoreSession getSession( LdapPrincipal principal )
     {
         return new DefaultCoreSession( principal, this );
     }
 
 
+    /**
+     * Get back a session for the give user and credentials bound with Simple Bind
+     */
     public CoreSession getSession( Dn principalDn, byte[] credentials ) throws LdapException
     {
         if ( !started )
@@ -981,6 +990,9 @@ public class DefaultDirectoryService imp
     }
 
 
+    /**
+     * Get back a session for a given user bound with SASL Bind
+     */
     public CoreSession getSession( Dn principalDn, byte[] credentials, String saslMechanism, String saslAuthId )
         throws Exception
     {

Modified: directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java?rev=1471770&r1=1471769&r2=1471770&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java (original)
+++ directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java Wed Apr 24 23:29:48 2013
@@ -405,7 +405,8 @@ public class AuthenticationInterceptor e
 
         if ( ( bindContext.getSession() != null ) &&
             ( bindContext.getSession().getEffectivePrincipal() != null ) &&
-            ( !bindContext.getSession().isAnonymous() ) )
+            ( !bindContext.getSession().isAnonymous() ) &&
+            ( !bindContext.getSession().isAdministrator() ) )
         {
             // null out the credentials
             bindContext.setCredentials( null );

Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java?rev=1471770&r1=1471769&r2=1471770&view=diff
==============================================================================
--- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java (original)
+++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java Wed Apr 24 23:29:48 2013
@@ -24,6 +24,7 @@ import static org.apache.directory.serve
 import static org.apache.directory.server.core.integ.IntegrationUtils.getAnonymousNetworkConnection;
 import static org.apache.directory.server.core.integ.IntegrationUtils.getNetworkConnectionAs;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
 import org.apache.directory.api.ldap.codec.api.LdapApiService;
@@ -35,19 +36,29 @@ import org.apache.directory.api.ldap.ext
 import org.apache.directory.api.ldap.extras.extended.PwdModifyResponse;
 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
 import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.AddRequest;
 import org.apache.directory.api.ldap.model.message.AddRequestImpl;
 import org.apache.directory.api.ldap.model.message.AddResponse;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.Response;
 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.api.InterceptorEnum;
+import org.apache.directory.server.core.api.authn.ppolicy.CheckQualityEnum;
+import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyConfiguration;
+import org.apache.directory.server.core.authn.AuthenticationInterceptor;
+import org.apache.directory.server.core.authn.ppolicy.PpolicyConfigContainer;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.server.ldap.handlers.extended.PwdModifyHandler;
+import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,7 +74,10 @@ import org.junit.runner.RunWith;
     transports =
         { @CreateTransport(protocol = "LDAP") },
     extendedOpHandlers =
-        { PwdModifyHandler.class })
+        { PwdModifyHandler.class },
+    allowAnonymousAccess = true)
+//disable changelog, for more info see DIRSERVER-1528
+@CreateDS(enableChangeLog = false, name = "PasswordPolicyTest")
 public class PwdModifyIT extends AbstractLdapTestUnit
 {
     private static final LdapApiService codec = LdapApiServiceFactory.getSingleton();
@@ -71,6 +85,9 @@ public class PwdModifyIT extends Abstrac
     private static final PasswordPolicyDecorator PP_REQ_CTRL =
         new PasswordPolicyDecorator( codec, new PasswordPolicyImpl() );
 
+    /** The passwordPolicy configuration */
+    private PasswordPolicyConfiguration policyConfig;
+
 
     /**
      * Get the PasswordPolicy control from a response
@@ -113,6 +130,54 @@ public class PwdModifyIT extends Abstrac
 
 
     /**
+     * Check that we can bind N times with a user/password
+     */
+    private void checkBind( LdapConnection connection, Dn userDn, String password, int nbIterations,
+        String expectedMessage ) throws Exception
+    {
+        for ( int i = 0; i < nbIterations; i++ )
+        {
+            try
+            {
+                connection.bind( userDn, password );
+            }
+            catch ( LdapAuthenticationException le )
+            {
+                assertEquals( expectedMessage, le.getMessage() );
+            }
+        }
+    }
+
+
+    /**
+     * Set a default PaswordPolicy configuration
+     */
+    @Before
+    public void setPwdPolicy() throws LdapException
+    {
+        policyConfig = new PasswordPolicyConfiguration();
+
+        policyConfig.setPwdMaxAge( 110 );
+        policyConfig.setPwdFailureCountInterval( 30 );
+        policyConfig.setPwdMaxFailure( 3 );
+        policyConfig.setPwdLockout( true );
+        policyConfig.setPwdLockoutDuration( 0 );
+        policyConfig.setPwdMinLength( 5 );
+        policyConfig.setPwdInHistory( 5 );
+        policyConfig.setPwdExpireWarning( 600 );
+        policyConfig.setPwdGraceAuthNLimit( 5 );
+        policyConfig.setPwdCheckQuality( CheckQualityEnum.CHECK_REJECT ); // DO NOT allow the password if its quality can't be checked
+
+        PpolicyConfigContainer policyContainer = new PpolicyConfigContainer();
+        policyContainer.setDefaultPolicy( policyConfig );
+        AuthenticationInterceptor authenticationInterceptor = ( AuthenticationInterceptor ) getService()
+            .getInterceptor( InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName() );
+
+        authenticationInterceptor.setPwdPolicies( policyContainer );
+    }
+
+
+    /**
      * Modify an existing user password while the user is connected
      */
     @Test
@@ -143,12 +208,19 @@ public class PwdModifyIT extends Abstrac
      * Modify an existing user password while the user is not connected
      */
     @Test
-    @Ignore
     public void testModifyUserPasswordAnonymous() throws Exception
     {
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, "User", "secret" );
+        addUser( adminConnection, "User1", "secret1" );
+
+        LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );
+
+        Entry entry = userConnection.lookup( "cn=User1,ou=system" );
+
+        assertNotNull( entry );
+
+        userConnection.close();
 
         // Bind as the user
         LdapConnection anonymousConnection = getAnonymousNetworkConnection( getLdapServer() );
@@ -156,13 +228,80 @@ public class PwdModifyIT extends Abstrac
 
         // Now change the password
         PwdModifyRequestImpl pwdModifyRequest = new PwdModifyRequestImpl();
-        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User,ou=system" ) );
-        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret" ) );
-        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secretBis" ) );
+        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
+        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
+        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );
+
+        // Send the request
+        PwdModifyResponse pwdModifyResponse = ( PwdModifyResponse ) anonymousConnection.extended( pwdModifyRequest );
+
+        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
+
+        // Check that we can now bind using the new credentials
+        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );
+
+        entry = userConnection.lookup( "cn=User1,ou=system" );
+
+        assertNotNull( entry );
+
+        userConnection.close();
+        anonymousConnection.close();
+        adminConnection.close();
+    }
+
+
+    /**
+     * Modify an existing user password while the user is not connected, when
+     * the PasswordPolicy is activated
+     */
+    @Test
+    public void testModifyUserPasswordAnonymousPPActivated() throws Exception
+    {
+        policyConfig.setPwdCheckQuality( CheckQualityEnum.CHECK_ACCEPT ); // allow the password if its quality can't be checked
+        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
+
+        addUser( adminConnection, "User2", "secret2" );
+        Dn userDn = new Dn( "cn=User2,ou=system" );
+
+        LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User2,ou=system", "secret2" );
+
+        Entry entry = userConnection.lookup( "cn=User2,ou=system" );
+
+        assertNotNull( entry );
+
+        userConnection.close();
+
+        // almost lock the user now
+        checkBind( userConnection, userDn, "badPassword", 2,
+            "INVALID_CREDENTIALS: Bind failed: ERR_229 Cannot authenticate user cn=User2,ou=system" );
+
+        // Bind as the user
+        LdapConnection anonymousConnection = getAnonymousNetworkConnection( getLdapServer() );
+        anonymousConnection.setTimeOut( 0L );
+
+        // Now change the password
+        PwdModifyRequestImpl pwdModifyRequest = new PwdModifyRequestImpl();
+        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User2,ou=system" ) );
+        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret2" ) );
+        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret2Bis" ) );
 
         // Send the request
         PwdModifyResponse pwdModifyResponse = ( PwdModifyResponse ) anonymousConnection.extended( pwdModifyRequest );
 
+        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
+
+        // Check that we can now bind using the new credentials
+        userConnection = getNetworkConnectionAs( ldapServer, "cn=User2,ou=system", "secret2Bis" );
+
+        entry = userConnection.lookup( "cn=User2,ou=system" );
+
+        assertNotNull( entry );
+
+        // almost lock the user now, the count should be reset
+        checkBind( userConnection, userDn, "badPassword", 2,
+            "INVALID_CREDENTIALS: Bind failed: ERR_229 Cannot authenticate user cn=User2,ou=system" );
+
+        userConnection.close();
         anonymousConnection.close();
         adminConnection.close();
     }