From 16a4c18b4c101e8e3dc7b8be756de1807970065f Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 19 Jul 2007 16:12:32 +0000
Subject: [PATCH] Update the server to provide more complete support for the password policy control as described in draft-behera-ldap-password-policy. In particular, improved support has been provided for all operations for the case in which a user must change his/her password before performing any other types of operations. These changes also provide enhanced support for add and modify operations that are rejected because a password change is not acceptable for some reason.
---
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java | 84 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 76 insertions(+), 8 deletions(-)
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index d7470cf..ee3a804 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -227,6 +227,8 @@
// Create a labeled block of code that we can break out of if a problem is
// detected.
+ boolean pwPolicyControlRequested = false;
+ PasswordPolicyErrorType pwpErrorType = null;
modifyProcessing:
{
DN entryDN = localOp.getEntryDN();
@@ -261,8 +263,20 @@
DN authzDN = localOp.getAuthorizationDN();
if ((authzDN != null) && (! authzDN.equals(entryDN)))
{
- // The user will not be allowed to do anything else before
- // the password gets changed.
+ // The user will not be allowed to do anything else before the
+ // password gets changed. Also note that we haven't yet checked the
+ // request controls so we need to do that now to see if the password
+ // policy request control was provided.
+ for (Control c : localOp.getRequestControls())
+ {
+ if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL))
+ {
+ pwPolicyControlRequested = true;
+ pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
+ break;
+ }
+ }
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_MUST_CHANGE_PASSWORD;
@@ -658,6 +672,10 @@
localOp.setProxiedAuthorizationDN(authorizationEntry.getDN());
}
}
+ else if (oid.equals(OID_PASSWORD_POLICY_CONTROL))
+ {
+ pwPolicyControlRequested = true;
+ }
// NYI -- Add support for additional controls.
else if (c.isCritical())
@@ -783,6 +801,9 @@
Privilege.PASSWORD_RESET,
localOp))
{
+ pwpErrorType =
+ PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
+
int msgID = MSGID_MODIFY_PWRESET_INSUFFICIENT_PRIVILEGES;
localOp.appendErrorMessage(getMessage(msgID));
localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
@@ -885,6 +906,8 @@
if (selfChange &&
(! pwPolicyState.getPolicy().allowUserPasswordChanges()))
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_NO_USER_PW_CHANGES;
@@ -898,6 +921,8 @@
if (pwPolicyState.getPolicy().requireSecurePasswordChanges() &&
(! clientConnection.isSecure()))
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_REQUIRE_SECURE_CHANGES;
@@ -910,6 +935,8 @@
// previous change, then reject it.
if (selfChange && pwPolicyState.isWithinMinimumAge())
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_TOO_YOUNG;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_WITHIN_MINIMUM_AGE;
@@ -944,10 +971,12 @@
// If there were multiple password values provided, then make
// sure that's OK.
- if (! localOp.isInternalOperation() &&
- ! pwPolicyState.getPolicy().allowExpiredPasswordChanges() &&
+ if ((! localOp.isInternalOperation()) &&
+ (! pwPolicyState.getPolicy().allowMultiplePasswordValues()) &&
(passwordsToAdd > 1))
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_MULTIPLE_VALUES_NOT_ALLOWED;
@@ -966,6 +995,9 @@
if ((!localOp.isInternalOperation()) &&
! pwPolicyState.getPolicy().allowPreEncodedPasswords())
{
+ pwpErrorType =
+ PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_NO_PREENCODED_PASSWORDS;
@@ -985,6 +1017,9 @@
// exist.
if (pwPolicyState.passwordMatches(v.getValue()))
{
+ pwpErrorType =
+ PasswordPolicyErrorType.PASSWORD_IN_HISTORY;
+
localOp.setResultCode(
ResultCode.ATTRIBUTE_OR_VALUE_EXISTS);
@@ -1044,6 +1079,9 @@
{
if ((!localOp.isInternalOperation()) && selfChange)
{
+ pwpErrorType =
+ PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_NO_PREENCODED_PASSWORDS;
@@ -1774,6 +1812,8 @@
pwPolicyState.getPolicy().requireCurrentPassword() &&
(! currentPasswordProvided))
{
+ pwpErrorType = PasswordPolicyErrorType.MUST_SUPPLY_OLD_PASSWORD;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_PW_CHANGE_REQUIRES_CURRENT_PW;
@@ -1787,6 +1827,8 @@
if ((numPasswords > 1) &&
(! pwPolicyState.getPolicy().allowMultiplePasswordValues()))
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_MULTIPLE_PASSWORDS_NOT_ALLOWED;
@@ -1856,6 +1898,9 @@
clearPasswords,
invalidReason))
{
+ pwpErrorType =
+ PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_PW_VALIDATION_FAILED;
@@ -1881,6 +1926,8 @@
if (selfChange || (! pwPolicyState.getPolicy().
skipValidationForAdministrators()))
{
+ pwpErrorType = PasswordPolicyErrorType.PASSWORD_IN_HISTORY;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_PW_IN_HISTORY;
@@ -1924,8 +1971,8 @@
{
// See if the account was locked for any reason.
wasLocked = pwPolicyState.lockedDueToIdleInterval() ||
- pwPolicyState.lockedDueToMaximumResetAge() ||
- pwPolicyState.lockedDueToFailures();
+ pwPolicyState.lockedDueToMaximumResetAge() ||
+ pwPolicyState.lockedDueToFailures();
// Update the password policy state attributes in the user's entry.
// If the modification fails, then these changes won't be applied.
@@ -1943,6 +1990,12 @@
}
else
{
+ if ((pwpErrorType == null) &&
+ pwPolicyState.getPolicy().forceChangeOnReset())
+ {
+ pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
+ }
+
pwPolicyState.setMustChangePassword(
pwPolicyState.getPolicy().forceChangeOnReset());
}
@@ -1971,6 +2024,8 @@
{
// The user will not be allowed to do anything else before
// the password gets changed.
+ pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
+
localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
int msgID = MSGID_MODIFY_MUST_CHANGE_PASSWORD;
@@ -2378,6 +2433,15 @@
}
+ // If the password policy request control was included, then make sure we
+ // send the corresponding response control.
+ if (pwPolicyControlRequested)
+ {
+ localOp.addResponseControl(
+ new PasswordPolicyResponseControl(null, 0, pwpErrorType));
+ }
+
+
// Indicate that it is now too late to attempt to cancel the operation.
localOp.setCancelResult(CancelResult.TOO_LATE);
@@ -5222,8 +5286,7 @@
}
}
- // Check to see if there are any controls in the request. If so,
- // then
+ // Check to see if there are any controls in the request. If so, then
// see if there is any special processing required.
boolean noOp = false;
LDAPPostReadRequestControl postReadRequest = null;
@@ -5487,6 +5550,11 @@
localOp.setProxiedAuthorizationDN(authorizationEntry.getDN());
}
}
+ else if (oid.equals(OID_PASSWORD_POLICY_CONTROL))
+ {
+ // We don't need to do anything here because it's already handled
+ // in LocalBackendAddOperation.handlePasswordPolicy().
+ }
// NYI -- Add support for additional controls.
else if (c.isCritical())
--
Gitblit v1.10.0