s3:registry: fix a comment in create_sorted_subkeys()
[ira/wip.git] / source3 / registry / reg_backend_db.c
index 667fa021546b267a2324bc247e932a42f6d3fec2..245e14b6d4686d4fa7a03db52080dcfdd0d30b7f 100644 (file)
 static struct db_context *regdb = NULL;
 static int regdb_refcount;
 
-static bool regdb_key_exists(const char *key);
+static bool regdb_key_exists(struct db_context *db, const char *key);
 static bool regdb_key_is_base_key(const char *key);
+static int regdb_fetch_keys_internal(struct db_context *db, const char *key,
+                                    struct regsubkey_ctr *ctr);
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+                                     struct regsubkey_ctr *ctr);
 
 /* List the deepest path into the registry.  All part components will be created.*/
 
@@ -173,14 +177,14 @@ static WERROR init_registry_key_internal(const char *add_path)
                        goto fail;
                }
 
-               regdb_fetch_keys(base, subkeys);
+               regdb_fetch_keys_internal(regdb, base, subkeys);
                if (*subkeyname) {
                        werr = regsubkey_ctr_addkey(subkeys, subkeyname);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto fail;
                        }
                }
-               if (!regdb_store_keys( base, subkeys)) {
+               if (!regdb_store_keys_internal(regdb, base, subkeys)) {
                        werr = WERR_CAN_NOT_COMPLETE;
                        goto fail;
                }
@@ -202,7 +206,7 @@ WERROR init_registry_key(const char *add_path)
 {
        WERROR werr;
 
-       if (regdb_key_exists(add_path)) {
+       if (regdb_key_exists(regdb, add_path)) {
                return WERR_OK;
        }
 
@@ -239,7 +243,7 @@ WERROR init_registry_data(void)
 {
        WERROR werr;
        TALLOC_CTX *frame = talloc_stackframe();
-       REGVAL_CTR *values;
+       struct regval_ctr *values;
        int i;
        UNISTR2 data;
 
@@ -248,13 +252,13 @@ WERROR init_registry_data(void)
         * If all do already exist, we can save the writes.
         */
        for (i=0; builtin_registry_paths[i] != NULL; i++) {
-               if (!regdb_key_exists(builtin_registry_paths[i])) {
+               if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
                        goto do_init;
                }
        }
 
        for (i=0; builtin_registry_values[i].path != NULL; i++) {
-               values = TALLOC_ZERO_P(frame, REGVAL_CTR);
+               values = TALLOC_ZERO_P(frame, struct regval_ctr);
                if (values == NULL) {
                        werr = WERR_NOMEM;
                        goto done;
@@ -294,7 +298,7 @@ do_init:
        /* loop over all of the predefined paths and add each component */
 
        for (i=0; builtin_registry_paths[i] != NULL; i++) {
-               if (regdb_key_exists(builtin_registry_paths[i])) {
+               if (regdb_key_exists(regdb, builtin_registry_paths[i])) {
                        continue;
                }
                werr = init_registry_key_internal(builtin_registry_paths[i]);
@@ -307,7 +311,7 @@ do_init:
 
        for (i=0; builtin_registry_values[i].path != NULL; i++) {
 
-               values = TALLOC_ZERO_P(frame, REGVAL_CTR);
+               values = TALLOC_ZERO_P(frame, struct regval_ctr);
                if (values == NULL) {
                        werr = WERR_NOMEM;
                        goto fail;
@@ -510,13 +514,100 @@ int regdb_get_seqnum(void)
        return regdb->get_seqnum(regdb);
 }
 
+
+static WERROR regdb_delete_key_with_prefix(struct db_context *db,
+                                          const char *keyname,
+                                          const char *prefix)
+{
+       char *path;
+       WERROR werr = WERR_NOMEM;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (keyname == NULL) {
+               werr = WERR_INVALID_PARAM;
+               goto done;
+       }
+
+       if (prefix == NULL) {
+               path = discard_const_p(char, keyname);
+       } else {
+               path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname);
+               if (path == NULL) {
+                       goto done;
+               }
+       }
+
+       path = normalize_reg_path(mem_ctx, path);
+       if (path == NULL) {
+               goto done;
+       }
+
+       werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path));
+
+       /* treat "not" found" as ok */
+       if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
+               werr = WERR_OK;
+       }
+
+done:
+       talloc_free(mem_ctx);
+       return werr;
+}
+
+
+static WERROR regdb_delete_values(struct db_context *db, const char *keyname)
+{
+       return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX);
+}
+
+static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname)
+{
+       return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX);
+}
+
+static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname)
+{
+       return regdb_delete_key_with_prefix(db, keyname, NULL);
+}
+
+static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
+{
+       WERROR werr;
+
+       werr = regdb_delete_values(db, keyname);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
+                         REG_VALUE_PREFIX, keyname, win_errstr(werr)));
+               goto done;
+       }
+
+       werr = regdb_delete_secdesc(db, keyname);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
+                         REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
+               goto done;
+       }
+
+       werr = regdb_delete_subkeylist(db, keyname);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1, (__location__ " Deleting %s failed: %s\n",
+                         keyname, win_errstr(werr)));
+               goto done;
+       }
+
+done:
+       return werr;
+}
+
 /***********************************************************************
  Add subkey strings to the registry tdb under a defined key
  fmt is the same format as tdb_pack except this function only supports
  fstrings
  ***********************************************************************/
 
