Browse Source

Bug 197886 - Avoid overflow of UUID generator

It is theoretically possible to overflow the UUID generator if you
generate more than 10M UUIDs in a single minute.  Though this is
a highly unlikely scenario, we should avoid creating any duplicate
UUIDs.  This patch makes the server reject any ADD operations or
import tasks that would overflow the UUID generator.
Nathan Kinder 15 years ago
parent
commit
bae65ae53a

+ 23 - 8
ldap/servers/slapd/add.c

@@ -73,10 +73,10 @@
 /* Forward declarations */
 /* Forward declarations */
 static int add_internal_pb (Slapi_PBlock *pb);
 static int add_internal_pb (Slapi_PBlock *pb);
 static void op_shared_add (Slapi_PBlock *pb);
 static void op_shared_add (Slapi_PBlock *pb);
-static void add_created_attrs(Operation *op, Slapi_Entry *e);
+static int add_created_attrs(Operation *op, Slapi_Entry *e);
 static int check_rdn_for_created_attrs(Slapi_Entry *e);
 static int check_rdn_for_created_attrs(Slapi_Entry *e);
 static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry);
 static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry);
-static void add_uniqueid (Slapi_Entry *e);
+static int add_uniqueid (Slapi_Entry *e);
 static PRBool check_oc_subentry(Slapi_Entry *e, struct berval	**vals, char *normtype);
 static PRBool check_oc_subentry(Slapi_Entry *e, struct berval	**vals, char *normtype);
 
 
 /* This function is called to process operation that come over external connections */
 /* This function is called to process operation that come over external connections */
@@ -630,8 +630,12 @@ static void op_shared_add (Slapi_PBlock *pb)
 	slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);
 	slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);
 	if (!repl_op && lastmod)
 	if (!repl_op && lastmod)
 	{
 	{
-		add_created_attrs(operation, e);
-		/* JCM - We could end up with an entry without a uniqueid...??? */
+		if (add_created_attrs(operation, e) != 0)
+		{
+			send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+				"cannot insert computed attributes", 0, NULL);
+			goto done;
+		}
 	}
 	}
 
 
 	/* expand objectClass values to reflect the inheritance hierarchy */
 	/* expand objectClass values to reflect the inheritance hierarchy */
@@ -640,7 +644,12 @@ static void op_shared_add (Slapi_PBlock *pb)
 
 
     /* uniqueid needs to be generated for entries added during legacy replication */
     /* uniqueid needs to be generated for entries added during legacy replication */
     if (legacy_op)
     if (legacy_op)
-        add_uniqueid (e);
+	if (add_uniqueid(e) != UID_SUCCESS)
+	{
+		send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+			"cannot insert computed attributes", 0, NULL);
+		goto done;
+	}
 
 
 	/*
 	/*
 	 * call the pre-add plugins. if they succeed, call
 	 * call the pre-add plugins. if they succeed, call
@@ -742,7 +751,7 @@ done:
 	slapi_ch_free_string(&proxystr);
 	slapi_ch_free_string(&proxystr);
 }
 }
 
 
-static void
+static int 
 add_created_attrs(Operation *op, Slapi_Entry *e)
 add_created_attrs(Operation *op, Slapi_Entry *e)
 {
 {
 	char   buf[20];
 	char   buf[20];
@@ -786,7 +795,11 @@ add_created_attrs(Operation *op, Slapi_Entry *e)
 	bv.bv_len = strlen(bv.bv_val);
 	bv.bv_len = strlen(bv.bv_val);
 	slapi_entry_attr_replace(e, "modifytimestamp", bvals);
 	slapi_entry_attr_replace(e, "modifytimestamp", bvals);
 
 
-    add_uniqueid (e);
+	if (add_uniqueid(e) != UID_SUCCESS ) {
+		return( -1 );
+	}
+
+	return( 0 );
 }
 }
 
 
 
 
@@ -901,7 +914,7 @@ static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry)
     return;
     return;
 }
 }
 
 
-static void
+static int
 add_uniqueid (Slapi_Entry *e)
 add_uniqueid (Slapi_Entry *e)
 {
 {
     char *uniqueid;
     char *uniqueid;
@@ -918,6 +931,8 @@ add_uniqueid (Slapi_Entry *e)
 		LDAPDebug(LDAP_DEBUG_ANY, "add_created_attrs: uniqueid generation failed for %s; error = %d\n", 
 		LDAPDebug(LDAP_DEBUG_ANY, "add_created_attrs: uniqueid generation failed for %s; error = %d\n", 
 				   slapi_entry_get_dn_const(e), rc, 0);
 				   slapi_entry_get_dn_const(e), rc, 0);
 	}
 	}
+
+	return( rc );
 }
 }
 
 
 static PRBool
 static PRBool

+ 15 - 4
ldap/servers/slapd/back-ldbm/import-threads.c

@@ -77,7 +77,7 @@ static void import_decref_entry(struct backentry *ep)
 }
 }
 
 
 /* generate uniqueid if requested */
 /* generate uniqueid if requested */
