andykimpe / rpms / 389-ds-base

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