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/14 21:15:52 UTC

svn commit: r1467813 - in /directory: apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/ apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/ shared/trunk/ldap/extras/codec-api/src/main/jav...

Author: elecharny
Date: Sun Apr 14 19:15:51 2013
New Revision: 1467813

URL: http://svn.apache.org/r1467813
Log:
o Fixed a NPE if the pwdGraceAuthNLimit is set to 0 with an expired pwdAge 
o Added some more protections against NPE in PP code
o Added some tests for PP
o Renamed a class (type)
o Renamed two methods (typoes too, I guess)

Added:
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthNRemaining.java
      - copied, changed from r1466005, directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthsRemaining.java
Removed:
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthsRemaining.java
Modified:
    directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.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/ppolicy/PasswordPolicyIT.java
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponse.java
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponseImpl.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyDecorator.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyGrammar.java
    directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyTest.java

Modified: directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java (original)
+++ directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java Sun Apr 14 19:15:51 2013
@@ -174,6 +174,7 @@ public abstract class AbstractAuthentica
             LOG.debug( "checking if account with the Dn {} is locked", userEntry.getDn() );
 
             Attribute accountLockAttr = userEntry.get( PWD_ACCOUNT_LOCKED_TIME_AT );
+
             if ( accountLockAttr != null )
             {
                 String lockedTime = accountLockAttr.getString();
@@ -186,23 +187,26 @@ public abstract class AbstractAuthentica
                     Date lockedDate = DateUtils.getDate( lockedTime );
                     long unlockTime = pPolicyConfig.getPwdLockoutDuration() * 1000L;
                     unlockTime += lockedDate.getTime();
-                    
+
                     Date unlockDate = new Date( unlockTime );
                     Date now = DateUtils.getDate( DateUtils.getGeneralizedTime() );
-                    
-                    if( unlockDate.after( now ) )
+
+                    if ( unlockDate.after( now ) )
                     {
-                        throw new PasswordPolicyException( "account will remain locked till " + unlockDate, ACCOUNT_LOCKED.getValue() );
+                        throw new PasswordPolicyException( "account will remain locked till " + unlockDate,
+                            ACCOUNT_LOCKED.getValue() );
                     }
                     else
                     {
                         // remove pwdAccountLockedTime attribute
-                        Modification pwdAccountLockMod = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE,  accountLockAttr );
-                        ModifyOperationContext modContext = new ModifyOperationContext( directoryService.getAdminSession() );
+                        Modification pwdAccountLockMod = new DefaultModification(
+                            ModificationOperation.REMOVE_ATTRIBUTE, accountLockAttr );
+                        ModifyOperationContext modContext = new ModifyOperationContext(
+                            directoryService.getAdminSession() );
                         modContext.setDn( userEntry.getDn() );
-                        
+
                         modContext.setModItems( Collections.singletonList( pwdAccountLockMod ) );
-                        
+
                         directoryService.getPartitionNexus().modify( modContext );
                     }
                 }
@@ -210,6 +214,7 @@ public abstract class AbstractAuthentica
         }
 
         Attribute pwdStartTimeAttr = userEntry.get( PWD_START_TIME_AT );
+
         if ( pwdStartTimeAttr != null )
         {
             Date pwdStartTime = DateUtils.getDate( pwdStartTimeAttr.getString() );
@@ -222,6 +227,7 @@ public abstract class AbstractAuthentica
         }
 
         Attribute pwdEndTimeAttr = userEntry.get( PWD_END_TIME_AT );
