summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2009-07-13 17:15:14 +0200
committerMichael Adam <obnox@samba.org>2009-07-15 14:01:56 +0200
commitc52dd1d5b81ce71855a3215f1b23704ac450fdee (patch)
tree1250546905fdeac7c9c857108b932dda33d55f90
parent109ea29b2c1a3bc752f9afda2c0010b9e675aa83 (diff)
downloadsamba-c52dd1d5b81ce71855a3215f1b23704ac450fdee.tar.gz
samba-c52dd1d5b81ce71855a3215f1b23704ac450fdee.tar.bz2
samba-c52dd1d5b81ce71855a3215f1b23704ac450fdee.zip
s3:registry: use transaction wrapper in create_sorted_subkeys()
Michael
-rw-r--r--source3/registry/reg_backend_db.c99
1 files changed, 51 insertions, 48 deletions
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index e0e234f7c6..11e6f66760 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -1174,39 +1174,55 @@ static int cmp_keynames(const void *p1, const void *p2)
return StrCaseCmp(*((char **)p1), *((char **)p2));
}
-static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+struct create_sorted_subkeys_context {
+ const char *key;
+ const char *sorted_keyname;
+};
+
+static NTSTATUS create_sorted_subkeys_action(struct db_context *db,
+ void *private_data)
{
char **sorted_subkeys;
struct regsubkey_ctr *ctr;
- bool result = false;
NTSTATUS status;
char *buf;
char *p;
int i, res;
size_t len;
int num_subkeys;
- WERROR werr;
+ struct create_sorted_subkeys_context *sorted_ctx;
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("create_sorted_subkeys: transaction_start "
- "failed\n"));
- return false;
- }
+ sorted_ctx = (struct create_sorted_subkeys_context *)private_data;
- werr = regsubkey_ctr_init(talloc_tos(), &ctr);
- if (!W_ERROR_IS_OK(werr)) {
- goto commit;
+ /*
+ * In this function, we only treat failing of the actual write to
+ * the db as a real error. All preliminary errors, at a stage when
+ * nothing has been written to the DB yet are treated as success
+ * to be committed (as an empty transaction).
+ *
+ * The reason is that this (disposable) call might be nested in other
+ * transactions. Doing a cancel here would destroy the possibility of
+ * a transaction_commit for transactions that we might be wrapped in.
+ */
+
+ status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr));
+ if (!NT_STATUS_IS_OK(status)) {
+ /* don't treat this as an error */
+ status = NT_STATUS_OK;
+ goto done;
}
- res = regdb_fetch_keys_internal(regdb, key, ctr);
+ res = regdb_fetch_keys_internal(db, sorted_ctx->key, ctr);
if (res == -1) {
- goto commit;
+ /* don't treat this as an error */
+ goto done;
}
num_subkeys = regsubkey_ctr_numkeys(ctr);
sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
if (sorted_subkeys == NULL) {
- goto commit;
+ /* don't treat this as an error */
+ goto done;
}
len = 4 + 4*num_subkeys;
@@ -1215,7 +1231,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
regsubkey_ctr_specific_key(ctr, i));
if (sorted_subkeys[i] == NULL) {
- goto commit;
+ /* don't treat this as an error */
+ goto done;
}
len += strlen(sorted_subkeys[i])+1;
}
@@ -1224,7 +1241,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
buf = talloc_array(ctr, char, len);
if (buf == NULL) {
- goto commit;
+ /* don't treat this as an error */
+ goto done;
}
p = buf + 4 + 4*num_subkeys;
@@ -1238,43 +1256,28 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
}
status = dbwrap_store_bystring(
- regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len),
+ db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf,
+ len),
TDB_REPLACE);
- if (!NT_STATUS_IS_OK(status)) {
- /*
- * Don't use a "goto commit;" here, this would commit the broken
- * transaction. See below for an explanation.
- */
- goto cancel;
- }
- result = true;
+done:
+ talloc_free(ctr);
+ return status;
+}
-commit:
- /*
- * We only get here via the "goto commit" when we did not write anything
- * yet. Using transaction_commit even in a failure case is necessary
- * because this (disposable) call might be nested in other
- * transactions. Doing a cancel here would destroy the possibility of
- * a transaction_commit for transactions that we might be wrapped in.
- */
- if (regdb->transaction_commit(regdb) == -1) {
- DEBUG(0, ("create_sorted_subkeys: transaction_commit "
- "failed\n"));
- result = false;
- }
- goto done;
+static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+{
+ NTSTATUS status;
+ struct create_sorted_subkeys_context sorted_ctx;
-cancel:
- if (regdb->transaction_cancel(regdb) == -1) {
- smb_panic("create_sorted_subkeys: transaction_cancel "
- "failed\n");
- }
- result = false;
+ sorted_ctx.key = key;
+ sorted_ctx.sorted_keyname = sorted_keyname;
-done:
- TALLOC_FREE(ctr);
- return result;
+ status = dbwrap_trans_do(regdb,
+ create_sorted_subkeys_action,
+ &sorted_ctx);
+
+ return NT_STATUS_IS_OK(status);
}
struct scan_subkey_state {