The branch, master has been updated via e579c84 s3:registry: implement regdb_set_secdesc() with regdb_trans_do() via 861f04b s3:registry: implement regdb_store_values() with regdb_trans_do() via 6832ae4 s3:registry: change regdb_store_values_internal() from bool to NTSTATUS return code via e1d7cfb s3:registry: use the regdb_trans_do wrapper instead of using dbwrap_trans_do directly in the registry db code. via 9352a95 s3:registry: add regdb_trans_do(): a transaction wrapper that will check the regdb version via 5ef1173 s3:registry: drop log level of unknown regdb version message in regdb_init() to 0 from 1d4de78 Fix bug 8433, segfault in iconv.c
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e579c84b4fc28ccf95cc8e6cc53c6001f5494ec1 Author: Michael Adam <ob...@samba.org> Date: Tue Aug 30 16:30:01 2011 +0200 s3:registry: implement regdb_set_secdesc() with regdb_trans_do() Autobuild-User: Michael Adam <ob...@samba.org> Autobuild-Date: Fri Sep 2 00:51:40 CEST 2011 on sn-devel-104 commit 861f04bec0172b80d20773f9be882ce08f5e3784 Author: Michael Adam <ob...@samba.org> Date: Tue Aug 30 14:06:22 2011 +0200 s3:registry: implement regdb_store_values() with regdb_trans_do() This adds the runtime check for changed regdb format version to store_values commit 6832ae4c6de815c326315de5b5e3a5a612d74af7 Author: Michael Adam <ob...@samba.org> Date: Tue Aug 30 16:11:01 2011 +0200 s3:registry: change regdb_store_values_internal() from bool to NTSTATUS return code commit e1d7cfb41b3b25ad1460570e998d0a6b38a4a1f0 Author: Michael Adam <ob...@samba.org> Date: Tue Aug 30 16:00:21 2011 +0200 s3:registry: use the regdb_trans_do wrapper instead of using dbwrap_trans_do directly in the registry db code. This verifies the regdb format version number before the corresponding write operations. commit 9352a95bfda2d1a3255d8ad158af0fcef442b53e Author: Michael Adam <ob...@samba.org> Date: Mon Aug 29 17:06:27 2011 +0200 s3:registry: add regdb_trans_do(): a transaction wrapper that will check the regdb version If the version has changed since initialization, the write will fail with ACCESS_DENIED. commit 5ef11737bc8e32446f3819df17af4ae0e93270a0 Author: Michael Adam <ob...@samba.org> Date: Tue Aug 30 15:59:30 2011 +0200 s3:registry: drop log level of unknown regdb version message in regdb_init() to 0 ----------------------------------------------------------------------- Summary of changes: source3/registry/reg_backend_db.c | 196 +++++++++++++++++++++++++++---------- 1 files changed, 144 insertions(+), 52 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 58e7b33..0218f05 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -49,8 +49,8 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static int regdb_fetch_values_internal(struct db_context *db, const char* key, struct regval_ctr *values); -static bool regdb_store_values_internal(struct db_context *db, const char *key, - struct regval_ctr *values); +static NTSTATUS regdb_store_values_internal(struct db_context *db, const char *key, + struct regval_ctr *values); static WERROR regdb_store_subkey_list(struct db_context *db, const char *parent, const char *key); @@ -59,6 +59,48 @@ static WERROR regdb_create_subkey_internal(struct db_context *db, const char *key, const char *subkey); + +struct regdb_trans_ctx { + NTSTATUS (*action)(struct db_context *, void *); + void *private_data; +}; + +static NTSTATUS regdb_trans_do_action(struct db_context *db, void *private_data) +{ + NTSTATUS status; + int32_t version_id; + struct regdb_trans_ctx *ctx = (struct regdb_trans_ctx *)private_data; + + version_id = dbwrap_fetch_int32(db, REGDB_VERSION_KEYNAME); + + if (version_id != REGVER_V3) { + DEBUG(0, ("ERROR: changed registry version %d found while " + "trying to write to the registry. Version %d " + "expected. Denying access.\n", + version_id, REGVER_V3)); + return NT_STATUS_ACCESS_DENIED; + } + + status = ctx->action(db, ctx->private_data); + return status; +} + +static WERROR regdb_trans_do(struct db_context *db, + NTSTATUS (*action)(struct db_context *, void *), + void *private_data) +{ + NTSTATUS status; + struct regdb_trans_ctx ctx; + + + ctx.action = action; + ctx.private_data = private_data; + + status = dbwrap_trans_do(db, regdb_trans_do_action, &ctx); + + return ntstatus_to_werror(status); +} + /* List the deepest path into the registry. All part components will be created.*/ /* If you want to have a part of the path controlled by the tdb and part by @@ -220,9 +262,9 @@ WERROR init_registry_key(const char *add_path) init_ctx.add_path = add_path; - return ntstatus_to_werror(dbwrap_trans_do(regdb, - init_registry_key_action, - &init_ctx)); + return regdb_trans_do(regdb, + init_registry_key_action, + &init_ctx); } /*********************************************************************** @@ -293,9 +335,12 @@ static NTSTATUS init_registry_data_action(struct db_context *db, { regdb_ctr_add_value(values, &builtin_registry_values[i]); - regdb_store_values_internal(db, + status = regdb_store_values_internal(db, builtin_registry_values[i].path, values); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } } TALLOC_FREE(values); } @@ -355,9 +400,9 @@ do_init: * transaction behaviour. */ - werr = ntstatus_to_werror(dbwrap_trans_do(regdb, - init_registry_data_action, - NULL)); + werr = regdb_trans_do(regdb, + init_registry_data_action, + NULL); done: TALLOC_FREE(frame); @@ -615,7 +660,7 @@ WERROR regdb_init(void) } if (vers_id > expected_version || vers_id == 0) { - DEBUG(1, ("regdb_init: unknown registry version %d " + DEBUG(0, ("regdb_init: unknown registry version %d " "(code version = %d), refusing initialization\n", vers_id, expected_version)); return WERR_CAN_NOT_COMPLETE; @@ -1159,9 +1204,9 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, store_ctx.key = key; store_ctx.ctr = ctr; - werr = ntstatus_to_werror(dbwrap_trans_do(db, - regdb_store_keys_action, - &store_ctx)); + werr = regdb_trans_do(db, + regdb_store_keys_action, + &store_ctx); ret = W_ERROR_IS_OK(werr); @@ -1248,9 +1293,9 @@ static WERROR regdb_create_subkey_internal(struct db_context *db, create_ctx.key = key; create_ctx.subkey = subkey; - werr = ntstatus_to_werror(dbwrap_trans_do(db, - regdb_create_subkey_action, - &create_ctx)); + werr = regdb_trans_do(db, + regdb_create_subkey_action, + &create_ctx); done: talloc_free(mem_ctx); @@ -1290,9 +1335,9 @@ static WERROR regdb_create_basekey(struct db_context *db, const char *key) create_ctx.key = key; - werr = ntstatus_to_werror(dbwrap_trans_do(db, - regdb_create_basekey_action, - &create_ctx)); + werr = regdb_trans_do(db, + regdb_create_basekey_action, + &create_ctx); return werr; } @@ -1374,9 +1419,9 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey, bool lazy delete_ctx.path = path; delete_ctx.lazy = lazy; - werr = ntstatus_to_werror(dbwrap_trans_do(regdb, - regdb_delete_subkey_action, - &delete_ctx)); + werr = regdb_trans_do(regdb, + regdb_delete_subkey_action, + &delete_ctx); done: talloc_free(mem_ctx); @@ -1709,19 +1754,20 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) return regdb_fetch_values_internal(regdb, key, values); } -static bool regdb_store_values_internal(struct db_context *db, const char *key, - struct regval_ctr *values) +static NTSTATUS regdb_store_values_internal(struct db_context *db, + const char *key, + struct regval_ctr *values) { TDB_DATA old_data, data; char *keystr = NULL; TALLOC_CTX *ctx = talloc_stackframe(); int len; NTSTATUS status; - bool result = false; DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); if (!regdb_key_exists(db, key)) { + status = NT_STATUS_NOT_FOUND; goto done; } @@ -1730,6 +1776,7 @@ static bool regdb_store_values_internal(struct db_context *db, const char *key, len = regdb_pack_values(values, data.dptr, data.dsize); if (len <= 0) { DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n")); + status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1742,6 +1789,7 @@ static bool regdb_store_values_internal(struct db_context *db, const char *key, keystr = talloc_asprintf(ctx, "%s\\%s", REG_VALUE_PREFIX, key ); if (!keystr) { + status = NT_STATUS_NO_MEMORY; goto done; } keystr = normalize_reg_path(ctx, keystr); @@ -1755,22 +1803,45 @@ static bool regdb_store_values_internal(struct db_context *db, const char *key, && (old_data.dsize == data.dsize) && (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) { - result = true; + status = NT_STATUS_OK; goto done; } status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE); - result = NT_STATUS_IS_OK(status); - done: TALLOC_FREE(ctx); - return result; + return status; +} + +struct regdb_store_values_ctx { + const char *key; + struct regval_ctr *values; +}; + +static NTSTATUS regdb_store_values_action(struct db_context *db, + void *private_data) +{ + NTSTATUS status; + struct regdb_store_values_ctx *ctx = + (struct regdb_store_values_ctx *)private_data; + + status = regdb_store_values_internal(db, ctx->key, ctx->values); + + return status; } bool regdb_store_values(const char *key, struct regval_ctr *values) { - return regdb_store_values_internal(regdb, key, values); + WERROR werr; + struct regdb_store_values_ctx ctx; + + ctx.key = key; + ctx.values = values; + + werr = regdb_trans_do(regdb, regdb_store_values_action, &ctx); + + return W_ERROR_IS_OK(werr); } static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, @@ -1821,47 +1892,68 @@ done: return err; } -static WERROR regdb_set_secdesc(const char *key, - struct security_descriptor *secdesc) +struct regdb_set_secdesc_ctx { + const char *key; + struct security_descriptor *secdesc; +}; + +static NTSTATUS regdb_set_secdesc_action(struct db_context *db, + void *private_data) { - TALLOC_CTX *mem_ctx = talloc_stackframe(); char *tdbkey; - WERROR err = WERR_NOMEM; + NTSTATUS status; TDB_DATA tdbdata; + struct regdb_set_secdesc_ctx *ctx = + (struct regdb_set_secdesc_ctx *)private_data; + TALLOC_CTX *frame = talloc_stackframe(); - if (!regdb_key_exists(regdb, key)) { - err = WERR_BADFILE; + tdbkey = talloc_asprintf(frame, "%s\\%s", REG_SECDESC_PREFIX, ctx->key); + if (tdbkey == NULL) { goto done; } - tdbkey = talloc_asprintf(mem_ctx, "%s\\%s", REG_SECDESC_PREFIX, key); + tdbkey = normalize_reg_path(frame, tdbkey); if (tdbkey == NULL) { + status = NT_STATUS_NO_MEMORY; goto done; } - tdbkey = normalize_reg_path(mem_ctx, tdbkey); - if (tdbkey == NULL) { - err = WERR_NOMEM; + if (ctx->secdesc == NULL) { + /* assuming a delete */ + status = dbwrap_delete_bystring(db, tdbkey); goto done; } - if (secdesc == NULL) { - /* assuming a delete */ - err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb, - tdbkey)); + status = marshall_sec_desc(frame, ctx->secdesc, &tdbdata.dptr, + &tdbdata.dsize); + if (!NT_STATUS_IS_OK(status)) { goto done; } - err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc, - &tdbdata.dptr, - &tdbdata.dsize)); - W_ERROR_NOT_OK_GOTO_DONE(err); + status = dbwrap_store_bystring(db, tdbkey, tdbdata, 0); - err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey, - tdbdata, 0)); +done: + TALLOC_FREE(frame); + return status; +} - done: - TALLOC_FREE(mem_ctx); +static WERROR regdb_set_secdesc(const char *key, + struct security_descriptor *secdesc) +{ + WERROR err; + struct regdb_set_secdesc_ctx ctx; + + if (!regdb_key_exists(regdb, key)) { + err = WERR_BADFILE; + goto done; + } + + ctx.key = key; + ctx.secdesc = secdesc; + + err = regdb_trans_do(regdb, regdb_set_secdesc_action, &ctx); + +done: return err; } -- Samba Shared Repository