idmap_tdb2: fix a race condition in idmap_tdb2_allocate_id().
authorMichael Adam <obnox@samba.org>
Tue, 5 Aug 2008 20:38:44 +0000 (22:38 +0200)
committerMichael Adam <obnox@samba.org>
Tue, 5 Aug 2008 21:43:53 +0000 (23:43 +0200)
The race is a regression introduced by the change to dbwrap.
It might have led to two concurrent processes returning the same id.

This fix is achieved by changing dbwrap_change_uint32_atomic() to
match the original behaviour of tdb_change_uint32_atomic(), which
is the following: *oldval is used as initial value when
the value does not yet exist and that the old value should be
returned in *oldval.

dbwrap_change_uint32_atomic() is used (only) in idmap_tdb2.c,
to get new ids.

Michael
(This used to be commit 72bd83fea7572a6202027b200d192c05023aa633)

source3/lib/dbwrap_util.c

index 07e50827d44d2437f80fce77e09653225fcfc2ec..14baec11a3c40c8a8362617f15078d1d4e80a11f 100644 (file)
@@ -110,9 +110,13 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
                return -1;
        }
 
-       if ((rec->value.dptr != NULL)
-           && (rec->value.dsize == sizeof(val))) {
+       if (rec->value.dptr == NULL) {
+               val = *oldval;
+       } else if (rec->value.dsize == sizeof(val)) {
                val = IVAL(rec->value.dptr, 0);
+               *oldval = val;
+       } else {
+               return -1;
        }
 
        val += change_val;