ldap/servers/slapd/add.c | 31 +++++++++++++++++++-------
ldap/servers/slapd/back-ldbm/import-threads.c | 19 ++++++++++++---
ldap/servers/slapd/uuid.c | 6 +----
3 files changed, 40 insertions(+), 16 deletions(-)
New commits:
commit bae65ae53a7e77c0159007e37bd596b6fa80da35
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Mon Nov 29 15:40:31 2010 -0800
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.
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 200d79c..0bf6ef0 100644
--- a/ldap/servers/slapd/add.c
+++ b/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
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index f7dfe44..6320568 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/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);
diff --git a/ldap/servers/slapd/uuid.c b/ldap/servers/slapd/uuid.c
index 43aa003..5e26be2 100644
--- a/ldap/servers/slapd/uuid.c
+++ b/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 (×tamp, &clock_seq);
-
- if (timestamp == (uuid_time_t)NEED_TIME_UPDATE)
+ * time calls are made by a uuid_update_state */
+ if (update_time_mt(×tamp, &clock_seq) == UUID_TIME_ERROR)
{
slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uuid_create_mt: generator ran "
"out of sequence numbers.\n");