s3:registry: eliminate race condition in creating/scanning sorted subkeys
authorMichael Adam <obnox@samba.org>
Mon, 8 Feb 2010 10:01:47 +0000 (11:01 +0100)
committerMichael Adam <obnox@samba.org>
Mon, 8 Feb 2010 21:56:10 +0000 (22:56 +0100)
Called, from key_exists, scan_sorted_subkeys re-creates the sorted
subkeys record of the given key and then searches through it.
The race is that between creation and parsing of the sorted subkey
record, another process that stores some other subkey of the same
parent key will delete the sorted subkey record, resulting in an
WERR_BADFILE of an operation that should actually succeed.

This patch fixes the issue by wrapping the creation and parsing
into a transaction.

Michael

source3/registry/reg_backend_db.c

index 96d581c9eadda5ff97459cfb05258484a2a4fb81..2339d6b389973dd917dcd59dbae10b3baf4d337a 100644 (file)
@@ -1372,14 +1372,31 @@ static bool scan_parent_subkeys(struct db_context *db, const char *parent,
        if (state.scanned) {
                result = state.found;
        } else {
+               res = db->transaction_start(db);
+               if (res != 0) {
+                       DEBUG(0, ("error starting transacion\n"));
+                       goto fail;
+               }
+
                if (!create_sorted_subkeys(path, key)) {
+                       res = db->transaction_cancel(db);
+                       if (res != 0) {
+                               smb_panic("Failed to cancel transaction.");
+                       }
                        goto fail;
                }
+
                res = db->parse_record(db, string_term_tdb_data(key),
                                       parent_subkey_scanner, &state);
                if ((res == 0) && (state.scanned)) {
                        result = state.found;
                }
+
+               res = db->transaction_commit(db);
+               if (res != 0) {
+                       DEBUG(0, ("error committing transaction\n"));
+                       result = false;
+               }
        }
 
  fail: