From e627deb0b7849bb8119b9566dd093b92ce9a2dbd Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 02 Aug 2006 20:31:50 +0000
Subject: [PATCH] Add a new account expiration feature to the password policy.  This will make it possible for accounts to be given an expiration time, after which it will not be possible to authenticate as that user or target that user with the proxied authorization control.

---
 opends/src/server/org/opends/server/core/PasswordPolicyState.java |  189 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 154 insertions(+), 35 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/PasswordPolicyState.java b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
index 44df8ff..a164336 100644
--- a/opends/src/server/org/opends/server/core/PasswordPolicyState.java
+++ b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -102,11 +102,14 @@
   // successful.
   private boolean useGraceLogin;
 
+  // Indicates whether the user's account is expired.
+  private ConditionResult isAccountExpired;
+
   // Indicates whether the user's account is disabled.
   private ConditionResult isDisabled;
 
   // Indicates whether the user's password is expired.
-  private ConditionResult isExpired;
+  private ConditionResult isPasswordExpired;
 
   // Indicates whether the warning to send to the client would be the first
   // warning for the user.
@@ -213,7 +216,8 @@
     currentTime            = TimeThread.getTime();
     modifications          = new LinkedList<Modification>();
     isDisabled             = ConditionResult.UNDEFINED;
-    isExpired              = ConditionResult.UNDEFINED;
+    isAccountExpired       = ConditionResult.UNDEFINED;
+    isPasswordExpired      = ConditionResult.UNDEFINED;
     isFirstWarning         = ConditionResult.UNDEFINED;
     isIdleLocked           = ConditionResult.UNDEFINED;
     isResetLocked          = ConditionResult.UNDEFINED;
@@ -1004,7 +1008,7 @@
             debugMessage(DebugLogCategory.PASSWORD_POLICY,
                          DebugLogSeverity.INFO, CLASS_NAME, "isDisabled",
                          "User " + userDNString +
-                         " is not administratively disabled.");
+                         " is administratively disabled.");
           }
 
           isDisabled = ConditionResult.TRUE;
@@ -1017,7 +1021,7 @@
             debugMessage(DebugLogCategory.PASSWORD_POLICY,
                          DebugLogSeverity.INFO, CLASS_NAME, "isDisabled",
                          "User " + userDNString +
-                         " is administratively disabled.");
+                         " is not administratively disabled.");
           }
 
           isDisabled = ConditionResult.FALSE;
