@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); }
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; } } } }