You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/12/15 13:09:17 UTC

svn commit: r1551018 - in /directory: apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/ apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/ shared/trunk/ldap/extras/cod...

Author: kayyagari
Date: Sun Dec 15 12:09:17 2013
New Revision: 1551018

URL: http://svn.apache.org/r1551018
Log:
o included ppolicy response control in the pwdmodify extended operation's respone (DIRSERVER-1935)
o added the test case(with some modifications) provided by Lukas Theisen

Modified:
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java
    directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyIT.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/pwdModify/PasswordModifyFactory.java

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java?rev=1551018&r1=1551017&r2=1551018&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java Sun Dec 15 12:09:17 2013
@@ -26,6 +26,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+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.ldap.extras.extended.PwdModifyRequest;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyResponse;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyResponseImpl;
@@ -35,6 +37,8 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.entry.ModificationOperation;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.exception.LdapOperationException;
+import org.apache.directory.api.ldap.model.message.Control;
 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;
@@ -123,6 +127,13 @@ public class PwdModifyHandler implements
         // We can try to update the userPassword now
         ModifyOperationContext modifyContext = new ModifyOperationContext( adminSession );
         modifyContext.setDn( userDn );
+
+        Control ppolicyControl = req.getControl( PasswordPolicy.OID );
+        if( ppolicyControl != null )
+        {
+            modifyContext.addRequestControl( ppolicyControl );
+        }
+        
         List<Modification> modifications = new ArrayList<Modification>();
         Modification modification = null;
 
@@ -165,6 +176,9 @@ public class PwdModifyHandler implements
 
         modifyContext.setModItems( modifications );
 
+        ResultCodeEnum errorCode = null;
+        String errorMessage = null;
+        
         try
         {
             service.getOperationManager().modify( modifyContext );
@@ -172,19 +186,46 @@ public class PwdModifyHandler implements
             LOG.debug( "Password modified for user " + userDn );
 
             // Ok, all done
-            requestor.getIoSession().write( new PwdModifyResponseImpl(
-                req.getMessageId(), ResultCodeEnum.SUCCESS ) );
+            PwdModifyResponseImpl pmrl = new PwdModifyResponseImpl(
+                req.getMessageId(), ResultCodeEnum.SUCCESS );
+            
+            ppolicyControl = modifyContext.getResponseControl( PasswordPolicy.OID );
+            
+            if( ppolicyControl != null )
+            {
+                pmrl.addControl( ppolicyControl );
+            }
+            
+            requestor.getIoSession().write( pmrl );
+            
+            return;
+        }
+        catch ( LdapOperationException loe )
+        {
+            errorCode = loe.getResultCode();
+            errorMessage = loe.getMessage();
         }
         catch ( LdapException le )
         {
-            LOG.error( "Cannot modify the password for user " + userDn + ", exception : " + le.getMessage() );
-            // We can't modify the password
-            requestor.getIoSession().write( new PwdModifyResponseImpl(
-                req.getMessageId(), ResultCodeEnum.INVALID_CREDENTIALS, "Cannot modify the password for user "
-                    + userDn + ", exception : " + le.getMessage() ) );
-
-            return;
+            // this exception means something else must be wrong
+            errorCode = ResultCodeEnum.OTHER;
+            errorMessage = le.getMessage();
+        }
+        
+        // We can't modify the password
+        LOG.error( "Cannot modify the password for user " + userDn + ", exception : " + errorMessage );
+        PwdModifyResponseImpl errorPmrl = new PwdModifyResponseImpl(
+            req.getMessageId(), errorCode, "Cannot modify the password for user "
+                + userDn + ", exception : " + errorMessage );
+        
+        ppolicyControl = modifyContext.getResponseControl( PasswordPolicy.OID );
+        
+        if( ppolicyControl != null )
+        {
+            errorPmrl.addControl( ppolicyControl );
         }
+
+        requestor.getIoSession().write( errorPmrl );
     }
 
 
@@ -200,6 +241,13 @@ public class PwdModifyHandler implements
         // Try to update the userPassword
         ModifyOperationContext modifyContext = new ModifyOperationContext( adminSession );
         modifyContext.setDn( principalDn );
+
+        Control ppolicyControl = req.getControl( PasswordPolicy.OID );
+        if( ppolicyControl != null )
+        {
+            modifyContext.addRequestControl( ppolicyControl );
+        }
+
         List<Modification> modifications = new ArrayList<Modification>();
         Modification modification = null;
 
@@ -228,6 +276,9 @@ public class PwdModifyHandler implements
 
         modifyContext.setModItems( modifications );
 
