/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
* Portions copyright 2011-2013 ForgeRock AS.
*/
/**
* This class contains test cases that verify the appropriate handling of the
* password policy control as defined in draft-behera-ldap-password-policy.
*/
public class PasswordPolicyControlTestCase
extends ControlsTestCase
{
/**
* Make sure that the server is running.
*
* @throws Exception If an unexpected problem occurs.
*/
@BeforeClass()
public void startServer()
throws Exception
{
}
/**
* Tests that an appropriate password policy response control is returned for
* an add operation when the user's password is in a "must change" state.
* This test will also ensure that the bind response is also capable of
* including the password policy response control with the "change after
* reset" error type set.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAddMustChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
w.writeMessage(message);
message = r.readMessage();
found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* an add operation in which the proposed password is pre-encoded.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAddPreEncodedPassword()
throws Exception
{
try
{
w.writeMessage(message);
message = r.readMessage();
"{SSHA}0pZPpMIm6xSBIW4hGvR/72fjO4M9p3Ff1g7QFw=="));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* an add operation in which the proposed password fails validation.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAddPasswordFailsValidation()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--add", "password-validator:Length-Based Password Validator");
try
{
w.writeMessage(message);
message = r.readMessage();
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--remove", "password-validator:Length-Based Password Validator");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a bind operation in which the user's account is locked due to
* authentication failures.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testBindLockedDueToFailures()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "lockout-failure-count:3");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
for (int i=1; i <= 3; i++)
{
w.writeMessage(message);
message = r.readMessage();
}
bindRequest = new BindRequestProtocolOp(
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "lockout-failure-count:0");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a compare operation when the user's password is in a "must change" state.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testCompareMustChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a delete operation when the user's password is in a "must change" state.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testDeleteMustChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl",
"",
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
try
{
w.writeMessage(message);
message = r.readMessage();
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Creates test data for testModifyMustChange.
*
* Fields:
* <userDN> <entryDN> <changeAfterReset>
*
* @return Returns test data for testModifyMustChange.
*/
return new Object[][] {
// User does not need to change their password.
{ "uid=test.admin,o=test", "uid=test.admin,o=test", false },
{ "uid=test.admin,o=test", "uid=test.user,o=test", false },
{ "uid=test.admin,o=test", "o=test", false },
// User does need to change their password.
{ "uid=test.user,o=test", "uid=test.admin,o=test", true },
{ "uid=test.user,o=test", "uid=test.user,o=test", true },
{ "uid=test.user,o=test", "o=test", true }
};
}
/**
* Tests that an appropriate password policy response control is
* returned for a modify operation when the user's password is in a
* "must change" state.
*
* @param userDN
* The name of the user to bind as.
* @param entryDN
* The name of the entry to modify.
* @param changeAfterReset
* {@code true} if change after reset is expected.
* @throws Exception
* If an unexpected problem occurs.
*/
throws Exception
{
"dn: uid=test.admin,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.admin",
"givenName: Test Admin",
"sn: Admin",
"cn: Test Admin",
"userPassword: password",
"ds-privilege-name: bypass-acl");
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"foo"));
w.writeMessage(message);
message = r.readMessage();
if (changeAfterReset)
{
}
else
{
}
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
if (changeAfterReset) {
} else {
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is
* returned for a modify operation when the authorized user is forced to
* change their own password before changing a different entry.
*
* @throws Exception
* If an unexpected problem occurs.
*/
@Test
public void testAuthzModifyMustChange()
throws Exception
{
"dn: uid=test.admin,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.admin",
"givenName: Test Admin",
"sn: Admin",
"cn: Test Admin",
"userPassword: password",
"ds-privilege-name: bypass-acl",
"ds-privilege-name: proxied-auth");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=authz.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: authz.user",
"givenName: Authz",
"sn: User",
"cn: Authz User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"foo"));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a modify operation when users do not have permission to change their own
* passwords.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testModifyCannotChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "allow-user-password-changes:false");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"newpassword"));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "allow-user-password-changes:true");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a modify operation when the proposed password is in the user's password
* history.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyPasswordInHistory()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "password-history-count:5");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"password"));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "password-history-count:0");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a modify operation when the user didn't provide their current password when
* it was required.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyMissingCurrentPassword()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "password-change-requires-current-password:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"newpassword"));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "password-change-requires-current-password:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a modify operation when the user tried to perform multiple password changes
* without respecting the minimum age.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyMinimumPasswordAge()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "min-password-age:24 hours");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
"newpassword"));
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "min-password-age:0 seconds");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a modify DN operation when the user's password is in a "must change" state.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyDNMustChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl",
"",
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
try
{
w.writeMessage(message);
message = r.readMessage();
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
/**
* Tests that an appropriate password policy response control is returned for
* a search operation when the user's password is in a "must change" state.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testSearchMustChange()
throws Exception
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:true");
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-privilege-name: bypass-acl");
try
{
w.writeMessage(message);
message = r.readMessage();
0, false,
new LinkedHashSet<String>());
w.writeMessage(message);
message = r.readMessage();
boolean found = false;
{
{
if(c instanceof LDAPControl)
{
}
else
{
}
found = true;
}
}
}
finally
{
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
"--set", "force-change-on-add:false");
StaticUtils.close(s);
}
}
}