From 55bd12c1c9501fac8d94aee3ee1c2f9a68b652ff Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Thu, 15 May 2014 16:08:11 +0000
Subject: [PATCH] Fix OPENDJ-1443: OpenDJ returns an "invalid credential:expired" when password has expired even if the expired provided password is wrong

---
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java |   43 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
index 2cc5694..12a7638 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2013 ForgeRock AS.
+ *      Portions copyright 2011-2014 ForgeRock AS.
  */
 package org.opends.server.workflowelement.localbackend;
 
@@ -520,8 +520,9 @@
               ERR_BIND_OPERATION_NO_PASSWORD.get());
         }
 
-        // Perform a number of password policy state checks for the user.
-        checkPasswordPolicyState(userEntry, null);
+        // Perform a number of password policy state checks for the
+        // non-authenticated user.
+        checkUnverifiedPasswordPolicyState(userEntry, null);
 
         // Invoke pre-operation plugins.
         if (!invokePreOpPlugins())
@@ -535,6 +536,8 @@
         {
           setResultCode(ResultCode.SUCCESS);
 
+          checkVerifiedPasswordPolicyState(userEntry, null);
+
           if (DirectoryServer.lockdownMode()
               && (!ClientConnection.hasPrivilege(userEntry,
                   Privilege.BYPASS_LOCKDOWN)))
@@ -742,10 +745,9 @@
           saslAuthUserEntry, false);
       if (authPolicyState.isPasswordPolicy())
       {
-        // Account is managed locally: perform password policy checks that will
-        // need to be completed regardless of whether the authentication was
-        // successful.
-        checkPasswordPolicyState(saslAuthUserEntry, saslHandler);
+        // Account is managed locally: perform password policy checks that can
+        // be completed before we have checked authentication was successful.
+        checkUnverifiedPasswordPolicyState(saslAuthUserEntry, saslHandler);
       }
     }
 
@@ -757,6 +759,8 @@
     {
       if (authPolicyState != null && authPolicyState.isPasswordPolicy())
       {
+        checkVerifiedPasswordPolicyState(saslAuthUserEntry, saslHandler);
+
         PasswordPolicyState pwPolicyState =
           (PasswordPolicyState) authPolicyState;
 
@@ -882,7 +886,8 @@
 
 
   /**
-   * Validates a number of password policy state constraints for the user.
+   * Validates a number of password policy state constraints for the user. This
+   * will be called before the offered credentials are checked.
    *
    * @param userEntry
    *          The entry for the user that is authenticating.
@@ -892,7 +897,7 @@
    * @throws DirectoryException
    *           If a problem occurs that should cause the bind to fail.
    */
-  protected void checkPasswordPolicyState(
+  protected void checkUnverifiedPasswordPolicyState(
       Entry userEntry, SASLMechanismHandler<?> saslHandler)
       throws DirectoryException
   {
@@ -944,7 +949,27 @@
                        ERR_BIND_OPERATION_INSECURE_SIMPLE_BIND.get());
       }
     }
+  }
 
+  /**
+   * Perform policy checks for accounts when the credentials are correct.
+   *
+   * @param userEntry
+   *          The entry for the user that is authenticating.
+   * @param saslHandler
+   *          The SASL mechanism handler if this is a SASL bind, or {@code null}
+   *          for a simple bind.
+   * @throws DirectoryException
+   *           If a problem occurs that should cause the bind to fail.
+   */
+  protected void checkVerifiedPasswordPolicyState(
+      Entry userEntry, SASLMechanismHandler<?> saslHandler)
+      throws DirectoryException
+  {
+    PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState;
+    PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();
+
+    boolean isSASLBind = (saslHandler != null);
 
     // Check to see if the user is administratively disabled or locked.
     if (pwPolicyState.isDisabled())

--
Gitblit v1.10.0