Browse Source

Bug 681015 - RFE: allow fine grained password policy duration attributes in days, hours, minutes, as well

https://bugzilla.redhat.com/show_bug.cgi?id=681015

Description: Adding an ability to handle ##D|d, ##H|h, ##M|m, ##S|s
format to the fine grained password policy duration attributes:
  passwordMinAge, passwordMaxAge, passwordWarning,
  passwordLockoutDuration
Valid value for these duraton parameters are
  . duration in seconds with no extension
  . duration in days, hours, minutes, and seconds with extesion
    D|d, H|h, M|m, and S|s, respectively.
The value should be less than MAX_ALLOWED_TIME_IN_SECS - current_time.
Noriko Hosoi 14 năm trước cách đây
mục cha
commit
53839a8b27

+ 6 - 5
ldap/servers/slapd/modify.c

@@ -109,15 +109,16 @@ static struct attr_value_check {
 	{CONFIG_PW_EXP_ATTRIBUTE, attr_check_onoff, 0, 0},
 	{CONFIG_PW_UNLOCK_ATTRIBUTE, attr_check_onoff, 0, 0},
 	{CONFIG_PW_HISTORY_ATTRIBUTE, attr_check_onoff, 0, 0},
-	{CONFIG_PW_MINAGE_ATTRIBUTE, check_pw_minage_value, -1, -1},
-	{CONFIG_PW_WARNING_ATTRIBUTE, attr_check_minmax, 0, -1},
+	{CONFIG_PW_MINAGE_ATTRIBUTE, check_pw_duration_value, -1, -1},
+	{CONFIG_PW_WARNING_ATTRIBUTE, check_pw_duration_value, 0, -1},
 	{CONFIG_PW_MINLENGTH_ATTRIBUTE, attr_check_minmax, 2, 512},
 	{CONFIG_PW_MAXFAILURE_ATTRIBUTE, attr_check_minmax, 1, 32767},
 	{CONFIG_PW_INHISTORY_ATTRIBUTE, attr_check_minmax, 2, 24},
-	{CONFIG_PW_LOCKDURATION_ATTRIBUTE, check_pw_lockduration_value, -1, -1},
+	{CONFIG_PW_LOCKDURATION_ATTRIBUTE, check_pw_duration_value, -1, -1},
 	{CONFIG_PW_RESETFAILURECOUNT_ATTRIBUTE, check_pw_resetfailurecount_value, -1, -1},
 	{CONFIG_PW_GRACELIMIT_ATTRIBUTE, attr_check_minmax, 0, -1},
-	{CONFIG_PW_STORAGESCHEME_ATTRIBUTE, check_pw_storagescheme_value, -1, -1}
+	{CONFIG_PW_STORAGESCHEME_ATTRIBUTE, check_pw_storagescheme_value, -1, -1},
+	{CONFIG_PW_MAXAGE_ATTRIBUTE, check_pw_duration_value, -1, -1}
 };
 
 /* This function is called to process operation that come over external connections */