-static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
+static bool regdb_store_keys_internal2(struct db_context *db,
+                                      const char *key,
+                                      struct regsubkey_ctr *ctr)
 {
        TDB_DATA dbuf;
        uint8 *buffer = NULL;
@@ -590,7 +681,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
 
        dbuf.dptr = buffer;
        dbuf.dsize = len;
-       status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE);
+       status = dbwrap_store_bystring(db, keyname, dbuf, TDB_REPLACE);
        if (!NT_STATUS_IS_OK(status)) {
                ret = false;
                goto done;
@@ -603,7 +694,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
        keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
                                  keyname);
        if (keyname != NULL) {
-               dbwrap_delete_bystring(regdb, keyname);
+               dbwrap_delete_bystring(db, keyname);
        }
 
 done:
@@ -617,17 +708,17 @@ done:
  do not currently exist
  ***********************************************************************/
 
-bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+                                     struct regsubkey_ctr *ctr)
 {
        int num_subkeys, old_num_subkeys, i;
        char *path = NULL;
        struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
        char *oldkeyname = NULL;
        TALLOC_CTX *ctx = talloc_stackframe();
-       NTSTATUS status;
        WERROR werr;
 
-       if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
                goto fail;
        }
 
@@ -642,7 +733,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                return false;
        }
 
-       regdb_fetch_keys(key, old_subkeys);
+       regdb_fetch_keys_internal(db, key, old_subkeys);
 
        num_subkeys = regsubkey_ctr_numkeys(ctr);
        old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
@@ -669,7 +760,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
 
        TALLOC_FREE(old_subkeys);
 
-       if (regdb->transaction_start(regdb) != 0) {
+       if (db->transaction_start(db) != 0) {
                DEBUG(0, ("regdb_store_keys: transaction_start failed\n"));
                goto fail;
        }
@@ -684,7 +775,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                goto cancel;
        }
 