+
         if ( pwdEndTimeAttr != null )
         {
             Date pwdEndTime = DateUtils.getDate( pwdEndTimeAttr.getString() );
@@ -237,18 +243,26 @@ public abstract class AbstractAuthentica
         if ( pPolicyConfig.getPwdMaxIdle() > 0 )
         {
             Attribute pwdLastSuccessTimeAttr = userEntry.get( PWD_LAST_SUCCESS_AT );
-            long time = pPolicyConfig.getPwdMaxIdle() * 1000L;
-            time += DateUtils.getDate( pwdLastSuccessTimeAttr.getString() ).getTime();
 
-            if ( System.currentTimeMillis() >= time )
+            // Let's be sure that the user has already logged in
+            if ( pwdLastSuccessTimeAttr != null )
             {
-                throw new PasswordPolicyException(
-                    "account locked due to the max idle time of the password was exceeded", ACCOUNT_LOCKED.getValue() );
+                long time = pPolicyConfig.getPwdMaxIdle() * 1000L;
+                time += DateUtils.getDate( pwdLastSuccessTimeAttr.getString() ).getTime();
+
+                if ( System.currentTimeMillis() >= time )
+                {
+                    throw new PasswordPolicyException(
+                        "account locked due to the max idle time of the password was exceeded",
+                        ACCOUNT_LOCKED.getValue() );
+                }
             }
         }
 
+        // Chekc that the password is not too old and need to be disabled
         if ( pPolicyConfig.getPwdMaxAge() > 0 )
         {
+            // In case we have a grace number of attempts
             if ( pPolicyConfig.getPwdGraceAuthNLimit() > 0 )
             {
                 Attribute pwdGraceUseAttr = userEntry.get( PWD_GRACE_USE_TIME_AT );
@@ -265,13 +279,19 @@ public abstract class AbstractAuthentica
             }
             else
             {
+                // No grace attempt : check if the password has expired or not
                 Attribute pwdChangeTimeAttr = userEntry.get( PWD_CHANGED_TIME_AT );
-                boolean expired = PasswordUtil.isPwdExpired( pwdChangeTimeAttr.getString(),
-                    pPolicyConfig.getPwdMaxAge() );
 
-                if ( expired )
+                // If the attr is null, this is the admin user. We don't block it
+                if ( pwdChangeTimeAttr != null )
                 {
-                    throw new PasswordPolicyException( "paasword expired", PASSWORD_EXPIRED.getValue() );
+                    boolean expired = PasswordUtil.isPwdExpired( pwdChangeTimeAttr.getString(),
+                        pPolicyConfig.getPwdMaxAge() );
+
+                    if ( expired )
+                    {
+                        throw new PasswordPolicyException( "paasword expired", PASSWORD_EXPIRED.getValue() );
+                    }
                 }
             }
         }

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=1467813&r1=1467812&r2=1467813&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 Sun Apr 14 19:15:51 2013
@@ -655,7 +655,7 @@ public class AuthenticationInterceptor e
                             numGraceAuth = policyConfig.getPwdGraceAuthNLimit() - 1;
                         }
 
-                        pwdRespCtrl.getResponse().setGraceAuthNsRemaining( numGraceAuth );
+                        pwdRespCtrl.getResponse().setGraceAuthNRemaining( numGraceAuth );
 
                         pwdGraceUseAttr.add( DateUtils.getGeneralizedTime() );
                         Modification pwdGraceUseMod = new DefaultModification( ADD_ATTRIBUTE, pwdGraceUseAttr );

Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/PasswordPolicyIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/PasswordPolicyIT.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/PasswordPolicyIT.java (original)
+++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/PasswordPolicyIT.java Sun Apr 14 19:15:51 2013
@@ -22,7 +22,6 @@ package org.apache.directory.server.ppol
 
 import static org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum.INSUFFICIENT_PASSWORD_QUALITY;
 import static org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum.PASSWORD_EXPIRED;
-import static org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum.PASSWORD_TOO_SHORT;
 import static org.apache.directory.api.ldap.model.constants.PasswordPolicySchemaConstants.PWD_ACCOUNT_LOCKED_TIME_AT;
 import static org.apache.directory.api.ldap.model.constants.PasswordPolicySchemaConstants.PWD_CHANGED_TIME_AT;
 import static org.apache.directory.api.ldap.model.constants.PasswordPolicySchemaConstants.PWD_FAILURE_TIME_AT;
@@ -111,6 +110,9 @@ public class PasswordPolicyIT extends Ab
         new PasswordPolicyDecorator( codec, new PasswordPolicyImpl() );
 
 
+    /**
+     * Set a default PaswordPolicy configuration
+     */
     @Before
     public void setPwdPolicy() throws LdapException
     {
@@ -131,10 +133,8 @@ public class PasswordPolicyIT extends Ab
         policyContainer.setDefaultPolicy( policyConfig );
         AuthenticationInterceptor authenticationInterceptor = ( AuthenticationInterceptor ) getService()
             .getInterceptor( InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName() );
-        authenticationInterceptor.setPwdPolicies( policyContainer );
 
-        AuthenticationInterceptor authInterceptor = ( AuthenticationInterceptor ) getService()
-            .getInterceptor( InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName() );
+        authenticationInterceptor.setPwdPolicies( policyContainer );
     }
 
 
@@ -145,6 +145,9 @@ public class PasswordPolicyIT extends Ab
     }
 
 
+    /**
+     * Get the PasswordPolicy control from a response
+     */
     private PasswordPolicy getPwdRespCtrl( Response resp ) throws Exception
     {
         Control control = resp.getControls().get( PP_REQ_CTRL.getOid() );
@@ -158,48 +161,87 @@ public class PasswordPolicyIT extends Ab
     }
 
 
-    @Test
-    public void testAddUserWithClearTextPwd() throws Exception
+    /**
+     * Add a user with a password
+     */
+    private void addUser( LdapConnection adminConnection, String user, Object password ) throws Exception
     {
-        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
-
-        Dn userDn = new Dn( "cn=user,ou=system" );
         Entry userEntry = new DefaultEntry(
-            userDn,
+            "cn=" + user + ",ou=system",
             "ObjectClass: top",
             "ObjectClass: person",
-            "cn: user",
-            "sn: user_sn",
-            "userPassword: 1234" );
+            "cn", user,
+            "sn", user + "_sn",
+            "userPassword", password );
 
         AddRequest addRequest = new AddRequestImpl();
         addRequest.setEntry( userEntry );
         addRequest.addControl( PP_REQ_CTRL );
 
         AddResponse addResp = adminConnection.add( addRequest );
