From 5d0af207adc99bba2b4ed7d34670a2e3e4ae0d0f Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Mon, 12 Mar 2007 13:38:34 +0000
Subject: [PATCH] The following update to core.PasswordPolicyState.java, along with some small changes to consumers of its API are the result of a review in preparation for password policy state management extended operation (issue 579).
---
opendj-sdk/opends/src/server/org/opends/server/core/PasswordPolicyState.java | 3070 +++++++++++++++++++++++++---------------------------------
opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java | 1
opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java | 30
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java | 3
4 files changed, 1,337 insertions(+), 1,767 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
index 51909be..2c75910 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
@@ -1542,7 +1542,7 @@
pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
- pwPolicyState.clearAuthFailureTimes();
+ pwPolicyState.clearFailureLockout();
if (isFirstWarning)
{
@@ -1574,21 +1574,15 @@
setResultCode(ResultCode.INVALID_CREDENTIALS);
setAuthFailureReason(msgID, message);
- int maxAllowedFailures
- = pwPolicyState.getPolicy().getLockoutFailureCount();
- if (maxAllowedFailures > 0)
+ if (pwPolicyState.getPolicy().getLockoutFailureCount() > 0)
{
pwPolicyState.updateAuthFailureTimes();
- if (pwPolicyState.getAuthFailureTimes().size() >=
- maxAllowedFailures)
+ if (pwPolicyState.lockedDueToFailures())
{
- pwPolicyState.lockDueToFailures();
-
AccountStatusNotificationType notificationType;
- int lockoutDuration
- = pwPolicyState.getPolicy().getLockoutDuration();
- if (lockoutDuration > 0)
+ int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
+ if (lockoutDuration > -1)
{
notificationType = AccountStatusNotificationType.
ACCOUNT_TEMPORARILY_LOCKED;
@@ -2073,23 +2067,17 @@
if (saslHandler.isPasswordBased(saslMechanism))
{
- int maxAllowedFailures
- = pwPolicyState.getPolicy().getLockoutFailureCount();
- if (maxAllowedFailures > 0)
+ if (pwPolicyState.getPolicy().getLockoutFailureCount() > 0)
{
pwPolicyState.updateAuthFailureTimes();
- if (pwPolicyState.getAuthFailureTimes().size() >=
- maxAllowedFailures)
+ if (pwPolicyState.lockedDueToFailures())
{
- pwPolicyState.lockDueToFailures();
-
AccountStatusNotificationType notificationType;
int msgID;
String message;
- int lockoutDuration
- = pwPolicyState.getPolicy().getLockoutDuration();
- if (lockoutDuration > 0)
+ int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
+ if (lockoutDuration > -1)
{
notificationType = AccountStatusNotificationType.
ACCOUNT_TEMPORARILY_LOCKED;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
index 8623ba4..ea571a1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -1286,7 +1286,6 @@
// Update the password policy state attributes in the user's entry.
// If the modification fails, then these changes won't be applied.
pwPolicyState.setPasswordChangedTime();
- pwPolicyState.clearAuthFailureTimes();
pwPolicyState.clearFailureLockout();
pwPolicyState.clearGraceLoginTimes();
pwPolicyState.clearWarnedTime();
@@ -1297,7 +1296,7 @@
pwPolicyState.setMustChangePassword(! selfChange);
}
- if (pwPolicyState.getRequiredChangeTime() > 0)
+ if (pwPolicyState.getPolicy().getRequireChangeByTime() > 0)
{
pwPolicyState.setRequiredChangeTime();
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/PasswordPolicyState.java b/opendj-sdk/opends/src/server/org/opends/server/core/PasswordPolicyState.java
index c604154..e13717b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/PasswordPolicyState.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -85,106 +85,83 @@
{
-
- // Indicates whether to debug password policy processing performed wth this
- // state object.
- private boolean debug;
+ // The user entry with which this state information is associated.
+ private final Entry userEntry;
// Indicates whether the user entry itself should be updated or if the updates
// should be stored as modifications.
- private boolean updateEntry;
+ private final boolean updateEntry;
- // Indicates whether an expiration warning message should be sent if the
- // authentication is successful.
- private boolean sendExpirationWarning;
+ // Indicates whether to debug password policy processing performed wth this
+ // state object.
+ private final boolean debug;
- // Indicates whether a grace login will be used if the authentication is
- // successful.
- private boolean useGraceLogin;
+ // The string representation of the user's DN.
+ private final String userDNString;
+
+ // The password policy with which the account is associated.
+ private final PasswordPolicy passwordPolicy;
+
+ // The current time for use in all password policy calculations.
+ private final long currentTime;
+
+ // The time that the user's password was last changed.
+ private long passwordChangedTime = Long.MIN_VALUE;
// Indicates whether the user's account is expired.
- private ConditionResult isAccountExpired;
+ private ConditionResult isAccountExpired = ConditionResult.UNDEFINED;
// Indicates whether the user's account is disabled.
- private ConditionResult isDisabled;
+ private ConditionResult isDisabled = ConditionResult.UNDEFINED;
// Indicates whether the user's password is expired.
- private ConditionResult isPasswordExpired;
+ private ConditionResult isPasswordExpired = ConditionResult.UNDEFINED;
// Indicates whether the warning to send to the client would be the first
// warning for the user.
- private ConditionResult isFirstWarning;
+ private ConditionResult isFirstWarning = ConditionResult.UNDEFINED;
// Indicates whether the user's account is locked by the idle lockout.
- private ConditionResult isIdleLocked;
-
- // Indicates whether the user's account is locked by administrative reset.
- private ConditionResult isResetLocked;
+ private ConditionResult isIdleLocked = ConditionResult.UNDEFINED;
// Indicates whether the user may use a grace login if the password is expired
// and there are one or more grace logins remaining.
- private ConditionResult mayUseGraceLogin;
+ private ConditionResult mayUseGraceLogin = ConditionResult.UNDEFINED;
// Indicates whether the user's password must be changed.
- private ConditionResult mustChangePassword;
+ private ConditionResult mustChangePassword = ConditionResult.UNDEFINED;
// Indicates whether the user should be warned of an upcoming expiration.
- private ConditionResult shouldWarn;
-
- // The user entry with which this state information is associated.
- private Entry userEntry;
+ private ConditionResult shouldWarn = ConditionResult.UNDEFINED;
// The number of seconds until the user's account is automatically unlocked.
- private int secondsUntilUnlock;
-
- // The number of seconds until the user's password expires.
- private int secondsUntilExpiration;
-
- // The set of modifications that should be applied to the user's entry.
- private LinkedList<Modification> modifications;
+ private int secondsUntilUnlock = Integer.MIN_VALUE;
// The set of authentication failure times for this user.
- private List<Long> authFailureTimes;
+ private List<Long> authFailureTimes = null;
// The set of grace login times for this user.
- private List<Long> graceLoginTimes;
-
- // The time that the user's account was created.
- private long createTime;
-
- // The current time for use in all password policy calculations.
- private long currentTime;
+ private List<Long> graceLoginTimes = null;
// The time that the user's password should expire (or did expire).
- private long expirationTime;
+ private long expirationTime = Long.MIN_VALUE;
// The time that the user's entry was locked due to too many authentication
// failures.
- private long failureLockedTime;
-
- // The time that the user's entry was locked due to the idle lockout.
- private long idleLockedTime;
+ private long failureLockedTime = Long.MIN_VALUE;
// The time that the user last authenticated to the Directory Server.
- private long lastLoginTime;
-
- // The time that the user's password was last changed.
- private long passwordChangedTime;
+ private long lastLoginTime = Long.MIN_VALUE;
// The last required change time with which the user complied.
- private long requiredChangeTime;
+ private long requiredChangeTime = Long.MIN_VALUE;
// The time that the user was first warned about an upcoming expiration.
- private long warnedTime;
+ private long warnedTime = Long.MIN_VALUE;
- // The password policy with which the account is associated.
- private PasswordPolicy passwordPolicy;
-
- // The string representation of the current time.
- private String currentGeneralizedTime;
-
- // The string representation of the user's DN.
- private String userDNString;
+ // The set of modifications that should be applied to the user's entry.
+ private LinkedList<Modification> modifications
+ = new LinkedList<Modification>();
@@ -204,62 +181,37 @@
*/
public PasswordPolicyState(Entry userEntry, boolean updateEntry,
boolean debug)
- throws DirectoryException
+ throws DirectoryException
{
this.userEntry = userEntry;
this.updateEntry = updateEntry;
this.debug = debug;
- userDNString = userEntry.getDN().toString();
- passwordPolicy = getPasswordPolicyInternal();
- currentGeneralizedTime = TimeThread.getGeneralizedTime();
- currentTime = TimeThread.getTime();
- modifications = new LinkedList<Modification>();
- isDisabled = ConditionResult.UNDEFINED;
- isAccountExpired = ConditionResult.UNDEFINED;
- isPasswordExpired = ConditionResult.UNDEFINED;
- isFirstWarning = ConditionResult.UNDEFINED;
- isIdleLocked = ConditionResult.UNDEFINED;
- isResetLocked = ConditionResult.UNDEFINED;
- mayUseGraceLogin = ConditionResult.UNDEFINED;
- mustChangePassword = ConditionResult.UNDEFINED;
- shouldWarn = ConditionResult.UNDEFINED;
- expirationTime = Long.MIN_VALUE;
- failureLockedTime = Long.MIN_VALUE;
- idleLockedTime = Long.MIN_VALUE;
- lastLoginTime = Long.MIN_VALUE;
- requiredChangeTime = Long.MIN_VALUE;
- warnedTime = Long.MIN_VALUE;
- authFailureTimes = null;
- sendExpirationWarning = false;
- useGraceLogin = false;
- secondsUntilExpiration = Integer.MIN_VALUE;
- secondsUntilUnlock = Integer.MIN_VALUE;
-
-
- // Get the time that the user's account was created.
- AttributeType type =
- DirectoryServer.getAttributeType(OP_ATTR_CREATE_TIMESTAMP_LC);
- if (type == null)
- {
- type = DirectoryServer.getDefaultAttributeType(OP_ATTR_CREATE_TIMESTAMP);
- }
-
- createTime = getGeneralizedTime(type);
-
+ userDNString = userEntry.getDN().toString();
+ passwordPolicy = getPasswordPolicyInternal(this.userEntry, this.debug);
+ currentTime = TimeThread.getTime();
// Get the password changed time for the user.
- type = DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_CHANGED_TIME_LC);
+ AttributeType type
+ = DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_CHANGED_TIME_LC);
if (type == null)
{
type = DirectoryServer.getDefaultAttributeType(
- OP_ATTR_PWPOLICY_CHANGED_TIME);
+ OP_ATTR_PWPOLICY_CHANGED_TIME);
}
passwordChangedTime = getGeneralizedTime(type);
if (passwordChangedTime <= 0)
{
- passwordChangedTime = createTime;
+ // Get the time that the user's account was created.
+ AttributeType createTimeType
+ = DirectoryServer.getAttributeType(OP_ATTR_CREATE_TIMESTAMP_LC);
+ if (createTimeType == null)
+ {
+ createTimeType
+ = DirectoryServer.getDefaultAttributeType(OP_ATTR_CREATE_TIMESTAMP);
+ }
+ passwordChangedTime = getGeneralizedTime(createTimeType);
if (passwordChangedTime <= 0)
{
@@ -267,9 +219,8 @@
if (debug)
{
- debugWarning(
- "Could not determine password changed time " +
- "for user %s", userDNString);
+ debugWarning("Could not determine password changed time for user %s.",
+ userDNString);
}
}
}
@@ -278,42 +229,36 @@
/**
- * Retrieves the password policy for the user.
+ * Retrieves the password policy for the user. If the user entry contains the
+ * ds-pwp-password-policy-dn attribute (whether real or virtual), that
+ * password policy is returned, otherwise the default password policy is
+ * returned.
+ *
+ * @param userEntry The user entry.
+ * @param debug Indicates whether to enable debugging for the
+ * operations performed.
*
* @return The password policy for the user.
*
* @throws DirectoryException If a problem occurs while attempting to
* determine the password policy for the user.
*/
- private PasswordPolicy getPasswordPolicyInternal()
- throws DirectoryException
+ private static PasswordPolicy getPasswordPolicyInternal(Entry userEntry,
+ boolean debug)
+ throws DirectoryException
{
- // See if the user entry contains the ds-pwp-password-policy-dn attribute to
- // select a custom objectclass (whether real or virtual).
+ String userDNString = userEntry.getDN().toString();
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_POLICY_DN, true);
List<Attribute> attrList = userEntry.getAttribute(type);
- if ((attrList == null) || attrList.isEmpty())
+ if (attrList != null)
{
- // There is no policy subentry defined, so we'll use the default.
- if (debug)
+ for (Attribute a : attrList)
{
- if (debugEnabled())
- {
- debugInfo("Using the default password policy for user %s",
- userDNString);
- }
- }
+ if(a.getValues().isEmpty()) continue;
- return DirectoryServer.getDefaultPasswordPolicy();
- }
-
-
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
- {
+ AttributeValue v = a.getValues().iterator().next();
DN subentryDN;
try
{
@@ -328,11 +273,10 @@
if (debug)
{
- debugError(
- "Could not parse password policy subentry " +
- "DN %s for user %s: %s",
- v.getStringValue(), userDNString,
- stackTraceToSingleLineString(e));
+ debugError("Could not parse password policy subentry DN %s " +
+ "for user %s: %s",
+ v.getStringValue(), userDNString,
+ stackTraceToSingleLineString(e));
}
int msgID = MSGID_PWPSTATE_CANNOT_DECODE_SUBENTRY_VALUE_AS_DN;
@@ -347,9 +291,8 @@
{
if (debug)
{
- debugError(
- "Password policy subentry %s for user %s " +
- "is not defined in the Directory Server.",
+ debugError("Password policy subentry %s for user %s " +
+ "is not defined in the Directory Server.",
String.valueOf(subentryDN), userDNString);
}
@@ -357,33 +300,30 @@
String message = getMessage(msgID, userDNString,
String.valueOf(subentryDN));
throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(), message,
- msgID);
+ DirectoryServer.getServerErrorResultCode(), message,
+ msgID);
}
- else
+
+ if (debug)
{
- if (debug)
- {
if (debugEnabled())
{
- debugInfo("Using password policy subentry %s for user " +
- "%s.", String.valueOf(subentryDN), userDNString);
+ debugInfo("Using password policy subentry %s for user %s.",
+ String.valueOf(subentryDN), userDNString);
}
}
- return policy;
- }
+ return policy;
}
}
-
- // This shouldn't happen, but if it does then use the default.
+ // There is no policy subentry defined: use the default.
if (debug)
{
if (debugEnabled())
{
- debugInfo("Falling back to the default password policy for " +
- "user %s", userDNString);
+ debugInfo("Using the default password policy for user %s",
+ userDNString);
}
}
@@ -392,52 +332,52 @@
- /**
- * Retrieves the value of the specified attribute as a string.
- *
- * @param attributeType The attribute type whose value should be retrieved.
- *
- * @return The value of the specified attribute as a string, or
- * <CODE>null</CODE> if there is no such value.
- */
+ /**
+ * Retrieves the value of the specified attribute as a string.
+ *
+ * @param attributeType The attribute type whose value should be retrieved.
+ *
+ * @return The value of the specified attribute as a string, or
+ * <CODE>null</CODE> if there is no such value.
+ */
private String getValue(AttributeType attributeType)
{
+ String stringValue = null;
+
List<Attribute> attrList = userEntry.getAttribute(attributeType);
- if ((attrList == null) || attrList.isEmpty())
+ if (attrList != null)
{
- if (debug)
+ for (Attribute a : attrList)
+ {
+ if (a.getValues().isEmpty()) continue;
+
+ stringValue = a.getValues().iterator().next().getStringValue();
+ break ;
+ }
+ }
+
+ if (debug)
+ {
+ if (stringValue == null)
{
if (debugEnabled())
{
debugInfo("Returning null because attribute %s does not " +
- "exist in user entry %s", attributeType.getNameOrOID(),
- userDNString);
+ "exist in user entry %s",
+ attributeType.getNameOrOID(), userDNString);
}
}
-
- return null;
- }
-
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
+ else
{
- String stringValue = v.getStringValue();
-
- if (debug)
+ if (debugEnabled())
{
- if (debugEnabled())
- {
- debugInfo("Returning value %s for user %s", stringValue,
- userDNString);
- }
+ debugInfo("Returning value %s for user %s",
+ stringValue, userDNString);
}
-
- return stringValue;
}
}
- return null;
+ return stringValue;
}
@@ -457,31 +397,20 @@
private long getGeneralizedTime(AttributeType attributeType)
throws DirectoryException
{
+ long timeValue = -1 ;
+
List<Attribute> attrList = userEntry.getAttribute(attributeType);
- if ((attrList == null) || attrList.isEmpty())
+ if (attrList != null)
{
- if (debug)
+ for (Attribute a : attrList)
{
- if (debugEnabled())
- {
- debugInfo("Returning -1 because attribute %s does not " +
- "exist in user entry %s", attributeType.getNameOrOID(),
- userDNString);
- }
- }
+ if (a.getValues().isEmpty()) continue;
- return -1;
- }
-
-
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
- {
+ AttributeValue v = a.getValues().iterator().next();
try
{
- return GeneralizedTimeSyntax.decodeGeneralizedTimeValue(
- v.getNormalizedValue());
+ timeValue = GeneralizedTimeSyntax.decodeGeneralizedTimeValue(
+ v.getNormalizedValue());
}
catch (Exception e)
{
@@ -492,11 +421,10 @@
if (debug)
{
- debugWarning(
- "Unable to decode value %s for attribute " +
- "%s in user entry %s: %s",
- v.getStringValue(),
- attributeType.getNameOrOID(), userDNString);
+ debugWarning("Unable to decode value %s for attribute %s " +
+ "in user entry %s: %s",
+ v.getStringValue(), attributeType.getNameOrOID(),
+ userDNString, stackTraceToSingleLineString(e));
}
int msgID = MSGID_PWPSTATE_CANNOT_DECODE_GENERALIZED_TIME;
@@ -506,21 +434,25 @@
throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
message, msgID, e);
}
+ break ;
}
}
-
if (debug)
{
- if (debugEnabled())
+ if (timeValue == -1)
{
- debugInfo("Returning -1 for attribute %s in user entry %s " +
- "because all options have been exhausted.",
- attributeType.getNameOrOID(), userDNString);
+ if (debugEnabled())
+ {
+ debugInfo("Returning -1 because attribute %s does not " +
+ "exist in user entry %s",
+ attributeType.getNameOrOID(), userDNString);
+ }
}
+ // FIXME: else to be consistent...
}
- return -1;
+ return timeValue;
}
@@ -544,9 +476,46 @@
ArrayList<Long> timeValues = new ArrayList<Long>();
List<Attribute> attrList = userEntry.getAttribute(attributeType);
- if ((attrList == null) || attrList.isEmpty())
+ if (attrList != null)
{
- if (debug)
+ for (Attribute a : attrList)
+ {
+ for (AttributeValue v : a.getValues())
+ {
+ try
+ {
+ timeValues.add(GeneralizedTimeSyntax.decodeGeneralizedTimeValue(
+ v.getNormalizedValue()));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ if (debug)
+ {
+ debugWarning("Unable to decode value %s for attribute %s" +
+ "in user entry %s: %s",
+ v.getStringValue(), attributeType.getNameOrOID(),
+ userDNString, stackTraceToSingleLineString(e));
+ }
+
+ int msgID = MSGID_PWPSTATE_CANNOT_DECODE_GENERALIZED_TIME;
+ String message = getMessage(msgID, v.getStringValue(),
+ attributeType.getNameOrOID(),
+ userDNString, String.valueOf(e));
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID, e);
+ }
+ }
+ }
+ }
+
+ if (debug)
+ {
+ if (timeValues.isEmpty())
{
if (debugEnabled())
{
@@ -555,47 +524,7 @@
attributeType.getNameOrOID(), userDNString);
}
}
-
- return timeValues;
}
-
-
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
- {
- try
- {
- timeValues.add(GeneralizedTimeSyntax.decodeGeneralizedTimeValue(
- v.getNormalizedValue()));
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "Unable to decode value %s for attribute " +
- "%s in user entry %s: %s",
- v.getStringValue(),
- attributeType.getNameOrOID(),
- userDNString, e);
- }
-
- int msgID = MSGID_PWPSTATE_CANNOT_DECODE_GENERALIZED_TIME;
- String message = getMessage(msgID, v.getStringValue(),
- attributeType.getNameOrOID(),
- userDNString, String.valueOf(e));
- throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
- message, msgID, e);
- }
- }
- }
-
return timeValues;
}
@@ -607,40 +536,26 @@
*
* @param attributeType The attribute type whose value should be parsed as a
* Boolean.
- * @param defaultValue The default value that should be used if the
- * specified attribute does not exist.
*
- * @return The requested Boolean value, or the default value if the specified
- * attribute does not exist with a Boolean value.
+ * @return The attribute's value represented as a ConditionResult value, or
+ * ConditionResult.UNDEFINED if the specified attribute does not
+ * exist in the entry.
*
* @throws DirectoryException If the value cannot be decoded as a Boolean.
*/
- private boolean getBoolean(AttributeType attributeType, boolean defaultValue)
+ private ConditionResult getBoolean(AttributeType attributeType)
throws DirectoryException
{
List<Attribute> attrList = userEntry.getAttribute(attributeType);
- if ((attrList == null) || attrList.isEmpty())
+ if (attrList != null)
{
- if (debug)
+ for (Attribute a : attrList)
{
- if (debugEnabled())
- {
- debugInfo("Returning default of %b because attribute " +
- "%s does not exist in user entry %s",
- defaultValue, attributeType.getNameOrOID(),
- attributeType.getNameOrOID());
- }
- }
+ if (a.getValues().isEmpty()) continue;
- return defaultValue;
- }
+ String valueString
+ = toLowerCase(a.getValues().iterator().next().getStringValue());
-
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
- {
- String valueString = toLowerCase(v.getStringValue());
if (valueString.equals("true") || valueString.equals("yes") ||
valueString.equals("on") || valueString.equals("1"))
{
@@ -648,61 +563,58 @@
{
if (debugEnabled())
{
- debugInfo("Attribute %s resolves to true for user " +
- "entry %s", attributeType.getNameOrOID(), userDNString);
+ debugInfo("Attribute %s resolves to true for user entry %s",
+ attributeType.getNameOrOID(), userDNString);
}
}
- return true;
+ return ConditionResult.TRUE;
}
- else if (valueString.equals("false") || valueString.equals("no") ||
+
+ if (valueString.equals("false") || valueString.equals("no") ||
valueString.equals("off") || valueString.equals("0"))
{
if (debug)
{
if (debugEnabled())
{
- debugInfo("Attribute %s resolves to false for user " +
- "entry %s", attributeType.getNameOrOID(), userDNString);
+ debugInfo("Attribute %s resolves to false for user entry %s",
+ attributeType.getNameOrOID(), userDNString);
}
}
- return false;
+ return ConditionResult.FALSE;
}
- else
+
+ if (debug)
{
- if (debug)
- {
- debugError(
- "Unable to resolve value %s for attribute " +
- "%s in user entry %us as a Boolean.",
+ debugError("Unable to resolve value %s for attribute %s " +
+ "in user entry %s as a Boolean.",
valueString, attributeType.getNameOrOID(),
userDNString);
- }
-
- int msgID = MSGID_PWPSTATE_CANNOT_DECODE_BOOLEAN;
- String message = getMessage(msgID, v.getStringValue(),
- attributeType.getNameOrOID(),
- userDNString);
- throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
- message, msgID);
}
+
+ int msgID = MSGID_PWPSTATE_CANNOT_DECODE_BOOLEAN;
+ String message = getMessage(msgID, valueString,
+ attributeType.getNameOrOID(),
+ userDNString);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID);
}
}
-
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning default of %b for attribute %s in " +
- "user entry %s because all options have been " +
- "exhausted.", defaultValue, attributeType.getNameOrOID(),
- userDNString);
+ debugInfo("Returning %s because attribute %s does not exist " +
+ "in user entry %s",
+ ConditionResult.UNDEFINED.toString(),
+ attributeType.getNameOrOID(), userDNString);
}
}
- return defaultValue;
+ return ConditionResult.UNDEFINED;
}
@@ -720,21 +632,6 @@
/**
- * Retrieves the set of modifications that correspond to changes made in
- * password policy processing that may need to be applied to the user entry.
- *
- * @return The set of modifications that correspond to changes made in
- * password policy processing that may need to be applied to the user
- * entry.
- */
- public LinkedList<Modification> getModifications()
- {
- return modifications;
- }
-
-
-
- /**
* 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.
@@ -743,9 +640,14 @@
{
List<Attribute> attrList =
userEntry.getAttribute(passwordPolicy.getPasswordAttribute());
- for (Attribute a : attrList)
+ if (attrList != null)
{
- return a.getValues();
+ for (Attribute a : attrList)
+ {
+ if (a.getValues().isEmpty()) continue;
+
+ return a.getValues();
+ }
}
return new LinkedHashSet<AttributeValue>(0);
@@ -754,47 +656,6 @@
/**
- * Indicates whether the associated password policy requires that
- * authentication be performed in a secure manner.
- *
- * @return <CODE>true</CODE> if the associated password policy requires that
- * authentication be performed in a secure manner, or
- * <CODE>false</CODE> if not.
- */
- public boolean requireSecureAuthentication()
- {
- return passwordPolicy.requireSecureAuthentication();
- }
-
-
-
- /**
- * Retrieves time that this password policy state object was created.
- *
- * @return The time that this password policy state object was created.
- */
- public long getCurrentTime()
- {
- return currentTime;
- }
-
-
-
- /**
- * Retrieves the generalized time representation of the time that this
- * password policy state object was created.
- *
- * @return The generalized time representation of the time that this
- * password policy state object was created.
- */
- public String getCurrentGeneralizedTime()
- {
- return currentGeneralizedTime;
- }
-
-
-
- /**
* Sets a new value for the password changed time equal to the current time.
*/
public void setPasswordChangedTime()
@@ -808,6 +669,8 @@
}
}
+ // passwordChangedTime is computed in the constructor from values in the
+ // entry.
if (passwordChangedTime != currentTime)
{
passwordChangedTime = currentTime;
@@ -850,87 +713,71 @@
*/
public boolean isDisabled()
{
- if ((isDisabled == null) || (isDisabled == ConditionResult.UNDEFINED))
- {
- AttributeType type =
- DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_DISABLED, true);
- try
- {
- if (getBoolean(type, false))
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("User %s is administratively disabled.", userDNString);
- }
- }
-
- isDisabled = ConditionResult.TRUE;
- return true;
- }
- else
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("User %s is not administratively disabled.",
- userDNString);
- }
- }
-
- isDisabled = ConditionResult.FALSE;
- return false;
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "User %s is considered administratively disabled " +
- "because an error occurred while attempting to make " +
- "the determination: %s.",
- userDNString, stackTraceToSingleLineString(e));
- }
-
- isDisabled = ConditionResult.TRUE;
- return true;
- }
- }
-
- if (isDisabled == ConditionResult.FALSE)
+ if (isDisabled != ConditionResult.UNDEFINED)
{
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning stored result of false for user %s",
- userDNString);
+ debugInfo("Returning stored result of %b for user %s",
+ (isDisabled == ConditionResult.TRUE), userDNString);
}
}
- return false;
+ return isDisabled == ConditionResult.TRUE;
}
- else
+
+ AttributeType type =
+ DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_DISABLED, true);
+ try
{
+ isDisabled = getBoolean(type);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ isDisabled = ConditionResult.TRUE;
if (debug)
{
- if (debugEnabled())
- {
- debugInfo("Returning stored result of true for user %s",
- userDNString);
- }
+ debugWarning("User %s is considered administratively disabled " +
+ "because an error occurred while attempting to make " +
+ "the determination: %s.",
+ userDNString, stackTraceToSingleLineString(e));
}
return true;
}
+
+ if (isDisabled == ConditionResult.UNDEFINED)
+ {
+ isDisabled = ConditionResult.FALSE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("User %s is not administratively disabled since the" +
+ " attribute \"%s\" is not present in the entry.",
+ userDNString, OP_ATTR_ACCOUNT_DISABLED);
+ }
+ }
+ return false;
+ }
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("User %s %s administratively disabled.",
+ userDNString,
+ ((isDisabled == ConditionResult.TRUE) ? " is" : " is not"));
+ }
+ }
+
+ return isDisabled == ConditionResult.TRUE;
}
@@ -954,27 +801,27 @@
}
+ if (isDisabled == isDisabled())
+ {
+ return; // requested state matches current state
+ }
+
+ this.isDisabled = ConditionResult.inverseOf(this.isDisabled);
+
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_DISABLED, true);
- LinkedHashSet<AttributeValue> values;
if (isDisabled)
{
- if (this.isDisabled == ConditionResult.TRUE)
- {
- return;
- }
-
- this.isDisabled = ConditionResult.TRUE;
- values = new LinkedHashSet<AttributeValue>(1);
- values.add(new AttributeValue(type, String.valueOf(isDisabled)));
-
+ LinkedHashSet<AttributeValue> values
+ = new LinkedHashSet<AttributeValue>(1);
+ values.add(new AttributeValue(type, String.valueOf(true)));
Attribute a = new Attribute(type, OP_ATTR_ACCOUNT_DISABLED, 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
@@ -984,15 +831,7 @@
}
else
{
- if (this.isDisabled == ConditionResult.FALSE)
- {
- return;
- }
-
- this.isDisabled = ConditionResult.FALSE;
- values = new LinkedHashSet<AttributeValue>(1);
- values.add(new AttributeValue(type, String.valueOf(isDisabled)));
-
+ // erase
if (updateEntry)
{
userEntry.removeAttribute(type);
@@ -1015,252 +854,250 @@
*/
public boolean isAccountExpired()
{
- if ((isAccountExpired == null) ||
- (isAccountExpired == ConditionResult.UNDEFINED))
+ if (isAccountExpired != ConditionResult.UNDEFINED)
{
- AttributeType type =
- DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_EXPIRATION_TIME,
- true);
- try
- {
- long expirationTime = getGeneralizedTime(type);
- if (expirationTime < 0)
- {
- // The user doesn't have an expiration time in their entry, so it
- // can't be expired.
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("The account for user %s is not expired because " +
- "there is no expiration time in the user's entry.",
- userDNString);
- }
- }
-
- isAccountExpired = ConditionResult.FALSE;
- return false;
- }
- else if (expirationTime > currentTime)
- {
- // The user does have an expiration time, but it hasn't arrived yet.
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("The account for user %s is not expired because the " +
- "expiration time has not yet arrived.", userDNString);
- }
- }
-
- isAccountExpired = ConditionResult.FALSE;
- return false;
- }
- else
- {
- // The user does have an expiration time, and it is in the past.
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("The account for user %s is expired because the " +
- "expiration time in that account has passed.", userDNString);
- }
- }
-
- isAccountExpired = ConditionResult.TRUE;
- return true;
- }
- }
- catch (Exception e)
+ if(debug)
{
if (debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e);
+ debugInfo("Returning stored result of %b for user %s",
+ (isAccountExpired == ConditionResult.TRUE), userDNString);
}
+ }
- if (debug)
- {
- debugWarning(
- "User %s is considered to have an expired account " +
- "because an error occurred while attempting to make " +
- "the determination: %s.",
+ return isAccountExpired == ConditionResult.TRUE;
+ }
+
+ AttributeType type =
+ DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_EXPIRATION_TIME,
+ true);
+
+ long expirationTime;
+ try
+ {
+ expirationTime = getGeneralizedTime(type);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ isAccountExpired = ConditionResult.TRUE;
+ if (debug)
+ {
+ debugWarning("User %s is considered to have an expired account " +
+ "because an error occurred while attempting to make " +
+ "the determination: %s.",
userDNString, stackTraceToSingleLineString(e));
- }
-
- isAccountExpired = ConditionResult.TRUE;
- return true;
- }
- }
-
-
- if (isAccountExpired == ConditionResult.FALSE)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning stored result of false for user %s",
- userDNString);
- }
- }
-
- return false;
- }
- else
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning stored result of true for user %s",
- userDNString);
- }
}
return true;
}
+
+ if (expirationTime > currentTime)
+ {
+ // The user does have an expiration time, but it hasn't arrived yet.
+ isAccountExpired = ConditionResult.FALSE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("The account for user %s is not expired because the " +
+ "expiration time has not yet arrived.", userDNString);
+ }
+ }
+ }
+ else if (expirationTime >= 0)
+ {
+ // The user does have an expiration time, and it is in the past.
+ isAccountExpired = ConditionResult.TRUE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("The account for user %s is expired because the " +
+ "expiration time in that account has passed.", userDNString);
+ }
+ }
+ }
+ else
+ {
+ // The user doesn't have an expiration time in their entry, so it
+ // can't be expired.
+ isAccountExpired = ConditionResult.FALSE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("The account for user %s is not expired because " +
+ "there is no expiration time in the user's entry.",
+ userDNString);
+ }
+ }
+ }
+
+ return isAccountExpired == ConditionResult.TRUE;
}
/**
* Retrieves the set of times of failed authentication attempts for the user.
+ * If authentication failure time expiration is enabled, and there are expired
+ * times in the entry, these times are removed from the instance field and an
+ * update is provided to delete those values from the entry.
*
- * @return The set of times of failed authentication attempts for the user.
+ * @return The set of times of failed authentication attempts for the user,
+ * which will be an empty list in the case of no valid (unexpired)
+ * times in the entry.
*/
- public List<Long> getAuthFailureTimes()
+ private List<Long> getAuthFailureTimes()
{
- if (authFailureTimes == null)
+ if (authFailureTimes != null)
{
- AttributeType type =
- DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_FAILURE_TIME_LC);
- if (type == null)
- {
- type = DirectoryServer.getDefaultAttributeType(
- OP_ATTR_PWPOLICY_FAILURE_TIME);
- }
-
- try
- {
- authFailureTimes = getGeneralizedTimes(type);
-
-
- // Remove any expired failures from the list.
- if (passwordPolicy.getLockoutFailureExpirationInterval() > 0)
- {
- LinkedHashSet<AttributeValue> values = null;
-
- long expirationTime = currentTime -
- (passwordPolicy.getLockoutFailureExpirationInterval()*1000L);
- Iterator<Long> iterator = authFailureTimes.iterator();
- while (iterator.hasNext())
- {
- long l = iterator.next();
- if (l < expirationTime)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Removing expired auth failure time %d for user " +
- "%s", l, userDNString);
- }
- }
-
- iterator.remove();
-
- if (values == null)
- {
- values = new LinkedHashSet<AttributeValue>();
- }
-
- values.add(new AttributeValue(type,
- GeneralizedTimeSyntax.format(l)));
- }
- }
-
- if (values != null)
- {
- Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_FAILURE_TIME,
- values);
- ArrayList<Attribute> removeList = new ArrayList<Attribute>(1);
- removeList.add(a);
-
-
- if (authFailureTimes.isEmpty())
- {
- if (updateEntry)
- {
- userEntry.removeAttribute(type);
- }
- }
- else
- {
- LinkedHashSet<AttributeValue> keepValues =
- new LinkedHashSet<AttributeValue>(authFailureTimes.size());
- for (Long l : authFailureTimes)
- {
- keepValues.add(new AttributeValue(type,
- GeneralizedTimeSyntax.format(l)));
- }
-
- ArrayList<Attribute> keepList = new ArrayList<Attribute>(1);
- keepList.add(new Attribute(type, OP_ATTR_PWPOLICY_FAILURE_TIME,
- keepValues));
-
- if (updateEntry)
- {
- userEntry.putAttribute(type, keepList);
- }
- }
-
-
- if (! updateEntry)
- {
- modifications.add(new Modification(ModificationType.DELETE, a,
- true));
- }
- }
- }
- }
- catch (Exception e)
+ if(debug)
{
if (debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e);
+ debugInfo("Returning stored auth failure time list of %d " +
+ "elements for user %s" +
+ authFailureTimes.size(), userDNString);
}
+ }
- if (debug)
+ return authFailureTimes;
+ }
+
+ AttributeType type =
+ DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_FAILURE_TIME_LC);
+ if (type == null)
+ {
+ type = DirectoryServer.getDefaultAttributeType(
+ OP_ATTR_PWPOLICY_FAILURE_TIME);
+ }
+
+ try
+ {
+ authFailureTimes = getGeneralizedTimes(type);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ if (debug)
+ {
+ debugWarning("Error while processing auth failure times " +
+ "for user %s: %s",
+ userDNString, stackTraceToSingleLineString(e));
+ }
+
+ authFailureTimes = new ArrayList<Long>();
+
+ if (updateEntry)
+ {
+ userEntry.removeAttribute(type);
+ }
+ else
+ {
+ modifications.add(new Modification(ModificationType.REPLACE,
+ new Attribute(type), true));
+ }
+
+ return authFailureTimes;
+ }
+
+ if (authFailureTimes.isEmpty())
+ {
+ if (debug)
+ {
+ if (debugEnabled())
{
- debugWarning(
- "Error while processing auth failure times " +
- "for user %s: %s",
- userDNString,
- stackTraceToSingleLineString(e));
+ debugInfo("Returning an empty auth failure time list for user %s" +
+ " because the attribute is absent from the entry.",
+ userDNString);
}
+ }
- authFailureTimes = new ArrayList<Long>();
+ return authFailureTimes;
+ }
+ // Remove any expired failures from the list.
+ if (passwordPolicy.getLockoutFailureExpirationInterval() > 0)
+ {
+ LinkedHashSet<AttributeValue> valuesToRemove = null;
+
+ long expirationTime = currentTime -
+ (passwordPolicy.getLockoutFailureExpirationInterval() * 1000L);
+ Iterator<Long> iterator = authFailureTimes.iterator();
+ while (iterator.hasNext())
+ {
+ long l = iterator.next();
+ if (l < expirationTime)
+ {
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Removing expired auth failure time %d for user %s",
+ l, userDNString);
+ }
+ }
+
+ iterator.remove();
+
+ if (valuesToRemove == null)
+ {
+ valuesToRemove = new LinkedHashSet<AttributeValue>();
+ }
+
+ valuesToRemove.add(new AttributeValue(type,
+ GeneralizedTimeSyntax.format(l)));
+ }
+ }
+
+ if (valuesToRemove != null)
+ {
if (updateEntry)
{
- userEntry.removeAttribute(type);
+ if (authFailureTimes.isEmpty())
+ {
+ userEntry.removeAttribute(type);
+ }
+ else
+ {
+ LinkedHashSet<AttributeValue> keepValues =
+ new LinkedHashSet<AttributeValue>(authFailureTimes.size());
+ for (Long l : authFailureTimes)
+ {
+ keepValues.add(
+ new AttributeValue(type, GeneralizedTimeSyntax.format(l)));
+ }
+ ArrayList<Attribute> keepList = new ArrayList<Attribute>(1);
+ keepList.add(new Attribute(type, OP_ATTR_PWPOLICY_FAILURE_TIME,
+ keepValues));
+ userEntry.putAttribute(type, keepList);
+ }
}
else
{
- modifications.add(new Modification(ModificationType.REPLACE,
- new Attribute(type), true));
+ Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_FAILURE_TIME,
+ valuesToRemove);
+ modifications.add(new Modification(ModificationType.DELETE, a,
+ true));
}
}
}
-
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning auth failure time list of %d " +
- "elements for user %s" +
+ debugInfo("Returning auth failure time list of %d elements for user %s",
authFailureTimes.size(), userDNString);
}
}
@@ -1272,10 +1109,13 @@
/**
* Updates the set of authentication failure times to include the current
- * time.
+ * time. If the number of failures reaches the policy configuration limit,
+ * lock the account.
*/
public void updateAuthFailureTimes()
{
+ assert passwordPolicy.getLockoutFailureCount() > 0;
+
if (debug)
{
if (debugEnabled())
@@ -1287,6 +1127,7 @@
List<Long> failureTimes = getAuthFailureTimes();
+ // Note: failureTimes == this.authFailureTimes
long highestFailureTime = -1;
for (Long l : failureTimes)
{
@@ -1337,15 +1178,30 @@
{
modifications.add(new Modification(ModificationType.ADD, addAttr, true));
}
+
+ // Now check to see if there have been sufficient failures to lock the
+ // account.
+ if (passwordPolicy.getLockoutFailureCount() <= failureTimes.size())
+ {
+ setFailureLockedTime(highestFailureTime);
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Locking user account %s due to too many failures.",
+ userDNString);
+ }
+ }
+ }
}
/**
* Updates the user entry to remove any record of previous authentication
- * failures.
+ * failure times.
*/
- public void clearAuthFailureTimes()
+ private void clearAuthFailureTimes()
{
if (debug)
{
@@ -1361,7 +1217,8 @@
{
return;
}
- failureTimes.clear();
+
+ failureTimes.clear(); // Note: failureTimes == this.authFailureTimes
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_FAILURE_TIME_LC);
@@ -1383,206 +1240,68 @@
}
-
/**
- * Indicates whether the associated user should be considered locked out as a
- * result of too many authentication failures.
+ * Retrieves the time of an authentication failure lockout for the user.
*
- * @return <CODE>true</CODE> if the user is currently locked out due to too
- * many authentication failures, or <CODE>false</CODE> if not.
+ * @return The time of an authentication failure lockout for the user, or -1
+ * if no such time is present in the entry.
*/
- public boolean lockedDueToFailures()
+ private long getFailureLockedTime()
{
- int maxFailures = passwordPolicy.getLockoutFailureCount();
- if (maxFailures <= 0)
+ if (failureLockedTime != Long.MIN_VALUE)
{
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s because lockout due to " +
- "failures is not enabled.", userDNString);
- }
- }
-
- return false;
+ return failureLockedTime;
}
-
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_LOCKED_TIME_LC);
if (type == null)
{
type = DirectoryServer.getDefaultAttributeType(
- OP_ATTR_PWPOLICY_LOCKED_TIME);
+ OP_ATTR_PWPOLICY_LOCKED_TIME);
}
- // Get the locked time from the user's entry. If it's not there, then the
- // account is not locked.
- if (failureLockedTime == Long.MIN_VALUE)
+ try
{
- try
- {
- failureLockedTime = getGeneralizedTime(type);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "Returning true for user %s because an error occurred: %s",
- userDNString, stackTraceToSingleLineString(e));
- }
-
- return true;
- }
+ failureLockedTime = getGeneralizedTime(type);
}
-
- if (failureLockedTime <= 0)
- {
- // There is no failure locked time, but that doesn't mean that the
- // account isn't locked anyway due to the maximum number of failures
- // (which may happen in certain cases due to synchronization latency).
- List<Long> failureTimes = getAuthFailureTimes();
- if ((failureTimes != null) && (failureTimes.size() >= maxFailures))
- {
- // The account isn't locked but should be, so do so now.
- lockDueToFailures();
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Setting the lock for user " + userDNString +
- " because there were enough preexisting failures even " +
- "though there was no account locked time.");
- }
- }
-
- return true;
- }
-
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user because there is no locked " +
- "time.", userDNString);
- }
- }
-
- return false;
- }
-
- // There is a failure locked time, but it may be expired. See if that's the
- // case.
- if (passwordPolicy.getLockoutDuration() > 0)
- {
- long unlockTime = failureLockedTime +
- (1000L * passwordPolicy.getLockoutDuration());
- if (unlockTime > currentTime)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s because there is a locked " +
- "time and the lockout duration has not been reached.",
- userDNString);
- }
-
- secondsUntilUnlock = (int) (unlockTime - currentTime);
- }
-
- return true;
- }
- else
- {
- if (updateEntry)
- {
- userEntry.removeAttribute(type);
- }
- else
- {
- modifications.add(new Modification(ModificationType.REPLACE,
- new Attribute(type), true));
- }
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s " +
- "because the existing lockout has expired.", userDNString);
- }
- }
-
- return false;
- }
- }
- else
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s " +
- "because there is a locked time and no lockout duration.",
- userDNString);
- }
- }
-
- return true;
- }
- }
-
-
-
- /**
- * 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>.
- *
- * @return The length of time in seconds until the user's account is
- * automatically unlocked, or -1 if the account is not locked or the
- * lockout requires administrative action to clear.
- */
- public int getSecondsUntilUnlock()
- {
- if (secondsUntilUnlock < 0)
- {
- return -1;
- }
- else
- {
- return secondsUntilUnlock;
- }
- }
-
-
-
- /**
- * Updates the user account to indicate that it has been locked due to too
- * many authentication failures.
- */
- public void lockDueToFailures()
- {
- if (debug)
+ catch (Exception e)
{
if (debugEnabled())
{
- debugInfo("Locking user account %s due to too many failures.",
- userDNString);
+ debugCaught(DebugLogLevel.ERROR, e);
}
+
+ failureLockedTime = currentTime;
+ if (debug)
+ {
+ debugWarning("Returning current time for user %s because an error " +
+ "occurred: %s",
+ userDNString, stackTraceToSingleLineString(e));
+ }
+
+ return failureLockedTime;
}
- failureLockedTime = currentTime;
+ // An expired locked time is handled in lockedDueToFailures.
+ return failureLockedTime;
+ }
+
+
+
+ /**
+ Sets the failure lockout attribute in the entry to the requested time.
+
+ @param time The time to which to set the entry's failure lockout attribute.
+ */
+ private void setFailureLockedTime(final long time)
+ {
+ if (time == getFailureLockedTime())
+ {
+ return;
+ }
+
+ failureLockedTime = time;
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_LOCKED_TIME_LC);
@@ -1596,11 +1315,11 @@
values.add(new AttributeValue(type,
GeneralizedTimeSyntax.format(failureLockedTime)));
Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_LOCKED_TIME, 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
@@ -1612,24 +1331,26 @@
/**
- * Updates the user account to remove any record of a previous lockout due to
- * failed authentications.
+ * Updates the user entry to remove any record of previous authentication
+ * failure lockout.
*/
- public void clearFailureLockout()
+ private void clearFailureLockedTime()
{
if (debug)
{
if (debugEnabled())
{
- debugInfo("Clearing lockout failures for user %s", userDNString);
+ debugInfo("Clearing failure lockout time for user %s.", userDNString);
}
}
- if (! lockedDueToFailures())
+ if (-1L == getFailureLockedTime())
{
return;
}
+ failureLockedTime = -1L;
+
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_LOCKED_TIME_LC);
if (type == null)
@@ -1652,6 +1373,174 @@
/**
+ * Indicates whether the associated user should be considered locked out as a
+ * result of too many authentication failures. In the case of an expired
+ * lock-out, this routine produces the update to clear the lock-out attribute
+ * and the authentication failure timestamps.
+ * In case the failure lockout time is absent from the entry, but sufficient
+ * authentication failure timestamps are present in the entry, this routine
+ * produces the update to set the lock-out attribute.
+ *
+ * @return <CODE>true</CODE> if the user is currently locked out due to too
+ * many authentication failures, or <CODE>false</CODE> if not.
+ */
+ public boolean lockedDueToFailures()
+ {
+ // FIXME: Introduce a state field to cache the computed value of this
+ // method. Note that only a cached "locked" status can be returned due to
+ // the possibility of intervening updates to this.failureLockedTime by
+ // updateAuthFailureTimes.
+
+ // Check if the feature is enabled in the policy.
+ final int maxFailures = passwordPolicy.getLockoutFailureCount();
+ if (maxFailures <= 0)
+ {
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning false for user %s because lockout due to " +
+ "failures is not enabled.", userDNString);
+ }
+ }
+
+ return false;
+ }
+
+ // Get the locked time from the user's entry. If it is present and not
+ // expired, the account is locked. If it is absent, the failure timestamps
+ // must be checked, since failure timestamps sufficient to lock the
+ // account could be produced across the synchronization topology within the
+ // synchronization latency. Also, note that IETF
+ // draft-behera-ldap-password-policy-09 specifies "19700101000000Z" as
+ // the value to be set under a "locked until reset" regime; however, this
+ // implementation accepts the value as a locked entry, but observes the
+ // lockout expiration policy for all values including this one.
+ // FIXME: This "getter" is unusual in that it might produce an update to the
+ // entry in two cases. Does it make sense to factor the methods so that,
+ // e.g., an expired lockout is reported, and clearing the lockout is left to
+ // the caller?
+ if (getFailureLockedTime() < 0L)
+ {
+ // There was no locked time present in the entry; however, sufficient
+ // failure times might have accumulated to trigger a lockout.
+ if (getAuthFailureTimes().size() < maxFailures)
+ {
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning false for user %s because there is no " +
+ "locked time.", userDNString);
+ }
+ }
+
+ return false;
+ }
+
+ // The account isn't locked but should be, so do so now.
+ setFailureLockedTime(currentTime);// FIXME: set to max(failureTimes)?
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Locking user %s because there were enough existing " +
+ "failures even though there was no account locked time.",
+ userDNString);
+ }
+ }
+ // Fall through...
+ }
+
+ // There is a failure locked time, but it may be expired.
+ if (passwordPolicy.getLockoutDuration() > 0)
+ {
+ final long unlockTime = getFailureLockedTime() +
+ (1000L * passwordPolicy.getLockoutDuration());
+ if (unlockTime > currentTime)
+ {
+ secondsUntilUnlock = (int) (unlockTime - currentTime);
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning true for user %s because there is a locked " +
+ "time and the lockout duration has not been reached.",
+ userDNString);
+ }
+ }
+
+ return true;
+ }
+
+ // The lockout in the entry has expired...
+ clearFailureLockout();
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning false for user %s " +
+ "because the existing lockout has expired.", userDNString);
+ }
+ }
+
+ assert -1L == getFailureLockedTime();
+ return false;
+ }
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning true for user %s " +
+ "because there is a locked time and no lockout duration.",
+ userDNString);
+ }
+ }
+
+ assert -1L <= getFailureLockedTime();
+ return true;
+ }
+
+
+
+ /**
+ * 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>.
+ *
+ * @return The length of time in seconds until the user's account is
+ * automatically unlocked, or -1 if the account is not locked or the
+ * lockout requires administrative action to clear.
+ */
+ public int getSecondsUntilUnlock()
+ {
+ // secondsUntilUnlock is only set when failureLockedTime is present and
+ // PasswordPolicy.getLockoutDuration is enabled; hence it is not
+ // unreasonable to find secondsUntilUnlock uninitialized.
+ assert failureLockedTime != Long.MIN_VALUE;
+
+ return (secondsUntilUnlock < 0) ? -1 : secondsUntilUnlock;
+ }
+
+
+
+ /**
+ * Updates the user account to remove any record of a previous lockout due to
+ * failed authentications.
+ */
+ public void clearFailureLockout()
+ {
+ clearAuthFailureTimes();
+ clearFailureLockedTime();
+ }
+
+
+
+ /**
* Retrieves the time that the user last authenticated to the Directory
* Server.
*
@@ -1660,139 +1549,125 @@
*/
public long getLastLoginTime()
{
- if (lastLoginTime == Long.MIN_VALUE)
+ if (lastLoginTime != Long.MIN_VALUE)
{
- AttributeType type = passwordPolicy.getLastLoginTimeAttribute();
- String format = passwordPolicy.getLastLoginTimeFormat();
-
- if ((type == null) || (format == null))
+ if (debug)
{
- if (debug)
+ if (debugEnabled())
{
- if (debugEnabled())
- {
- debugInfo("Returning -1 for user %s because no last " +
- "login time will be maintained.", userDNString);
- }
+ debugInfo("Returning stored last login time of %d for user %s.",
+ lastLoginTime, userDNString);
}
-
- lastLoginTime = -1;
- return lastLoginTime;
}
- List<Attribute> attrList = userEntry.getAttribute(type);
- if ((attrList == null) || attrList.isEmpty())
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning -1 for user %s because no last " +
- "login time value exists.", userDNString);
- }
- }
+ return lastLoginTime;
+ }
- lastLoginTime = -1;
- return lastLoginTime;
+ // The policy configuration must be checked since the entry cannot be
+ // evaluated without both an attribute name and timestamp format.
+ AttributeType type = passwordPolicy.getLastLoginTimeAttribute();
+ String format = passwordPolicy.getLastLoginTimeFormat();
+
+ if ((type == null) || (format == null))
+ {
+ lastLoginTime = -1;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning -1 for user %s because no last login time " +
+ "will be maintained.", userDNString);
+ }
}
+ return lastLoginTime;
+ }
+
+ lastLoginTime = -1;
+ List<Attribute> attrList = userEntry.getAttribute(type);
+
+ if (attrList != null)
+ {
for (Attribute a : attrList)
{
- for (AttributeValue v : a.getValues())
+ if (a.getValues().isEmpty()) continue;
+
+ String valueString = a.getValues().iterator().next().getStringValue();
+
+ try
{
- String valueString = v.getStringValue();
- SimpleDateFormat dateFormat;
+ SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+ lastLoginTime = dateFormat.parse(valueString).getTime();
- try
- {
- dateFormat = new SimpleDateFormat(format);
- lastLoginTime = dateFormat.parse(valueString).getTime();
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning last login time of %s for user " +
- "%s decoded using current last login " +
- "time format.", lastLoginTime, userDNString);
- }
- }
-
- return lastLoginTime;
- }
- catch (Exception e)
+ if (debug)
{
if (debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- // This could mean that the last login time was encoded using a
- // previous format.
- for (String f : passwordPolicy.getPreviousLastLoginTimeFormats())
- {
- try
- {
- dateFormat = new SimpleDateFormat(f);
- lastLoginTime = dateFormat.parse(valueString).getTime();
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning last login time of %s for " +
- "user %s decoded using previous " +
- "last login time format of %s",
- lastLoginTime, userDNString, f);
- }
- }
-
- return lastLoginTime;
+ debugInfo("Returning last login time of %d for user %s" +
+ "decoded using current last login time format.",
+ lastLoginTime, userDNString);
}
- catch (Exception e2)
+ }
+
+ return lastLoginTime;
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ // This could mean that the last login time was encoded using a
+ // previous format.
+ for (String f : passwordPolicy.getPreviousLastLoginTimeFormats())
+ {
+ try
+ {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(f);
+ lastLoginTime = dateFormat.parse(valueString).getTime();
+
+ if (debug)
{
if (debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e2);
+ debugInfo("Returning last login time of %d for user %s" +
+ "decoded using previous last login time format of %s.",
+ lastLoginTime, userDNString, f);
}
}
+
+ return lastLoginTime;
}
-
-
- if (debug)
+ catch (Exception e2)
{
- debugWarning(
- "Returning -1 for user %s because the " +
- "last login time value %s could not " +
- "be parsed using any known format.",
- userDNString, valueString);
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
}
-
- lastLoginTime = -1;
- return lastLoginTime;
}
+
+ assert lastLoginTime == -1;
+ if (debug)
+ {
+ debugWarning("Returning -1 for user %s because the last login " +
+ "time value %s could not be parsed using any known format.",
+ userDNString, valueString);
+ }
+
+ return lastLoginTime;
}
}
-
-
- // We shouldn't get here.
- if (debug)
- {
- debugWarning(
- "Returning -1 for user %s because even though " +
- "there appears to be a last login time " +
- "value we couldn't decipher it.",
- userDNString);
- }
- return -1;
}
+ assert lastLoginTime == -1;
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning previously calculated last login time " +
- "of %s for user %s", lastLoginTime, userDNString);
+ debugInfo("Returning %d for user %s because no last " +
+ "login time value exists.", lastLoginTime, userDNString);
}
}
@@ -1829,10 +1704,9 @@
if (debug)
{
- debugWarning(
- "Unable to set last login time for user %s because an " +
- "error occurred: %s",
- userDNString, stackTraceToSingleLineString(e));
+ debugWarning("Unable to set last login time for user %s because an " +
+ "error occurred: %s",
+ userDNString, stackTraceToSingleLineString(e));
}
return;
@@ -1859,11 +1733,11 @@
values.add(new AttributeValue(type, timestamp));
Attribute a = new Attribute(type, type.getNameOrOID(), 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
@@ -1892,264 +1766,207 @@
*/
public boolean lockedDueToIdleInterval()
{
- if ((isIdleLocked == null) || (isIdleLocked == ConditionResult.UNDEFINED))
+ if (isIdleLocked != ConditionResult.UNDEFINED)
{
- if (passwordPolicy.getIdleLockoutInterval() <= 0)
+ if (debug)
{
- if (debug)
+ if (debugEnabled())
{
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s because no idle lockout " +
- "interval is defined.", userDNString);
- }
+ debugInfo("Returning stored result of %b for user %s",
+ (isIdleLocked == ConditionResult.TRUE), userDNString);
}
-
- isIdleLocked = ConditionResult.FALSE;
- return false;
}
- long lockTime = currentTime -
- (passwordPolicy.getIdleLockoutInterval() * 1000L);
- long lastLoginTime = getLastLoginTime();
- if (lastLoginTime > 0)
+ return isIdleLocked == ConditionResult.TRUE;
+ }
+
+ // Return immediately if this feature is disabled, since the feature is not
+ // responsible for any state attribute in the entry.
+ if (passwordPolicy.getIdleLockoutInterval() <= 0)
+ {
+ isIdleLocked = ConditionResult.FALSE;
+
+ if (debug)
{
- if (lastLoginTime > lockTime)
+ if (debugEnabled())
{
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s because the last login " +
- "time is in an acceptable window.", userDNString);
- }
- }
-
- isIdleLocked = ConditionResult.FALSE;
- return false;
+ debugInfo("Returning false for user %s because no idle lockout " +
+ "interval is defined.", userDNString);
}
- else
- {
- if (passwordChangedTime > lockTime)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user because the password " +
- "changed time is in an acceptable window.", userDNString);
- }
- }
+ }
- isIdleLocked = ConditionResult.FALSE;
- return false;
+ return false;
+ }
+
+ long lockTime = currentTime -
+ (1000L * passwordPolicy.getIdleLockoutInterval());
+ if(lockTime < 0) lockTime = 0;
+
+ long lastLoginTime = getLastLoginTime();
+ if (lastLoginTime > lockTime || passwordChangedTime > lockTime)
+ {
+ isIdleLocked = ConditionResult.FALSE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ StringBuilder reason = new StringBuilder();
+ if(lastLoginTime > lockTime)
+ {
+ reason.append("the last login time is in an acceptable window");
}
else
{
- if (debug)
+ if(lastLoginTime < 0)
{
- if (debugEnabled())
- {
- debugInfo("Returning true for user because neither last " +
- "login time nor password changed time are in an " +
- "acceptable window.", userDNString);
- }
+ reason.append("there is no last login time, but ");
}
-
- isIdleLocked = ConditionResult.TRUE;
- return true;
+ reason.append(
+ "the password changed time is in an acceptable window");
}
+ debugInfo("Returning false for user %s because %s.",
+ userDNString, reason.toString());
}
}
- else
- {
- if (passwordChangedTime < lockTime)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s because there is no last " +
- "login time and the password changed time is not in " +
- "an acceptable window.", userDNString);
- }
- }
-
- isIdleLocked = ConditionResult.TRUE;
- return true;
- }
- else
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s because there is no " +
- "last login time but the password changed time is in an " +
- "acceptable window.", userDNString);
- }
- }
-
- isIdleLocked = ConditionResult.FALSE;
- return false;
- }
- }
- }
-
-
- if (isIdleLocked == ConditionResult.TRUE)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning stored result of true for user %s",
- userDNString);
- }
- }
-
- return true;
}
else
{
+ isIdleLocked = ConditionResult.TRUE;
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning stored result of false for user %s",
- userDNString);
+ String reason = (lastLoginTime < 0)
+ ? "there is no last login time and the password " +
+ "changed time is not in an acceptable window"
+ : "neither last login time nor password " +
+ "changed time are in an acceptable window";
+ debugInfo("Returning true for user %s because %s.",
+ userDNString, reason);
}
}
-
- return false;
}
+
+ return isIdleLocked == ConditionResult.TRUE;
}
- /**
- * Indicates whether the user's password must be changed before any other
- * operation can be performed.
- *
- * @return <CODE>true</CODE> if the user's password must be changed before
- * any other operation can be performed.
- */
+/**
+* Indicates whether the user's password must be changed before any other
+* operation can be performed.
+*
+* @return <CODE>true</CODE> if the user's password must be changed before
+* any other operation can be performed.
+*/
public boolean mustChangePassword()
{
- // If the password policy doesn't use force change on add or force change on
- // reset, or if it forbits the user from changing their password, then this
- // must return false.
- if (! passwordPolicy.allowUserPasswordChanges())
- {
- return false;
- }
- else if (! (passwordPolicy.forceChangeOnAdd() ||
- passwordPolicy.forceChangeOnReset()))
- {
- return false;
- }
-
- if ((mustChangePassword == null) ||
- (mustChangePassword == ConditionResult.UNDEFINED))
- {
- AttributeType type =
- DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_RESET_REQUIRED_LC);
- if (type == null)
- {
- type = DirectoryServer.getDefaultAttributeType(
- OP_ATTR_PWPOLICY_RESET_REQUIRED);
- }
-
- try
- {
- boolean resetRequired = getBoolean(type, false);
- if (resetRequired)
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %", userDNString);
- }
- }
-
- mustChangePassword = ConditionResult.TRUE;
- return true;
- }
- else
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning false for user %s", userDNString);
- }
- }
-
- mustChangePassword = ConditionResult.FALSE;
- return false;
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s because an unexpected " +
- "error occurred: %s",
- userDNString, stackTraceToSingleLineString(e));
- }
- }
-
- mustChangePassword = ConditionResult.TRUE;
- return true;
- }
- }
-
-
- if (mustChangePassword == ConditionResult.TRUE)
+ if(mustChangePassword != ConditionResult.UNDEFINED)
{
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning stored result of true for user %s",
- userDNString);
+ debugInfo("Returning stored result of %b for user %s.",
+ (mustChangePassword == ConditionResult.TRUE), userDNString);
}
}
+ return mustChangePassword == ConditionResult.TRUE;
+ }
+
+ // If the password policy doesn't use force change on add or force change on
+ // reset, or if it forbids the user from changing his password, then return
+ // false.
+ // FIXME: the only getter responsible for a state attribute (pwdReset) that
+ // considers the policy before checking the entry for the presence of the
+ // attribute.
+ if (! (passwordPolicy.allowUserPasswordChanges()
+ && (passwordPolicy.forceChangeOnAdd()
+ || passwordPolicy.forceChangeOnReset())))
+ {
+ mustChangePassword = ConditionResult.FALSE;
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning false for user %s because neither force " +
+ "change on add nor force change on reset is enabled, " +
+ "or users are not allowed to self-modify passwords.",
+ userDNString);
+
+ }
+ }
+
+ return false;
+ }
+
+ AttributeType type =
+ DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_RESET_REQUIRED_LC);
+ if (type == null)
+ {
+ type = DirectoryServer.getDefaultAttributeType(
+ OP_ATTR_PWPOLICY_RESET_REQUIRED);
+ }
+
+ try
+ {
+ mustChangePassword = getBoolean(type);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ mustChangePassword = ConditionResult.TRUE;
+ if (debug)
+ {
+ debugWarning("Returning true for user %s because an error occurred: %s",
+ userDNString, stackTraceToSingleLineString(e));
+ }
+
return true;
}
- else
+
+ if(mustChangePassword == ConditionResult.UNDEFINED)
{
- if (debug)
+ mustChangePassword = ConditionResult.FALSE;
+ if(debug)
{
if (debugEnabled())
{
- debugInfo("Returning stored result of false for user %s",
- userDNString);
+ debugInfo("Returning %b for user since the attribute \"%s\"" +
+ " is not present in the entry.",
+ false, userDNString, OP_ATTR_PWPOLICY_RESET_REQUIRED);
}
}
return false;
}
+
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning %b for user %s.",
+ (mustChangePassword == ConditionResult.TRUE), userDNString);
+ }
+ }
+
+ return mustChangePassword == ConditionResult.TRUE;
}
- /**
- * Updates the user entry to indicate whether the user's password must be
- * changed.
- *
- * @param mustChangePassword Indicates whether the user's password must be
- * changed.
- */
+/**
+* Updates the user entry to indicate whether the user's password must be
+* changed.
+*
+* @param mustChangePassword Indicates whether the user's password must be
+* changed.
+*/
public void setMustChangePassword(boolean mustChangePassword)
{
if (debug)
@@ -2161,8 +1978,8 @@
}
}
- if (mustChangePassword ==
- (this.mustChangePassword == ConditionResult.TRUE)){
+ if (mustChangePassword == mustChangePassword())
+ {
return; // requested state matches current state
}
@@ -2198,6 +2015,7 @@
}
else
{
+ // erase
if (updateEntry)
{
userEntry.removeAttribute(type);
@@ -2222,6 +2040,8 @@
*/
public boolean lockedDueToMaximumResetAge()
{
+ // This feature is reponsible for neither a state field nor an entry state
+ // attribute.
if (passwordPolicy.getMaximumPasswordResetAge() <= 0)
{
if (debug)
@@ -2229,14 +2049,14 @@
if (debugEnabled())
{
debugInfo("Returning false for user %s because there is no maximum " +
- "reset age .", userDNString);
+ "reset age.", userDNString);
}
}
return false;
}
- if (!mustChangePassword())
+ if (! mustChangePassword())
{
if (debug)
{
@@ -2448,17 +2268,15 @@
}
}
-
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning password expiration time of %s for user " +
- "%s", expirationTime, userDNString);
+ debugInfo("Returning password expiration time of %d for user %s.",
+ expirationTime, userDNString);
}
}
- secondsUntilExpiration = (int) (expirationTime - currentTime);
return expirationTime;
}
@@ -2478,14 +2296,7 @@
getPasswordExpirationTime();
}
- if (isPasswordExpired == ConditionResult.TRUE)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return isPasswordExpired == ConditionResult.TRUE;
}
@@ -2500,6 +2311,8 @@
*/
public boolean isWithinMinimumAge()
{
+ // This feature is reponsible for neither a state field nor entry state
+ // attribute.
int minAge = passwordPolicy.getMinimumPasswordAge();
if (minAge <= 0)
{
@@ -2546,7 +2359,10 @@
// The user is within the minimum age.
if (debug)
{
- debugWarning("Returning true.");
+ if (debugEnabled())
+ {
+ debugInfo("Returning true.");
+ }
}
return true;
@@ -2575,14 +2391,7 @@
getPasswordExpirationTime();
}
- if (mayUseGraceLogin == ConditionResult.TRUE)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return mayUseGraceLogin == ConditionResult.TRUE;
}
@@ -2602,14 +2411,7 @@
getPasswordExpirationTime();
}
- if (shouldWarn == ConditionResult.TRUE)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return shouldWarn == ConditionResult.TRUE;
}
@@ -2629,14 +2431,7 @@
getPasswordExpirationTime();
}
- if (isFirstWarning == ConditionResult.TRUE)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return isFirstWarning == ConditionResult.TRUE;
}
@@ -2677,41 +2472,50 @@
*/
public long getRequiredChangeTime()
{
- if (requiredChangeTime == Long.MIN_VALUE)
+ if (requiredChangeTime != Long.MIN_VALUE)
{
- AttributeType type = DirectoryServer.getAttributeType(
- OP_ATTR_PWPOLICY_CHANGED_BY_REQUIRED_TIME,
- true);
- try
- {
- requiredChangeTime = getGeneralizedTime(type);
- }
- catch (Exception e)
+ if (debug)
{
if (debugEnabled())
{
- debugCaught(DebugLogLevel.ERROR, e);
+ debugInfo("Returning stored required change time of %d for user %s",
+ requiredChangeTime, userDNString);
}
-
- if (debug)
- {
- debugWarning(
- "An error occurred while attempting to " +
- "determine the required change time for " +
- "user %s: %s",
- userDNString, stackTraceToSingleLineString(e));
- }
-
- requiredChangeTime = -1;
}
+
+ return requiredChangeTime;
}
+ AttributeType type = DirectoryServer.getAttributeType(
+ OP_ATTR_PWPOLICY_CHANGED_BY_REQUIRED_TIME, true);
+
+ try
+ {
+ requiredChangeTime = getGeneralizedTime(type);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ requiredChangeTime = -1;
+ if (debug)
+ {
+ debugWarning("Returning %d for user %s because an error occurred: %s",
+ requiredChangeTime, userDNString,
+ stackTraceToSingleLineString(e));
+ }
+
+ return requiredChangeTime;
+ }
if (debug)
{
if (debugEnabled())
{
- debugInfo("Returning required change time of %s for user %s",
+ debugInfo("Returning required change time of %d for user %s",
requiredChangeTime, userDNString);
}
}
@@ -2735,29 +2539,26 @@
}
}
-
- long reqChangeTime = getRequiredChangeTime();
- if (reqChangeTime != passwordPolicy.getRequireChangeByTime())
+ long requiredChangeByTimePolicy = passwordPolicy.getRequireChangeByTime();
+ if (getRequiredChangeTime() != requiredChangeByTimePolicy)
{
- reqChangeTime = passwordPolicy.getRequireChangeByTime();
- requiredChangeTime = reqChangeTime;
-
AttributeType type = DirectoryServer.getAttributeType(
- OP_ATTR_PWPOLICY_CHANGED_BY_REQUIRED_TIME,
- true);
+ OP_ATTR_PWPOLICY_CHANGED_BY_REQUIRED_TIME, true);
+
LinkedHashSet<AttributeValue> values =
new LinkedHashSet<AttributeValue>(1);
- String timeValue = GeneralizedTimeSyntax.format(passwordChangedTime);
+ String timeValue =
+ GeneralizedTimeSyntax.format(requiredChangeByTimePolicy);
values.add(new AttributeValue(type, timeValue));
Attribute a = new Attribute(type,
OP_ATTR_PWPOLICY_CHANGED_BY_REQUIRED_TIME,
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
@@ -2795,10 +2596,8 @@
if (debug)
{
- debugWarning(
- "Unable to decode the warned time for user " +
- "%s: %s",
- userDNString, stackTraceToSingleLineString(e));
+ debugWarning("Unable to decode the warned time for user %s: %s",
+ userDNString, stackTraceToSingleLineString(e));
}
warnedTime = -1;
@@ -2848,11 +2647,11 @@
values.add(GeneralizedTimeSyntax.createGeneralizedTimeValue(currentTime));
Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_WARNED_TIME, 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
@@ -2876,6 +2675,20 @@
*/
public void clearWarnedTime()
{
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Clearing warned time for user %s", userDNString);
+ }
+ }
+
+ if (getWarnedTime() < 0)
+ {
+ return;
+ }
+ warnedTime = -1;
+
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_WARNED_TIME, true);
if (updateEntry)
@@ -2931,10 +2744,9 @@
if (debug)
{
- debugWarning(
- "Error while processing grace login times " +
- "for user %s: %s",
- userDNString, stackTraceToSingleLineString(e));
+ debugWarning("Error while processing grace login times " +
+ "for user %s: %s",
+ userDNString, stackTraceToSingleLineString(e));
}
graceLoginTimes = new ArrayList<Long>();
@@ -3015,7 +2827,7 @@
{
highestGraceTime = currentTime;
}
- graceTimes.add(highestGraceTime);
+ graceTimes.add(highestGraceTime); // graceTimes == this.graceLoginTimes
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME_LC);
@@ -3025,31 +2837,31 @@
OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME);
}
- LinkedHashSet<AttributeValue> values =
- new LinkedHashSet<AttributeValue>(graceTimes.size());
- for (Long l : graceTimes)
- {
- values.add(new AttributeValue(type, GeneralizedTimeSyntax.format(l)));
- }
-
- Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME,
- values);
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(a);
-
- LinkedHashSet<AttributeValue> addValues =
- new LinkedHashSet<AttributeValue>(1);
- addValues.add(new AttributeValue(type,
- GeneralizedTimeSyntax.format(highestGraceTime)));
- Attribute addAttr = new Attribute(type, OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME,
- addValues);
-
if (updateEntry)
{
+ LinkedHashSet<AttributeValue> values =
+ new LinkedHashSet<AttributeValue>(graceTimes.size());
+ for (Long l : graceTimes)
+ {
+ values.add(new AttributeValue(type, GeneralizedTimeSyntax.format(l)));
+ }
+
+ Attribute a = new Attribute(type, OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME,
+ values);
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(a);
+
userEntry.putAttribute(type, attrList);
}
else
{
+ LinkedHashSet<AttributeValue> addValues =
+ new LinkedHashSet<AttributeValue>(1);
+ addValues.add(new AttributeValue(type,
+ GeneralizedTimeSyntax.format(highestGraceTime)));
+ Attribute addAttr = new Attribute(type, OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME,
+ addValues);
+
modifications.add(new Modification(ModificationType.ADD, addAttr, true));
}
}
@@ -3074,7 +2886,7 @@
{
return;
}
- graceTimes.clear();
+ graceTimes.clear(); // graceTimes == this.graceLoginTimes
AttributeType type =
DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME_LC);
@@ -3109,107 +2921,75 @@
List<Attribute> attrList =
userEntry.getAttribute(passwordPolicy.getPasswordAttribute());
- if (attrList != null)
+
+ if (attrList == null)
{
- if (passwordPolicy.usesAuthPasswordSyntax())
+ return clearPasswords;
+ }
+
+ for (Attribute a : attrList)
+ {
+ boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax();
+
+ for (AttributeValue v : a.getValues())
{
- for (Attribute a : attrList)
+ try
{
- for (AttributeValue v : a.getValues())
+ StringBuilder[] pwComponents;
+ if (usesAuthPasswordSyntax)
{
- try
+ pwComponents =
+ AuthPasswordSyntax.decodeAuthPassword(v.getStringValue());
+ }
+ else
+ {
+ String[] userPwComponents =
+ UserPasswordSyntax.decodeUserPassword(v.getStringValue());
+ pwComponents = new StringBuilder[userPwComponents.length];
+ for (int i = 0; i < userPwComponents.length; ++i)
{
- StringBuilder[] pwComponents =
- AuthPasswordSyntax.decodeAuthPassword(v.getStringValue());
- PasswordStorageScheme scheme =
- DirectoryServer.getAuthPasswordStorageScheme(
- pwComponents[0].toString());
- if (scheme == null)
- {
- if (debug)
- {
- debugWarning("User entry %s contains an " +
- "authPassword with scheme %s " +
- "that is not defined in the " +
- "server.", userDNString, pwComponents[0]);
- }
-
- continue;
- }
- else if (scheme.isReversible())
- {
- ByteString clearValue =
- scheme.getAuthPasswordPlaintextValue(
- pwComponents[1].toString(),
- pwComponents[2].toString());
- clearPasswords.add(clearValue);
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "Cannot get clear authPassword " +
- "value for user %s: %s",
- userDNString, e);
- }
+ pwComponents[i] = new StringBuilder(userPwComponents[i]);
}
}
- }
- }
- else
- {
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
+
+ String schemeName = pwComponents[0].toString();
+ PasswordStorageScheme scheme = (usesAuthPasswordSyntax)
+ ? DirectoryServer.getAuthPasswordStorageScheme(schemeName)
+ : DirectoryServer.getPasswordStorageScheme(schemeName);
+ if (scheme == null)
{
- try
+ if (debug)
{
- String[] pwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getStringValue());
- PasswordStorageScheme scheme =
- DirectoryServer.getPasswordStorageScheme(pwComponents[0]);
- if (scheme == null)
- {
- if (debug)
- {
- debugWarning(
- "User entry %s contains a password " +
- "with scheme %s that is not " +
- "defined in the server.",
- userDNString, pwComponents[0]);
- }
-
- continue;
- }
- else if (scheme.isReversible())
- {
- ByteString clearValue =
- scheme.getPlaintextValue(
- new ASN1OctetString(pwComponents[1]));
- clearPasswords.add(clearValue);
- }
+ debugWarning("User entry %s contains a password with scheme %s " +
+ "that is not defined in the server.",
+ userDNString, schemeName);
}
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
- if (debug)
- {
- debugWarning(
- "Cannot get clear password value for " +
- "user %s: %s", userDNString, e);
- }
- }
+ continue;
+ }
+
+ if (scheme.isReversible())
+ {
+ ByteString clearValue = (usesAuthPasswordSyntax)
+ ? scheme.getAuthPasswordPlaintextValue(
+ pwComponents[1].toString(),
+ pwComponents[2].toString())
+ : scheme.getPlaintextValue(
+ new ASN1OctetString(pwComponents[1].toString()));
+ clearPasswords.add(clearValue);
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ if (debug)
+ {
+ debugWarning("Cannot get clear password value foruser %s: %s",
+ userDNString, e);
}
}
}
@@ -3249,122 +3029,80 @@
return false;
}
-
- if (passwordPolicy.usesAuthPasswordSyntax())
+ for (Attribute a : attrList)
{
- for (Attribute a : attrList)
+ boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax();
+
+ for (AttributeValue v : a.getValues())
{
- for (AttributeValue v : a.getValues())
+ try
{
- try
+ StringBuilder[] pwComponents;
+ if (usesAuthPasswordSyntax)
{
- StringBuilder[] pwComponents =
+ pwComponents =
AuthPasswordSyntax.decodeAuthPassword(v.getStringValue());
- PasswordStorageScheme scheme =
- DirectoryServer.getAuthPasswordStorageScheme(
- pwComponents[0].toString());
- if (scheme == null)
+ }
+ else
+ {
+ String[] userPwComponents =
+ UserPasswordSyntax.decodeUserPassword(v.getStringValue());
+ pwComponents = new StringBuilder[userPwComponents.length];
+ for (int i = 0; i < userPwComponents.length; ++i)
{
- if (debug)
- {
- debugWarning(
- "User entry %s contains a password with scheme %s " +
- "that is not defined in the server.",
- userDNString, pwComponents[0]);
- }
-
- continue;
- }
-
- if (scheme.authPasswordMatches(password, pwComponents[1].toString(),
- pwComponents[2].toString()))
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s because the provided " +
- "password matches a value encoded with scheme %s",
- userDNString, pwComponents[0]);
- }
- }
-
- return true;
+ pwComponents[i] = new StringBuilder(userPwComponents[i]);
}
}
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
+ String schemeName = pwComponents[0].toString();
+ PasswordStorageScheme scheme = (usesAuthPasswordSyntax)
+ ? DirectoryServer.getAuthPasswordStorageScheme(schemeName)
+ : DirectoryServer.getPasswordStorageScheme(schemeName);
+ if (scheme == null)
+ {
if (debug)
{
- debugError(
- "An error occurred while attempting to process a " +
- "password value for user %s: %s",
- userDNString, stackTraceToSingleLineString(e));
+ debugWarning("User entry %s contains a password with scheme %s " +
+ "that is not defined in the server.",
+ userDNString, schemeName);
}
+
+ continue;
+ }
+
+ boolean passwordMatches = (usesAuthPasswordSyntax)
+ ? scheme.authPasswordMatches(password,
+ pwComponents[1].toString(),
+ pwComponents[2].toString())
+ : scheme.passwordMatches(password,
+ new ASN1OctetString(pwComponents[1].toString()));
+ if (passwordMatches)
+ {
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Returning true for user %s because the provided " +
+ "password matches a value encoded with scheme %s",
+ userDNString, schemeName);
+ }
+ }
+
+ return true;
}
}
- }
- }
- else
- {
- for (Attribute a : attrList)
- {
- for (AttributeValue v : a.getValues())
+ catch (Exception e)
{
- try
+ if (debugEnabled())
{
- String[] pwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getStringValue());
- PasswordStorageScheme scheme =
- DirectoryServer.getPasswordStorageScheme(pwComponents[0]);
- if (scheme == null)
- {
- if (debug)
- {
- debugWarning(
- "User entry %s contains a password with scheme %s " +
- "that is not defined in the server.",
- userDNString, pwComponents[0]);
- }
-
- continue;
- }
-
- if (scheme.passwordMatches(password,
- new ASN1OctetString(pwComponents[1])))
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Returning true for user %s because the provided " +
- "password matches a value encoded with scheme %s",
- userDNString, pwComponents[0]);
- }
- }
-
- return true;
- }
+ debugCaught(DebugLogLevel.ERROR, e);
}
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
- if (debug)
- {
- debugError(
- "An error occurred while attempting to process a " +
- "password value for user %s: %s",
- userDNString, stackTraceToSingleLineString(e));
- }
+ if (debug)
+ {
+ debugWarning("An error occurred while attempting to process a " +
+ "password value for user %s: %s",
+ userDNString, stackTraceToSingleLineString(e));
}
}
}
@@ -3553,354 +3291,187 @@
LinkedHashSet<AttributeValue> updatedValues =
new LinkedHashSet<AttributeValue>();
- if (passwordPolicy.usesAuthPasswordSyntax())
- {
- for (Attribute a : attrList)
- {
- Iterator<AttributeValue> iterator = a.getValues().iterator();
- while (iterator.hasNext())
- {
- AttributeValue v = iterator.next();
+ boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax();
- try
+ for (Attribute a : attrList)
+ {
+ Iterator<AttributeValue> iterator = a.getValues().iterator();
+ while (iterator.hasNext())
+ {
+ AttributeValue v = iterator.next();
+
+ try
+ {
+ StringBuilder[] pwComponents;
+ if (usesAuthPasswordSyntax)
{
- StringBuilder[] pwComponents =
+ pwComponents =
AuthPasswordSyntax.decodeAuthPassword(v.getStringValue());
- String schemeName = pwComponents[0].toString();
- PasswordStorageScheme scheme =
- DirectoryServer.getAuthPasswordStorageScheme(schemeName);
- if (scheme == null)
+ }
+ else
+ {
+ String[] userPwComponents =
+ UserPasswordSyntax.decodeUserPassword(v.getStringValue());
+ pwComponents = new StringBuilder[userPwComponents.length];
+ for (int i = 0; i < userPwComponents.length; ++i)
+ {
+ pwComponents[i] = new StringBuilder(userPwComponents[i]);
+ }
+ }
+
+ String schemeName = pwComponents[0].toString();
+ PasswordStorageScheme scheme = (usesAuthPasswordSyntax)
+ ? DirectoryServer.getAuthPasswordStorageScheme(schemeName)
+ : DirectoryServer.getPasswordStorageScheme(schemeName);
+ if (scheme == null)
+ {
+ if (debug)
+ {
+ debugWarning("Skipping password value for user %s because the " +
+ "associated storage scheme %s is not configured for use.",
+ userDNString, schemeName);
+ }
+
+ continue;
+ }
+
+ boolean passwordMatches = (usesAuthPasswordSyntax)
+ ? scheme.authPasswordMatches(password,
+ pwComponents[1].toString(),
+ pwComponents[2].toString())
+ : scheme.passwordMatches(password,
+ new ASN1OctetString(pwComponents[1].toString()));
+ if (passwordMatches)
+ {
+ if (passwordPolicy.isDefaultStorageScheme(schemeName))
+ {
+ existingDefaultSchemes.add(schemeName);
+ updatedValues.add(v);
+ }
+ else if (passwordPolicy.isDeprecatedStorageScheme(schemeName))
{
if (debug)
{
- debugWarning(
- "Skipping password value for user %s because the " +
- "associated storage scheme %s is not " +
- "configured for use.",
- userDNString, schemeName);
- }
-
- continue;
- }
-
- if (scheme.authPasswordMatches(password, pwComponents[1].toString(),
- pwComponents[2].toString()))
- {
- if (passwordPolicy.isDefaultStorageScheme(schemeName))
- {
- existingDefaultSchemes.add(schemeName);
- updatedValues.add(v);
- }
- else if (passwordPolicy.isDeprecatedStorageScheme(schemeName))
- {
- if (debug)
+ if (debugEnabled())
{
- if (debugEnabled())
- {
- debugInfo("Marking password with scheme %s for removal " +
- "from user entry %s", pwComponents[0], userDNString);
- }
+ debugInfo("Marking password with scheme %s for removal " +
+ "from user entry %s.", schemeName, userDNString);
}
-
- iterator.remove();
- removedValues.add(v);
}
- else
- {
- updatedValues.add(v);
- }
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
- if (debug)
+ iterator.remove();
+ removedValues.add(v);
+ }
+ else
{
- debugWarning(
- "Skipping password value for user %s because an " +
- "error occurred while attempting to decode it " +
- "based on the user password syntax: %s",
- userDNString, stackTraceToSingleLineString(e));
+ updatedValues.add(v);
}
}
}
- }
-
- if (removedValues.isEmpty())
- {
- if (debug)
+ catch (Exception e)
{
if (debugEnabled())
{
- debugInfo("User entry %s does not have any password values " +
- "encoded using deprecated schemes.", userDNString);
- }
- }
- }
- else
- {
- LinkedHashSet<AttributeValue> addedValues = new
- LinkedHashSet<AttributeValue>();
- for (PasswordStorageScheme s :
- passwordPolicy.getDefaultStorageSchemes())
- {
- if (! existingDefaultSchemes.contains(
- toLowerCase(s.getStorageSchemeName())))
- {
- try
- {
- ByteString encodedPassword = s.encodeAuthPassword(password);
- AttributeValue v = new AttributeValue(type, encodedPassword);
- addedValues.add(v);
- updatedValues.add(v);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "Unable to encode password for user %s using " +
- "default scheme %s: %s",
- userDNString, s.getStorageSchemeName(),
- stackTraceToSingleLineString(e));
- }
- }
- }
- }
-
- if (updatedValues.isEmpty())
- {
- if (debug)
- {
- debugWarning(
- "Not updating user entry %s because removing " +
- "deprecated schemes would leave the user " +
- "without a password.", userDNString);
- }
-
- return;
- }
- else
- {
- Attribute a = new Attribute(type, type.getNameOrOID(), removedValues);
- if (! updateEntry)
- {
- modifications.add(new Modification(ModificationType.DELETE, a,
- true));
- }
-
- if (! addedValues.isEmpty())
- {
- Attribute a2 = new Attribute(type, type.getNameOrOID(),
- addedValues);
- if (! updateEntry)
- {
- modifications.add(new Modification(ModificationType.ADD, a2,
- true));
- }
- }
-
- ArrayList<Attribute> newList = new ArrayList<Attribute>(1);
- newList.add(new Attribute(type, type.getNameOrOID(), updatedValues));
- if (updateEntry)
- {
- userEntry.putAttribute(type, newList);
+ debugCaught(DebugLogLevel.ERROR, e);
}
if (debug)
{
- if (debugEnabled())
- {
- debugInfo("Updating user entry %s to replace password values " +
- "encoded with deprecated schemes with values encoded " +
- "with the default schemes.", userDNString);
- }
+ debugWarning("Skipping password value for user %s because an " +
+ "error occurred while attempting to decode it " +
+ "based on the user password syntax: %s",
+ userDNString, stackTraceToSingleLineString(e));
}
}
}
}
- else
+
+ if (removedValues.isEmpty())
{
- for (Attribute a : attrList)
+ if (debug)
{
- Iterator<AttributeValue> iterator = a.getValues().iterator();
- while (iterator.hasNext())
+ if (debugEnabled())
{
- AttributeValue v = iterator.next();
-
- try
- {
- String[] pwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getStringValue());
- PasswordStorageScheme scheme =
- DirectoryServer.getPasswordStorageScheme(pwComponents[0]);
- if (scheme == null)
- {
- if (debug)
- {
- debugWarning(
- "Skipping password value for user %s because the " +
- "associated storage scheme %s is not " +
- "configured for use.",
- userDNString, pwComponents[0]);
- }
-
- continue;
- }
-
- if (scheme.passwordMatches(password,
- new ASN1OctetString(pwComponents[1])))
- {
- if (passwordPolicy.isDefaultStorageScheme(pwComponents[0]))
- {
- existingDefaultSchemes.add(pwComponents[0]);
- updatedValues.add(v);
- }
- else if (passwordPolicy.isDeprecatedStorageScheme(
- pwComponents[0]))
- {
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Marking password with scheme %s for removal " +
- "from user entry %s", pwComponents[0], userDNString);
- }
- }
-
- iterator.remove();
- removedValues.add(v);
- }
- else
- {
- updatedValues.add(v);
- }
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
-
- if (debug)
- {
- debugWarning(
- "Skipping password value for user %s because an error " +
- "occurred while attempting to decode it based on " +
- "the user password syntax: %s",
- userDNString, stackTraceToSingleLineString(e));
- }
- }
+ debugInfo("User entry %s does not have any password values " +
+ "encoded using deprecated schemes.", userDNString);
}
}
- if (removedValues.isEmpty())
+ return;
+ }
+
+ LinkedHashSet<AttributeValue> addedValues = new
+ LinkedHashSet<AttributeValue>();
+ for (PasswordStorageScheme s :
+ passwordPolicy.getDefaultStorageSchemes())
+ {
+ if (! existingDefaultSchemes.contains(
+ toLowerCase(s.getStorageSchemeName())))
{
- if (debug)
+ try
+ {
+ ByteString encodedPassword = (usesAuthPasswordSyntax)
+ ? s.encodeAuthPassword(password)
+ : s.encodePasswordWithScheme(password);
+ AttributeValue v = new AttributeValue(type, encodedPassword);
+ addedValues.add(v);
+ updatedValues.add(v);
+ }
+ catch (Exception e)
{
if (debugEnabled())
{
- debugInfo("User entry %s does not have any password values " +
- "encoded using deprecated schemes.", userDNString);
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ if (debug)
+ {
+ debugWarning("Unable to encode password for user %s using " +
+ "default scheme %s: %s",
+ userDNString, s.getStorageSchemeName(),
+ stackTraceToSingleLineString(e));
}
}
}
- else
+ }
+
+ if (updatedValues.isEmpty())
+ {
+ if (debug)
{
- LinkedHashSet<AttributeValue> addedValues = new
- LinkedHashSet<AttributeValue>();
- for (PasswordStorageScheme s :
- passwordPolicy.getDefaultStorageSchemes())
- {
- if (! existingDefaultSchemes.contains(
- toLowerCase(s.getStorageSchemeName())))
- {
- try
- {
- ByteString encodedPassword = s.encodePasswordWithScheme(password);
- AttributeValue v = new AttributeValue(type, encodedPassword);
- addedValues.add(v);
- updatedValues.add(v);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- debugCaught(DebugLogLevel.ERROR, e);
- }
+ debugWarning("Not updating user entry %s because removing " +
+ "deprecated schemes would leave the user without a password.",
+ userDNString);
+ }
- if (debug)
- {
- debugWarning(
- "Unable to encode password for user %s using " +
- "default scheme %s: %s",
- userDNString, s.getStorageSchemeName(),
- stackTraceToSingleLineString(e));
- }
- }
- }
- }
+ return;
+ }
- if (updatedValues.isEmpty())
- {
- if (debug)
- {
- debugWarning(
- "Not updating user entry %s because removing " +
- "deprecated schemes would leave the user " +
- "without a password.", userDNString);
- }
+ if (updateEntry)
+ {
+ ArrayList<Attribute> newList = new ArrayList<Attribute>(1);
+ newList.add(new Attribute(type, type.getNameOrOID(), updatedValues));
+ userEntry.putAttribute(type, newList);
+ }
+ else
+ {
+ Attribute a = new Attribute(type, type.getNameOrOID(), removedValues);
+ modifications.add(new Modification(ModificationType.DELETE, a, true));
- return;
- }
- else
- {
- Attribute a = new Attribute(type, type.getNameOrOID(), removedValues);
- if (! updateEntry)
- {
- modifications.add(new Modification(ModificationType.DELETE, a,
- true));
- }
+ if (! addedValues.isEmpty())
+ {
+ Attribute a2 = new Attribute(type, type.getNameOrOID(), addedValues);
+ modifications.add(new Modification(ModificationType.ADD, a2, true));
+ }
+ }
- if (! addedValues.isEmpty())
- {
- Attribute a2 = new Attribute(type, type.getNameOrOID(),
- addedValues);
- if (! updateEntry)
- {
- modifications.add(new Modification(ModificationType.ADD, a2,
- true));
- }
- }
-
- ArrayList<Attribute> newList = new ArrayList<Attribute>(1);
- newList.add(new Attribute(type, type.getNameOrOID(), updatedValues));
- if (updateEntry)
- {
- userEntry.putAttribute(type, newList);
- }
-
- if (debug)
- {
- if (debugEnabled())
- {
- debugInfo("Updating user entry %sto replace password values " +
- "encoded with deprecated schemes with values encoded " +
- "with the default schemes.", userDNString);
- }
- }
- }
+ if (debug)
+ {
+ if (debugEnabled())
+ {
+ debugInfo("Updating user entry %s to replace password values " +
+ "encoded with deprecated schemes with values encoded " +
+ "with the default schemes.", userDNString);
}
}
}
@@ -3924,10 +3495,9 @@
{
if (debug)
{
- debugWarning(
- "Unable to generate a new password for user %s " +
- "because no password generator has been " +
- "defined in the associated password policy.",
+ debugWarning("Unable to generate a new password for user %s because " +
+ "no password generator has been defined in the associated " +
+ "password policy.",
userDNString);
}
@@ -3993,6 +3563,21 @@
/**
+ * Retrieves the set of modifications that correspond to changes made in
+ * password policy processing that may need to be applied to the user entry.
+ *
+ * @return The set of modifications that correspond to changes made in
+ * password policy processing that may need to be applied to the user
+ * entry.
+ */
+ public LinkedList<Modification> getModifications()
+ {
+ return modifications;
+ }
+
+
+
+ /**
* Performs an internal modification to update the user's entry, if necessary.
* This will do nothing if no modifications are required.
*
@@ -4033,4 +3618,3 @@
}
}
}
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
index 84d4d80..2853b65 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -1101,7 +1101,6 @@
// Clear any record of grace logins, auth failures, and expiration
// warnings.
- pwPolicyState.clearAuthFailureTimes();
pwPolicyState.clearFailureLockout();
pwPolicyState.clearGraceLoginTimes();
pwPolicyState.clearWarnedTime();
--
Gitblit v1.10.0