ldap/servers/slapd/libglobs.c | 50 ++++++---------------
ldap/servers/slapd/slapi-private.h | 6 --
ldap/servers/slapd/time.c | 85 ++++++++++++++++++++++++++++++++++++-
3 files changed, 102 insertions(+), 39 deletions(-)
New commits:
commit 5727b8899700f574026bc9be5a1990c4c66619cf
Author: Noriko Hosoi <nhosoi(a)jiji.usersys.redhat.com>
Date: Wed Jan 19 16:49:57 2011 -0800
Bug 627993 - Inconsistent storage of password expiry times
https://bugzilla.redhat.com/show_bug.cgi?id=627993
Description: Allows passwordLockoutDuration, passwordResetFailureCount,
passwordMaxAge, passwordMinAge, passwordWarning to have <days>D|d,
<hours>H|h, <min>M|m, and <sec>S|s in addition to the current
representation <sec> in seconds.
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index e547b47..15f2aca 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -2163,7 +2163,6 @@ int
config_set_pw_lockduration( const char *attrname, char *value, char *errorbuf, int apply
) {
int retVal = LDAP_SUCCESS;
long duration = 0; /* in minutes */
- char *endp = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -2173,11 +2172,11 @@ config_set_pw_lockduration( const char *attrname, char *value,
char *errorbuf, i
errno = 0;
/* in seconds */
- duration = strtol(value, &endp, 10);
+ duration = parse_duration(value);
- if ( *endp != '\0' || errno == ERANGE || duration <= 0 || duration >
(MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
+ if ( errno == ERANGE || duration <= 0 || duration > (MAX_ALLOWED_TIME_IN_SECS -
current_time()) ) {
PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
- "password lockout duration \"%s\" seconds is invalid. ",
+ "password lockout duration \"%s\" is invalid. ",
value );
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -2195,7 +2194,6 @@ int
config_set_pw_resetfailurecount( const char *attrname, char *value, char *errorbuf, int
apply ) {
int retVal = LDAP_SUCCESS;
long duration = 0; /* in minutes */
- char *endp = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -2205,11 +2203,11 @@ config_set_pw_resetfailurecount( const char *attrname, char
*value, char *errorb
errno = 0;
/* in seconds */
- duration = strtol(value, &endp, 10);
+ duration = parse_duration(value);
- if ( *endp != '\0' || errno == ERANGE || duration < 0 || duration >
(MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
+ if ( errno == ERANGE || duration < 0 || duration > (MAX_ALLOWED_TIME_IN_SECS -
current_time()) ) {
PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
- "password reset count duration \"%s\" seconds is invalid. ",
+ "password reset count duration \"%s\" is invalid. ",
value );
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -3269,7 +3267,6 @@ int
config_set_pw_maxage( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
long age;
- char *endp = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -3279,11 +3276,11 @@ config_set_pw_maxage( const char *attrname, char *value, char
*errorbuf, int app
errno = 0;
/* age in seconds */
- age = strtol(value, &endp, 10);
+ age = parse_duration(value);
- if ( *endp != '\0' || errno == ERANGE || age <= 0 || age >
(MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
+ if ( age <= 0 || age > (MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
- "%s: password maximum age \"%s\" seconds is invalid. ",
+ "%s: password maximum age \"%s\" is invalid. ",
attrname, value );
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -3299,7 +3296,6 @@ int
config_set_pw_minage( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
long age;
- char *endPtr = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
if ( config_value_is_null( attrname, value, errorbuf, 1 )) {
@@ -3308,24 +3304,11 @@ config_set_pw_minage( const char *attrname, char *value, char
*errorbuf, int app
errno = 0;
/* age in seconds */
- age = strtol(value, &endPtr, 0 );
- /* endPtr should never be NULL, but we check just in case; if the
- value contains no digits, or a string that does not begin with
- a valid digit (e.g. "z2"), the days will be 0, and endPtr will
- point to the beginning of value; if days contains at least 1
- valid digit string, endPtr will point to the character after
- the end of the first valid digit string in value. Example:
- value = " 2 3 " endPtr will point at the space character
- between the 2 and the 3. So, we should be able to simply
- check to see if the character at *(endPtr - 1) is a digit.
- */
- if ( (age < 0) ||
- (age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
- (endPtr == NULL) || (endPtr == value) || !isdigit(*(endPtr-1)) ||
- errno == ERANGE ) {
+ age = parse_duration(value);
+ if ( age < 0 || age > (MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
- "%s: password minimum age \"%s\" seconds is invalid. ",
- attrname, value );
+ "%s: password minimum age \"%s\" is invalid. ",
+ attrname, value );
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
}
@@ -3340,7 +3323,6 @@ int
config_set_pw_warning( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
long sec;
- char *endp = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -3350,11 +3332,11 @@ config_set_pw_warning( const char *attrname, char *value, char
*errorbuf, int ap
errno = 0;
/* in seconds */
- sec = strtol(value, &endp, 10);
+ sec = parse_duration(value);
- if (*endp != '\0' || errno == ERANGE || sec < 0) {
+ if (errno == ERANGE || sec < 0) {
PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
- "%s: password warning age \"%s\" seconds is invalid, password
warning "
+ "%s: password warning age \"%s\" is invalid, password warning
"
"age must range from 0 to %ld seconds",
attrname, value, LONG_MAX );
retVal = LDAP_OPERATIONS_ERROR;
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 44e9bb3..0873a75 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1117,10 +1117,10 @@ time_t read_localTime(struct berval* from);
time_t parse_localTime(char* from);
void write_localTime(time_t from, struct berval* into);
time_t current_time( void );
-char* format_genTime(time_t from);
void write_genTime(time_t from, struct berval* into);
time_t read_genTime(struct berval* from);
-time_t parse_genTime(char* from);
+long parse_duration(char *value);
+char *gen_duration(long duration);
/* Client SSL code */
int slapd_security_library_is_initialized( void );
@@ -1226,8 +1226,6 @@ void DS_Sleep(PRIntervalTime ticks);
/* plugin.c */
int plugin_enabled(const char *plugin_name, void *identity);
-int is_slapd_running();
-
#ifdef __cplusplus
}
#endif
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 12e02ce..bf58cdf 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -399,5 +399,88 @@ parse_genTime (char* from)
tbv.bv_val = from;
tbv.bv_len = strlen (from);
- return read_genTime(&tbv);
+ return read_genTime(&tbv);
+}
+
+/*
+ * Return Value:
+ * Success: duration in seconds
+ * Failure: -1
+ */
+long
+parse_duration(char *value)
+{
+ char *input = NULL;
+ char *endp;
+ long duration = -1;
+ int times = 1;
+
+ if (NULL == value || '\0' == *value) {
+ goto bail;
+ }
+ input = slapi_ch_strdup(value);
+ endp = input + strlen(input) - 1;
+ while ((' ' == *endp || '\t' == *endp) && endp >= input)
{
+ endp--;
+ }
+ if ((endp == input) && !isdigit(*input)) {
+ goto bail;
+ }
+ if ('d' == *endp || 'D' == *endp) {
+ times = 60 * 60 * 24;
+ *endp = '\0';
+ } else if ('h' == *endp || 'H' == *endp) {
+ times = 60 * 60;
+ *endp = '\0';
+ } else if ('m' == *endp || 'M' == *endp) {
+ times = 60;
+ *endp = '\0';
+ } else if ('s' == *endp || 'S' == *endp) {
+ times = 1;
+ *endp = '\0';
+ }
+
+ duration = strtol(input, &endp, 10);
+ if ( *endp != '\0' || errno == ERANGE ) {
+ duration = -1;
+ goto bail;
+ }
+ duration *= times;
+
+bail:
+ slapi_ch_free_string(&input);
+ return duration;
+}
+
+/*
+ * caller is responsible to free the returned string
+ */
+char *
+gen_duration(long duration)
+{
+ char *duration_str = NULL;
+ long remainder = 0;
+ long devided = duration;
+ int devider[] = {60, 60, 24, 0};
+ char *unit[] = {"", "M", "H", "D", NULL};
+ int i = 0;
+
+ if (0 > duration) {
+ goto bail;
+ } else if (0 == duration) {
+ duration_str = strdup("0");
+ goto bail;
+ }
+ do {
+ remainder = devided % devider[i];
+ if (remainder) {
+ break;
+ }
+ devided /= devider[i++];
+ } while (devider[i]);
+
+ duration_str = slapi_ch_smprintf("%ld%s", devided, unit[i]);
+
+bail:
+ return duration_str;
}