Explorar o código

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 %!s(int64=15) %!d(string=hai) anos
pai
achega
bae65ae53a

+ 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");