From 316d1ca1865cf303714810da8a4066ae19261512 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Fri, 19 Jul 2013 13:45:22 -0700 Subject: [PATCH] Ticket #47435 - Very large entryusn values after enabling the USN plugin and the lastusn value is negative. 1. Bug description: The initial value of lastusn is -1, but since the entryusn has the unsigned long long integer type, the server returns 18446744073709551615 == 0XFFFFFFFFFFFFFFFF. Fix description: The initial value "-1" is returned as it is. 2. Bug description: Entryusn syntax is defined as an integer in the schema. If negative values are accidentally stored in the entryusn value in the database, it was casted to the unsigned integer in the entryusn initialization code (usn_get_last_usn). Fix description: When an entryusn value is retrieved from the database, it's checked as a singed integer once and if it is negative, it's replaced with the initial value "-1". --- ldap/servers/plugins/usn/usn.c | 20 ++++++++++++++------ ldap/servers/slapd/back-ldbm/back-ldbm.h | 1 + ldap/servers/slapd/back-ldbm/ldbm_usn.c | 6 +++++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c index 338517f..db47591 100644 --- a/ldap/servers/plugins/usn/usn.c +++ b/ldap/servers/plugins/usn/usn.c @@ -695,9 +695,13 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, } if (be && be->be_usn_counter) { /* get a next USN counter from be_usn_counter; - * then minus 1 from it */ - PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, - slapi_counter_get_value(be->be_usn_counter)-1); + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); + } usn_berval.bv_len = strlen(usn_berval.bv_val); slapi_entry_attr_replace(e, attr, vals); } @@ -714,9 +718,13 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, continue; } /* get a next USN counter from be_usn_counter; - * then minus 1 from it */ - PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, - slapi_counter_get_value(be->be_usn_counter)-1); + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); + } usn_berval.bv_len = strlen(usn_berval.bv_val); if (USN_LAST_USN_ATTR_CORE_LEN+strlen(be->be_name)+2 > attr_len) { diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index 19c64ac..c0bea8d 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -877,6 +877,7 @@ typedef struct _back_search_result_set #define LDBM_ERROR_FOUND_DUPDN 9999 /* Initial entryusn value */ +#define SIGNEDINITIALUSN (-1) #define INITIALUSN (PRUint64)(-1) /* changelog backup dir name diff --git a/ldap/servers/slapd/back-ldbm/ldbm_usn.c b/ldap/servers/slapd/back-ldbm/ldbm_usn.c index 403e279..7c11a68 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_usn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_usn.c @@ -124,6 +124,7 @@ usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn) DBC *dbc = NULL; DBT key; /* For the last usn */ DBT value; + PRInt64 signed_last_usn; if (NULL == last_usn) { return rc; @@ -167,7 +168,10 @@ usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn) p = (char *)key.data; } if (0 == rc) { - *last_usn = strtoll(++p, (char **)NULL, 0); /* key.data: =num */ + signed_last_usn = strtoll(++p, (char **)NULL, 0); /* key.data: =num */ + if (signed_last_usn > SIGNEDINITIALUSN) { + *last_usn = signed_last_usn; + } } } else if (DB_NOTFOUND == rc) { /* if empty, it's okay. This is just a beginning. */ -- 1.8.1.4