-       regdb_fetch_keys(key, old_subkeys);
+       regdb_fetch_keys_internal(db, key, old_subkeys);
 
        /*
         * Make the store operation as safe as possible without transactions:
@@ -721,66 +812,14 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                        continue;
                }
 
-               /* (a) Delete the value list for this key */
-
-               path = talloc_asprintf(ctx, "%s/%s/%s",
-                               REG_VALUE_PREFIX,
-                               key,
-                               oldkeyname );
-               if (!path) {
-                       goto cancel;
-               }
-               path = normalize_reg_path(ctx, path);
-               if (!path) {
-                       goto cancel;
-               }
-               /* Ignore errors here, we might have no values around */
-               dbwrap_delete_bystring(regdb, path);
-               TALLOC_FREE(path);
-
-               /* (b) Delete the secdesc for this key */
-
-               path = talloc_asprintf(ctx, "%s/%s/%s",
-                               REG_SECDESC_PREFIX,
-                               key,
-                               oldkeyname );
-               if (!path) {
-                       goto cancel;
-               }
-               path = normalize_reg_path(ctx, path);
+               path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
                if (!path) {
                        goto cancel;
                }
-               status = dbwrap_delete_bystring(regdb, path);
-               /* Don't fail if there are no values around. */
-               if (!NT_STATUS_IS_OK(status) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
-               {
-                       DEBUG(1, ("Deleting %s failed: %s\n", path,
-                                 nt_errstr(status)));
-                       goto cancel;
-               }
-               TALLOC_FREE(path);
 
-               /* (c) Delete the list of subkeys of this key */
+               werr = regdb_delete_key_lists(db, path);
+               W_ERROR_NOT_OK_GOTO(werr, cancel);
 
-               path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
-               if (!path) {
-                       goto cancel;
-               }
-               path = normalize_reg_path(ctx, path);
-               if (!path) {
-                       goto cancel;
-               }
-               status = dbwrap_delete_bystring(regdb, path);
-               /* Don't fail if the subkey record was not found. */
-               if (!NT_STATUS_IS_OK(status) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
-               {
-                       DEBUG(1, ("Deleting %s failed: %s\n", path,
-                                 nt_errstr(status)));
-                       goto cancel;
-               }
                TALLOC_FREE(path);
        }
 
@@ -788,7 +827,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
 
        /* (2) store the subkey list for the parent */
 
-       if (!regdb_store_keys_internal(key, ctr) ) {
+       if (!regdb_store_keys_internal2(db, key, ctr)) {
                DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
                         "for parent [%s]\n", key));
                goto cancel;
@@ -805,7 +844,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                        goto cancel;
                }
 