-        assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, addResp.getLdapResult().getResultCode() );
-
-        PasswordPolicy respCtrl = getPwdRespCtrl( addResp );
-        assertNotNull( respCtrl );
-        assertEquals( PASSWORD_TOO_SHORT, respCtrl.getResponse().getPasswordPolicyError() );
-
-        Attribute pwdAt = userEntry.get( SchemaConstants.USER_PASSWORD_AT );
-        pwdAt.clear();
-        pwdAt.add( "12345" );
-
-        addResp = adminConnection.add( addRequest );
         assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
-        respCtrl = getPwdRespCtrl( addResp );
+        PasswordPolicy respCtrl = getPwdRespCtrl( addResp );
         assertNull( respCtrl );
+    }
 
-        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), "12345" );
+
+    /**
+     * Check we can bind a user with a given password
+     */
+    private void checkBindSuccess( Dn userDn, String password ) throws Exception
+    {
+        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
         assertNotNull( userConnection );
         assertTrue( userConnection.isAuthenticated() );
+
         userConnection.close();
-        adminConnection.close();
     }
 
 
+    /**
+     * Check we cannot bind a user with a given password
+     */
+    private void checkBindFailure( Dn userDn, String password ) throws Exception
+    {
+        try
+        {
+            LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
+            assertNull( userConnection );
+            assertFalse( userConnection.isAuthenticated() );
+
+            userConnection.close();
+        }
+        catch ( LdapException le )
+        {
+            // Expected
+        }
+    }
+
+
+    /**
+     * 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() );
+            }
+        }
+    }
+
+
+    /**
+     * Test that we can't inject a hashed password when the ChekcQuality is CHECK_REJECT,
+     * and that we can when the CheckQuality is CHECK_ACCEPT
+     */
     @Test
     public void testAddUserWithHashedPwd() throws Exception
     {
@@ -219,6 +261,7 @@ public class PasswordPolicyIT extends Ab
         addRequest.setEntry( userEntry );
         addRequest.addControl( PP_REQ_CTRL );
 
+        // We should get a failure
         AddResponse addResp = adminConnection.add( addRequest );
         assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, addResp.getLdapResult().getResultCode() );
 
@@ -226,6 +269,7 @@ public class PasswordPolicyIT extends Ab
         assertNotNull( respCtrl );
         assertEquals( INSUFFICIENT_PASSWORD_QUALITY, respCtrl.getResponse().getPasswordPolicyError() );
 
+        // Relax the Check Quality to CHECK_ACCEPT
         policyConfig.setPwdCheckQuality( CheckQualityEnum.CHECK_ACCEPT ); // allow the password if its quality can't be checked
         Attribute pwdAt = userEntry.get( SchemaConstants.USER_PASSWORD_AT );
         pwdAt.clear();
@@ -371,39 +415,6 @@ public class PasswordPolicyIT extends Ab
 
 
     /**
-     * Check we can bind a user with a given password
-     */
-    private void checkBindSuccess( Dn userDn, String password ) throws Exception
-    {
-        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
-        assertNotNull( userConnection );
-        assertTrue( userConnection.isAuthenticated() );
-
-        userConnection.close();
-    }
-
-
-    /**
-     * Check we cannot bind a user wth a given password
-     */
-    private void checkBindFailure( Dn userDn, String password ) throws Exception
-    {
-        try
-        {
-            LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
-            assertNull( userConnection );
-            assertFalse( userConnection.isAuthenticated() );
-
-            userConnection.close();
-        }
-        catch ( LdapException le )
-        {
-            // Expected
-        }
-    }
-
-
-    /**
      * Test the number of password we keep in history
      */
     @Test
@@ -414,15 +425,9 @@ public class PasswordPolicyIT extends Ab
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
         Dn userDn = new Dn( "cn=userPwdHist,ou=system" );
-        Entry userEntry = new DefaultEntry(
-            userDn.toString(),
-            "ObjectClass: top",
-            "ObjectClass: person",
-            "cn: userPwdHist",
-            "sn: userPwdHist_sn",
-            "userPassword: 12345" );
 
-        adminConnection.add( userEntry );
+        addUser( adminConnection, "userPwdHist", "12345" );
+
         checkBindSuccess( userDn, "12345" );
 
         Entry entry = adminConnection.lookup( userDn, "*", "+" );
@@ -500,7 +505,7 @@ public class PasswordPolicyIT extends Ab
             "sn: userLen_sn",
             "userPassword: 1234" );
 
-        // Tryu with a password below the minLength
+        // Try with a password below the minLength
         try
         {
             adminConnection.add( userEntry );
@@ -538,6 +543,177 @@ public class PasswordPolicyIT extends Ab
     }
 
 