-static void import_generate_uniqueid(ImportJob *job, Slapi_Entry *e)
+static int import_generate_uniqueid(ImportJob *job, Slapi_Entry *e)
 {
 {
     const char *uniqueid = slapi_entry_get_uniqueid(e);
     const char *uniqueid = slapi_entry_get_uniqueid(e);
     int rc;
     int rc;
@@ -106,6 +106,8 @@ static void import_generate_uniqueid(ImportJob *job, Slapi_Entry *e)
                        escape_string(slapi_entry_get_dn_const(e), ebuf), rc, 0 );
                        escape_string(slapi_entry_get_dn_const(e), ebuf), rc, 0 );
         }                
         }                
     }
     }
+
+    return( rc );
 }
 }
 
 
 
 
@@ -628,7 +630,10 @@ import_producer(void *param)
         }
         }
 
 
         /* generate uniqueid if necessary */
         /* generate uniqueid if necessary */
-        import_generate_uniqueid(job, e);
+        if (import_generate_uniqueid(job, e) != UID_SUCCESS) {
+            goto error;
+        }
+
         if (g_get_global_lastmod()) {
         if (g_get_global_lastmod()) {
             import_add_created_attrs(e);
             import_add_created_attrs(e);
         }
         }
@@ -789,7 +794,9 @@ index_set_entry_to_fifo(ImportWorkerInfo *info, Slapi_Entry *e,
     PRIntervalTime sleeptime = PR_MillisecondsToInterval(import_sleep_time);
     PRIntervalTime sleeptime = PR_MillisecondsToInterval(import_sleep_time);
 
 
     /* generate uniqueid if necessary */
     /* generate uniqueid if necessary */
-    import_generate_uniqueid(job, e);
+    if (import_generate_uniqueid(job, e) != UID_SUCCESS) {
+        goto bail;
+    }
 
 
     ep = import_make_backentry(e, id);
     ep = import_make_backentry(e, id);
     if (NULL == ep) {
     if (NULL == ep) {
@@ -2794,7 +2801,11 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
     /* Let's do this inside the lock !*/
     /* Let's do this inside the lock !*/
     id = job->lead_ID + 1;
     id = job->lead_ID + 1;
     /* generate uniqueid if necessary */
     /* generate uniqueid if necessary */
-    import_generate_uniqueid(job, entry);
+    if (import_generate_uniqueid(job, entry) != UID_SUCCESS) {
+        import_abort_all(job, 1);
+        PR_Unlock(job->wire_lock);
+        return -1;
+    }
 
 
     /* make into backentry */
     /* make into backentry */
     ep = import_make_backentry(entry, id);
     ep = import_make_backentry(entry, id);

+ 2 - 4
ldap/servers/slapd/uuid.c

@@ -365,10 +365,8 @@ static int uuid_create_mt(guid_t *uuid)
 	unsigned16 clock_seq = 0;
 	unsigned16 clock_seq = 0;
 
 
 	/* just bumps time sequence number. the actual
 	/* just bumps time sequence number. the actual
-       time calls are made by a uuid_update_state */
-    update_time_mt (&timestamp, &clock_seq);
-
-	if (timestamp == (uuid_time_t)NEED_TIME_UPDATE)
+	 * time calls are made by a uuid_update_state */
+	if (update_time_mt(&timestamp, &clock_seq) == UUID_TIME_ERROR)
 	{
 	{
 		slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uuid_create_mt: generator ran "
 		slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uuid_create_mt: generator ran "
 						 "out of sequence numbers.\n");
 						 "out of sequence numbers.\n");