Blame SOURCES/0045-Ticket-47960-cookie_change_info-returns-random-negat.patch

f92ce9
From 254ba1f6adf1575f5992ccc1a228ecd10ce96cc5 Mon Sep 17 00:00:00 2001
f92ce9
From: Noriko Hosoi <nhosoi@redhat.com>
f92ce9
Date: Fri, 12 Dec 2014 15:41:36 -0800
f92ce9
Subject: [PATCH 45/53] Ticket #47960 - cookie_change_info returns random
f92ce9
 negative number if there was no change in a tree
f92ce9
f92ce9
Description: An additional fix for the type mismatch for the change
f92ce9
numbers.  Change Number is declared as "unsigned long" in the Retro
f92ce9
Changelog plugin, while cookie_change_info in the Content Sync plugin
f92ce9
is "int", which could end up with a negative number when the change
f92ce9
number passes (2^31 - 1).
f92ce9
f92ce9
Changing the type of cookie_change_info to "unsigned long".
f92ce9
f92ce9
https://fedorahosted.org/389/ticket/47960
f92ce9
f92ce9
Reviewed by rmeggins@redhat.com and tbordaz@redhat.com (Thank you,
f92ce9
Rich and Thierry!!)
f92ce9
f92ce9
(cherry picked from commit 96c130b432ce0b15028e325c0e337679291aef9f)
f92ce9
(cherry picked from commit 61a4e7035742612a1a8bf42b16e93cc55776dc31)
f92ce9
---
f92ce9
 ldap/servers/plugins/sync/sync.h         |  9 +++--
f92ce9
 ldap/servers/plugins/sync/sync_refresh.c | 32 +++++++++++++-----
f92ce9
 ldap/servers/plugins/sync/sync_util.c    | 56 ++++++++++++++++++++------------
f92ce9
 3 files changed, 65 insertions(+), 32 deletions(-)
f92ce9
f92ce9
diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
f92ce9
index 0bcec7a..803c656 100644
f92ce9
--- a/ldap/servers/plugins/sync/sync.h
f92ce9
+++ b/ldap/servers/plugins/sync/sync.h
f92ce9
@@ -64,10 +64,12 @@
f92ce9
 #define CL_ATTR_NEWSUPERIOR "newsuperior"
f92ce9
 #define CL_SRCH_BASE "cn=changelog"
f92ce9
 
f92ce9
+#define SYNC_INVALID_CHANGENUM ((unsigned long)-1)
f92ce9
+
f92ce9
 typedef struct sync_cookie {
f92ce9
 	char *cookie_client_signature;
f92ce9
 	char *cookie_server_signature;
f92ce9
-	int cookie_change_info;
f92ce9
+	unsigned long cookie_change_info;
f92ce9
 } Sync_Cookie;
f92ce9
 
f92ce9
 typedef struct sync_update {
f92ce9
@@ -80,8 +82,8 @@ typedef struct sync_update {
f92ce9
 
f92ce9
 typedef struct sync_callback {
f92ce9
 	Slapi_PBlock *orig_pb;
f92ce9
-	int changenr;
f92ce9
-	int change_start;
f92ce9
+	unsigned long changenr;
f92ce9
+	unsigned long change_start;
f92ce9
 	int cb_err;
f92ce9
 	Sync_UpdateNode *cb_updates;
f92ce9
 } Sync_CallBackData;
f92ce9
@@ -112,6 +114,7 @@ int sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie);
f92ce9
 void sync_cookie_free (Sync_Cookie **freecookie);
f92ce9
 char * sync_cookie2str(Sync_Cookie *cookie);
f92ce9
 int sync_number2int(char *nrstr);
f92ce9
+unsigned long sync_number2ulong(char *nrstr);
f92ce9
 char *sync_nsuniqueid2uuid(const char *nsuniqueid);
f92ce9
 
f92ce9
 int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb);
f92ce9
diff --git a/ldap/servers/plugins/sync/sync_refresh.c b/ldap/servers/plugins/sync/sync_refresh.c
f92ce9
index 4e256e6..bfff77b 100644
f92ce9
--- a/ldap/servers/plugins/sync/sync_refresh.c
f92ce9
+++ b/ldap/servers/plugins/sync/sync_refresh.c
f92ce9
@@ -293,9 +293,9 @@ sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_C
f92ce9
 	cb_data.orig_pb = pb;
f92ce9
 	cb_data.change_start = client_cookie->cookie_change_info;
f92ce9
 