+        ResultCodeEnum errorCode = null;
+        String errorMessage = null;
+        
         try
         {
             service.getOperationManager().modify( modifyContext );
@@ -235,20 +286,46 @@ public class PwdModifyHandler implements
             LOG.debug( "Password modified for user " + principalDn );
 
             // Ok, all done
-            requestor.getIoSession().write( new PwdModifyResponseImpl(
-                req.getMessageId(), ResultCodeEnum.SUCCESS ) );
+            PwdModifyResponseImpl pmrl = new PwdModifyResponseImpl(
+                req.getMessageId(), ResultCodeEnum.SUCCESS );
+            
+            ppolicyControl = modifyContext.getResponseControl( PasswordPolicy.OID );
+            
+            if( ppolicyControl != null )
+            {
+                pmrl.addControl( ppolicyControl );
+            }
+            
+            requestor.getIoSession().write( pmrl );
+            return;
+        }
+        catch ( LdapOperationException loe )
+        {
+            errorCode = loe.getResultCode();
+            errorMessage = loe.getMessage();
         }
         catch ( LdapException le )
         {
-            LOG.error( "Cannot modify the password for user " + principalDn + ", exception : " + le.getMessage() );
-            // We can't modify the password
-            requestor.getIoSession().write(
-                new PwdModifyResponseImpl( req.getMessageId(), ResultCodeEnum.INVALID_CREDENTIALS,
-                    "Cannot modify the password for user "
-                        + principalDn + ", exception : " + le.getMessage() ) );
+            // this exception means something else must be wrong
+            errorCode = ResultCodeEnum.OTHER;
+            errorMessage = le.getMessage();
+        }
+        
+        // We can't modify the password
+        LOG.error( "Cannot modify the password for user " + principalDn + ", exception : " + errorMessage );
 
-            return;
+        PwdModifyResponseImpl errorPmrl = new PwdModifyResponseImpl( req.getMessageId(), errorCode,
+            "Cannot modify the password for user "
+                + principalDn + ", exception : " + errorMessage );
+
+        ppolicyControl = modifyContext.getResponseControl( PasswordPolicy.OID );
+        
+        if( ppolicyControl != null )
+        {
+            errorPmrl.addControl( ppolicyControl );
         }
+
+        requestor.getIoSession().write( errorPmrl );
     }
 
 
@@ -289,7 +366,7 @@ public class PwdModifyHandler implements
         {
             Dn principalDn = requestor.getCoreSession().getEffectivePrincipal().getDn();
 
-            LOG.debug( "Trying to modify password for user " + principalDn );
+            LOG.debug( "User {} trying to modify password of user {}", principalDn, userDn );
 
             // First, check that the userDn is null : we can't change the password of someone else
             // except if we are admin
@@ -299,10 +376,10 @@ public class PwdModifyHandler implements
                 if ( !requestor.getCoreSession().isAdministrator() )
                 {
                     // No : error
-                    LOG.error( "Cannot access to another user's password to modify it" );
+                    LOG.error( "Non-admin user cannot access another user's password to modify it" );
                     requestor.getIoSession().write( new PwdModifyResponseImpl(
                         req.getMessageId(), ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS,
-                        "Cannot access to another user's password to modify it" ) );
+                        "Non-admin user cannot access another user's password to modify it" ) );
                 }
                 else
                 {

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=1551018&r1=1551017&r2=1551018&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 Sun Dec 15 12:09:17 2013
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertNul
 import org.apache.directory.api.ldap.codec.api.LdapApiService;
 import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
 import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum;
 import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyImpl;
 import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyRequestImpl;
@@ -400,4 +401,61 @@ public class PwdModifyIT extends Abstrac
 
         adminConnection.close();
     }
