From c65fd9ebfdb53ab356c9f92bf5c44a437575be15 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Thu, 02 Feb 2012 17:31:49 +0000
Subject: [PATCH] Fix for OPENDJ-418. When formatting the last login time to store in an attribute, we are not using UTC timezone, if the attribute has a generalizedTime syntax. Ideally, the format should end with the 'Z' character. This is not enforced though.

---
 opends/src/server/org/opends/server/core/PasswordPolicyState.java |   65 ++++++++++++++++++--------------
 1 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/PasswordPolicyState.java b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
index 47cabf7..5966b69 100644
--- a/opends/src/server/org/opends/server/core/PasswordPolicyState.java
+++ b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -23,25 +23,14 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011 ForgeRock AS
+ *      Portions Copyright 2011-2012 ForgeRock AS
  */
 package org.opends.server.core;
 
 
 
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
+import java.util.*;
 
 import org.opends.messages.Message;
 import org.opends.messages.MessageBuilder;
@@ -56,9 +45,9 @@
 import org.opends.server.schema.UserPasswordSyntax;
 import org.opends.server.types.*;
 
+import static org.opends.messages.CoreMessages.*;
 import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.loggers.debug.DebugLogger.*;
-import static org.opends.messages.CoreMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
 import static org.opends.server.util.StaticUtils.*;
 
@@ -92,9 +81,6 @@
   // Indicates whether the user's account is expired.
   private ConditionResult isAccountExpired = ConditionResult.UNDEFINED;
 
-  // Indicates whether the user's account is disabled.
-  private ConditionResult isDisabled = ConditionResult.UNDEFINED;
-
   // Indicates whether the user's password is expired.
   private ConditionResult isPasswordExpired = ConditionResult.UNDEFINED;
 
@@ -290,6 +276,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public PasswordPolicy getAuthenticationPolicy()
   {
     return passwordPolicy;
@@ -1275,6 +1262,8 @@
       return lastLoginTime;
     }
 
+    boolean isGeneralizedTime =
+        type.getSyntax().getSyntaxName().equals(SYNTAX_GENERALIZED_TIME_NAME);
     lastLoginTime = -1;
     List<Attribute> attrList = userEntry.getAttribute(type);
 
@@ -1289,6 +1278,10 @@
         try
         {
           SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+          if (isGeneralizedTime)
+          {
+            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+          }
           lastLoginTime = dateFormat.parse(valueString).getTime();
 
           if (debugEnabled())
@@ -1314,6 +1307,10 @@
             try
             {
               SimpleDateFormat dateFormat = new SimpleDateFormat(f);
+              if (isGeneralizedTime)
+              {
+                dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+              }
               lastLoginTime = dateFormat.parse(valueString).getTime();
 
               if (debugEnabled())
@@ -1390,6 +1387,12 @@
     try
     {
       SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+      // If the attribute has a Generalized Time syntax, make it UTC time.
+      if (type.getSyntax().getSyntaxName()
+          .equals(SYNTAX_GENERALIZED_TIME_NAME))
+      {
+        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+      }
       timestamp = dateFormat.format(new Date(lastLoginTime));
       this.lastLoginTime = dateFormat.parse(timestamp).getTime();
     }
@@ -1497,20 +1500,20 @@
                          (1000L * passwordPolicy.getIdleLockoutInterval());
     if(lockTime < 0) lockTime = 0;
 
-    long lastLoginTime = getLastLoginTime();
-    if (lastLoginTime > lockTime || getPasswordChangedTime() > lockTime)
+    long theLastLoginTime = getLastLoginTime();
+    if (theLastLoginTime > lockTime || getPasswordChangedTime() > lockTime)
     {
       isIdleLocked = ConditionResult.FALSE;
       if (debugEnabled())
       {
         StringBuilder reason = new StringBuilder();
-        if(lastLoginTime > lockTime)
+        if(theLastLoginTime > lockTime)
         {
           reason.append("the last login time is in an acceptable window");
         }
         else
         {
-          if(lastLoginTime < 0)
+          if(theLastLoginTime < 0)
           {
             reason.append("there is no last login time, but ");
           }
@@ -1526,7 +1529,7 @@
       isIdleLocked = ConditionResult.TRUE;
       if (debugEnabled())
       {
-        String reason = (lastLoginTime < 0)
+        String reason = (theLastLoginTime < 0)
             ? "there is no last login time and the password " +
             "changed time is not in an acceptable window"
             : "neither last login time nor password " +
@@ -1813,7 +1816,7 @@
           {
             // We're at least in the warning period, but the password may be
             // expired.
-            long warnedTime = getWarnedTime();
+            long theWarnedTime = getWarnedTime();
 
             if (passwordExpirationTime > currentTime)
             {
@@ -1821,7 +1824,7 @@
               shouldWarn        = ConditionResult.TRUE;
               isPasswordExpired = ConditionResult.FALSE;
 
-              if (warnedTime < 0)
+              if (theWarnedTime < 0)
               {
                 isFirstWarning = ConditionResult.TRUE;
                 setWarnedTime();
@@ -1838,7 +1841,8 @@
 
                 if (! passwordPolicy.isExpirePasswordsWithoutWarning())
                 {
-                  passwordExpirationTime = warnedTime + (warningInterval*1000L);
+                  passwordExpirationTime =
+                      theWarnedTime + (warningInterval*1000L);
                 }
               }
             }
@@ -1852,9 +1856,10 @@
                 isFirstWarning    = ConditionResult.FALSE;
                 isPasswordExpired = ConditionResult.TRUE;
               }
-              else if (warnedTime > 0)
+              else if (theWarnedTime > 0)
               {
-                passwordExpirationTime = warnedTime + (warningInterval*1000L);
+                passwordExpirationTime =
+                    theWarnedTime + (warningInterval*1000L);
                 if (passwordExpirationTime > currentTime)
                 {
                   shouldWarn        = ConditionResult.TRUE;
@@ -2411,8 +2416,8 @@
       return -1;
     }
 
-    List<Long> graceLoginTimes = getGraceLoginTimes();
-    return maxGraceLogins - graceLoginTimes.size();
+    List<Long> theGraceLoginTimes = getGraceLoginTimes();
+    return maxGraceLogins - theGraceLoginTimes.size();
   }
 
 
@@ -2626,6 +2631,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean passwordMatches(ByteString password)
   {
     List<Attribute> attrList =
@@ -3671,6 +3677,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void finalizeStateAfterBind()
          throws DirectoryException
   {

--
Gitblit v1.10.0