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
3 changed files with 40 additions and 16 deletions
  1. 23 8
      ldap/servers/slapd/add.c
  2. 15 4
      ldap/servers/slapd/back-ldbm/import-threads.c
  3. 2 4
      ldap/servers/slapd/uuid.c

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

@@ -73,10 +73,10 @@
 /* Forward declarations */
 static int add_internal_pb (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 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);
 
 /* 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);
 	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 */
@@ -640,7 +644,12 @@ static void op_shared_add (Slapi_PBlock *pb)
 
     /* uniqueid needs to be generated for entries added during legacy replication */
     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
@@ -742,7 +751,7 @@ done:
 	slapi_ch_free_string(&proxystr);
 }
 
-static void
+static int 
 add_created_attrs(Operation *op, Slapi_Entry *e)
 {
 	char   buf[20];
@@ -786,7 +795,11 @@ add_created_attrs(Operation *op, Slapi_Entry *e)
 	bv.bv_len = strlen(bv.bv_val);
 	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;
 }
 
-static void
+static int
 add_uniqueid (Slapi_Entry *e)
 {
     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", 
 				   slapi_entry_get_dn_const(e), rc, 0);
 	}
+
+	return( rc );
 }
 
 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 */
-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);
     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 );
         }                
     }
+
+    return( rc );
 }
 
 
@@ -628,7 +630,10 @@ import_producer(void *param)
         }
 
         /* generate uniqueid if necessary */
-        import_generate_uniqueid(job, e);
+        if (import_generate_uniqueid(job, e) != UID_SUCCESS) {
+            goto error;
+        }
+
         if (g_get_global_lastmod()) {
             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);
 
     /* 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);
     if (NULL == ep) {
@@ -2794,7 +2801,11 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
     /* Let's do this inside the lock !*/
     id = job->lead_ID + 1;
     /* 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 */
     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;
 
 	/* 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 "
 						 "out of sequence numbers.\n");