+    /**
+     * Test the pwdMaxAge configuration. The password should expire when the pwdMaxAge is reached, and
+     * the password should be locked as we don't have a grace limit. 
+     */
+    @Test
+    public void testPwdMaxAgeNoGraceAuthNLimit() throws Exception
+    {
+        policyConfig.setPwdMaxAge( 5 );
+        policyConfig.setPwdGraceAuthNLimit( 0 );
+
+        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
+
+        Dn userDn = new Dn( "cn=userMaxAge,ou=system" );
+        String password = "12345";
+
+        addUser( adminConnection, "userMaxAge", password );
+
+        BindRequest bindReq = new BindRequestImpl();
+        bindReq.setDn( userDn );
+        bindReq.setCredentials( password.getBytes() );
+        bindReq.addControl( PP_REQ_CTRL );
+
+        LdapConnection userCon = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
+        userCon.setTimeOut( 0 );
+
+        Thread.sleep( 1000 ); // sleep for one second so that the password expire warning will be sent
+
+        BindResponse bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+
+        PasswordPolicy respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertTrue( respCtrl.getResponse().getTimeBeforeExpiration() > 0 );
+
+        Thread.sleep( 4500 ); // sleep for four seconds and a half so that the password expires
+
+        // this time it should fail
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, bindResp.getLdapResult().getResultCode() );
+
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertEquals( PASSWORD_EXPIRED, respCtrl.getResponse().getPasswordPolicyError() );
+        adminConnection.close();
+    }
+
+
+    /**
+     * Test the pwdMaxAge configuration with a grace limit. We should be able to bind two
+     * times when the password has expired. 
+     */
+    @Test
+    public void testPwdMaxAgeWithGraceAuthNLimit() throws Exception
+    {
+        policyConfig.setPwdMaxAge( 5 );
+        policyConfig.setPwdGraceAuthNLimit( 2 );
+
+        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
+
+        Dn userDn = new Dn( "cn=userMaxAge,ou=system" );
+        String password = "12345";
+
+        addUser( adminConnection, "userMaxAge", password );
+
+        BindRequest bindReq = new BindRequestImpl();
+        bindReq.setDn( userDn );
+        bindReq.setCredentials( password.getBytes() );
+        bindReq.addControl( PP_REQ_CTRL );
+
+        LdapConnection userCon = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
+        userCon.setTimeOut( 0 );
+
+        Thread.sleep( 1000 ); // sleep for one second so that the password expire warning will be sent
+
+        BindResponse bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+
+        PasswordPolicy respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertTrue( respCtrl.getResponse().getTimeBeforeExpiration() > 0 );
+
+        Thread.sleep( 4500 ); // sleep for four seconds and a half so that the password expires
+
+        // bind for one more time, should succeed
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertEquals( 1, respCtrl.getResponse().getGraceAuthNRemaining() );
+
+        // bind for one last time, should succeed
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertEquals( 0, respCtrl.getResponse().getGraceAuthNRemaining() );
+
+        // this time it should fail
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, bindResp.getLdapResult().getResultCode() );
+
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertEquals( PASSWORD_EXPIRED, respCtrl.getResponse().getPasswordPolicyError() );
+        adminConnection.close();
+    }
+
+
+    /**
+     * Test the pwdMaxAge configuration with a grace period. We should be able to bind for a 
+     * period of time when the password has expired. 
+     */
+    @Test
+    public void testPwdMaxAgeWithGraceExpire() throws Exception
+    {
+        policyConfig.setPwdMaxAge( 5 );
+        policyConfig.setPwdGraceExpire( 2 );
+
+        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
+
+        Dn userDn = new Dn( "cn=userMaxAge,ou=system" );
+        String password = "12345";
+
+        addUser( adminConnection, "userMaxAge", password );
+
+        BindRequest bindReq = new BindRequestImpl();
+        bindReq.setDn( userDn );
+        bindReq.setCredentials( password.getBytes() );
+        bindReq.addControl( PP_REQ_CTRL );
+
+        LdapConnection userCon = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
+        userCon.setTimeOut( 0 );
+
+        Thread.sleep( 1000 ); // sleep for one second so that the password expire warning will be sent
+
+        BindResponse bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+
+        PasswordPolicy respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertTrue( respCtrl.getResponse().getTimeBeforeExpiration() > 0 );
+
+        Thread.sleep( 4500 ); // sleep for four seconds and a half so that the password expires
+
+        // bind for one more time, should succeed
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertEquals( 1, respCtrl.getResponse().getGraceAuthNRemaining() );
+
+        // Wait 1 second, we should still be able to bind
+        // bind for one last time, should succeed
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertNotNull( respCtrl );
+        assertEquals( 0, respCtrl.getResponse().getGraceAuthNRemaining() );
+
+        // this time it should fail
+        bindResp = userCon.bind( bindReq );
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, bindResp.getLdapResult().getResultCode() );
+
+        respCtrl = getPwdRespCtrl( bindResp );
+        assertEquals( PASSWORD_EXPIRED, respCtrl.getResponse().getPasswordPolicyError() );
+        adminConnection.close();
+    }
+
+
+    /**
+     * Test the pwdMaxAge configuration. The password should expire when the pwdMaxAge is reached.
+     * @throws Exception
+     */
     @Test
     public void testPwdMaxAgeAndGraceAuth() throws Exception
     {
@@ -549,19 +725,8 @@ public class PasswordPolicyIT extends Ab
 
         Dn userDn = new Dn( "cn=userMaxAge,ou=system" );
         String password = "12345";
-        Entry userEntry = new DefaultEntry(
-            userDn.toString(),
-            "ObjectClass: top",
-            "ObjectClass: person",
-            "cn: userMaxAge",
-            "sn: userMaxAge_sn",
-            "userPassword: " + password );
-
-        AddRequest addRequest = new AddRequestImpl();
-        addRequest.setEntry( userEntry );
-        addRequest.addControl( PP_REQ_CTRL );
 
-        adminConnection.add( addRequest );
+        addUser( adminConnection, "userMaxAge", password );
 
         BindRequest bindReq = new BindRequestImpl();
         bindReq.setDn( userDn );
@@ -587,14 +752,14 @@ public class PasswordPolicyIT extends Ab
         assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
         respCtrl = getPwdRespCtrl( bindResp );
         assertNotNull( respCtrl );
-        assertEquals( 1, respCtrl.getResponse().getGraceAuthNsRemaining() );
+        assertEquals( 1, respCtrl.getResponse().getGraceAuthNRemaining() );
 
         // this extra second sleep is necessary to modify pwdGraceUseTime attribute with a different timestamp
         Thread.sleep( 1000 );
         bindResp = userCon.bind( bindReq );
         assertEquals( ResultCodeEnum.SUCCESS, bindResp.getLdapResult().getResultCode() );
         respCtrl = getPwdRespCtrl( bindResp );
-        assertEquals( 0, respCtrl.getResponse().getGraceAuthNsRemaining() );
+        assertEquals( 0, respCtrl.getResponse().getGraceAuthNRemaining() );
 
         // this time it should fail
         bindResp = userCon.bind( bindReq );
@@ -666,22 +831,8 @@ public class PasswordPolicyIT extends Ab
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
         Dn userDn = new Dn( "cn=userGrace,ou=system" );
-        Entry userEntry = new DefaultEntry(
-            userDn.toString(),
-            "ObjectClass: top",
-            "ObjectClass: person",
-            "cn: userGrace",
-            "sn: userGrace_sn",
-            "userPassword: 12345" );
 
-        AddRequest addRequest = new AddRequestImpl();
-        addRequest.setEntry( userEntry );
-        addRequest.addControl( PP_REQ_CTRL );
-
-        AddResponse addResp = adminConnection.add( addRequest );
-        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
-        PasswordPolicy respCtrl = getPwdRespCtrl( addResp );
-        assertNull( respCtrl );
+        addUser( adminConnection, "userGrace", "12345" );
 
         BindRequest bindReq = new BindRequestImpl();
         bindReq.setDn( userDn );
@@ -694,9 +845,9 @@ public class PasswordPolicyIT extends Ab
         BindResponse bindResp = userConnection.bind( bindReq );
         assertTrue( userConnection.isAuthenticated() );
         PasswordPolicy ppolicy = getPwdRespCtrl( bindResp );
-        assertEquals( 1, ppolicy.getResponse().getGraceAuthNsRemaining() );
+        assertEquals( 1, ppolicy.getResponse().getGraceAuthNRemaining() );
 
-        userEntry = adminConnection.lookup( userDn, "+" );
+        Entry userEntry = adminConnection.lookup( userDn, "+" );
         Attribute pwdGraceAuthUseTime = userEntry.get( PasswordPolicySchemaConstants.PWD_GRACE_USE_TIME_AT );
         assertNotNull( pwdGraceAuthUseTime );
 
@@ -732,22 +883,8 @@ public class PasswordPolicyIT extends Ab
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
         Dn userDn = new Dn( "cn=userLockout4,ou=system" );
-        Entry userEntry = new DefaultEntry(
-            userDn.toString(),
-            "ObjectClass: top",
-            "ObjectClass: person",
-            "cn: userLockout4",
-            "sn: userLockout4_sn",
-            "userPassword: 12345" );
 
-        AddRequest addRequest = new AddRequestImpl();
-        addRequest.setEntry( userEntry );
-        addRequest.addControl( PP_REQ_CTRL );
-
-        AddResponse addResp = adminConnection.add( addRequest );
-        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
-        PasswordPolicy respCtrl = getPwdRespCtrl( addResp );
-        assertNull( respCtrl );
+        addUser( adminConnection, "userLockout4", "12345" );
 
         BindRequest bindReq = new BindRequestImpl();
         bindReq.setDn( userDn );
@@ -762,7 +899,7 @@ public class PasswordPolicyIT extends Ab
             assertFalse( userConnection.isAuthenticated() );
         }
 
