opends/src/server/org/opends/server/core/BindOperation.java
@@ -1263,7 +1263,8 @@ // Check to see if the user has a password. If not, then fail. // FIXME -- We need to have a way to enable/disable debugging. pwPolicyState = new PasswordPolicyState(userEntry, false, false); AttributeType pwType = pwPolicyState.getPasswordAttribute(); AttributeType pwType = pwPolicyState.getPolicy().getPasswordAttribute(); List<Attribute> pwAttr = userEntry.getAttribute(pwType); if ((pwAttr == null) || (pwAttr.isEmpty())) @@ -1378,7 +1379,8 @@ pwPolicyErrorType = PasswordPolicyErrorType.PASSWORD_EXPIRED; } int maxGraceLogins = pwPolicyState.getMaxAllowedGraceLogins(); int maxGraceLogins = pwPolicyState.getPolicy().getGraceLoginCount(); if ((maxGraceLogins > 0) && pwPolicyState.mayUseGraceLogin()) { List<Long> graceLoginTimes = pwPolicyState.getGraceLoginTimes(); @@ -1656,7 +1658,8 @@ setResultCode(ResultCode.INVALID_CREDENTIALS); setAuthFailureReason(msgID, message); int maxAllowedFailures = pwPolicyState.getMaxAllowedFailures(); int maxAllowedFailures = pwPolicyState.getPolicy().getLockoutFailureCount(); if (maxAllowedFailures > 0) { pwPolicyState.updateAuthFailureTimes(); @@ -1667,7 +1670,8 @@ AccountStatusNotificationType notificationType; int lockoutDuration = pwPolicyState.getLockoutDuration(); int lockoutDuration = pwPolicyState.getPolicy().getLockoutDuration(); if (lockoutDuration > 0) { notificationType = AccountStatusNotificationType. @@ -1893,7 +1897,8 @@ pwPolicyErrorType = PasswordPolicyErrorType.PASSWORD_EXPIRED; } int maxGraceLogins = pwPolicyState.getMaxAllowedGraceLogins(); int maxGraceLogins = pwPolicyState.getPolicy().getGraceLoginCount(); if ((maxGraceLogins > 0) && pwPolicyState.mayUseGraceLogin()) { List<Long> graceLoginTimes = @@ -2137,7 +2142,8 @@ if (saslHandler.isPasswordBased(saslMechanism)) { int maxAllowedFailures = pwPolicyState.getMaxAllowedFailures(); int maxAllowedFailures = pwPolicyState.getPolicy().getLockoutFailureCount(); if (maxAllowedFailures > 0) { pwPolicyState.updateAuthFailureTimes(); @@ -2150,7 +2156,8 @@ int msgID; String message; int lockoutDuration = pwPolicyState.getLockoutDuration(); int lockoutDuration = pwPolicyState.getPolicy().getLockoutDuration(); if (lockoutDuration > 0) { notificationType = AccountStatusNotificationType. opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -1277,7 +1277,8 @@ boolean enabledStateChanged = false; boolean wasLocked = false; int numPasswords; if (currentEntry.hasAttribute(pwPolicyState.getPasswordAttribute())) if (currentEntry.hasAttribute( pwPolicyState.getPolicy().getPasswordAttribute())) { // It may actually have more than one, but we can't tell the // difference if the values are encoded, and its enough for our @@ -1299,7 +1300,7 @@ for (Modification m : modifications) { if (m.getAttribute().getAttributeType().equals( pwPolicyState.getPasswordAttribute())) pwPolicyState.getPolicy().getPasswordAttribute())) { passwordChanged = true; if (! selfChange) @@ -1333,8 +1334,8 @@ pwPolicyState.clearGraceLoginTimes(); pwPolicyState.clearWarnedTime(); if (pwPolicyState.forceChangeOnAdd() || pwPolicyState.forceChangeOnReset()) if (pwPolicyState.getPolicy().forceChangeOnAdd() || pwPolicyState.getPolicy().forceChangeOnReset()) { pwPolicyState.setMustChangePassword(! selfChange); } @@ -1421,7 +1422,8 @@ // If the modification is updating the password attribute, then // perform any necessary password policy processing. This processing // should be skipped for synchronization operations. boolean isPassword = t.equals(pwPolicyState.getPasswordAttribute()); boolean isPassword = t.equals(pwPolicyState.getPolicy().getPasswordAttribute()); if (isPassword && (!(isSynchronizationOperation()))) { // If the attribute contains any options, then reject it. Passwords @@ -1440,7 +1442,8 @@ // If it's a self change, then see if that's allowed. if (selfChange && (! pwPolicyState.allowUserPasswordChanges())) if (selfChange && (! pwPolicyState.getPolicy().allowUserPasswordChanges())) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -1452,7 +1455,7 @@ // If we require secure password changes, then makes sure it's a // secure communication channel. if (pwPolicyState.requireSecurePasswordChanges() && if (pwPolicyState.getPolicy().requireSecurePasswordChanges() && (! clientConnection.isSecure())) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -1501,8 +1504,8 @@ // If there were multiple password values provided, then make // sure that's OK. if ((!isInternalOperation()) && (! pwPolicyState.allowMultiplePasswordValues()) && if (! isInternalOperation() && ! pwPolicyState.getPolicy().allowExpiredPasswordChanges() && (passwordsToAdd > 1)) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -1521,7 +1524,7 @@ if (pwPolicyState.passwordIsPreEncoded(v.getValue())) { if ((!isInternalOperation()) && ! pwPolicyState.allowPreEncodedPasswords()) ! pwPolicyState.getPolicy().allowPreEncodedPasswords()) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -1616,128 +1619,124 @@ appendErrorMessage(getMessage(msgID)); break modifyProcessing; } else boolean found = false; for (Attribute attr : attrList) { boolean found = false; for (Attribute attr : attrList) for (AttributeValue av : attr.getValues()) { for (AttributeValue av : attr.getValues()) if (pwPolicyState.getPolicy().usesAuthPasswordSyntax()) { if (pwPolicyState.usesAuthPasswordSyntax()) if (AuthPasswordSyntax.isEncoded(av.getValue())) { if (AuthPasswordSyntax.isEncoded(av.getValue())) try { try StringBuilder[] compoenents = AuthPasswordSyntax.decodeAuthPassword( av.getStringValue()); PasswordStorageScheme scheme = DirectoryServer. getAuthPasswordStorageScheme( compoenents[0].toString()); if (scheme != null) { StringBuilder[] compoenents = AuthPasswordSyntax.decodeAuthPassword( av.getStringValue()); PasswordStorageScheme scheme = DirectoryServer. getAuthPasswordStorageScheme( compoenents[0].toString()); if (scheme != null) if (scheme.authPasswordMatches( v.getValue(), compoenents[1].toString(), compoenents[2].toString())) { if (scheme.authPasswordMatches( v.getValue(), compoenents[1].toString(), compoenents[2].toString())) { encodedValues.add(av); found = true; } encodedValues.add(av); found = true; } } catch (DirectoryException de) { assert debugException(CLASS_NAME, "run", de); setResultCode(de.getResultCode()); int msgID = MSGID_MODIFY_CANNOT_DECODE_PW; appendErrorMessage(getMessage(msgID, de.getErrorMessage())); break modifyProcessing; } } else catch (DirectoryException de) { if (av.equals(v)) { encodedValues.add(v); found = true; } assert debugException(CLASS_NAME, "run", de); setResultCode(de.getResultCode()); int msgID = MSGID_MODIFY_CANNOT_DECODE_PW; appendErrorMessage( getMessage(msgID, de.getErrorMessage())); break modifyProcessing; } } else { if (UserPasswordSyntax.isEncoded(av.getValue())) if (av.equals(v)) { try encodedValues.add(v); found = true; } } } else { if (UserPasswordSyntax.isEncoded(av.getValue())) { try { String[] compoenents = UserPasswordSyntax.decodeUserPassword( av.getStringValue()); PasswordStorageScheme scheme = DirectoryServer.getPasswordStorageScheme( toLowerCase(compoenents[0])); if (scheme != null) { String[] compoenents = UserPasswordSyntax.decodeUserPassword( av.getStringValue()); PasswordStorageScheme scheme = DirectoryServer.getPasswordStorageScheme( toLowerCase( compoenents[0].toString())); if (scheme != null) if (scheme.passwordMatches( v.getValue(), new ASN1OctetString(compoenents[1]))) { if (scheme.passwordMatches( v.getValue(), new ASN1OctetString(compoenents[1]))) { encodedValues.add(av); found = true; } encodedValues.add(av); found = true; } } catch (DirectoryException de) { assert debugException(CLASS_NAME, "run", de); setResultCode(de.getResultCode()); int msgID = MSGID_MODIFY_CANNOT_DECODE_PW; appendErrorMessage(getMessage(msgID, de.getErrorMessage())); break modifyProcessing; } } else catch (DirectoryException de) { if (av.equals(v)) { encodedValues.add(v); found = true; } assert debugException(CLASS_NAME, "run", de); setResultCode(de.getResultCode()); int msgID = MSGID_MODIFY_CANNOT_DECODE_PW; appendErrorMessage(getMessage(msgID, de.getErrorMessage())); break modifyProcessing; } } else { if (av.equals(v)) { encodedValues.add(v); found = true; } } } } if (found) { if (currentPasswords == null) { currentPasswords = new LinkedList<AttributeValue>(); } currentPasswords.add(v); numPasswords--; } else { setResultCode(ResultCode.UNWILLING_TO_PERFORM); int msgID = MSGID_MODIFY_INVALID_PASSWORD; appendErrorMessage(getMessage(msgID)); break modifyProcessing; } currentPasswordProvided = true; } if (found) { if (currentPasswords == null) { currentPasswords = new LinkedList<AttributeValue>(); } currentPasswords.add(v); numPasswords--; } else { setResultCode(ResultCode.UNWILLING_TO_PERFORM); int msgID = MSGID_MODIFY_INVALID_PASSWORD; appendErrorMessage(getMessage(msgID)); break modifyProcessing; } currentPasswordProvided = true; } } @@ -2283,7 +2282,8 @@ { // If it was a self change, then see if the current password was // provided and handle accordingly. if (selfChange && pwPolicyState.requireCurrentPassword() && if (selfChange && pwPolicyState.getPolicy().requireCurrentPassword() && (! currentPasswordProvided)) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -2297,7 +2297,7 @@ // If this change would result in multiple password values, then see // if that's OK. if ((numPasswords > 1) && (! pwPolicyState.allowMultiplePasswordValues())) (! pwPolicyState.getPolicy().allowMultiplePasswordValues())) { setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -2308,7 +2308,8 @@ // If any of the password values should be validated, then do so now. if (selfChange || (! pwPolicyState.skipValidationForAdministrators())) if (selfChange || (! pwPolicyState.getPolicy().skipValidationForAdministrators())) { if (newPasswords != null) { opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Portions Copyright 2006 Sun Microsystems, Inc. * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server.core; @@ -717,7 +717,7 @@ * * @return The password policy associated with this state information. */ public PasswordPolicy getPasswordPolicy() public PasswordPolicy getPolicy() { assert debugEnter(CLASS_NAME, "getPasswordPolicy"); @@ -727,20 +727,6 @@ /** * Retrieves the user entry associated with this state information. * * @return The user entry associated with this state information. */ public Entry getUserEntry() { assert debugEnter(CLASS_NAME, "getUserEntry"); return userEntry; } /** * Retrieves the set of modifications that correspond to changes made in * password policy processing that may need to be applied to the user entry. * @@ -758,20 +744,6 @@ /** * Retrieves the attribute type used to hold user passwords. * * @return The attribute type used to hold user passwords. */ public AttributeType getPasswordAttribute() { assert debugEnter(CLASS_NAME, "getPasswordAttribute"); return passwordPolicy.getPasswordAttribute(); } /** * Retrieves the set of values for the password attribute from the user entry. * * @return The set of values for the password attribute from the user entry. @@ -810,173 +782,6 @@ /** * Indicates whether the associated password policy requires that password * changes be performed in a secure manner. * * @return <CODE>true</CODE> if the associated password policy requires that * password changes be performed in a secure manner, or * <CODE>false</CODE> if not. */ public boolean requireSecurePasswordChanges() { assert debugEnter(CLASS_NAME, "requireSecurePasswordChanges"); return passwordPolicy.requireSecurePasswordChanges(); } /** * Indicates whether the associated password policy allows multiple different * password values to be maintained. * * @return <CODE>true</CODE> if the associated password policy allows * multiple different password values to be maintained, or * <CODE>false</CODE> if it does not. */ public boolean allowMultiplePasswordValues() { assert debugEnter(CLASS_NAME, "allowMultiplePasswordValues"); return passwordPolicy.allowMultiplePasswordValues(); } /** * Indicates whether the associated password policy allows new passwords to be * provided in a pre-encoded form. * * @return <CODE>true</CODE> if the associated password policy allows new * passwords to be provided in a pre-encoded form, or * <CODE>false</CODE> if not. */ public boolean allowPreEncodedPasswords() { assert debugEnter(CLASS_NAME, "allowPreEncodedPasswords"); return passwordPolicy.allowPreEncodedPasswords(); } /** * Indicates whether the associated password policy allows end users to change * their own passwords. * * @return <CODE>true</CODE> if the associated password policy allows end * users to change their own passwords, or <CODE>false</CODE> if not. */ public boolean allowUserPasswordChanges() { assert debugEnter(CLASS_NAME, "allowUserPasswordChanges"); return passwordPolicy.allowUserPasswordChanges(); } /** * Indicates whether users will be required to provide their current password * when choosing a new one. * * @return <CODE>true</CODE> if users will be required to provide their * current password when choosing a new one, or <CODE>false</CODE> * if not. */ public boolean requireCurrentPassword() { assert debugEnter(CLASS_NAME, "requireCurrentPassword"); return passwordPolicy.requireCurrentPassword(); } /** * Indicates whether administrative password resets should be allowed to * bypass validity checks for the new password. * * @return <CODE>true</CODE> if administrative password resets should be * allowed to bypass validity checks for the new password, or * <CODE>false</CODE> if not. */ public boolean skipValidationForAdministrators() { assert debugEnter(CLASS_NAME, "skipValidationForAdministrators"); return passwordPolicy.skipValidationForAdministrators(); } /** * Indicates whether users should be required to change their passwords when * they first authenticate after their account has been added. * * @return <CODE>true</CODE> if users should be required to change their * passwords when they first authenticate after their account has * been added, or <CODE>false</CODE> if not. */ public boolean forceChangeOnAdd() { assert debugEnter(CLASS_NAME, "forceChangeOnAdd"); return passwordPolicy.forceChangeOnAdd(); } /** * Indicates whether users should be required to change their passwords after * they have been reset by an administrator. * * @return <CODE>true</CODE> if users should be required to change their * passwords after they have been reset by an administrator, or * <CODE>false</CODE> if not. */ public boolean forceChangeOnReset() { assert debugEnter(CLASS_NAME, "forceChangeOnReset"); return passwordPolicy.forceChangeOnReset(); } /** * Indicates whether user passwords will be allowed to expire even if the user * has never seen an expiration warning notification. * * @return <CODE>true</CODE> if user passwords will be allowed to expire even * if the user has never seen an expiration warning notification, or * <CODE>false</CODE> if they will always be guaranteed at least one * warning before the password expires. */ public boolean expirePasswordsWithoutWarning() { assert debugEnter(CLASS_NAME, "expirePasswordsWithoutWarning"); return passwordPolicy.expirePasswordsWithoutWarning(); } /** * Retrieves the time that the user's password was last changed. * * @return The time that the user's password was last changed. */ public long getPasswordChangedTime() { assert debugEnter(CLASS_NAME, "getPasswordChangedTime"); return passwordChangedTime; } /** * Retrieves time that this password policy state object was created. * * @return The time that this password policy state object was created. @@ -1593,22 +1398,6 @@ /** * Retrieves the maximum number of password failures that will be allowed * before a user account is locked. * * @return The maximum number of password failures that will be allowed * before a user account is locked, or zero if there is no maximum. */ public int getMaxAllowedFailures() { assert debugEnter(CLASS_NAME, "getMaxAllowedFailures"); return passwordPolicy.getLockoutFailureCount(); } /** * Indicates whether the associated user should be considered locked out as a * result of too many authentication failures. * @@ -1768,23 +1557,6 @@ /** * Retrieves the length of time in seconds that a user's account will be * locked due to failed attempts before it will be automatically unlocked. * * @return The length of time in seconds that a user's account will be * locked due to failed attempts before it will be automatically * unlocked, or zero if accounts will not be automatically unlocked. */ public int getLockoutDuration() { assert debugEnter(CLASS_NAME, "getLockoutDuration"); return passwordPolicy.getLockoutDuration(); } /** * Retrieves the length of time in seconds until the user's account is * automatically unlocked. This should only be called after calling * <CODE>lockedDueToFailures</CODE>. @@ -2397,6 +2169,13 @@ " to set the reset flag to " + mustChangePassword); } if (mustChangePassword == (this.mustChangePassword == ConditionResult.TRUE)){ return; // requested state matches current state } this.mustChangePassword = ConditionResult.inverseOf(this.mustChangePassword); AttributeType type = DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_RESET_REQUIRED_LC); @@ -2408,23 +2187,16 @@ if (mustChangePassword) { if (this.mustChangePassword == ConditionResult.TRUE) { return; } this.mustChangePassword = ConditionResult.TRUE; LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); values.add(new AttributeValue(type, String.valueOf(mustChangePassword))); values.add(new AttributeValue(type, String.valueOf(true))); Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_RESET_REQUIRED, values); ArrayList<Attribute> attrList = new ArrayList<Attribute>(1); attrList.add(a); if (updateEntry) { ArrayList<Attribute> attrList = new ArrayList<Attribute>(1); attrList.add(a); userEntry.putAttribute(type, attrList); } else @@ -2434,13 +2206,6 @@ } else { if (this.mustChangePassword == ConditionResult.FALSE) { return; } this.mustChangePassword = ConditionResult.FALSE; if (updateEntry) { userEntry.removeAttribute(type); @@ -2736,22 +2501,6 @@ /** * Indicates whether users will be allowed to change their passwords if they * are expired. * * @return <CODE>true</CODE> if users will be allowed to change their * passwords if they are expired, or <CODE>false</CODE> if not. */ public boolean allowExpiredPasswordChanges() { assert debugEnter(CLASS_NAME, "allowExpiredPasswordChanges"); return passwordPolicy.allowExpiredPasswordChanges(); } /** * Indicates whether the user's last password change was within the minimum * password age. * @@ -3170,22 +2919,6 @@ /** * Retrieves the maximum number of grace logins that the user will be allowed * according to the associated password policy. * * @return The maximum number of grace logins that the user will be allowed * according to the associated password policy. */ public int getMaxAllowedGraceLogins() { assert debugEnter(CLASS_NAME, "getMaxAllowedGraceLogins"); return passwordPolicy.getGraceLoginCount(); } /** * Retrieves the times that the user has authenticated to the server using a * grace login. * @@ -3680,23 +3413,6 @@ /** * Indicates whether the user's password is stored using the auth password * syntax or the user password syntax. * * @return <CODE>true</CODE> if the user's password is stored using the auth * password syntax, or <CODE>false</CODE> if it is stored using the * user password syntax. */ public boolean usesAuthPasswordSyntax() { assert debugEnter(CLASS_NAME, "usesAuthPasswordSyntax"); return passwordPolicy.usesAuthPasswordSyntax(); } /** * Indicates whether the provided password value is pre-encoded. * * @param passwordValue The value for which to make the determination. opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -592,7 +592,7 @@ // make sure that's OK. if (oldPassword == null) { if (selfChange && pwPolicyState.requireCurrentPassword()) if (selfChange && pwPolicyState.getPolicy().requireCurrentPassword()) { operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -637,7 +637,8 @@ // If it is a self password change and we don't allow that, then reject // the request. if (selfChange && (! pwPolicyState.allowUserPasswordChanges())) if (selfChange && (! pwPolicyState.getPolicy().allowUserPasswordChanges())) { if (pwPolicyRequested) { @@ -670,7 +671,7 @@ // If we require secure password changes and the connection isn't secure, // then reject the request. if (pwPolicyState.requireSecurePasswordChanges() && if (pwPolicyState.getPolicy().requireSecurePasswordChanges() && (! operation.getClientConnection().isSecure())) { if (oldPassword == null) @@ -728,7 +729,7 @@ // If the user's password is expired and it's a self-change request, then // see if that's OK. if ((selfChange && pwPolicyState.isPasswordExpired() && (! pwPolicyState.allowExpiredPasswordChanges()))) (! pwPolicyState.getPolicy().allowExpiredPasswordChanges()))) { if (pwPolicyRequested) { @@ -825,7 +826,7 @@ // by an internal operation or during synchronization, so we don't // need to check for those cases. isPreEncoded = true; if (! pwPolicyState.allowPreEncodedPasswords()) if (! pwPolicyState.getPolicy().allowPreEncodedPasswords()) { if (oldPassword == null) { @@ -847,7 +848,8 @@ } else { if (selfChange || (! pwPolicyState.skipValidationForAdministrators())) if (selfChange || (! pwPolicyState.getPolicy().skipValidationForAdministrators())) { HashSet<ByteString> clearPasswords; if (oldPassword == null) @@ -950,7 +952,7 @@ // If the current password was provided, then remove all matching values // from the user's entry and replace them with the new password. // Otherwise replace all password values. AttributeType attrType = pwPolicyState.getPasswordAttribute(); AttributeType attrType = pwPolicyState.getPolicy().getPasswordAttribute(); List<Modification> modList = new ArrayList<Modification>(); if (oldPassword != null) { @@ -959,7 +961,7 @@ pwPolicyState.getPasswordValues(); LinkedHashSet<AttributeValue> deleteValues = new LinkedHashSet<AttributeValue>(existingValues.size()); if (pwPolicyState.usesAuthPasswordSyntax()) if (pwPolicyState.getPolicy().usesAuthPasswordSyntax()) { for (AttributeValue v : existingValues) { @@ -1006,7 +1008,7 @@ UserPasswordSyntax.decodeUserPassword(v.getStringValue()); PasswordStorageScheme scheme = DirectoryServer.getPasswordStorageScheme( toLowerCase(components[0].toString())); toLowerCase(components[0])); if (scheme == null) { // The password is encoded using an unknown scheme. Remove it @@ -1078,7 +1080,8 @@ } else { pwPolicyState.setMustChangePassword(pwPolicyState.forceChangeOnReset()); pwPolicyState.setMustChangePassword( pwPolicyState.getPolicy().forceChangeOnReset()); } @@ -1121,7 +1124,7 @@ ModifyOperation modifyOperation = internalConnection.processModify(userDN, modList); ResultCode resultCode = modifyOperation.getResultCode(); if (resultCode != resultCode.SUCCESS) if (resultCode != ResultCode.SUCCESS) { operation.setResultCode(resultCode); operation.setErrorMessage(modifyOperation.getErrorMessage());