-               if (!regdb_store_keys_internal(key, subkeys)) {
+               if (!regdb_store_keys_internal2(db, key, subkeys)) {
                        DEBUG(0,("regdb_store_keys: Failed to store "
                                 "new record for key [%s]\n", key));
                        goto cancel;
@@ -827,9 +866,9 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                        goto cancel;
                }
 
-               if (regdb_fetch_keys( path, subkeys ) == -1) {
+               if (regdb_fetch_keys_internal(db, path, subkeys) == -1) {
                        /* create a record with 0 subkeys */
-                       if (!regdb_store_keys_internal(path, subkeys)) {
+                       if (!regdb_store_keys_internal2(db, path, subkeys)) {
                                DEBUG(0,("regdb_store_keys: Failed to store "
                                         "new record for key [%s]\n", path));
                                goto cancel;
@@ -840,7 +879,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                TALLOC_FREE(path);
        }
 
-       if (regdb->transaction_commit(regdb) != 0) {
+       if (db->transaction_commit(db) != 0) {
                DEBUG(0, ("regdb_store_keys: Could not commit transaction\n"));
                goto fail;
        }
@@ -849,7 +888,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
        return true;
 
 cancel:
-       if (regdb->transaction_cancel(regdb) != 0) {
+       if (db->transaction_cancel(db) != 0) {
                smb_panic("regdb_store_keys: transaction_cancel failed\n");
        }
 
@@ -859,8 +898,145 @@ fail:
        return false;
 }
 
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+       return regdb_store_keys_internal(regdb, key, ctr);
+}
+
+static WERROR regdb_create_subkey(const char *key, const char *subkey)
+{
+       WERROR werr;
+       struct regsubkey_ctr *subkeys;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
+               werr = WERR_NOT_FOUND;
+               goto done;
+       }
+
+       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) {
+               werr = WERR_REG_IO_FAILURE;
+               goto done;
+       }
+
+       if (regsubkey_ctr_key_exists(subkeys, subkey)) {
+               werr = WERR_OK;
+               goto done;
+       }
+
+       talloc_free(subkeys);
+
+       if (regdb->transaction_start(regdb) != 0) {
+               werr = WERR_REG_IO_FAILURE;
+               goto done;
+       }
+
+       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+       W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+       if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) {
+               werr = WERR_REG_IO_FAILURE;
+               goto cancel;
+       }
+
+       werr = regsubkey_ctr_addkey(subkeys, subkey);
+       W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+       if (!regdb_store_keys_internal2(regdb, key, subkeys)) {
+               DEBUG(0, (__location__ " failed to store new subkey list for "
+                        "parent key %s\n", key));
+               werr = WERR_REG_IO_FAILURE;
+               goto cancel;
+       }
+
+       if (regdb->transaction_commit(regdb) != 0) {
+               werr = WERR_REG_IO_FAILURE;
+               DEBUG(0, (__location__ " failed to commit transaction\n"));
+       }
+
+       goto done;
+
+cancel:
+       if (regdb->transaction_cancel(regdb) != 0) {
+               smb_panic("regdb_create_subkey: transaction_cancel failed\n");
+       }
+
+done:
+       talloc_free(mem_ctx);
+       return werr;
+}
+
+static WERROR regdb_delete_subkey(const char *key, const char *subkey)
+{
+       WERROR werr;
+       struct regsubkey_ctr *subkeys;
+       char *path;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
+               werr = WERR_NOT_FOUND;
+               goto done;
+       }
+
+       path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey);
+       if (path == NULL) {
+               werr = WERR_NOMEM;
+               goto done;
+       }
+
+       if (!regdb_key_exists(regdb, path)) {
+               werr = WERR_OK;
+               goto done;
+       }
+
+       if (regdb->transaction_start(regdb) != 0) {
+               werr = WERR_REG_IO_FAILURE;
+               goto done;
+       }
+
+       werr = regdb_delete_key_lists(regdb, path);
+       W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+       W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+       if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) {
+               werr = WERR_REG_IO_FAILURE;
+               goto cancel;
+       }
+
+       werr = regsubkey_ctr_delkey(subkeys, subkey);
+       W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+       if (!regdb_store_keys_internal2(regdb, key, subkeys)) {
+               DEBUG(0, (__location__ " failed to store new subkey_list for "
+                        "parent key %s\n", key));
+               werr = WERR_REG_IO_FAILURE;
+               goto cancel;
+       }
+
+       if (regdb->transaction_commit(regdb) != 0) {
+               DEBUG(0, (__location__ " failed to commit transaction\n"));
+               werr = WERR_REG_IO_FAILURE;
+       }
+
+       goto done;
 
-static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
+cancel:
+       if (regdb->transaction_cancel(regdb) != 0) {
+               smb_panic("regdb_delete_subkey: transaction_cancel failed\n");
+       }
+
+done:
+       talloc_free(mem_ctx);
+       return werr;
+}
+
+static TDB_DATA regdb_fetch_key_internal(struct db_context *db,
+                                        TALLOC_CTX *mem_ctx, const char *key)
 {
        char *path = NULL;
        TDB_DATA data;
@@ -870,7 +1046,7 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
                return make_tdb_data(NULL, 0);
        }
 
-       data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+       data = dbwrap_fetch_bystring(db, mem_ctx, path);
 
        TALLOC_FREE(path);
        return data;
@@ -927,7 +1103,7 @@ done:
  * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
  * the potentially large subkey record.
  *
- * The sorted subkey record is deleted in regdb_store_keys_internal and
+ * The sorted subkey record is deleted in regdb_store_keys_internal2 and
  * recreated on demand.
  */
 
@@ -960,7 +1136,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
                goto fail;
        }
 
