From 0e87ef45f8048b462c14115512671e5db56d4bbe Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Tue, 31 Jul 2007 17:31:26 +0000
Subject: [PATCH] Update the password policy code so that the sum of the minimum password age and the password expiration warning interval must always be less than the maximum password age.  This ensures that the minimum password age will itself always be less than the maximum age, and will also prevent a scenario in which the user could receive password expiration warning messages during a period when he/she cannot change the password due to the minimum age.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java |   73 ++++++++++++++++++++++++
 opends/src/server/org/opends/server/core/PasswordPolicy.java                                 |   24 ++++++++
 opends/src/server/org/opends/server/messages/CoreMessages.java                               |   35 +++++++++++
 3 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/PasswordPolicy.java b/opends/src/server/org/opends/server/core/PasswordPolicy.java
index 37e40a4..20f02bf 100644
--- a/opends/src/server/org/opends/server/core/PasswordPolicy.java
+++ b/opends/src/server/org/opends/server/core/PasswordPolicy.java
@@ -844,6 +844,30 @@
       String message = getMessage(msgID, String.valueOf(configEntryDN));
       throw new ConfigException(msgID, message);
     }
+
+    // If both a maximum password age and a warning interval are provided, then
+    // ensure that the warning interval is less than the maximum age.  Further,
+    // if a minimum age is specified, then the sum of the minimum age and the
+    // warning interval should be less than the maximum age.
+    if (maximumPasswordAge > 0)
+    {
+      int warnInterval = Math.max(0, warningInterval);
+      if (minimumPasswordAge > 0)
+      {
+        if ((warnInterval + minimumPasswordAge) >= maximumPasswordAge)
+        {
+          msgID = MSGID_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE;
+          String message = getMessage(msgID, String.valueOf(configEntryDN));
+          throw new ConfigException(msgID, message);
+        }
+      }
+      else if (warnInterval >= maximumPasswordAge)
+      {
+        msgID = MSGID_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE;
+        String message = getMessage(msgID, String.valueOf(configEntryDN));
+        throw new ConfigException(msgID, message);
+      }
+    }
   }
 
 
diff --git a/opends/src/server/org/opends/server/messages/CoreMessages.java b/opends/src/server/org/opends/server/messages/CoreMessages.java
index 56aedf4..4fd0e24 100644
--- a/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -6329,6 +6329,29 @@
 
 
   /**
+   * The message ID for the message that will be used if the maximum password
+   * age is enabled, but the warning interval is longer than the maximum age.
+   * This takes a single argument, which is the DN of the password policy
+   * configuration entry.
+   */
+  public static final int MSGID_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_ERROR | 633;
+
+
+
+  /**
+   * The message ID for the message that will be used if the maximum password
+   * age is enabled, but the sum of the warning interval and the minimum age is
+   * greater than the maximum age.  This takes a single argument, which is the
+   * DN of the password policy configuration entry.
+   */
+  public static final int
+       MSGID_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE =
+            CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_ERROR | 634;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined
    * in this class.
    */
@@ -7897,6 +7920,18 @@
                     "contain any values for attribute " +
                     ATTR_PWPOLICY_DEFAULT_SCHEME + ", which specifies " +
                     "the set of default password storage schemes");
+    registerMessage(MSGID_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE,
+                    "The password policy configuration entry \"%s\" is " +
+                    "invalid because if a maximum password age is " +
+                    "configured, then the password expiration warning " +
+                    "interval must be shorter than the maximum password age");
+    registerMessage(MSGID_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE,
+                    "The password policy configuration entry \"%s\" is " +
+                    "invalid because if both a minimum password age and a " +
+                    "maximum password age are configured, then the sum of " +
+                    "the minimum password age and the password expiration " +
+                    "warning interval must be shorter than the maximum " +
+                    "password age");
     registerMessage(MSGID_PWPOLICY_DESCRIPTION_PW_ATTR,
                     "Specifies the attribute type used to hold user " +
                     "passwords.  This attribute type must be defined in the " +
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
index 72a650a..1edafcc 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
@@ -5111,6 +5111,79 @@
 
 
   /**
+   * Tests to ensure that the server will reject an attempt to set the password
+   * expiration warning interval to a value larger than the maximum password
+   * age.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testWarningIntervalGreaterThanMaxAge()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+      "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
+      "changetype: modify",
+      "replace: ds-cfg-maximum-password-age",
+      "ds-cfg-maximum-password-age: 5 days",
+      "-",
+      "replace: ds-cfg-password-expiration-warning-interval",
+      "ds-cfg-password-expiration-warning-interval: 10 days");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, System.out, System.err) ==
+                0);
+  }
+
+
+
+  /**
+   * Tests to ensure that the server will reject an attempt to set the sum of
+   * the password expiration warning interval and the minimum password age to a
+   * value larger than the maximum password age.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMinAgePlusWarningIntervalGreaterThanMaxAge()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+      "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
+      "changetype: modify",
+      "replace: ds-cfg-maximum-password-age",
+      "ds-cfg-maximum-password-age: 5 days",
+      "-",
+      "replace: ds-cfg-minimum-password-age",
+      "ds-cfg-minimum-password-age: 3 days",
+      "-",
+      "replace: ds-cfg-password-expiration-warning-interval",
+      "ds-cfg-password-expiration-warning-interval: 3 days");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, System.out, System.err) ==
+                0);
+  }
+
+
+
+  /**
    * Tests the <CODE>toString</CODE> methods with the default password policy.
    */
   @Test()

--
Gitblit v1.10.0