mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
26.11.2009 591624adc1b6a24fc0f6293cbd4e1122df816ac3
Fix issue 3750 - Forcing a password change after admin reset causes unexpected behavior.
2 files modified
108 ■■■■ changed files
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java 22 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java 86 ●●●● patch | view | raw | blame | history
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;
          }
        }
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
  {