You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by lu...@apache.org on 2014/01/24 21:10:49 UTC
svn commit: r1561139 - in /directory/apacheds/trunk:
interceptors/authn/src/main/java/org/apache/directory/server/core/authn/
protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/
server-integ/src/test/java/org/apache/director...
Author: lucastheisen
Date: Fri Jan 24 20:10:49 2014
New Revision: 1561139
URL: http://svn.apache.org/r1561139
Log:
DIRSERVER-1928: PasswordPolicy should be ignored from Admin session
Modified:
directory/apacheds/trunk/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
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/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/ppolicy/PasswordPolicyIT.java
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=1561139&r1=1561138&r2=1561139&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 Fri Jan 24 20:10:49 2014
@@ -358,7 +358,7 @@ public class AuthenticationInterceptor e
try
{
- check( entry, userPassword.getValue(), policyConfig );
+ check( addContext, entry, userPassword.getValue(), policyConfig );
}
catch ( PasswordPolicyException e )
{
@@ -917,7 +917,7 @@ public class AuthenticationInterceptor e
if ( pwdModDetails.isAddOrReplace() )
{
- if ( isPwdTooYoung( entry, policyConfig ) )
+ if ( isPwdTooYoung( modifyContext, entry, policyConfig ) )
{
if ( isPPolicyReqCtrlPresent )
{
@@ -936,7 +936,7 @@ public class AuthenticationInterceptor e
try
{
- check( entry, newPassword, policyConfig );
+ check( modifyContext, entry, newPassword, policyConfig );
}
catch ( PasswordPolicyException e )
{
@@ -1252,9 +1252,15 @@ public class AuthenticationInterceptor e
// ---------- private methods ----------------
- private void check( Entry entry, byte[] password, PasswordPolicyConfiguration policyConfig )
+ private void check( OperationContext operationContext, Entry entry,
+ byte[] password, PasswordPolicyConfiguration policyConfig )
throws LdapException
{
+ // https://issues.apache.org/jira/browse/DIRSERVER-1928
+ if ( operationContext.getSession().isAnAdministrator() )
+ {
+ return;
+ }
final CheckQualityEnum qualityVal = policyConfig.getPwdCheckQuality();
if ( qualityVal == CheckQualityEnum.NO_CHECK )
@@ -1363,9 +1369,15 @@ public class AuthenticationInterceptor e
* @return true if the password is young, false otherwise
* @throws LdapException
*/
- private boolean isPwdTooYoung( Entry userEntry, PasswordPolicyConfiguration policyConfig ) throws LdapException
+ private boolean isPwdTooYoung( OperationContext operationContext,
+ Entry userEntry, PasswordPolicyConfiguration policyConfig ) throws LdapException
{
- if ( policyConfig.getPwdMinAge() == 0 )
+ // https://issues.apache.org/jira/browse/DIRSERVER-1928
+ if ( operationContext.getSession().isAnAdministrator() )
+ {
+ return false;
+ }
+ if ( policyConfig.getPwdMinAge() == 0 )
{
return false;
}
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=1561139&r1=1561138&r2=1561139&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 Fri Jan 24 20:10:49 2014
@@ -235,10 +235,9 @@ public class PwdModifyHandler implements
PwdModifyRequest req )
{
DirectoryService service = requestor.getLdapServer().getDirectoryService();
- CoreSession adminSession = service.getAdminSession();
// Try to update the userPassword
- ModifyOperationContext modifyContext = new ModifyOperationContext( adminSession );
+ ModifyOperationContext modifyContext = new ModifyOperationContext( requestor.getCoreSession() );
modifyContext.setDn( principalDn );
Control ppolicyControl = req.getControl( PasswordPolicy.OID );
@@ -416,7 +415,8 @@ public class PwdModifyHandler implements
// Ok, we were able to bind using the userIdentity and the password. Let's
// modify the password now
- ModifyOperationContext modifyContext = new ModifyOperationContext( adminSession );
+ ModifyOperationContext modifyContext = new ModifyOperationContext(
+ service.getSession( userDn, oldPassword ) );
modifyContext.setDn( userDn );
List<Modification> modifications = new ArrayList<Modification>();
Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
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=1561139&r1=1561138&r2=1561139&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 Fri Jan 24 20:10:49 2014
@@ -24,9 +24,11 @@ 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.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+
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;
@@ -35,6 +37,7 @@ import org.apache.directory.api.ldap.ext
import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
import org.apache.directory.api.ldap.extras.extended.PwdModifyRequestImpl;
import org.apache.directory.api.ldap.extras.extended.PwdModifyResponse;
+import org.apache.directory.api.ldap.model.entry.Attribute;
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;
@@ -147,6 +150,21 @@ public class PwdModifyIT extends Abstrac
}
}
}
+
+
+ private void safeCloseConnections( LdapConnection... connections )
+ {
+ for ( LdapConnection connection : connections ) {
+ if ( connection != null ) {
+ try {
+ connection.close();
+ }
+ catch ( Exception e ) {
+ // may wanna log a message or something
+ }
+ }
+ }
+ }
/**
@@ -402,7 +420,64 @@ public class PwdModifyIT extends Abstrac
adminConnection.close();
}
-
+
+ /**
+ * Modify an existing user password with an admin account
+ */
+ @Test
+ public void testModifyPasswordTooSoon() throws Exception
+ {
+ LdapConnection adminConnection = null;
+ LdapConnection userConnection = null;
+ int minAge = policyConfig.getPwdMinAge();
+ try {
+ policyConfig.setPwdMinAge( 1000 );
+
+ adminConnection = getAdminNetworkConnection( getLdapServer() );
+ addUser( adminConnection, "User7", "secret7" );
+ Entry userEntry = adminConnection.lookup( "cn=User7,ou=system", "*", "+" );
+ Attribute attribute = userEntry.get( "pwdHistory" );
+ assertEquals( 1, attribute.size() );
+
+ PwdModifyRequestImpl pwdModifyRequest = null;
+ PwdModifyResponse pwdModifyResponse = null;
+
+ // Fail modify user with user account
+ try {
+ userConnection = getNetworkConnectionAs( getLdapServer(), "cn=User7,ou=system", "secret7" );
+ pwdModifyRequest = new PwdModifyRequestImpl();
+ pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User7,ou=system" ) );
+ pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret4Bis" ) );
+ pwdModifyResponse = (PwdModifyResponse)userConnection.extended( pwdModifyRequest );
+ assertNotEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
+ }
+ finally {
+ safeCloseConnections( userConnection );
+ }
+
+ // Modify the user with the admin account
+ pwdModifyRequest = new PwdModifyRequestImpl();
+ pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User7,ou=system" ) );
+ pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret4Bis" ) );
+ pwdModifyResponse = (PwdModifyResponse)adminConnection.extended( pwdModifyRequest );
+ assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
+ userEntry = adminConnection.lookup( "cn=User7,ou=system", "*", "+" );
+ attribute = userEntry.get( "pwdHistory" );
+ assertEquals( 2, attribute.size() );
+
+ // Now try to bind with the new password
+ userConnection = getNetworkConnectionAs( ldapServer, "cn=User7,ou=system", "secret4Bis" );
+ Entry entry = userConnection.lookup( "cn=User7,ou=system" );
+
+ assertNotNull( entry );
+ }
+ finally {
+ policyConfig.setPwdMinAge( minAge );
+ safeCloseConnections( userConnection, adminConnection );
+ }
+ }
+
+
/**
* Attempt to modify an existing user password and fail. Then process the
* password policy control from the response.
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=1561139&r1=1561138&r2=1561139&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 Fri Jan 24 20:10:49 2014
@@ -37,8 +37,10 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import org.apache.directory.api.ldap.codec.api.LdapApiService;
-import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
+
+import java.nio.charset.Charset;
+
+
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;
@@ -103,14 +105,13 @@ import org.junit.runner.RunWith;
@CreateDS(enableChangeLog = false, name = "PasswordPolicyTest")
public class PasswordPolicyIT extends AbstractLdapTestUnit
{
- private PasswordPolicyConfiguration policyConfig;
-
- private static final LdapApiService codec = LdapApiServiceFactory.getSingleton();
-
private static final PasswordPolicy PP_REQ_CTRL =
new PasswordPolicyImpl();
+ private PasswordPolicyConfiguration policyConfig;
+
+
/**
* Set a default PaswordPolicy configuration
*/
@@ -187,6 +188,38 @@ public class PasswordPolicyIT extends Ab
/**
+ * Changes the password of the user in the users own context from the
+ * old value to the new value.
+ *
+ * @param userDn
+ * @param oldPassword
+ * @param newPassword
+ * @return The ModifyResponse from the attempt
+ * @throws Exception If unable to obtain the connection with the
+ * provided user an oldPassword.
+ */
+ private ModifyResponse changePassword( Dn userDn, String oldPassword, byte[] newPassword ) throws Exception
+ {
+ LdapConnection userConnection = null;
+ try {
+ userConnection = getNetworkConnectionAs( ldapServer, userDn.toString(), oldPassword );
+ ModifyRequest modifyRequest = new ModifyRequestImpl();
+ modifyRequest.setName( userDn );
+ modifyRequest.replace( "userPassword", newPassword );
+ return userConnection.modify( modifyRequest );
+ }
+ finally {
+ userConnection.close();
+ }
+ }
+
+ private ModifyResponse changePassword( Dn userDn, String oldPassword, String newPassword ) throws Exception
+ {
+ return changePassword( userDn, oldPassword, newPassword.getBytes( Charset.forName( "UTF-8" ) ) );
+ }
+
+
+ /**
* Check we can bind a user with a given password
*/
private void checkBindSuccess( Dn userDn, String password ) throws Exception
@@ -204,18 +237,23 @@ public class PasswordPolicyIT extends Ab
*/
private void checkBindFailure( Dn userDn, String password ) throws Exception
{
+ LdapConnection userConnection = null;
try
{
- LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
+ userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), password );
assertNull( userConnection );
- assertFalse( userConnection.isAuthenticated() );
-
- userConnection.close();
}
catch ( LdapException le )
{
// Expected
}
+ finally
+ {
+ if ( userConnection != null )
+ {
+ userConnection.close();
+ }
+ }
}
@@ -242,7 +280,12 @@ public class PasswordPolicyIT extends Ab
/**
* 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
+ *
+ * Ignored because if an admin can avoid password policy anyway, and add's are
+ * performed by an admin, then this case would not get caught. If there is a case
+ * where a user adds another user then we should put that case here.
*/
+ @Ignore
@Test
public void testAddUserWithHashedPwd() throws Exception
{
@@ -287,6 +330,30 @@ public class PasswordPolicyIT extends Ab
adminConnection.close();
}
+
+ @Test
+ public void testModifyUserWithHashedPwd() throws Exception
+ {
+ Dn userDn = new Dn( "cn=hashedpwdm,ou=system" );
+ LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );
+ Entry userEntry = new DefaultEntry(
+ userDn.toString(),
+ "ObjectClass: top",
+ "ObjectClass: person",
+ "cn: hashedpwdm",
+ "sn: hashedpwdm_sn",
+ "userPassword", "set4now" );
+ adminConnection.add( userEntry );
+
+ byte[] password = PasswordUtil.createStoragePassword( "12345", LdapSecurityConstants.HASH_METHOD_CRYPT );
+ assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION,
+ changePassword( userDn, "set4now", password ).getLdapResult().getResultCode() );
+
+ checkBindFailure( userDn, "12345" );
+
+ adminConnection.close();
+ }
+
@Test
public void testPwdLockoutForever() throws Exception
@@ -385,32 +452,21 @@ public class PasswordPolicyIT extends Ab
"cn: userMinAge",
"sn: userMinAge_sn",
"userPassword: 12345" );
-
adminConnection.add( userEntry );
- Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, "userPassword",
- "123456" );
// We should not be able to modify the password : it's too recent
- try
- {
- adminConnection.modify( userDn, modification );
- fail();
- }
- catch ( LdapException LdapInvalidAttributeValueException )
- {
- // Expected
- }
+ assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION,
+ changePassword( userDn, "12345", "123456" ).getLdapResult().getResultCode() );
// Wait for the pwdMinAge delay to be over
Thread.sleep( 5000 );
// Now, we should be able to modify the password
- adminConnection.modify( userDn, modification );
+ assertEquals( ResultCodeEnum.SUCCESS,
+ changePassword( userDn, "12345", "123456" ).getLdapResult().getResultCode() );
+
+ checkBindSuccess( userDn, "123456" );
- LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), userDn.getName(), "123456" );
- assertNotNull( userConnection );
- assertTrue( userConnection.isAuthenticated() );
- userConnection.close();
adminConnection.close();
}
@@ -504,40 +560,25 @@ public class PasswordPolicyIT extends Ab
"ObjectClass: person",
"cn: userLen",
"sn: userLen_sn",
- "userPassword: 1234" );
+ "userPassword: set4now" );
+ adminConnection.add( userEntry );
// Try with a password below the minLength
- try
- {
- adminConnection.add( userEntry );
- fail();
- }
- catch ( LdapInvalidAttributeValueException liave )
- {
- // Expected
- }
+ assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION,
+ changePassword( userDn, "set4now", "1234" ).getLdapResult().getResultCode() );
checkBindFailure( userDn, "1234" );
// Try with a password above the maxLength
- userEntry.put( "userPassword", "12345678" );
-
- try
- {
- adminConnection.add( userEntry );
- fail();
- }
- catch ( LdapInvalidAttributeValueException liave )
- {
- // Expected
- }
+ assertEquals( ResultCodeEnum.CONSTRAINT_VIOLATION,
+ changePassword( userDn, "set4now", "12345678" ).getLdapResult().getResultCode() );
checkBindFailure( userDn, "12345678" );
// And try with a correct password
- userEntry.put( "userPassword", "123456" );
+ assertEquals( ResultCodeEnum.SUCCESS,
+ changePassword( userDn, "set4now", "123456" ).getLdapResult().getResultCode() );
- adminConnection.add( userEntry );
checkBindSuccess( userDn, "123456" );
adminConnection.close();