f92ce9
-	filter = slapi_ch_smprintf("(&(changenumber>=%d)(changenumber<=%d))",
f92ce9
-					client_cookie->cookie_change_info,
f92ce9
-					server_cookie->cookie_change_info);
f92ce9
+	filter = slapi_ch_smprintf("(&(changenumber>=%lu)(changenumber<=%lu))",
f92ce9
+	                           client_cookie->cookie_change_info,
f92ce9
+	                           server_cookie->cookie_change_info);
f92ce9
 	slapi_search_internal_set_pb(
f92ce9
 		seq_pb, 
f92ce9
 		CL_SRCH_BASE,
f92ce9
@@ -305,7 +305,7 @@ sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_C
f92ce9
 		0,
f92ce9
 		NULL, NULL, 
f92ce9
 		plugin_get_default_component_id(),
f92ce9
-		0);							  
f92ce9
+		0);
f92ce9
 
f92ce9
 	rc = slapi_search_internal_callback_pb (
f92ce9
 		seq_pb, &cb_data, NULL, sync_read_entry_from_changelog, NULL);
f92ce9
@@ -460,6 +460,7 @@ sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data)
f92ce9
 	int chg_req;
f92ce9
 	int prev = 0;
f92ce9
 	int index = 0;
f92ce9
+	unsigned long chgnum = 0;
f92ce9
 	Sync_CallBackData *cb = (Sync_CallBackData *) cb_data;
f92ce9
 
f92ce9
 	if (cb == NULL) {
f92ce9
@@ -470,13 +471,28 @@ sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data)
f92ce9
 	if (uniqueid == NULL) {
f92ce9
 		slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, 
f92ce9
 			"Retro Changelog does not provied nsuniquedid."
f92ce9
-			"Check RCL plugin configuration." );
f92ce9
+			"Check RCL plugin configuration.\n" );
f92ce9
 		return(1);
f92ce9
 	}
f92ce9
-	chgtype = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHGTYPE);
f92ce9
 	chgnr = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHANGENUMBER);
f92ce9
-
f92ce9
-	index = sync_number2int(chgnr) - cb->change_start;
f92ce9
+	chgnum = sync_number2ulong(chgnr);
f92ce9
+	if (SYNC_INVALID_CHANGENUM == chgnum) {
f92ce9
+		slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, 
f92ce9
+			"Change number provided by Retro Changelog is invalid: %s\n", chgnr);
f92ce9
+		slapi_ch_free_string(&chgnr);
f92ce9
+		slapi_ch_free_string(&uniqueid);
f92ce9
+		return(1);
f92ce9
+	}
f92ce9
+	if (chgnum < cb->change_start) {
f92ce9
+		slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, 
f92ce9
+			"Change number provided by Retro Changelog %s is less than the initial number %lu\n",
f92ce9
+			chgnr, cb->change_start);
f92ce9
+		slapi_ch_free_string(&chgnr);
f92ce9
+		slapi_ch_free_string(&uniqueid);
f92ce9
+		return(1);
f92ce9
+	}
f92ce9
+	index = chgnum - cb->change_start;
f92ce9
+	chgtype = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHGTYPE);
f92ce9
 	chg_req = sync_str2chgreq(chgtype);
f92ce9
 	switch (chg_req){ 
f92ce9
 		case LDAP_REQ_ADD:
f92ce9
diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c
f92ce9
index af22bcb..67cb453 100644
f92ce9
--- a/ldap/servers/plugins/sync/sync_util.c
f92ce9
+++ b/ldap/servers/plugins/sync/sync_util.c
f92ce9
@@ -266,10 +266,10 @@ sync_cookie2str(Sync_Cookie *cookie)
f92ce9
 	char *cookiestr = NULL;
f92ce9
 
f92ce9
 	if (cookie) {
f92ce9
-		cookiestr = slapi_ch_smprintf("%s#%s#%d",
f92ce9
-				cookie->cookie_server_signature,
f92ce9
-				cookie->cookie_client_signature,
f92ce9
-				cookie->cookie_change_info);
f92ce9
+		cookiestr = slapi_ch_smprintf("%s#%s#%lu",
f92ce9
+		                               cookie->cookie_server_signature,
f92ce9
+		                               cookie->cookie_client_signature,
f92ce9
+		                               cookie->cookie_change_info);
f92ce9
 	}
f92ce9
 	return(cookiestr);
f92ce9
 }
f92ce9
@@ -370,10 +370,11 @@ sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data)
f92ce9
 			slapi_attr_first_value( chattr,&sval );
f92ce9
 			if ( NULL != sval ) {
f92ce9
 				value = slapi_value_get_berval ( sval );
f92ce9
-				if( NULL != value && NULL != value->bv_val &&
f92ce9
-					'\0' != value->bv_val[0]) {
f92ce9
-					cb->changenr = sync_number2int(value->bv_val);
f92ce9
-					cb->cb_err = 0; /* changenr successfully set */
f92ce9
+				if (value && value->bv_val && ('\0' != value->bv_val[0])) {
f92ce9
+					cb->changenr = sync_number2ulong(value->bv_val);
f92ce9
+					if (SYNC_INVALID_CHANGENUM != cb->changenr) {
f92ce9
+						cb->cb_err = 0; /* changenr successfully set */
f92ce9
+					}
f92ce9
 				}
f92ce9
 			}
f92ce9
 		}
