浏览代码

Ticket #47960 - cookie_change_info returns random negative number if there was no change in a tree

Description: When no changes had not been made, Retro Changelog db
was empty and the search callback sync_handle_cnum_entry in the
Content Synchronization had no chance to be called.  If it was not
called, an uninitialized garbage value in Sync_CallBackData was set
to cookie_change_info.

This patch checks if the search callback sync_handle_cnum_entry is
called or not.  If it is not called, set 0 to cookie_change_info.

https://fedorahosted.org/389/ticket/47960

Reviewed by [email protected] and [email protected] (Thank you,
Rich and Thierry!!)
Noriko Hosoi 11 年之前
父节点
当前提交
a908c6b57c
共有 2 个文件被更改,包括 12 次插入4 次删除
  1. 2 0
      ldap/servers/plugins/sync/sync.h
  2. 10 4
      ldap/servers/plugins/sync/sync_util.c

+ 2 - 0
ldap/servers/plugins/sync/sync.h

@@ -76,6 +76,8 @@ typedef struct sync_update {
 	Slapi_Entry *upd_e;
 } Sync_UpdateNode;
 
+#define SYNC_CALLBACK_PREINIT (-1)
+
 typedef struct sync_callback {
 	Slapi_PBlock *orig_pb;
 	int changenr;

+ 10 - 4
ldap/servers/plugins/sync/sync_util.c

@@ -373,6 +373,7 @@ sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data)
 				if( NULL != value && NULL != value->bv_val &&
 					'\0' != value->bv_val[0]) {
 					cb->changenr = sync_number2int(value->bv_val);
+					cb->cb_err = 0; /* changenr successfully set */
 				}
 			}
 		}
@@ -500,7 +501,7 @@ sync_cookie_get_change_info(Sync_CallBackData *scbd)
 	slapi_pblock_init(seq_pb);
 
 	slapi_seq_internal_set_pb(seq_pb, base, SLAPI_SEQ_LAST, attrname, NULL, NULL, 0, 0, 
-		plugin_get_default_component_id(), 0);							  
+		plugin_get_default_component_id(), 0);
 
 	rc = slapi_seq_internal_callback_pb (seq_pb, scbd, NULL, sync_handle_cnum_entry, NULL);
 	slapi_pblock_destroy(seq_pb);
@@ -518,15 +519,20 @@ sync_cookie_create (Slapi_PBlock *pb)
 
 	Sync_CallBackData scbd;
 	int rc;
-	Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie));
-
+	Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_calloc(1, sizeof(Sync_Cookie));
 
+	scbd.cb_err = SYNC_CALLBACK_PREINIT;
 	rc = sync_cookie_get_change_info (&scbd);
 
 	if (rc == 0) {
 		sc->cookie_server_signature = sync_cookie_get_server_info(pb);
 		sc->cookie_client_signature = sync_cookie_get_client_info(pb);
-		sc->cookie_change_info = scbd.changenr;
+		if (scbd.cb_err == SYNC_CALLBACK_PREINIT) {
+			/* changenr is not initialized. */
+			sc->cookie_change_info = 0;
+		} else {
+			sc->cookie_change_info = scbd.changenr;
+		}
 	} else {
 		slapi_ch_free ((void **)&sc);
 		sc = NULL;