@@ -713,7 +714,7 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
 			while ( tmpmods && *tmpmods )
 			{
 				if ((*tmpmods)->mod_bvalues != NULL &&
-				!SLAPI_IS_MOD_DELETE((*tmpmods)->mod_op))
+				    !SLAPI_IS_MOD_DELETE((*tmpmods)->mod_op))
 				{
 					for (i=0; i < numattr; i++)
 					{

+ 45 - 32
ldap/servers/slapd/pw.c

@@ -1604,19 +1604,37 @@ new_passwdPolicy(Slapi_PBlock *pb, char *dn)
 				slapi_attr_get_type(attr, &attr_name);
 				if (!strcasecmp(attr_name, "passwordminage")) {
 					if ((sval = attr_get_present_values(attr))) {
-						pwdpolicy->pw_minage = slapi_value_get_long(*sval);
+						pwdpolicy->pw_minage = slapi_value_get_timelong(*sval);
+						if (-1 == pwdpolicy->pw_minage) {
+							LDAPDebug2Args(LDAP_DEBUG_ANY, 
+								"Password Policy Entry%s: Invalid passwordMinAge: %s\n",
+								slapi_entry_get_dn_const(pw_entry),
+								slapi_value_get_string(*sval));
+						}
 					}
 				}
 				else
 				if (!strcasecmp(attr_name, "passwordmaxage")) {
 					if ((sval = attr_get_present_values(attr))) {
-						pwdpolicy->pw_maxage = slapi_value_get_long(*sval);
+						pwdpolicy->pw_maxage = slapi_value_get_timelong(*sval);
+						if (-1 == pwdpolicy->pw_maxage) {
+							LDAPDebug2Args(LDAP_DEBUG_ANY, 
+								"Password Policy Entry%s: Invalid passwordMaxAge: %s\n",
+								slapi_entry_get_dn_const(pw_entry),
+								slapi_value_get_string(*sval));
+						}
 					}
 				}
 				else
 				if (!strcasecmp(attr_name, "passwordwarning")) {
 					if ((sval = attr_get_present_values(attr))) {
-						pwdpolicy->pw_warning = slapi_value_get_long(*sval);
+						pwdpolicy->pw_warning = slapi_value_get_timelong(*sval);
+						if (-1 == pwdpolicy->pw_warning) {
+							LDAPDebug2Args(LDAP_DEBUG_ANY, 
+								"Password Policy Entry%s: Invalid passwordWarning: %s\n",
+								slapi_entry_get_dn_const(pw_entry),
+								slapi_value_get_string(*sval));
+						}
 					}
 				}
 				else
@@ -1899,40 +1917,35 @@ pw_boolean_str2value (const char *str)
 }
 
 int
-check_pw_minage_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf )
-{
-	int retVal = LDAP_SUCCESS;
-	int age;
-	char *endPtr = NULL;
-
-	age = strtol(value, &endPtr, 0 );
-	if ( (age < 0) || 
-		(age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
-		(endPtr == NULL) || (endPtr == value) || !isdigit(*(endPtr-1)) )
-	{
-		PR_snprintf ( errorbuf, BUFSIZ, 
-				"password minimum age \"%s\" seconds is invalid. ",
-				value );
-		retVal = LDAP_CONSTRAINT_VIOLATION;
-	}
-
-	return retVal;
-}
-
-int
-check_pw_lockduration_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf )
+check_pw_duration_value( const char *attr_name, char *value, 
+                       long minval, long maxval, char *errorbuf )
 {
 	int retVal = LDAP_SUCCESS;
-	long duration = 0; /* in minutes */
+	long age;
 
-	/* in seconds */
-	duration = strtol (value, NULL, 0);
-
-	if ( duration <= 0 || duration > (MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
+	age = parse_duration(value);
+	if (-1 == age) {
 		PR_snprintf ( errorbuf, BUFSIZ, 
-			"password lockout duration \"%s\" seconds is invalid. ",
-			value );
+		              "password minimum age \"%s\" is invalid. ", value );
 		retVal = LDAP_CONSTRAINT_VIOLATION;
+	} else if (0 == strcasecmp(CONFIG_PW_LOCKDURATION_ATTRIBUTE, attr_name)) {
+		if ( (age <= 0) ||
+			 (age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
+			 ((-1 != minval) && (age < minval)) ||
+			 ((-1 != maxval) && (age > maxval))) {
+			PR_snprintf ( errorbuf, BUFSIZ, "%s: \"%s\" seconds is invalid. ",
+			              attr_name, value );
+			retVal = LDAP_CONSTRAINT_VIOLATION;
+		}
+	} else {
+		if ( (age < 0) ||
+			 (age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
+			 ((-1 != minval) && (age < minval)) ||
+			 ((-1 != maxval) && (age > maxval))) {
+			PR_snprintf ( errorbuf, BUFSIZ, "%s: \"%s\" seconds is invalid. ",
+			              attr_name, value );
+			retVal = LDAP_CONSTRAINT_VIOLATION;
+		}
 	}
 
 	return retVal;

+ 1 - 2
ldap/servers/slapd/pw.h

@@ -88,8 +88,7 @@ struct passwordpolicyarray *new_passwdPolicy ( Slapi_PBlock *pb, char *dn );
 void delete_passwdPolicy( struct passwordpolicyarray **pwpolicy);
 
 /* function for checking the values of fine grained password policy attributes */
-int check_pw_minage_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf );
-int check_pw_lockduration_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf );
+int check_pw_duration_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf );
 int check_pw_resetfailurecount_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf );
 int check_pw_storagescheme_value( const char *attr_name, char *value, long minval, long maxval, char *errorbuf );
 

+ 18 - 0
ldap/servers/slapd/slapi-plugin.h

@@ -4173,6 +4173,24 @@ long long slapi_value_get_longlong(const Slapi_Value *value);
  */
 unsigned long long slapi_value_get_ulonglong(const Slapi_Value *value);
 
+/**
+ * Retrieves the value of a \c Slapi_Value structure as a long integer.
+ *
+ * \param value Pointer to the value you wish to get as a long integer.
+ *        The value could end with D or d for days, H or h for hours,
+ *        M or m for minutes, S or s for seconds, or no extension.
+ * \return A long integer that corresponds to the value stored in the
+ *         \c Slapi_Value structure.
+ * \return \c 0 if there is no value.
+ * \return \c -1 if the given value is invalid.
+ * \see slapi_value_get_int()
+ * \see slapi_value_get_uint()
+ * \see slapi_value_get_ulong()
+ * \see slapi_value_get_longlong()
+ * \see slapi_value_get_ulonglong()
+ */
+long slapi_value_get_timelong(const Slapi_Value *value);
+
 /**
  * Gets the length of a value contained in a \c Slapi_Value structure.
  *

+ 16 - 0
ldap/servers/slapd/value.c

@@ -509,6 +509,22 @@ slapi_value_get_ulonglong(const Slapi_Value *value)
         return r;
 }
 
+long 
+slapi_value_get_timelong(const Slapi_Value *value)
+{
+	long r= 0;
+	if(NULL!=value)
+	{
+		char *p;
+        p = slapi_ch_malloc(value->bv.bv_len + 1);
+        memcpy (p, value->bv.bv_val, value->bv.bv_len);
+        p [value->bv.bv_len] = '\0';
+        r = (long)parse_duration(p);
+        slapi_ch_free((void **)&p);
+	}
+	return r;
+}
+
 int
 slapi_value_compare(const Slapi_Attr *a,const Slapi_Value *v1,const Slapi_Value *v2)
 {