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(-)
New commits:
commit a94a75edd400471ed84ded1be7c3c62fc2c2b54d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Jul 19 13:45:22 2013 -0700
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".
https://fedorahosted.org/389/ticket/47435
Reviewed by Mark and Rich (Thank you!!)
(cherry picked from commit c94da991450da486b2032815b867bd2548a1614c)
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 108d7e1..9410998 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -865,6 +865,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. */