-        userEntry = adminConnection.lookup( userDn, "+" );
+        Entry userEntry = adminConnection.lookup( userDn, "+" );
         Attribute pwdAccountLockedTime = userEntry.get( PasswordPolicySchemaConstants.PWD_ACCOUNT_LOCKED_TIME_AT );
         assertNotNull( pwdAccountLockedTime );
 
@@ -780,44 +917,6 @@ public class PasswordPolicyIT extends Ab
     }
 
 
-    private void addUser( LdapConnection adminConnection, Dn userDn, String password ) throws Exception
-    {
-        Entry userEntry = new DefaultEntry(
-            userDn.toString(),
-            "ObjectClass: top",
-            "ObjectClass: person",
-            "cn: userLockout",
-            "sn: userLockout_sn",
-            "userPassword", password );
-
-        AddRequest addRequest = new AddRequestImpl();
-        addRequest.setEntry( userEntry );
-        addRequest.addControl( PP_REQ_CTRL );
-
-        AddResponse addResp = adminConnection.add( addRequest );
-        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
-        PasswordPolicy respCtrl = getPwdRespCtrl( addResp );
-        assertNull( respCtrl );
-    }
-
-
-    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() );
-            }
-        }
-    }
-
-
     /**
      * Check that we can't try more than N times to login with a wrong password before
      * being locked.
@@ -832,7 +931,7 @@ public class PasswordPolicyIT extends Ab
         Dn userDn = new Dn( "cn=userLockout,ou=system" );
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, userDn, "12345" );
+        addUser( adminConnection, "userLockout", "12345" );
 
         LdapConnection userConnection = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
         userConnection.setTimeOut( 0L );
@@ -866,7 +965,7 @@ public class PasswordPolicyIT extends Ab
         Dn userDn = new Dn( "cn=userLockout2,ou=system" );
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, userDn, "12345" );
+        addUser( adminConnection, "userLockout2", "12345" );
 
         LdapConnection userConnection = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
         userConnection.setTimeOut( 0L );
@@ -925,7 +1024,7 @@ public class PasswordPolicyIT extends Ab
         Dn userDn = new Dn( "cn=userLockout3,ou=system" );
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, userDn, "12345" );
+        addUser( adminConnection, "userLockout3", "12345" );
 
         LdapConnection userConnection = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
         userConnection.setTimeOut( 0L );
@@ -1002,7 +1101,7 @@ public class PasswordPolicyIT extends Ab
         Dn userDn = new Dn( "cn=userLockout,ou=system" );
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, userDn, "12345" );
+        addUser( adminConnection, "userLockout", "12345" );
 
         LdapConnection userConnection = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
 
@@ -1040,7 +1139,7 @@ public class PasswordPolicyIT extends Ab
         Dn userDn = new Dn( "cn=userLockout4,ou=system" );
         LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
 
-        addUser( adminConnection, userDn, "12345" );
+        addUser( adminConnection, "userLockout4", "12345" );
 
         LdapConnection userConnection = new LdapNetworkConnection( "localhost", ldapServer.getPort() );
         userConnection.setTimeOut( 0L );

Modified: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponse.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponse.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponse.java (original)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponse.java Sun Apr 14 19:15:51 2013
@@ -45,14 +45,14 @@ public interface PasswordPolicyResponse
     /**
      * @return The number of possible attempts on the password before it's locked
      */