@@ -1145,6 +1149,120 @@
 
 
   /**
+   * Indicates whether the user's account is currently expired.
+   *
+   * @return  <CODE>true</CODE> if the user's account is expired, or
+   *          <CODE>false</CODE> if not.
+   */
+  public boolean isAccountExpired()
+  {
+    assert debugEnter(CLASS_NAME, "isAccountExpired");
+
+    if ((isAccountExpired == null) ||
+        (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)
+          {
+            debugMessage(DebugLogCategory.PASSWORD_POLICY,
+                         DebugLogSeverity.INFO, CLASS_NAME, "isAccountExpired",
+                         "The account for user " + userDNString +
+                         " is not expired because there is no expiration " +
+                         "time in the user's entry.");
+          }
+
+          isAccountExpired = ConditionResult.FALSE;
+          return false;
+        }
+        else if (expirationTime > currentTime)
+        {
+          // The user does have an expiration time, but it hasn't arrived yet.
+          if (debug)
+          {
+            debugMessage(DebugLogCategory.PASSWORD_POLICY,
+                         DebugLogSeverity.INFO, CLASS_NAME, "isAccountExpired",
+                         "The account for user " + userDNString +
+                         " is not expired because the expiration time has " +
+                         "not yet arrived.");
+          }
+
+          isAccountExpired = ConditionResult.FALSE;
+          return false;
+        }
+        else
+        {
+          // The user does have an expiration time, and it is in the past.
+          if (debug)
+          {
+            debugMessage(DebugLogCategory.PASSWORD_POLICY,
+                         DebugLogSeverity.INFO, CLASS_NAME, "isAccountExpired",
+                         "The account for user " + userDNString +
+                         " is expired because the expiration time in that " +
+                         "account has passed.");
+          }
+
+          isAccountExpired = ConditionResult.TRUE;
+          return true;
+        }
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "isAccountExpired", e);
+
+        if (debug)
+        {
+          debugMessage(DebugLogCategory.PASSWORD_POLICY,
+                       DebugLogSeverity.WARNING, CLASS_NAME, "isAccountExpired",
+                       "User " + userDNString +" is considered to have an " +
+                       "expired account because an error occurred " +
+                       "while attempting to make the determination:  " +
+                       stackTraceToSingleLineString(e) + ".");
+        }
+
+        isAccountExpired = ConditionResult.TRUE;
+        return true;
+      }
+    }
+
+
+    if (isAccountExpired == ConditionResult.FALSE)
+    {
+      if (debug)
+      {
+        debugMessage(DebugLogCategory.PASSWORD_POLICY, DebugLogSeverity.INFO,
+                     CLASS_NAME, "isAccountExpired",
+                     "Returning stored result of false for user " +
+                     userDNString);
+      }
+
+      return false;
+    }
+    else
+    {
+      if (debug)
+      {
+        debugMessage(DebugLogCategory.PASSWORD_POLICY, DebugLogSeverity.INFO,
+                     CLASS_NAME, "isAccountExpired",
+                     "Returning stored result of true for user " +
+                     userDNString);
+      }
+
+      return true;
+    }
+  }
+
+
+
+  /**
    * Retrieves the set of times of failed authentication attempts for the user.
    *
    * @return  The set of times of failed authentication attempts for the user.
@@ -2339,11 +2457,11 @@
 
       if (expirationTime == Long.MAX_VALUE)
       {
-        expirationTime   = -1;
-        shouldWarn       = ConditionResult.FALSE;
-        isFirstWarning   = ConditionResult.FALSE;
-        isExpired        = ConditionResult.FALSE;
-        mayUseGraceLogin = ConditionResult.TRUE;
+        expirationTime    = -1;
+        shouldWarn        = ConditionResult.FALSE;
+        isFirstWarning    = ConditionResult.FALSE;
+        isPasswordExpired = ConditionResult.FALSE;
+        mayUseGraceLogin  = ConditionResult.TRUE;
       }
       else if (checkWarning)
       {
@@ -2357,9 +2475,9 @@
           {
             // The warning time is in the future, so we know the password isn't
             // expired.
-            shouldWarn     = ConditionResult.FALSE;
-            isFirstWarning = ConditionResult.FALSE;
-            isExpired      = ConditionResult.FALSE;
+            shouldWarn        = ConditionResult.FALSE;
+            isFirstWarning    = ConditionResult.FALSE;
+            isPasswordExpired = ConditionResult.FALSE;
           }
           else
           {
@@ -2370,8 +2488,8 @@
             if (expirationTime > currentTime)
             {
               // The password is not expired but we should warn the user.
-              shouldWarn = ConditionResult.TRUE;
-              isExpired  = ConditionResult.FALSE;
+              shouldWarn        = ConditionResult.TRUE;
+              isPasswordExpired = ConditionResult.FALSE;
 
               if (warnedTime < 0)
               {
@@ -2399,32 +2517,32 @@
               // expired if the user has not yet seen a warning.
               if (passwordPolicy.expirePasswordsWithoutWarning())
               {
-                shouldWarn     = ConditionResult.FALSE;
-                isFirstWarning = ConditionResult.FALSE;
-                isExpired      = ConditionResult.TRUE;
+                shouldWarn        = ConditionResult.FALSE;
+                isFirstWarning    = ConditionResult.FALSE;
+                isPasswordExpired = ConditionResult.TRUE;
               }
               else if (warnedTime > 0)
               {
                 expirationTime = warnedTime + (warningInterval*1000);
                 if (expirationTime > currentTime)
                 {
-                  shouldWarn     = ConditionResult.TRUE;
-                  isFirstWarning = ConditionResult.FALSE;
-                  isExpired      = ConditionResult.FALSE;
+                  shouldWarn        = ConditionResult.TRUE;
+                  isFirstWarning    = ConditionResult.FALSE;
+                  isPasswordExpired = ConditionResult.FALSE;
                 }
                 else
                 {
-                  shouldWarn     = ConditionResult.FALSE;
-                  isFirstWarning = ConditionResult.FALSE;
-                  isExpired      = ConditionResult.TRUE;
+                  shouldWarn        = ConditionResult.FALSE;
+                  isFirstWarning    = ConditionResult.FALSE;
+                  isPasswordExpired = ConditionResult.TRUE;
                 }
               }
               else
               {
-                shouldWarn     = ConditionResult.TRUE;
-                isFirstWarning = ConditionResult.TRUE;
-                isExpired      = ConditionResult.FALSE;
-                expirationTime = currentTime + (warningInterval*1000);
+                shouldWarn        = ConditionResult.TRUE;
+                isFirstWarning    = ConditionResult.TRUE;
+                isPasswordExpired = ConditionResult.FALSE;
+                expirationTime    = currentTime + (warningInterval*1000);
               }
             }
           }
@@ -2438,11 +2556,11 @@
 
           if (currentTime > expirationTime)
           {
-            isExpired = ConditionResult.TRUE;
+            isPasswordExpired = ConditionResult.TRUE;
           }
           else
           {
-            isExpired = ConditionResult.FALSE;
+            isPasswordExpired = ConditionResult.FALSE;
           }
         }
       }
@@ -2454,11 +2572,11 @@
 
         if (expirationTime < currentTime)
         {
-          isExpired = ConditionResult.TRUE;
+          isPasswordExpired = ConditionResult.TRUE;
         }
         else
         {
-          isExpired = ConditionResult.FALSE;
+          isPasswordExpired = ConditionResult.FALSE;
         }
       }
     }
@@ -2484,16 +2602,17 @@
    * @return  <CODE>true</CODE> if the user's password is currently expired, or
    *          <CODE>false</CODE> if not.
    */
-  public boolean isExpired()
+  public boolean isPasswordExpired()
   {
-    assert debugEnter(CLASS_NAME, "isExpired");
+    assert debugEnter(CLASS_NAME, "isPasswordExpired");
 
-    if ((isExpired == null) || (isExpired == ConditionResult.UNDEFINED))
+    if ((isPasswordExpired == null) ||
+        (isPasswordExpired == ConditionResult.UNDEFINED))
     {
       getPasswordExpirationTime();
     }
 
-    if (isExpired == ConditionResult.TRUE)
+    if (isPasswordExpired == ConditionResult.TRUE)
     {
       return true;
     }

--
Gitblit v1.10.0