SubentryPasswordPolicyTestCase.java revision 9aa1482c49865483f798f91ef7d16f03cc3ec811
0N/A/*
3845N/A * CDDL HEADER START
0N/A *
0N/A * The contents of this file are subject to the terms of the
0N/A * Common Development and Distribution License, Version 1.0 only
0N/A * (the "License"). You may not use this file except in compliance
0N/A * with the License.
0N/A *
0N/A * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
0N/A * or http://forgerock.org/license/CDDLv1.0.html.
0N/A * See the License for the specific language governing permissions
0N/A * and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL HEADER in each
0N/A * file and include the License file at legal-notices/CDDLv1_0.txt.
0N/A * If applicable, add the following below this CDDL HEADER, with the
0N/A * fields enclosed by brackets "[]" replaced with your own identifying
0N/A * information:
1472N/A * Portions Copyright [yyyy] [name of copyright owner]
1472N/A *
1472N/A * CDDL HEADER END
0N/A *
0N/A *
0N/A * Copyright 2010 Sun Microsystems, Inc.
1879N/A * Portions Copyright 2011-2015 ForgeRock AS.
1879N/A */
1879N/Apackage org.opends.server.core;
0N/A
0N/Aimport java.util.Collection;
0N/Aimport java.util.List;
0N/A
0N/Aimport org.forgerock.opendj.ldap.ByteString;
0N/Aimport org.forgerock.opendj.ldap.ResultCode;
0N/Aimport org.opends.server.TestCaseUtils;
0N/Aimport org.opends.server.api.AuthenticationPolicy;
0N/Aimport org.opends.server.api.PasswordValidator;
0N/Aimport org.opends.server.types.AttributeType;
0N/Aimport org.opends.server.types.DN;
0N/Aimport org.opends.server.types.Entry;
0N/Aimport org.opends.server.util.StaticUtils;
0N/Aimport org.testng.annotations.AfterClass;
3845N/Aimport org.testng.annotations.BeforeClass;
0N/Aimport org.testng.annotations.DataProvider;
0N/Aimport org.testng.annotations.Test;
0N/A
0N/Aimport static org.opends.server.TestCaseUtils.*;
0N/Aimport static org.opends.server.protocols.internal.InternalClientConnection.*;
0N/Aimport static org.testng.Assert.*;
0N/A
0N/A/**
0N/A * A set of test cases for the Directory Server subentry password policy.
0N/A */
0N/A@SuppressWarnings("javadoc")
0N/Apublic class SubentryPasswordPolicyTestCase
0N/A extends CoreTestCase
0N/A{
0N/A private static final String SUFFIX = "dc=example,dc=com";
0N/A private static final String BASE = "ou=People," + SUFFIX;
0N/A
0N/A @BeforeClass
0N/A public void setUp() throws Exception
0N/A {
0N/A TestCaseUtils.startServer();
0N/A TestCaseUtils.clearBackend("userRoot");
0N/A
0N/A // Add suffix entry.
0N/A DN suffixDN = DN.valueOf(SUFFIX);
0N/A if (DirectoryServer.getEntry(suffixDN) == null)
0N/A {
0N/A createEntry(suffixDN);
0N/A }
0N/A
0N/A // Add base entry.
0N/A DN baseDN = DN.valueOf(BASE);
0N/A if (DirectoryServer.getEntry(baseDN) == null)
0N/A {
0N/A createEntry(baseDN);
3845N/A }
0N/A
0N/A TestCaseUtils.addEntry(
0N/A "dn: uid=rogasawara," + BASE,
0N/A "objectclass: top",
0N/A "objectclass: person",
0N/A "objectclass: organizationalPerson",
0N/A "objectclass: inetOrgPerson",
0N/A "uid: rogasawara",
0N/A "userpassword: password",
1879N/A "mail: rogasawara@example.com",
1879N/A "givenname: Rodney",
"sn: Ogasawara",
"cn: Rodney Ogasawara",
"title: Sales, Director"
);
}
private void createEntry(DN suffixDN) throws Exception
{
Entry e = StaticUtils.createEntry(suffixDN);
AddOperation addOperation = getRootConnection().processAdd(e);
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(e.getName()));
}
@AfterClass
public void cleanUp() throws Exception
{
TestCaseUtils.clearBackend("userRoot");
}
/**
* Retrieves a set of invalid configurations that cannot be used to
* initialize a password policy.
*
* @return A set of invalid configurations that cannot be used to
* initialize a password policy.
*
* @throws Exception If an unexpected problem occurs.
*/
@DataProvider(name = "invalidConfigs")
public Object[][] getInvalidConfigurations()
throws Exception
{
List<Entry> entries = TestCaseUtils.makeEntries(
"dn: cn=Temp Policy 1," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy 1",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: 1",
"pwdAttribute: userPassword",
"",
"dn: cn=Temp Policy 2," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy 2",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300 seconds",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"",
"dn: cn=Temp Policy 3," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy 3",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: noSuchAttribute",
"",
"dn: cn=Temp Policy 4," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy 4",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: -3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"",
"dn: cn=Temp Policy 5," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy 5",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 2147483648",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"",
"dn: cn=Temp Policy 6," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: pwdValidatorPolicy",
"objectClass: subentry",
"cn: Temp Policy 6",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"",
"dn: cn=Temp Policy 7," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: pwdValidatorPolicy",
"objectClass: subentry",
"cn: Temp Policy 7",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"ds-cfg-password-validator: Not_A_DN",
"",
"dn: cn=Temp Policy 8," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: pwdValidatorPolicy",
"objectClass: subentry",
"cn: Temp Policy 8",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: userPassword",
"ds-cfg-password-validator: cn=Unique Characters Inexistant,cn=Password Validators,cn=config"
);
Object[][] configEntries = new Object[entries.size()][1];
for (int i=0; i < configEntries.length; i++)
{
configEntries[i] = new Object[] { entries.get(i) };
}
return configEntries;
}
/**
* Ensures that password policy creation will fail when given
* an invalid configuration.
*
* @param e The entry containing an invalid password policy
* configuration.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(dataProvider = "invalidConfigs")
public void testInvalidConfigurations(Entry e)
throws Exception
{
AddOperation addOperation = getRootConnection().processAdd(e);
assertNotEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNull(DirectoryServer.getEntry(e.getName()));
}
/**
* Ensures that password policy constructed from subentry
* is active and has a valid configuration.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testValidConfiguration()
throws Exception
{
PasswordPolicy defaultPolicy =
DirectoryServer.getDefaultPasswordPolicy();
assertNotNull(defaultPolicy);
// The values are selected on a basis that they
// should differ from default password policy.
Entry policyEntry = TestCaseUtils.addEntry(
"dn: cn=Temp Policy," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: authPassword",
"pwdMinAge: 600",
"pwdMaxAge: 2147483647",
"pwdInHistory: 5",
"pwdExpireWarning: 864000",
"pwdGraceAuthNLimit: 3",
"pwdFailureCountInterval: 3600",
"pwdAllowUserChange: FALSE",
"pwdSafeModify: TRUE"
);
PasswordPolicy policy = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(
DN.valueOf("cn=Temp Policy," + SUFFIX));
assertNotNull(policy);
// Check all pwp attributes for correct values.
assertEquals(policy.getLockoutDuration(), 300);
assertEquals(policy.getLockoutFailureCount(), 3);
assertEquals(policy.isForceChangeOnReset(), true);
assertTrue(policy.getPasswordAttribute(
).getPrimaryName().equalsIgnoreCase(
"authPassword"));
assertEquals(policy.getMinPasswordAge(), 600);
assertEquals(policy.getMaxPasswordAge(), 2147483647);
assertEquals(policy.getPasswordHistoryCount(), 5);
assertEquals(policy.getPasswordExpirationWarningInterval(), 864000);
assertEquals(policy.getGraceLoginCount(), 3);
assertEquals(policy.getLockoutFailureExpirationInterval(), 3600);
assertEquals(policy.isAllowUserPasswordChanges(), false);
assertEquals(policy.isPasswordChangeRequiresCurrentPassword(), true);
/* Check the password validator attributes for correct values.
* The default unit-test config has a single Password validator which is
* enabled for the default password policy.
*/
Collection<PasswordValidator<?>> validators = policy.getPasswordValidators();
assertEquals(validators.size(), 1);
for (PasswordValidator<?> validator : validators)
{
assertTrue(validator.toString().startsWith("org.opends.server.extensions.TestPasswordValidator"));
}
// Make sure this policy applies to the test entry
// its supposed to target and that its the same
// policy object as previously tested.
Entry testEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=rogasawara," + BASE));
assertNotNull(testEntry);
AuthenticationPolicy statePolicy = AuthenticationPolicy.forUser(testEntry,
false);
assertNotNull(statePolicy);
assertEquals(policy, statePolicy);
// Make sure this policy is gone and default
// policy is in effect instead.
TestCaseUtils.deleteEntry(policyEntry.getName());
statePolicy = AuthenticationPolicy.forUser(testEntry, false);
assertNotNull(statePolicy);
assertEquals(defaultPolicy, statePolicy);
}
/**
* Ensures that password policy constructed from subentry,
* containing a password validator reference,
* is active and has a valid configuration.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testValidConfigurationWithValidator()
throws Exception
{
PasswordPolicy defaultPolicy =
DirectoryServer.getDefaultPasswordPolicy();
assertNotNull(defaultPolicy);
// The values are selected on a basis that they
// should differ from default password policy.
Entry policyEntry = TestCaseUtils.addEntry(
"dn: cn=Temp Validator Policy," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: pwdValidatorPolicy",
"objectClass: subentry",
"cn: Temp Policy",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: TRUE",
"pwdAttribute: authPassword",
"pwdMinAge: 600",
"pwdMaxAge: 2147483647",
"pwdInHistory: 5",
"pwdExpireWarning: 864000",
"pwdGraceAuthNLimit: 3",
"pwdFailureCountInterval: 3600",
"pwdAllowUserChange: FALSE",
"pwdSafeModify: TRUE",
"ds-cfg-password-validator: cn=Unique Characters,cn=Password Validators,cn=config",
"ds-cfg-password-validator: cn=Length-Based Password Validator,cn=Password Validators,cn=config"
);
PasswordPolicy policy = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(
DN.valueOf("cn=Temp Validator Policy," + SUFFIX));
assertNotNull(policy);
// Check the password validator attributes for correct values.
Collection<PasswordValidator<?>> validators = policy.getPasswordValidators();
assertFalse(validators.isEmpty());
assertEquals(validators.size(), 2);
// Make sure this policy applies to the test entry
// its supposed to target and that its the same
// policy object as previously tested.
Entry testEntry = DirectoryServer.getEntry(DN.valueOf("uid=rogasawara," + BASE));
assertNotNull(testEntry);
AuthenticationPolicy statePolicy = AuthenticationPolicy.forUser(testEntry, false);
assertNotNull(statePolicy);
assertEquals(policy, statePolicy);
// Make sure this policy is gone and default
// policy is in effect instead.
TestCaseUtils.deleteEntry(policyEntry.getName());
statePolicy = AuthenticationPolicy.forUser(testEntry, false);
assertNotNull(statePolicy);
assertEquals(defaultPolicy, statePolicy);
}
/**
* Ensures that password policy pwdPolicySubentry
* operational attribute reflects active password
* policy for a given user entry.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testPasswordPolicySubentryAttribute()
throws Exception
{
PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
assertNotNull(defaultPolicy);
Entry testEntry = DirectoryServer.getEntry(DN.valueOf("uid=rogasawara," + BASE));
assertNotNull(testEntry);
AttributeType attrType = DirectoryServer.getAttributeTypeOrNull("pwdpolicysubentry");
// Make sure that default policy is in effect
// for the user entry.
assertTrue(testEntry.hasAttribute(attrType));
assertTrue(testEntry.hasValue(attrType, null,
ByteString.valueOfUtf8(defaultPolicy.getDN().toString())));
// Add new subentry policy with the
// scope to apply to the user entry.
Entry policyEntry = TestCaseUtils.addEntry(
"dn: cn=Temp Policy," + SUFFIX,
"objectClass: top",
"objectClass: pwdPolicy",
"objectClass: subentry",
"cn: Temp Policy",
"subtreeSpecification: { base \"ou=people\" }",
"pwdLockoutDuration: 300",
"pwdMaxFailure: 3",
"pwdMustChange: true",
"pwdAttribute: userPassword"
);
// Make sure just added policy is in effect.
testEntry = DirectoryServer.getEntry(DN.valueOf("uid=rogasawara," + BASE));
assertNotNull(testEntry);
assertTrue(testEntry.hasAttribute(attrType));
assertTrue(testEntry.hasValue(attrType, null, ByteString.valueOfUtf8("cn=Temp Policy," + SUFFIX)));
// Remove subentry policy and make sure
// default policy is in effect again.
TestCaseUtils.deleteEntry(policyEntry.getName());
testEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=rogasawara," + BASE));
assertNotNull(testEntry);
assertTrue(testEntry.hasAttribute(attrType));
assertTrue(testEntry.hasValue(attrType, null,
ByteString.valueOfUtf8(defaultPolicy.getDN().toString())));
}
}