-       res = regdb_fetch_keys(key, ctr);
+       res = regdb_fetch_keys_internal(regdb, key, ctr);
        if (res == -1) {
                goto fail;
        }
@@ -1025,9 +1201,9 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
         * a transaction_commit for transactions that we might be wrapped in.
         */
        if (regdb->transaction_commit(regdb) == -1) {
-               DEBUG(0, ("create_sorted_subkeys: transaction_start "
+               DEBUG(0, ("create_sorted_subkeys: transaction_commit "
                          "failed\n"));
-               goto fail;
+               result = false;
        }
 
        TALLOC_FREE(ctr);
@@ -1077,7 +1253,8 @@ static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data,
        return 0;
 }
 
-static bool scan_parent_subkeys(const char *parent, const char *name)
+static bool scan_parent_subkeys(struct db_context *db, const char *parent,
+                               const char *name)
 {
        char *path = NULL;
        char *key = NULL;
@@ -1104,8 +1281,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
        }
        state.scanned = false;
 
-       res = regdb->parse_record(regdb, string_term_tdb_data(key),
-                                 parent_subkey_scanner, &state);
+       res = db->parse_record(db, string_term_tdb_data(key),
+                              parent_subkey_scanner, &state);
 
        if (state.scanned) {
                result = state.found;
@@ -1113,8 +1290,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
                if (!create_sorted_subkeys(path, key)) {
                        goto fail;
                }
-               res = regdb->parse_record(regdb, string_term_tdb_data(key),
-                                         parent_subkey_scanner, &state);
+               res = db->parse_record(db, string_term_tdb_data(key),
+                                      parent_subkey_scanner, &state);
                if ((res == 0) && (state.scanned)) {
                        result = state.found;
                }
@@ -1134,7 +1311,7 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
  * The exeption of this are keys without a parent key,
  * i.e. the "base" keys (HKLM, HKCU, ...).
  */
-static bool regdb_key_exists(const char *key)
+static bool regdb_key_exists(struct db_context *db, const char *key)
 {
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        TDB_DATA value;
@@ -1158,11 +1335,11 @@ static bool regdb_key_exists(const char *key)
        p = strrchr(path, '/');
        if (p == NULL) {
                /* this is a base key */
-               value = regdb_fetch_key_internal(mem_ctx, path);
+               value = regdb_fetch_key_internal(db, mem_ctx, path);
                ret = (value.dptr != NULL);
        } else {
                *p = '\0';
-               ret = scan_parent_subkeys(path, p+1);
+               ret = scan_parent_subkeys(db, path, p+1);
        }
 
 done:
@@ -1176,7 +1353,8 @@ done:
  released by the caller.
  ***********************************************************************/
 
-int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+static int regdb_fetch_keys_internal(struct db_context *db, const char *key,
+                                    struct regsubkey_ctr *ctr)
 {
        WERROR werr;
        uint32 num_items;
@@ -1190,16 +1368,16 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
 
        DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(db, key)) {
                goto done;
        }
 
-       werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum());
+       werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db));
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
 
-       value = regdb_fetch_key_internal(frame, key);
+       value = regdb_fetch_key_internal(db, frame, key);
 
        if (value.dptr == NULL) {
                DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
@@ -1230,11 +1408,16 @@ done:
        return ret;
 }
 
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+       return regdb_fetch_keys_internal(regdb, key, ctr);
+}
+
 /****************************************************************************
  Unpack a list of registry values frem the TDB
  ***************************************************************************/
 
