From 591624adc1b6a24fc0f6293cbd4e1122df816ac3 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 26 Jan 2009 13:11:18 +0000
Subject: [PATCH] Fix issue 3750 - Forcing a password change after admin reset causes unexpected behavior.
---
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java | 22 ++++++----
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java | 86 +++++++++++++++++++++++++++++++++++++------
2 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index dc83bc6..82d0f6e 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.workflowelement.localbackend;
@@ -282,6 +282,7 @@
* @throws DirectoryException If an unexpected problem occurs while applying
* the modification to the entry.
*/
+ @Override
public void addModification(Modification modification)
throws DirectoryException
{
@@ -529,15 +530,18 @@
}
- if ((! passwordChanged) && (! isInternalOperation()) &&
- pwPolicyState.mustChangePassword())
+ DN authzDN = getAuthorizationDN();
+ if ((!passwordChanged) && (!isInternalOperation())
+ && pwPolicyState.mustChangePassword())
{
- // The user will not be allowed to do anything else before the
- // password gets changed.
- pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(ERR_MODIFY_MUST_CHANGE_PASSWORD.get());
- break modifyProcessing;
+ if (authzDN != null && authzDN.equals(entryDN))
+ {
+ // The user did not attempt to change their password.
+ pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
+ setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+ appendErrorMessage(ERR_MODIFY_MUST_CHANGE_PASSWORD.get());
+ break modifyProcessing;
+ }
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java
index c481652..d54e352 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.controls;
@@ -33,6 +33,7 @@
import java.util.LinkedHashSet;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
@@ -653,18 +654,65 @@
+
/**
- * 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.
+ * Creates test data for testModifyMustChange.
*
- * @throws Exception If an unexpected problem occurs.
+ * Fields:
+ * <userDN> <entryDN> <changeAfterReset>
+ *
+ * @return Returns test data for testModifyMustChange.
*/
- @Test()
- public void testModifyMustChange()
+ @DataProvider(name = "testModifyMustChange")
+ public Object[][] createTestModifyMustChange() {
+ 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.
+ */
+ @Test(dataProvider="testModifyMustChange")
+ public void testModifyMustChange(String userDN, String entryDN, boolean changeAfterReset)
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
+ TestCaseUtils.addEntry(
+ "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");
+
TestCaseUtils.dsconfig(
"set-password-policy-prop",
"--policy-name", "Default Password Policy",
@@ -690,7 +738,7 @@
try
{
BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
- new ASN1OctetString("uid=test.user,o=test"), 3,
+ new ASN1OctetString(userDN), 3,
new ASN1OctetString("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
w.writeElement(message.encode());
@@ -705,7 +753,7 @@
"foo"));
ModifyRequestProtocolOp modifyRequest =
- new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+ new ModifyRequestProtocolOp(new ASN1OctetString(entryDN), mods);
ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>();
controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
@@ -716,7 +764,17 @@
message = LDAPMessage.decode(r.readElement().decodeAsSequence());
ModifyResponseProtocolOp modifyResponse =
message.getModifyResponseProtocolOp();
- assertFalse(modifyResponse.getResultCode() == LDAPResultCode.SUCCESS);
+
+ if (changeAfterReset)
+ {
+ assertEquals(modifyResponse.getResultCode(),
+ LDAPResultCode.UNWILLING_TO_PERFORM);
+ }
+ else
+ {
+ assertEquals(modifyResponse.getResultCode(),
+ LDAPResultCode.SUCCESS);
+ }
controls = message.getControls();
assertNotNull(controls);
@@ -729,8 +787,12 @@
{
PasswordPolicyResponseControl pwpControl =
PasswordPolicyResponseControl.decodeControl(c.getControl());
- assertEquals(pwpControl.getErrorType(),
- PasswordPolicyErrorType.CHANGE_AFTER_RESET);
+ if (changeAfterReset) {
+ assertEquals(pwpControl.getErrorType(),
+ PasswordPolicyErrorType.CHANGE_AFTER_RESET);
+ } else {
+ assertNull(pwpControl.getErrorType());
+ }
found = true;
}
}
@@ -759,7 +821,7 @@
*
* @throws Exception If an unexpected problem occurs.
*/
- @Test()
+ @Test
public void testModifyCannotChange()
throws Exception
{
--
Gitblit v1.10.0