@Test
 public void testNotUsername() {
   PasswordPolicy policy = new PasswordPolicy("notUsername");
   Assert.assertEquals(
       "invalidPasswordNotUsernameMessage", policy.validate("jdoe", "jdoe").getMessage());
   Assert.assertNull(policy.validate("jdoe", "ab&d1234"));
 }
 @Test(expected = IllegalStateException.class)
 public void noPasswordExpirationInMonth() {
   PasswordPolicy.builder()
       .maximumLength(0)
       .minimumDigit(0)
       .minimumLength(0)
       .minimumLowerCaseCharacter(0)
       .minimumSpecialCharacter(0)
       .minimumUpperCaseCharacter(0)
       .build();
 }
 @Test
 public void valid() {
   PasswordPolicy.builder()
       .maximumLength(0)
       .minimumDigit(0)
       .minimumLength(0)
       .minimumLowerCaseCharacter(0)
       .minimumSpecialCharacter(0)
       .minimumUpperCaseCharacter(0)
       .passwordExpirationInMonth(0)
       .build();
 }
  public boolean execute(CommandLine cmdLine) {
    ICustomerManager cm = m_container.getCustomerManager();
    List<String> domains = Collections.singletonList(ICustomerManager.EPA_CUSTOMER_DOMAIN);
    IIslandManager im = m_container.getIslandManager();
    int defaultIslandID = im.getDefaultIsland().getId();

    Customer cust =
        cm.createCustomer(
            ICustomerManager.EPA_CUSTOMER_NAME,
            "System", // fromAddress
            "System", // backendID
            "System", // templateID
            "System", // channel
            domains,
            "emsRootPW", // emsRootPassword
            false, // isPartialEnabled
            "System", // activeBrandKey
            "System", // externalID
            defaultIslandID,
            defaultIslandID,
            false);

    PasswordPolicy policy = new PasswordPolicy();
    policy.setUseStrongPasswords(true);
    cust.setPasswordPolicy(policy);
    cm.updateCustomers(Collections.singletonList(cust));

    IUserManager um = ManagementContainer.getInstance().getUserManager();
    UserAccount emsRoot = um.getUser("emsroot@" + ICustomerManager.EPA_CUSTOMER_DOMAIN);
    IAuthenticationManager am = ManagementContainer.getInstance().getAuthenticationManager();
    long seconds = 31556926; // Seconds in a year
    long time =
        System.currentTimeMillis() + (seconds * 100 * 1000L); // Lock the account for 100 years
    am.lockUserAccount(
        cust.getCustID(), emsRoot.getUserID(), "Locked from user details", "Unknown", time);

    return (cust != null);
  }
  @Test
  public void testDigits() {
    PasswordPolicy policy = new PasswordPolicy("digits");
    Assert.assertEquals(
        "invalidPasswordMinDigitsMessage", policy.validate("jdoe", "abcd").getMessage());
    Assert.assertArrayEquals(new Object[] {1}, policy.validate("jdoe", "abcd").getParameters());
    Assert.assertNull(policy.validate("jdoe", "abcd1"));

    policy = new PasswordPolicy("digits(2)");
    Assert.assertEquals(
        "invalidPasswordMinDigitsMessage", policy.validate("jdoe", "abcd1").getMessage());
    Assert.assertArrayEquals(new Object[] {2}, policy.validate("jdoe", "abcd1").getParameters());
    Assert.assertNull(policy.validate("jdoe", "abcd12"));
  }
  @Test
  public void testSpecialChars() {
    PasswordPolicy policy = new PasswordPolicy("specialChars");
    Assert.assertEquals(
        "invalidPasswordMinSpecialCharsMessage", policy.validate("jdoe", "abcd1234").getMessage());
    Assert.assertArrayEquals(new Object[] {1}, policy.validate("jdoe", "abcd1234").getParameters());
    Assert.assertNull(policy.validate("jdoe", "ab&d1234"));

    policy = new PasswordPolicy("specialChars(2)");
    Assert.assertEquals(
        "invalidPasswordMinSpecialCharsMessage", policy.validate("jdoe", "ab&d1234").getMessage());
    Assert.assertArrayEquals(new Object[] {2}, policy.validate("jdoe", "ab&d1234").getParameters());
    Assert.assertNull(policy.validate("jdoe", "ab&d-234"));
  }
  @Test
  public void testLength() {
    PasswordPolicy policy = new PasswordPolicy("length");
    Assert.assertEquals(
        "invalidPasswordMinLengthMessage", policy.validate("jdoe", "1234567").getMessage());
    Assert.assertArrayEquals(new Object[] {8}, policy.validate("jdoe", "1234567").getParameters());
    Assert.assertNull(policy.validate("jdoe", "12345678"));

    policy = new PasswordPolicy("length(4)");
    Assert.assertEquals(
        "invalidPasswordMinLengthMessage", policy.validate("jdoe", "123").getMessage());
    Assert.assertArrayEquals(new Object[] {4}, policy.validate("jdoe", "123").getParameters());
    Assert.assertNull(policy.validate("jdoe", "1234"));
  }
  @Test
  public void testUpperCase() {
    PasswordPolicy policy = new PasswordPolicy("upperCase");
    Assert.assertEquals(
        "invalidPasswordMinUpperCaseCharsMessage",
        policy.validate("jdoe", "abcd1234").getMessage());
    Assert.assertArrayEquals(new Object[] {1}, policy.validate("jdoe", "abcd1234").getParameters());
    Assert.assertNull(policy.validate("jdoe", "abCd1234"));

    policy = new PasswordPolicy("upperCase(2)");
    Assert.assertEquals(
        "invalidPasswordMinUpperCaseCharsMessage",
        policy.validate("jdoe", "abCd1234").getMessage());
    Assert.assertArrayEquals(new Object[] {2}, policy.validate("jdoe", "abCd1234").getParameters());
    Assert.assertNull(policy.validate("jdoe", "AbCd1234"));
  }
  @Test
  public void testComplex() {
    PasswordPolicy policy =
        new PasswordPolicy(
            "length(8) and digits(2) and lowerCase(2) and upperCase(2) and specialChars(2) and notUsername()");
    Assert.assertNotNull(policy.validate("jdoe", "12aaBB&"));
    Assert.assertNotNull(policy.validate("jdoe", "aaaaBB&-"));
    Assert.assertNotNull(policy.validate("jdoe", "12AABB&-"));
    Assert.assertNotNull(policy.validate("jdoe", "12aabb&-"));
    Assert.assertNotNull(policy.validate("jdoe", "12aaBBcc"));
    Assert.assertNotNull(policy.validate("12aaBB&-", "12aaBB&-"));

    Assert.assertNull(policy.validate("jdoe", "12aaBB&-"));
  }
  @Test
  public void testRegexPatterns() {
    PasswordPolicy policy = null;
    try {
      policy = new PasswordPolicy("regexPatterns");
      fail("Expected NullPointerEXception: Regex Pattern cannot be null.");
    } catch (NullPointerException e) {
      // Expected NPE as regex pattern is null.
    }

    try {
      policy = new PasswordPolicy("regexPatterns(*)");
      fail("Expected PatternSyntaxException: Regex Pattern cannot be null.");
    } catch (PatternSyntaxException e) {
      // Expected PSE as regex pattern(or any of its token) is not quantifiable.
    }

    try {
      policy = new PasswordPolicy("regexPatterns(*,**)");
      fail("Expected PatternSyntaxException: Regex Pattern cannot be null.");
    } catch (PatternSyntaxException e) {
      // Expected PSE as regex pattern(or any of its token) is not quantifiable.
    }

    // Fails to match one of the regex pattern
    policy = new PasswordPolicy("regexPatterns(jdoe,j*d)");
    Assert.assertEquals(
        "invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());

    //// Fails to match all of the regex patterns
    policy = new PasswordPolicy("regexPatterns(j*p,j*d,adoe)");
    Assert.assertEquals(
        "invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());

    policy = new PasswordPolicy("regexPatterns([a-z][a-z][a-z][a-z][0-9])");
    Assert.assertEquals(
        "invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());

    policy = new PasswordPolicy("regexPatterns(jdoe)");
    Assert.assertNull(policy.validate("jdoe", "jdoe"));

    policy = new PasswordPolicy("regexPatterns([a-z][a-z][a-z][a-z][0-9])");
    Assert.assertNull(policy.validate("jdoe", "jdoe0"));
  }
  /**
   * Validates a number of password policy state constraints for the user. This will be called
   * before the offered credentials are checked.
   *
   * @param userEntry The entry for the user that is authenticating.
   * @param saslHandler The SASL mechanism handler if this is a SASL bind, or {@code null} for a
   *     simple bind.
   * @throws DirectoryException If a problem occurs that should cause the bind to fail.
   */
  protected void checkUnverifiedPasswordPolicyState(
      Entry userEntry, SASLMechanismHandler<?> saslHandler) throws DirectoryException {
    PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState;
    PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();

    boolean isSASLBind = saslHandler != null;

    // If the password policy is configured to track authentication failures or
    // keep the last login time and the associated backend is disabled, then we
    // may need to reject the bind immediately.
    if ((policy.getStateUpdateFailurePolicy()
            == PasswordPolicyCfgDefn.StateUpdateFailurePolicy.PROACTIVE)
        && ((policy.getLockoutFailureCount() > 0)
            || ((policy.getLastLoginTimeAttribute() != null)
                && (policy.getLastLoginTimeFormat() != null)))
        && ((DirectoryServer.getWritabilityMode() == WritabilityMode.DISABLED)
            || (backend.getWritabilityMode() == WritabilityMode.DISABLED))) {
      // This policy isn't applicable to root users, so if it's a root
      // user then ignore it.
      if (!DirectoryServer.isRootDN(userEntry.getName())) {
        throw new DirectoryException(
            ResultCode.INVALID_CREDENTIALS,
            ERR_BIND_OPERATION_WRITABILITY_DISABLED.get(userEntry.getName()));
      }
    }

    // Check to see if the authentication must be done in a secure
    // manner.  If so, then the client connection must be secure.
    if (policy.isRequireSecureAuthentication() && !clientConnection.isSecure()) {
      if (isSASLBind) {
        if (!saslHandler.isSecure(saslMechanism)) {
          throw new DirectoryException(
              ResultCode.INVALID_CREDENTIALS,
              ERR_BIND_OPERATION_INSECURE_SASL_BIND.get(saslMechanism, userEntry.getName()));
        }
      } else {
        throw new DirectoryException(
            ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_INSECURE_SIMPLE_BIND.get());
      }
    }
  }
  public PasswordPolicy unmarshall(StaxUnmarshallerContext context) throws Exception {
    PasswordPolicy passwordPolicy = new PasswordPolicy();
    int originalDepth = context.getCurrentDepth();
    int targetDepth = originalDepth + 1;

    if (context.isStartOfDocument()) targetDepth += 1;

    while (true) {
      XMLEvent xmlEvent = context.nextEvent();
      if (xmlEvent.isEndDocument()) return passwordPolicy;

      if (xmlEvent.isAttribute() || xmlEvent.isStartElement()) {

        if (context.testExpression("MinimumPasswordLength", targetDepth)) {
          passwordPolicy.setMinimumPasswordLength(
              IntegerStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("RequireSymbols", targetDepth)) {
          passwordPolicy.setRequireSymbols(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("RequireNumbers", targetDepth)) {
          passwordPolicy.setRequireNumbers(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("RequireUppercaseCharacters", targetDepth)) {
          passwordPolicy.setRequireUppercaseCharacters(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("RequireLowercaseCharacters", targetDepth)) {
          passwordPolicy.setRequireLowercaseCharacters(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("AllowUsersToChangePassword", targetDepth)) {
          passwordPolicy.setAllowUsersToChangePassword(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("ExpirePasswords", targetDepth)) {
          passwordPolicy.setExpirePasswords(
              BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("MaxPasswordAge", targetDepth)) {
          passwordPolicy.setMaxPasswordAge(
              IntegerStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("PasswordReusePrevention", targetDepth)) {
          passwordPolicy.setPasswordReusePrevention(
              IntegerStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("HardExpiry", targetDepth)) {
          passwordPolicy.setHardExpiry(BooleanStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }
      } else if (xmlEvent.isEndElement()) {
        if (context.getCurrentDepth() < originalDepth) {
          return passwordPolicy;
        }
      }
    }
  }
  /**
   * 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.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    AttributeType attrType = DirectoryServer.getAttributeType("pwdpolicysubentry");

    // Make sure that default policy is in effect
    // for the user entry.
    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString())));

    // Add new subentry policy with the
    // scope to apply to the user entry.
    Entry policyEntry =
        TestCaseUtils.makeEntry(
            "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");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    // Make sure just added policy is in effect.
    testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, "cn=Temp Policy," + SUFFIX)));

    // Remove subentry policy and make sure
    // default policy is in effect again.
    TestCaseUtils.deleteEntry(policyEntry.getDN());

    testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString())));
  }
  /**
   * 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.makeEntry(
            "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");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    PasswordPolicy policy =
        (PasswordPolicy)
            DirectoryServer.getAuthenticationPolicy(
                DN.decode("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.decode("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.getDN());
    statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(defaultPolicy, statePolicy);
  }
  /**
   * 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.makeEntry(
            "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");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    PasswordPolicy policy =
        (PasswordPolicy)
            DirectoryServer.getAuthenticationPolicy(DN.decode("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.decode("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.getDN());
    statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(defaultPolicy, statePolicy);
  }
Example #16
0
  public static PasswordPolicySoap toSoapModel(PasswordPolicy model) {
    PasswordPolicySoap soapModel = new PasswordPolicySoap();

    soapModel.setPasswordPolicyId(model.getPasswordPolicyId());
    soapModel.setCompanyId(model.getCompanyId());
    soapModel.setUserId(model.getUserId());
    soapModel.setUserName(model.getUserName());
    soapModel.setCreateDate(model.getCreateDate());
    soapModel.setModifiedDate(model.getModifiedDate());
    soapModel.setDefaultPolicy(model.getDefaultPolicy());
    soapModel.setName(model.getName());
    soapModel.setDescription(model.getDescription());
    soapModel.setChangeable(model.getChangeable());
    soapModel.setChangeRequired(model.getChangeRequired());
    soapModel.setMinAge(model.getMinAge());
    soapModel.setCheckSyntax(model.getCheckSyntax());
    soapModel.setAllowDictionaryWords(model.getAllowDictionaryWords());
    soapModel.setMinAlphanumeric(model.getMinAlphanumeric());
    soapModel.setMinLength(model.getMinLength());
    soapModel.setMinLowerCase(model.getMinLowerCase());
    soapModel.setMinNumbers(model.getMinNumbers());
    soapModel.setMinSymbols(model.getMinSymbols());
    soapModel.setMinUpperCase(model.getMinUpperCase());
    soapModel.setRegex(model.getRegex());
    soapModel.setHistory(model.getHistory());
    soapModel.setHistoryCount(model.getHistoryCount());
    soapModel.setExpireable(model.getExpireable());
    soapModel.setMaxAge(model.getMaxAge());
    soapModel.setWarningTime(model.getWarningTime());
    soapModel.setGraceLimit(model.getGraceLimit());
    soapModel.setLockout(model.getLockout());
    soapModel.setMaxFailure(model.getMaxFailure());
    soapModel.setLockoutDuration(model.getLockoutDuration());
    soapModel.setRequireUnlock(model.getRequireUnlock());
    soapModel.setResetFailureCount(model.getResetFailureCount());
    soapModel.setResetTicketMaxAge(model.getResetTicketMaxAge());

    return soapModel;
  }
  /**
   * Performs the processing necessary for a simple bind operation.
   *
   * @return {@code true} if processing should continue for the operation, or {@code false} if not.
   * @throws DirectoryException If a problem occurs that should cause the bind operation to fail.
   */
  protected boolean processSimpleBind() throws DirectoryException {
    // See if this is an anonymous bind.  If so, then determine whether
    // to allow it.
    ByteString simplePassword = getSimplePassword();
    if (simplePassword == null || simplePassword.length() == 0) {
      return processAnonymousSimpleBind();
    }

    // See if the bind DN is actually one of the alternate root DNs
    // defined in the server.  If so, then replace it with the actual DN
    // for that user.
    DN actualRootDN = DirectoryServer.getActualRootBindDN(bindDN);
    if (actualRootDN != null) {
      bindDN = actualRootDN;
    }

    Entry userEntry;
    try {
      userEntry = backend.getEntry(bindDN);
    } catch (DirectoryException de) {
      logger.traceException(de);

      userEntry = null;

      if (de.getResultCode() == ResultCode.REFERRAL) {
        // Re-throw referral exceptions - these should be passed back
        // to the client.
        throw de;
      } else {
        // Replace other exceptions in case they expose any sensitive
        // information.
        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, de.getMessageObject());
      }
    }

    if (userEntry == null) {
      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_UNKNOWN_USER.get());
    } else {
      setUserEntryDN(userEntry.getName());
    }

    // Check to see if the user has a password. If not, then fail.
    // FIXME -- We need to have a way to enable/disable debugging.
    authPolicyState = AuthenticationPolicyState.forUser(userEntry, false);
    if (authPolicyState.isPasswordPolicy()) {
      // Account is managed locally.
      PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState;
      PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();

      AttributeType pwType = policy.getPasswordAttribute();
      List<Attribute> pwAttr = userEntry.getAttribute(pwType);
      if (pwAttr == null || pwAttr.isEmpty()) {
        throw new DirectoryException(
            ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_NO_PASSWORD.get());
      }

      // Perform a number of password policy state checks for the
      // non-authenticated user.
      checkUnverifiedPasswordPolicyState(userEntry, null);

      // Invoke pre-operation plugins.
      if (!invokePreOpPlugins()) {
        return false;
      }

      // Determine whether the provided password matches any of the stored
      // passwords for the user.
      if (pwPolicyState.passwordMatches(simplePassword)) {
        setResultCode(ResultCode.SUCCESS);

        checkVerifiedPasswordPolicyState(userEntry, null);

        if (DirectoryServer.lockdownMode()
            && !ClientConnection.hasPrivilege(userEntry, BYPASS_LOCKDOWN)) {
          throw new DirectoryException(
              ResultCode.INVALID_CREDENTIALS, ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
        }
        setAuthenticationInfo(
            new AuthenticationInfo(
                userEntry, getBindDN(), DirectoryServer.isRootDN(userEntry.getName())));

        // Set resource limits for the authenticated user.
        setResourceLimits(userEntry);

        // Perform any remaining processing for a successful simple
        // authentication.
        pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
        pwPolicyState.clearFailureLockout();

        if (isFirstWarning) {
          pwPolicyState.setWarnedTime();

          int numSeconds = pwPolicyState.getSecondsUntilExpiration();
          LocalizableMessage m = WARN_BIND_PASSWORD_EXPIRING.get(secondsToTimeString(numSeconds));

          pwPolicyState.generateAccountStatusNotification(
              AccountStatusNotificationType.PASSWORD_EXPIRING,
              userEntry,
              m,
              AccountStatusNotification.createProperties(
                  pwPolicyState, false, numSeconds, null, null));
        }

        if (isGraceLogin) {
          pwPolicyState.updateGraceLoginTimes();
        }

        pwPolicyState.setLastLoginTime();
      } else {
        setResultCode(ResultCode.INVALID_CREDENTIALS);
        setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());

        if (policy.getLockoutFailureCount() > 0) {
          generateAccountStatusNotificationForLockedBindAccount(userEntry, pwPolicyState);
        }
      }
    } else {
      // Check to see if the user is administratively disabled or locked.
      if (authPolicyState.isDisabled()) {
        throw new DirectoryException(
            ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_ACCOUNT_DISABLED.get());
      }

      // Invoke pre-operation plugins.
      if (!invokePreOpPlugins()) {
        return false;
      }

      if (authPolicyState.passwordMatches(simplePassword)) {
        setResultCode(ResultCode.SUCCESS);

        if (DirectoryServer.lockdownMode()
            && !ClientConnection.hasPrivilege(userEntry, BYPASS_LOCKDOWN)) {
          throw new DirectoryException(
              ResultCode.INVALID_CREDENTIALS, ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
        }
        setAuthenticationInfo(
            new AuthenticationInfo(
                userEntry, getBindDN(), DirectoryServer.isRootDN(userEntry.getName())));

        // Set resource limits for the authenticated user.
        setResourceLimits(userEntry);
      } else {
        setResultCode(ResultCode.INVALID_CREDENTIALS);
        setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());
      }
    }

    return true;
  }
  /**
   * Perform policy checks for accounts when the credentials are correct.
   *
   * @param userEntry The entry for the user that is authenticating.
   * @param saslHandler The SASL mechanism handler if this is a SASL bind, or {@code null} for a
   *     simple bind.
   * @throws DirectoryException If a problem occurs that should cause the bind to fail.
   */
  protected void checkVerifiedPasswordPolicyState(
      Entry userEntry, SASLMechanismHandler<?> saslHandler) throws DirectoryException {
    PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState;
    PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();

    boolean isSASLBind = saslHandler != null;

    // Check to see if the user is administratively disabled or locked.
    if (pwPolicyState.isDisabled()) {
      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_ACCOUNT_DISABLED.get());
    } else if (pwPolicyState.isAccountExpired()) {
      LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_EXPIRED.get();
      pwPolicyState.generateAccountStatusNotification(
          AccountStatusNotificationType.ACCOUNT_EXPIRED,
          userEntry,
          m,
          AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
    } else if (pwPolicyState.lockedDueToFailures()) {
      if (pwPolicyErrorType == null) {
        pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
      }

      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_ACCOUNT_FAILURE_LOCKED.get());
    } else if (pwPolicyState.lockedDueToIdleInterval()) {
      if (pwPolicyErrorType == null) {
        pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
      }

      LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_IDLE_LOCKED.get();
      pwPolicyState.generateAccountStatusNotification(
          AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED,
          userEntry,
          m,
          AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
    }

    // If it's a simple bind, or if it's a password-based SASL bind, then
    // perform a number of password-based checks.
    if (!isSASLBind || saslHandler.isPasswordBased(saslMechanism)) {
      // Check to see if the account is locked due to the maximum reset age.
      if (pwPolicyState.lockedDueToMaximumResetAge()) {
        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.ACCOUNT_LOCKED;
        }

        LocalizableMessage m = ERR_BIND_OPERATION_ACCOUNT_RESET_LOCKED.get();
        pwPolicyState.generateAccountStatusNotification(
            AccountStatusNotificationType.ACCOUNT_RESET_LOCKED,
            userEntry,
            m,
            AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
      }

      // Determine whether the password is expired, or whether the user
      // should be warned about an upcoming expiration.
      if (pwPolicyState.isPasswordExpired()) {
        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.PASSWORD_EXPIRED;
        }

        int maxGraceLogins = policy.getGraceLoginCount();
        if (maxGraceLogins > 0 && pwPolicyState.mayUseGraceLogin()) {
          List<Long> graceLoginTimes = pwPolicyState.getGraceLoginTimes();
          if (graceLoginTimes == null || graceLoginTimes.size() < maxGraceLogins) {
            isGraceLogin = true;
            mustChangePassword = true;

            if (pwPolicyWarningType == null) {
              pwPolicyWarningType = PasswordPolicyWarningType.GRACE_LOGINS_REMAINING;
              pwPolicyWarningValue = maxGraceLogins - (graceLoginTimes.size() + 1);
            }
          } else {
            LocalizableMessage m = ERR_BIND_OPERATION_PASSWORD_EXPIRED.get();

            pwPolicyState.generateAccountStatusNotification(
                AccountStatusNotificationType.PASSWORD_EXPIRED,
                userEntry,
                m,
                AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

            throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
          }
        } else {
          LocalizableMessage m = ERR_BIND_OPERATION_PASSWORD_EXPIRED.get();

          pwPolicyState.generateAccountStatusNotification(
              AccountStatusNotificationType.PASSWORD_EXPIRED,
              userEntry,
              m,
              AccountStatusNotification.createProperties(pwPolicyState, false, -1, null, null));

          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, m);
        }
      } else if (pwPolicyState.shouldWarn()) {
        int numSeconds = pwPolicyState.getSecondsUntilExpiration();

        if (pwPolicyWarningType == null) {
          pwPolicyWarningType = PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION;
          pwPolicyWarningValue = numSeconds;
        }

        isFirstWarning = pwPolicyState.isFirstWarning();
      }

      // Check to see if the user's password has been reset.
      if (pwPolicyState.mustChangePassword()) {
        mustChangePassword = true;

        if (pwPolicyErrorType == null) {
          pwPolicyErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
        }
      }
    }
  }