-    int getGraceAuthNsRemaining();
+    int getGraceAuthNRemaining();
 
 
     /**
      * Sets the number of remaining wrong authentication for this password
-     * @param graceAuthNsRemaining The number of remaining attempts
+     * @param graceAuthNRemaining The number of remaining attempts
      */
-    void setGraceAuthNsRemaining( int graceAuthNsRemaining );
+    void setGraceAuthNRemaining( int graceAuthNRemaining );
 
 
     /**

Modified: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponseImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponseImpl.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponseImpl.java (original)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyResponseImpl.java Sun Apr 14 19:15:51 2013
@@ -32,7 +32,7 @@ public class PasswordPolicyResponseImpl 
     private int timeBeforeExpiration = -1;
 
     /** number of remaining grace authentications */
-    private int graceAuthNsRemaining = -1;
+    private int graceAuthNRemaining = -1;
 
     /** number representing the password policy error */
     private PasswordPolicyErrorEnum ppolicyError;
@@ -59,18 +59,18 @@ public class PasswordPolicyResponseImpl 
     /**
      * {@inheritDoc}
      */
-    public int getGraceAuthNsRemaining()
+    public int getGraceAuthNRemaining()
     {
-        return graceAuthNsRemaining;
+        return graceAuthNRemaining;
     }
 
 
     /**
      * {@inheritDoc}
      */