+
+
+    /**
+     * Attempt to modify an existing user password and fail.  Then process the
+     * password policy control from the response.
+     */
+    @Test
+    public void testModifyUserPasswordWithPasswordPolicyControl() throws Exception
+    {
+        policyConfig.setPwdCheckQuality( CheckQualityEnum.CHECK_ACCEPT ); // allow the password if its quality can't be checked
+        policyConfig.setPwdMinLength( 5 );
+        policyConfig.setPwdMinAge( 5 );
+        
+        LdapConnection adminConnection = null;
+        LdapConnection userConnection = null;
+        try 
+        {
+            adminConnection = getAdminNetworkConnection( getLdapServer() );
+            adminConnection.setTimeOut( Long.MAX_VALUE );
+            addUser( adminConnection, "UserXY", "secret3" );
+            Dn userDn = new Dn( "cn=UserXY,ou=system" );
+            
+            userConnection = getNetworkConnectionAs( ldapServer, userDn.toString(), "secret3" );
+            PasswordPolicyDecorator passwordPolicyRequestControl =
+                    new PasswordPolicyDecorator( LdapApiServiceFactory.getSingleton(), new PasswordPolicyImpl() );
+            PwdModifyRequestImpl selfPwdModifyRequest = new PwdModifyRequestImpl();
+            selfPwdModifyRequest.setUserIdentity( Dn.getBytes( userDn ) );
+            selfPwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret3" ) );
+            selfPwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "1234567" ) );
+            selfPwdModifyRequest.addControl( passwordPolicyRequestControl );
+
+            // Send the request to update own password
+            PwdModifyResponse pwdModifyResponse = ( PwdModifyResponse ) userConnection.extended( selfPwdModifyRequest );
+            // passwordTooShort is a contstraint violation
+            assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION, pwdModifyResponse.getLdapResult().getResultCode() );
+            Control passwordPolicyResponseControl = pwdModifyResponse.getControl( passwordPolicyRequestControl.getOid() );
+            assertNotNull( passwordPolicyResponseControl );
+            assertEquals( PasswordPolicyErrorEnum.PASSWORD_TOO_YOUNG,
+                ((PasswordPolicyDecorator)passwordPolicyResponseControl)
+                    .getDecorated().getResponse().getPasswordPolicyError() );
+            
+            addUser( adminConnection, "UserZZ", "secret4" );
+            Dn otherUserDn = new Dn( "cn=UserZZ,ou=system" );
+
+            PwdModifyRequestImpl pwdModifyRequest = new PwdModifyRequestImpl();
+            pwdModifyRequest.setUserIdentity( Dn.getBytes( otherUserDn ) );
+            pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret4" ) );
+            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "1234567" ) );
+            pwdModifyResponse = ( PwdModifyResponse ) userConnection.extended( pwdModifyRequest );
+            assertEquals( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS, pwdModifyResponse.getLdapResult().getResultCode() );
+        }
+        finally 
+        {
+            adminConnection.close();
+            userConnection.close();
+        }
+    }    
 }

Modified: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/pwdModify/PasswordModifyFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/pwdModify/PasswordModifyFactory.java?rev=1551018&r1=1551017&r2=1551018&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/pwdModify/PasswordModifyFactory.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/pwdModify/PasswordModifyFactory.java Sun Dec 15 12:09:17 2013
@@ -30,10 +30,12 @@ import org.apache.directory.api.ldap.cod
 import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator;
 import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator;
 import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyRequest;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyRequestImpl;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyResponse;
 import org.apache.directory.api.ldap.extras.extended.PwdModifyResponseImpl;
+import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.ExtendedRequest;
 import org.apache.directory.api.ldap.model.message.ExtendedResponse;
 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
@@ -136,20 +138,19 @@ public class PasswordModifyFactory imple
         ByteBuffer buffer = ByteBuffer.wrap( value );
 
         PasswordModifyResponseContainer container = new PasswordModifyResponseContainer();
-
+        PwdModifyResponse pwdModifyResponse = null;
+        
         try
         {
             decoder.decode( buffer, container );
 
-            PwdModifyResponse pwdModifyResponse = container.getPwdModifyResponse();
+            pwdModifyResponse = container.getPwdModifyResponse();
 
             // Now, update the created response with what we got from the extendedResponse
             pwdModifyResponse.getLdapResult().setResultCode( response.getLdapResult().getResultCode() );
             pwdModifyResponse.getLdapResult().setDiagnosticMessage( response.getLdapResult().getDiagnosticMessage() );
             pwdModifyResponse.getLdapResult().setMatchedDn( response.getLdapResult().getMatchedDn() );
             pwdModifyResponse.getLdapResult().setReferral( response.getLdapResult().getReferral() );
-
-            return new PasswordModifyResponseDecorator( codec, pwdModifyResponse );
         }
         catch ( DecoderException de )
         {
@@ -158,13 +159,21 @@ public class PasswordModifyFactory imple
             String stackTrace = sw.toString();
 
             // Error while decoding the value. 
-            PwdModifyResponse pwdModifyResponse = new PwdModifyResponseImpl(
+            pwdModifyResponse = new PwdModifyResponseImpl(
                 decoratedResponse.getMessageId(),
                 ResultCodeEnum.OPERATIONS_ERROR,
                 stackTrace );
-
-            return new PasswordModifyResponseDecorator( codec, pwdModifyResponse );
         }
 
+        PasswordModifyResponseDecorator decorated = new PasswordModifyResponseDecorator( codec, pwdModifyResponse );
+        
+        Control ppolicyControl = response.getControl( PasswordPolicy.OID );
+        
+        if( ppolicyControl != null )
+        {
+            decorated.addControl( ppolicyControl );
+        }
+        
+        return decorated;
     }
 }