/** * 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); }
/** * 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; } } } }