summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/registry/reg_backend_db.c198
1 files changed, 102 insertions, 96 deletions
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index 6bf98d4c75..5c714a40b4 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -725,76 +725,32 @@ done:
do not currently exist
***********************************************************************/
-static bool regdb_store_keys_internal(struct db_context *db, const char *key,
- struct regsubkey_ctr *ctr)
+struct regdb_store_keys_context {
+ const char *key;
+ struct regsubkey_ctr *ctr;
+};
+
+static NTSTATUS regdb_store_keys_action(struct db_context *db,
+ void *private_data)
{
- int num_subkeys, old_num_subkeys, i;
+ struct regdb_store_keys_context *store_ctx;
+ WERROR werr;
+ int num_subkeys, i;
char *path = NULL;
struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
char *oldkeyname = NULL;
- TALLOC_CTX *ctx = talloc_stackframe();
- WERROR werr;
- bool ret = false;
-
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
- goto done;
- }
-
- /*
- * fetch a list of the old subkeys so we can determine if anything has
- * changed
- */
-
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto done;
- }
-
- regdb_fetch_keys_internal(db, key, old_subkeys);
-
- num_subkeys = regsubkey_ctr_numkeys(ctr);
- old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
- if ((num_subkeys && old_num_subkeys) &&
- (num_subkeys == old_num_subkeys)) {
-
- for (i = 0; i < num_subkeys; i++) {
- if (strcmp(regsubkey_ctr_specific_key(ctr, i),
- regsubkey_ctr_specific_key(old_subkeys, i))
- != 0)
- {
- break;
- }
- }
- if (i == num_subkeys) {
- /*
- * Nothing changed, no point to even start a tdb
- * transaction
- */
-
- ret = true;
- goto done;
- }
- }
-
- TALLOC_FREE(old_subkeys);
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (db->transaction_start(db) != 0) {
- DEBUG(0, ("regdb_store_keys: transaction_start failed\n"));
- goto done;
- }
+ store_ctx = (struct regdb_store_keys_context *)private_data;
/*
* Re-fetch the old keys inside the transaction
*/
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &old_subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- regdb_fetch_keys_internal(db, key, old_subkeys);
+ regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys);
/*
* Make the store operation as safe as possible without transactions:
@@ -823,21 +779,22 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key,
for (i=0; i<num_subkeys; i++) {
oldkeyname = regsubkey_ctr_specific_key(old_subkeys, i);
- if (regsubkey_ctr_key_exists(ctr, oldkeyname)) {
+ if (regsubkey_ctr_key_exists(store_ctx->ctr, oldkeyname)) {
/*
* It's still around, don't delete
*/
-
continue;
}
- path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ oldkeyname);
if (!path) {
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
werr = regdb_delete_key_lists(db, path);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
TALLOC_FREE(path);
}
@@ -846,47 +803,41 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key,
/* (2) store the subkey list for the parent */
- werr = regdb_store_keys_internal2(db, key, ctr);
+ werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
- "for parent [%s]: %s\n", key, win_errstr(werr)));
- goto cancel;
+ "for parent [%s]: %s\n", store_ctx->key,
+ win_errstr(werr)));
+ goto done;
}
/* (3) now create records for any subkeys that don't already exist */
- num_subkeys = regsubkey_ctr_numkeys(ctr);
+ num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
if (num_subkeys == 0) {
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- werr = regdb_store_keys_internal2(db, key, subkeys);
+ werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]: %s\n", key,
- win_errstr(werr)));
- goto cancel;
+ "new record for key [%s]: %s\n",
+ store_ctx->key, win_errstr(werr)));
+ goto done;
}
TALLOC_FREE(subkeys);
-
}
for (i=0; i<num_subkeys; i++) {
- path = talloc_asprintf(ctx, "%s/%s",
- key,
- regsubkey_ctr_specific_key(ctr, i));
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ regsubkey_ctr_specific_key(store_ctx->ctr, i));
if (!path) {
- goto cancel;
- }
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
if (regdb_fetch_keys_internal(db, path, subkeys) == -1) {
/* create a record with 0 subkeys */
@@ -895,7 +846,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key,
DEBUG(0,("regdb_store_keys: Failed to store "
"new record for key [%s]: %s\n", path,
win_errstr(werr)));
- goto cancel;
+ goto done;
}
}
@@ -903,20 +854,75 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key,
TALLOC_FREE(path);
}
- if (db->transaction_commit(db) != 0) {
- DEBUG(0, ("regdb_store_keys: Could not commit transaction\n"));
+ werr = WERR_OK;
+
+done:
+ talloc_free(mem_ctx);
+ return werror_to_ntstatus(werr);
+}
+
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr)
+{
+ int num_subkeys, old_num_subkeys, i;
+ struct regsubkey_ctr *old_subkeys = NULL;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ WERROR werr;
+ bool ret = false;
+ struct regdb_store_keys_context store_ctx;
+
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
goto done;
}
- ret = true;
- goto done;
+ /*
+ * fetch a list of the old subkeys so we can determine if anything has
+ * changed
+ */
-cancel:
- ret = false;
- if (db->transaction_cancel(db) != 0) {
- smb_panic("regdb_store_keys: transaction_cancel failed\n");
+ werr = regsubkey_ctr_init(ctx, &old_subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+ goto done;
}
+ regdb_fetch_keys_internal(db, key, old_subkeys);
+
+ num_subkeys = regsubkey_ctr_numkeys(ctr);
+ old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
+ if ((num_subkeys && old_num_subkeys) &&
+ (num_subkeys == old_num_subkeys)) {
+
+ for (i = 0; i < num_subkeys; i++) {
+ if (strcmp(regsubkey_ctr_specific_key(ctr, i),
+ regsubkey_ctr_specific_key(old_subkeys, i))
+ != 0)
+ {
+ break;
+ }
+ }
+ if (i == num_subkeys) {
+ /*
+ * Nothing changed, no point to even start a tdb
+ * transaction
+ */
+
+ ret = true;
+ goto done;
+ }
+ }
+
+ TALLOC_FREE(old_subkeys);
+
+ store_ctx.key = key;
+ store_ctx.ctr = ctr;
+
+ werr = ntstatus_to_werror(dbwrap_trans_do(db,
+ regdb_store_keys_action,
+ &store_ctx));
+
+ ret = W_ERROR_IS_OK(werr);
+
done:
TALLOC_FREE(ctx);