-    public void setGraceAuthNsRemaining( int graceAuthNsRemaining )
+    public void setGraceAuthNRemaining( int graceAuthNRemaining )
     {
-        this.graceAuthNsRemaining = graceAuthNsRemaining;
+        this.graceAuthNRemaining = graceAuthNRemaining;
     }
 
 

Modified: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyDecorator.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyDecorator.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyDecorator.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyDecorator.java Sun Apr 14 19:15:51 2013
@@ -113,9 +113,9 @@ public class PasswordPolicyDecorator ext
             timeBeforeExpirationTagLength = TLV.getNbBytes( getResponse().getTimeBeforeExpiration() );
             warningLength = 1 + TLV.getNbBytes( timeBeforeExpirationTagLength ) + timeBeforeExpirationTagLength;
         }
-        else if ( getResponse().getGraceAuthNsRemaining() >= 0 )
+        else if ( getResponse().getGraceAuthNRemaining() >= 0 )
         {
-            graceAuthNsRemainingTagLength = TLV.getNbBytes( getResponse().getGraceAuthNsRemaining() );
+            graceAuthNsRemainingTagLength = TLV.getNbBytes( getResponse().getGraceAuthNRemaining() );
             warningLength = 1 + TLV.getNbBytes( graceAuthNsRemainingTagLength ) + graceAuthNsRemainingTagLength;
         }
 
@@ -151,7 +151,7 @@ public class PasswordPolicyDecorator ext
             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
         }
 
-        if ( ( getResponse().getTimeBeforeExpiration() < 0 ) && ( getResponse().getGraceAuthNsRemaining() < 0 ) && (
+        if ( ( getResponse().getTimeBeforeExpiration() < 0 ) && ( getResponse().getGraceAuthNRemaining() < 0 ) && (
             getResponse().getPasswordPolicyError() == null ) )
         {
             return buffer;
@@ -174,11 +174,11 @@ public class PasswordPolicyDecorator ext
                     buffer.put( TLV.getBytes( timeBeforeExpirationTagLength ) );
                     buffer.put( BerValue.getBytes( getResponse().getTimeBeforeExpiration() ) );
                 }
-                else if ( getResponse().getGraceAuthNsRemaining() >= 0 )
+                else if ( getResponse().getGraceAuthNRemaining() >= 0 )
                 {
                     buffer.put( ( byte ) PasswordPolicyTags.GRACE_AUTHNS_REMAINING_TAG.getValue() );
                     buffer.put( TLV.getBytes( graceAuthNsRemainingTagLength ) );
-                    buffer.put( BerValue.getBytes( getResponse().getGraceAuthNsRemaining() ) );
+                    buffer.put( BerValue.getBytes( getResponse().getGraceAuthNRemaining() ) );
                 }
             }
 
@@ -207,9 +207,9 @@ public class PasswordPolicyDecorator ext
             sb.append( "   timeBeforeExpiration          : '" ).append( getResponse().getTimeBeforeExpiration() )
                 .append( '\n' );
         }
-        else if ( hasResponse() && getResponse().getGraceAuthNsRemaining() >= 0 )
+        else if ( hasResponse() && getResponse().getGraceAuthNRemaining() >= 0 )
         {
-            sb.append( "   graceAuthNsRemaining          : '" ).append( getResponse().getGraceAuthNsRemaining() )
+            sb.append( "   graceAuthNsRemaining          : '" ).append( getResponse().getGraceAuthNRemaining() )
                 .append( '\n' );
         }
 

Modified: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyGrammar.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyGrammar.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyGrammar.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/PasswordPolicyGrammar.java Sun Apr 14 19:15:51 2013
@@ -103,7 +103,7 @@ public class PasswordPolicyGrammar exten
             .getValue()] = new GrammarTransition(
             PasswordPolicyStates.PPOLICY_WARNING_TAG_STATE, PasswordPolicyStates.PPOLICY_GRACE_AUTHNS_REMAINING_STATE,
             PasswordPolicyTags.GRACE_AUTHNS_REMAINING_TAG.getValue(),
-            new StoreGraceAuthsRemaining() );
+            new StoreGraceAuthNRemaining() );
 
         // PasswordPolicyResponseValue ::= SEQUENCE {
         //              ...