-static int regdb_unpack_values(REGVAL_CTR *values, uint8 *buf, int buflen)
+static int regdb_unpack_values(struct regval_ctr *values, uint8 *buf, int buflen)
 {
        int             len = 0;
        uint32          type;
@@ -1279,11 +1462,11 @@ static int regdb_unpack_values(REGVAL_CTR *values, uint8 *buf, int buflen)
  Pack all values in all printer keys
  ***************************************************************************/
 
-static int regdb_pack_values(REGVAL_CTR *values, uint8 *buf, int buflen)
+static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen)
 {
        int             len = 0;
        int             i;
-       REGISTRY_VALUE  *val;
+       struct regval_blob      *val;
        int             num_values;
 
        if ( !values )
@@ -1314,7 +1497,7 @@ static int regdb_pack_values(REGVAL_CTR *values, uint8 *buf, int buflen)
  released by the caller.
  ***********************************************************************/
 
-int regdb_fetch_values( const char* key, REGVAL_CTR *values )
+int regdb_fetch_values(const char* key, struct regval_ctr *values)
 {
        char *keystr = NULL;
        TALLOC_CTX *ctx = talloc_stackframe();
@@ -1323,7 +1506,7 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
 
        DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                goto done;
        }
 
@@ -1334,7 +1517,7 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
 
        values->seqnum = regdb_get_seqnum();
 
-       value = regdb_fetch_key_internal(ctx, keystr);
+       value = regdb_fetch_key_internal(regdb, ctx, keystr);
 
        if (!value.dptr) {
                /* all keys have zero values by default */
@@ -1349,7 +1532,7 @@ done:
        return ret;
 }
 
-bool regdb_store_values( const char *key, REGVAL_CTR *values )
+bool regdb_store_values(const char *key, struct regval_ctr *values)
 {
        TDB_DATA old_data, data;
        char *keystr = NULL;
@@ -1360,7 +1543,7 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
 
        DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                goto done;
        }
 
@@ -1418,7 +1601,7 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
 
        DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                err = WERR_BADFILE;
                goto done;
        }
@@ -1455,11 +1638,10 @@ static WERROR regdb_set_secdesc(const char *key,
 {
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        char *tdbkey;
-       NTSTATUS status;
        WERROR err = WERR_NOMEM;
        TDB_DATA tdbdata;
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                err = WERR_BADFILE;
                goto done;
        }
@@ -1472,27 +1654,18 @@ static WERROR regdb_set_secdesc(const char *key,
 
        if (secdesc == NULL) {
                /* assuming a delete */
-               status = dbwrap_trans_delete_bystring(regdb, tdbkey);
-               if (NT_STATUS_IS_OK(status)) {
-                       err = WERR_OK;
-               } else {
-                       err = ntstatus_to_werror(status);
-               }
+               err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb,
+                                                                     tdbkey));
                goto done;
        }
 
        err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc,
                                                   &tdbdata.dptr,
                                                   &tdbdata.dsize));
-       if (!W_ERROR_IS_OK(err)) {
-               goto done;
-       }
+       W_ERROR_NOT_OK_GOTO_DONE(err);
 
-       status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               err = ntstatus_to_werror(status);
-               goto done;
-       }
+       err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey,
+                                                            tdbdata, 0));
 
  done:
        TALLOC_FREE(mem_ctx);
@@ -1504,7 +1677,7 @@ bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys)
        return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys));
 }
 
-bool regdb_values_need_update(REGVAL_CTR *values)
+bool regdb_values_need_update(struct regval_ctr *values)
 {
        return (regdb_get_seqnum() != values->seqnum);
 }
@@ -1513,11 +1686,13 @@ bool regdb_values_need_update(REGVAL_CTR *values)
  * Table of function pointers for default access
  */
  
-REGISTRY_OPS regdb_ops = {
+struct registry_ops regdb_ops = {
        .fetch_subkeys = regdb_fetch_keys,
        .fetch_values = regdb_fetch_values,
        .store_subkeys = regdb_store_keys,
        .store_values = regdb_store_values,
+       .create_subkey = regdb_create_subkey,
+       .delete_subkey = regdb_delete_subkey,
        .get_secdesc = regdb_get_secdesc,
        .set_secdesc = regdb_set_secdesc,
        .subkeys_need_update = regdb_subkeys_need_update,