[Date Prev][Date Next] [Chronological] [Thread] [Top]

ITS #7161, ppolicy pwdFailureTime resolution should be better than 1 second



I realize that development discussion is supposed to go to
openldap-devel, but despite having subscribed to that a month ago, none
of my postings have gone through. I hear they are having some technical
difficulties with that list, so for the sake of this submission not
being indefinitely delayed, here it is.

Attached is a proposed patch to fix ITS #7161. It uses the same method
as the accesslog module to generate a subsecond generalized time,
appending the o_tincr value from the operation structure as fractional
seconds. The only other code that looks at the value of that attribute
calls parse_time to pull seconds out of it (ignoring the fractional
second part), so other than modifying the format the attribute is stored
in I don't believe there are any other changes required with this.

>From 800de5001a42fb421d814b04b09154f1ecccdc0b Mon Sep 17 00:00:00 2001
From: "Paul B. Henson" <henson@acm.org>
Date: Fri, 23 May 2014 14:10:54 -0700
Subject: [PATCH] ITS#7161 ppolicy pwdFailureTime resolution should be better
 than 1 second

---
 servers/slapd/overlays/ppolicy.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c
index 83aa099..822d9fd 100644
--- a/servers/slapd/overlays/ppolicy.c
+++ b/servers/slapd/overlays/ppolicy.c
@@ -910,9 +910,10 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
 	int pwExpired = 0;
 	int ngut = -1, warn = -1, age, rc;
 	Attribute *a;
-	time_t now, pwtime = (time_t)-1;
-	char nowstr[ LDAP_LUTIL_GENTIME_BUFSIZE ];
-	struct berval timestamp;
+	time_t pwtime = (time_t)-1;
+	char timestr[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+	char failtimestr[ LDAP_LUTIL_GENTIME_BUFSIZE+8 ];
+	struct berval timestamp, failtimestamp;
 	BackendInfo *bi = op->o_bd->bd_info;
 	Entry *e;
 
@@ -929,10 +930,16 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
 		return SLAP_CB_CONTINUE;
 	}
 
-	now = slap_get_time(); /* stored for later consideration */
-	timestamp.bv_val = nowstr;
-	timestamp.bv_len = sizeof(nowstr);
-	slap_timestamp( &now, &timestamp );
+	timestamp.bv_val = timestr;
+	timestamp.bv_len = sizeof(timestr);
+	slap_timestamp( &op->o_time, &timestamp );
+
+	/* Separate timestamp for pwdFailureTime with subsecond granularity */
+	failtimestamp.bv_val = failtimestr;
+	failtimestamp.bv_len = sizeof(failtimestr);
+	slap_timestamp( &op->o_time, &failtimestamp );
+	snprintf( failtimestamp.bv_val + failtimestamp.bv_len-1, sizeof(".123456Z"), ".%06dZ", op->o_tincr );
+	failtimestamp.bv_len += STRLENOF(".123456");
 
 	if ( rs->sr_err == LDAP_INVALID_CREDENTIALS ) {
 		int i = 0, fc = 0;
@@ -946,8 +953,8 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
 		m->sml_values = ch_calloc( sizeof(struct berval), 2 );
 		m->sml_nvalues = ch_calloc( sizeof(struct berval), 2 );
 
-		ber_dupbv( &m->sml_values[0], &timestamp );
-		ber_dupbv( &m->sml_nvalues[0], &timestamp );
+		ber_dupbv( &m->sml_values[0], &failtimestamp );
+		ber_dupbv( &m->sml_nvalues[0], &failtimestamp );
 		m->sml_next = mod;
 		mod = m;
 
@@ -966,7 +973,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
 				 */
 				if (ppb->pp.pwdFailureCountInterval == 0) {
 					fc++;
-				} else if (now <=
+				} else if (op->o_time <=
 							parse_time(a->a_nvals[i].bv_val) +
 							ppb->pp.pwdFailureCountInterval) {
 
@@ -1052,7 +1059,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
 				 * the password older than the maximum age
 				 * allowed. (Ignore case 2 from I-D, it's just silly.)
 				 */
-				if (now - pwtime > ppb->pp.pwdMaxAge ) pwExpired = 1;
+				if (op->o_time - pwtime > ppb->pp.pwdMaxAge ) pwExpired = 1;
 			}
 		}
 
@@ -1108,7 +1115,7 @@ check_expiring_password:
 		if ((ppb->pp.pwdMaxAge < 1) || (pwExpired) || (ppb->pp.pwdExpireWarning < 1))
 			goto done;
 
-		age = (int)(now - pwtime);
+		age = (int)(op->o_time - pwtime);
 		
 		/*
 		 * We know that there is a password Change Time attribute - if
-- 
1.8.3.2