Copied: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthNRemaining.java (from r1466005, directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthsRemaining.java)
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthNRemaining.java?p2=directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthNRemaining.java&p1=directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthsRemaining.java&r1=1466005&r2=1467813&rev=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthsRemaining.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ppolicy_impl/StoreGraceAuthNRemaining.java Sun Apr 14 19:15:51 2013
@@ -30,13 +30,13 @@ import org.apache.directory.api.asn1.ber
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 @SuppressWarnings("rawtypes")
-public class StoreGraceAuthsRemaining extends AbstractReadInteger
+public class StoreGraceAuthNRemaining extends AbstractReadInteger
 {
 
     /**
      * Instantiates a new StoreCusec action.
      */
-    public StoreGraceAuthsRemaining()
+    public StoreGraceAuthNRemaining()
     {
         super( "PPolicy graceAuthnsRemains" );
     }
@@ -50,7 +50,7 @@ public class StoreGraceAuthsRemaining ex
     {
         PasswordPolicyContainer ppolicyContainer = ( PasswordPolicyContainer ) container;
 
-        ppolicyContainer.getPasswordPolicyResponseControl().getResponse().setGraceAuthNsRemaining( value );
+        ppolicyContainer.getPasswordPolicyResponseControl().getResponse().setGraceAuthNRemaining( value );
 
         ppolicyContainer.setGrammarEndAllowed( true );
     }

Modified: directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyTest.java?rev=1467813&r1=1467812&r2=1467813&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyTest.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ppolicy/PasswordPolicyTest.java Sun Apr 14 19:15:51 2013
@@ -28,7 +28,6 @@ import static org.junit.Assert.assertTru
 import java.nio.ByteBuffer;
 
 import org.apache.directory.api.ldap.extras.AbstractCodecServiceTest;
-import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
 import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
 import org.apache.directory.api.util.Strings;
 import org.junit.Test;
@@ -49,9 +48,13 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x08,
-                  ( byte ) 0xA0, 0x03, // timeBeforeExpiration
-                    ( byte ) 0x80, 0x01, 0x01,
-                  ( byte ) 0x81, 0x01, 0x01 // ppolicyError
+                ( byte ) 0xA0, 0x03, // timeBeforeExpiration
+                ( byte ) 0x80,
+                0x01,
+                0x01,
+                ( byte ) 0x81,
+                0x01,
+                0x01 // ppolicyError
         } );
 
         bb.flip();
@@ -77,9 +80,13 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x08,
-                  ( byte ) 0xA0, 0x03, // warning
-                    ( byte ) 0x81, 0x01, 0x01, // graceAuthNsRemaining
-                  ( byte ) 0x81, 0x01, 0x01 // error
+                ( byte ) 0xA0, 0x03, // warning
+                ( byte ) 0x81,
+                0x01,
+                0x01, // graceAuthNsRemaining
+                ( byte ) 0x81,
+                0x01,
+                0x01 // error
         } );
 
         bb.flip();
@@ -88,7 +95,7 @@ public class PasswordPolicyTest extends 
         PasswordPolicy passwordPolicy = ( PasswordPolicy ) control.decode( bb.array() );
 
         assertTrue( passwordPolicy.hasResponse() );
-        assertEquals( 1, passwordPolicy.getResponse().getGraceAuthNsRemaining() );
+        assertEquals( 1, passwordPolicy.getResponse().getGraceAuthNRemaining() );
         assertEquals( 1, passwordPolicy.getResponse().getPasswordPolicyError().getValue() );
 
         ByteBuffer encoded = ( ( PasswordPolicyDecorator ) passwordPolicy ).encode(
@@ -105,8 +112,8 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x05,
-                  ( byte ) 0xA0, 0x03,
-                    ( byte ) 0x80, 0x01, 0x01 //  timeBeforeExpiration
+                ( byte ) 0xA0, 0x03,
+                ( byte ) 0x80, 0x01, 0x01 //  timeBeforeExpiration
         } );
 
         bb.flip();
@@ -131,8 +138,8 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x05,
-                  ( byte ) 0xA0, 0x03,
-                    ( byte ) 0x81, 0x01, 0x01 //  graceAuthNsRemaining
+                ( byte ) 0xA0, 0x03,
+                ( byte ) 0x81, 0x01, 0x01 //  graceAuthNsRemaining
         } );
 
         bb.flip();
@@ -141,7 +148,7 @@ public class PasswordPolicyTest extends 
         PasswordPolicy passwordPolicy = ( PasswordPolicy ) control.decode( bb.array() );
 
         assertTrue( passwordPolicy.hasResponse() );
-        assertEquals( 1, passwordPolicy.getResponse().getGraceAuthNsRemaining() );
+        assertEquals( 1, passwordPolicy.getResponse().getGraceAuthNRemaining() );
 
         ByteBuffer encoded = ( ( PasswordPolicyDecorator ) passwordPolicy ).encode(
             ByteBuffer.allocate( ( ( PasswordPolicyDecorator ) passwordPolicy ).computeLength() ) );
@@ -157,7 +164,7 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x03,
-                  ( byte ) 0x81, 0x01, 0x01 //  error
+                ( byte ) 0x81, 0x01, 0x01 //  error
         } );
 
         bb.flip();
@@ -182,7 +189,7 @@ public class PasswordPolicyTest extends 
         bb.put( new byte[]
             {
                 0x30, 0x00
-            } );
+        } );
 
         bb.flip();