f92ce9
@@ -452,31 +453,30 @@ sync_cookie_get_client_info(Slapi_PBlock *pb)
f92ce9
 	clientinfo = slapi_ch_smprintf("%s:%s:%s",clientdn,targetdn,strfilter);
f92ce9
 	return (clientinfo);
f92ce9
 }
f92ce9
-static int
f92ce9
+static unsigned long
f92ce9
 sync_cookie_get_change_number(int lastnr, const char *uniqueid)
f92ce9
 {
f92ce9
 	Slapi_PBlock *srch_pb;
f92ce9
 	Slapi_Entry **entries;
f92ce9
 	Slapi_Entry *cl_entry;
f92ce9
 	int rv;
f92ce9
-	int newnr = -1;
f92ce9
+	unsigned long newnr = SYNC_INVALID_CHANGENUM;
f92ce9
 	char *filter = slapi_ch_smprintf("(&(changenumber>=%d)(targetuniqueid=%s))",lastnr,uniqueid);
f92ce9
 
f92ce9
 	srch_pb = slapi_pblock_new();
f92ce9
-    	slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE,
f92ce9
-           				LDAP_SCOPE_SUBTREE, filter,
f92ce9
-            				NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
f92ce9
- 	slapi_search_internal_pb(srch_pb);
f92ce9
+	slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE, LDAP_SCOPE_SUBTREE, filter,
f92ce9
+	                             NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
f92ce9
+	slapi_search_internal_pb(srch_pb);
f92ce9
 	slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv;;
f92ce9
-	if ( rv == LDAP_SUCCESS) {
f92ce9
+	if (rv == LDAP_SUCCESS) {
f92ce9
 		slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
f92ce9
-    		if (entries && *entries) {
f92ce9
+		if (entries && *entries) {
f92ce9
 			Slapi_Attr *attr;
f92ce9
 			Slapi_Value *val;
f92ce9
 			cl_entry = *entries; /* only use teh first one */
f92ce9
 			slapi_entry_attr_find(cl_entry, CL_ATTR_CHANGENUMBER, &attr);
f92ce9
 			slapi_attr_first_value(attr, &val;;
f92ce9
-			newnr = sync_number2int((char *)slapi_value_get_string(val));
f92ce9
+			newnr = sync_number2ulong((char *)slapi_value_get_string(val));
f92ce9
 		}
f92ce9
 	}
f92ce9
 
f92ce9
@@ -579,8 +579,8 @@ sync_cookie_parse (char *cookie)
f92ce9
 		if (p) {
f92ce9
 			*p = '\0';
f92ce9
 			sc->cookie_client_signature = slapi_ch_strdup(q);
f92ce9
-			sc->cookie_change_info = sync_number2int(p+1);
f92ce9
-			if (sc->cookie_change_info < 0) {
f92ce9
+			sc->cookie_change_info = sync_number2ulong(p+1);
f92ce9
+			if (SYNC_INVALID_CHANGENUM == sc->cookie_change_info) {
f92ce9
 				goto error_return;
f92ce9
 			}
f92ce9
 		} else {
f92ce9
@@ -716,14 +716,28 @@ sync_pblock_copy(Slapi_PBlock *src)
f92ce9
 	return dest;
f92ce9
 }
f92ce9
 
f92ce9
-int sync_number2int(char *chgnrstr)
f92ce9
+int
f92ce9
+sync_number2int(char *chgnrstr)
f92ce9
 {
f92ce9
 	char *end;
f92ce9
 	int nr;
f92ce9
-	nr = strtoul(chgnrstr, &end, 10);
f92ce9
+	nr = (int)strtoul(chgnrstr, &end, 10);
f92ce9
 	if ( *end == '\0') {
f92ce9
 		return (nr);
f92ce9
 	} else {
f92ce9
 		return (-1);
f92ce9
 	}
f92ce9
 }
f92ce9
+
f92ce9
+unsigned long
f92ce9
+sync_number2ulong(char *chgnrstr)
f92ce9
+{
f92ce9
+	char *end;
f92ce9
+	unsigned long nr;
f92ce9
+	nr = strtoul(chgnrstr, &end, 10);
f92ce9
+	if ( *end == '\0') {
f92ce9
+		return (nr);
f92ce9
+	} else {
f92ce9
+		return SYNC_INVALID_CHANGENUM;
f92ce9
+	}
f92ce9
+}
f92ce9
-- 
f92ce9
1.9.3
f92ce9