From 73626c266c3ea1b477185a428b2c1be64feff598 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 01:47:10 +0100 Subject: registry: Check for more specific LDB return codes, handle changing existing values better. (This used to be commit c8b22ef30c7fc0ccc15e9fc9a38fdc639fc4b976) --- source4/lib/registry/ldb.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 259315cc39..d56b63299d 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -478,13 +478,18 @@ static WERROR ldb_set_value(struct hive_key *parent, ldb_dn_add_child_fmt(msg->dn, "value=%s", name); ret = ldb_add(kd->ldb, msg); - if (ret < 0) { - ret = ldb_modify(kd->ldb, msg); - if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb))); - talloc_free(mem_ctx); - return WERR_FOOBAR; + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + int i; + for (i = 0; i < msg->num_elements; i++) { + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } + ret = ldb_modify(kd->ldb, msg); + } + + if (ret != LDB_SUCCESS) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb))); + talloc_free(mem_ctx); + return WERR_FOOBAR; } talloc_free(mem_ctx); -- cgit From 158a2eed334512c28a7101b3af2c364b4ac1b3fd Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 01:48:48 +0100 Subject: registry: Properly check return values from ldb_*() functions. There were a few cases left that attempted to detect errors from ldb_*() function calls using "(ret < 0)". As all LDB_* error codes are greater than zero, there was no chance any errors would be detected. Changed all such tests to use "(ret != LDB_SUCCESS)". (This used to be commit 0ed6f1b1628da5b922f02a5f9a6c60071b6277f2) --- source4/lib/registry/ldb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index d56b63299d..d87bc6cf8e 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -400,7 +400,7 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); - if (ret < 0) { + if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } @@ -432,7 +432,7 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *child) if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; - } else if (ret < 0) { + } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } @@ -455,7 +455,7 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; - } else if (ret < 0) { + } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); return WERR_FOOBAR; } -- cgit From 4d8a60f617f941ff6481bcfbac73d7ed69e43daa Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 01:50:33 +0100 Subject: When Windows initially creates a new value, the value name is "New Value #1". The '#' character was causing problems, as it was not being escaped for the dn, but the failure returned by ldb_dn_add_child_fmt() was not being caught. This was causing the new value to be added on the parent key, not the current key. When attempting to delete the new value (now on the parent key) the same escaping error was returned by ldb_dn_add_child_fmt(), causing the delete to delete the key and not the value. When attempting to rename a value, Windows first tries to ensure the new name does not already exist. When a value does not exist, Windows expects a return value of WERR_BADFILE, but WERR_NOT_FOUND was being returned instead. Providing the WERR_BADFILE that Windows expects allows values to be renamed. (This used to be commit 94fb39cfd967455ce5a554720c1c7e6183f91056) --- source4/lib/registry/ldb.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index d87bc6cf8e..884aed1579 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -112,6 +112,16 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, } +static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, value); + val.length = strlen(value); + + return ldb_dn_escape_value(mem_ctx, val); +} + static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { @@ -447,7 +457,12 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) struct ldb_dn *childdn; childdn = ldb_dn_copy(kd->ldb, kd->dn); - ldb_dn_add_child_fmt(childdn, "value=%s", child); + if (!ldb_dn_add_child_fmt(childdn, "value=%s", + reg_ldb_escape(childdn, child))) + { + talloc_free(childdn); + return WERR_FOOBAR; + } ret = ldb_delete(kd->ldb, childdn); @@ -475,7 +490,12 @@ static WERROR ldb_set_value(struct hive_key *parent, msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data); msg->dn = ldb_dn_copy(msg, kd->dn); - ldb_dn_add_child_fmt(msg->dn, "value=%s", name); + if (!ldb_dn_add_child_fmt(msg->dn, "value=%s", + reg_ldb_escape(mem_ctx, name))) + { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } ret = ldb_add(kd->ldb, msg); if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { -- cgit From 85d60d2d091a2eb6bd4c73c87c94b10ee93167ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 02:45:00 +0100 Subject: registry: Improve error codes and update tests. Rather than map the error returned by the registry to the correct error, return the correct error in the first place. Also deal with the fact that the right error code is now returned in a couple of places. (This used to be commit 1e31fcb8a097810a97e2d4bb1f243f1b34cc2415) --- source4/lib/registry/dir.c | 2 +- source4/lib/registry/ldb.c | 9 ++++++--- source4/lib/registry/patchfile.c | 10 +++++----- source4/lib/registry/regf.c | 2 +- source4/lib/registry/tests/hive.c | 4 ++-- source4/lib/registry/tests/registry.c | 16 ++++++++-------- 6 files changed, 23 insertions(+), 20 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index a13e3753b7..87d76e5eb7 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -282,7 +282,7 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, contents = file_load(path, &size, mem_ctx); talloc_free(path); if (contents == NULL) - return WERR_NOT_FOUND; + return WERR_BADFILE; if (type != NULL) *type = 4; /* FIXME */ diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 884aed1579..17fac4abb2 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -111,7 +111,6 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, return msg; } - static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value) { struct ldb_val val; @@ -303,7 +302,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, } if (res->count == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); @@ -410,8 +409,12 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + return WERR_ALREADY_EXISTS; + } + if (ret != LDB_SUCCESS) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); + DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index b6ad7dfb10..d859bc3134 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -132,10 +132,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, continue; } else { t1 = NULL; - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_NOT_FOUND; } - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_NOT_FOUND)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -174,10 +174,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, name, &type2, &contents2); } else - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_BADFILE; if(!W_ERROR_IS_OK(error2) && - !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + !W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting value by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -210,7 +210,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (W_ERROR_IS_OK(error2)) continue; - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting value by name: %s\n", win_errstr(error2))); return error2; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 9b126cc808..475ec7bb5d 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -575,7 +575,7 @@ static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx, } if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - return WERR_NOT_FOUND; + return WERR_BADFILE; return error; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 22b4785222..f72b7d6bf3 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -174,7 +174,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, @@ -215,7 +215,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "deleting value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value"); error = hive_key_del_value(subkey, "Answer"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 75fbe1cbea..59e31f55dc 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -195,15 +195,15 @@ static bool test_del_key(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "getting predefined key failed"); - error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey); + error = reg_key_add_name(rctx, root, "Polen", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating key return code"); torture_assert(tctx, newkey != NULL, "Creating new key"); - error = reg_key_del(root, "Hamburg"); + error = reg_key_del(root, "Polen"); torture_assert_werr_ok(tctx, error, "Delete key"); - error = reg_key_del(root, "Hamburg"); + error = reg_key_del(root, "Polen"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "Delete missing key"); @@ -239,7 +239,7 @@ static bool test_flush_key(struct torture_context *tctx, void *_data) struct registry_key *root, *subkey; WERROR error; - if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey)) + if (!create_test_key(tctx, rctx, "Bremen", &root, &subkey)) return false; error = reg_key_flush(subkey); @@ -416,7 +416,7 @@ static bool test_get_value(struct torture_context *tctx, void *_data) error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, @@ -447,12 +447,12 @@ static bool test_del_value(struct torture_context *tctx, void *_data) uint32_t value = 42; uint32_t type; - if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) + if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey)) return false; error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, @@ -464,7 +464,7 @@ static bool test_del_value(struct torture_context *tctx, void *_data) error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); return true; -- cgit From e490415e2e300452e152373eb79fb437fb11449d Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 02:51:51 +0100 Subject: When Windows attempts to create a new key, it looks for an available key name starting with "New Key #1" and iterating up to "New Key #99" before giving up. ldb_open_key() calls reg_path_to_ldb() to build the appropriate dn from the key name. reg_path_to_ldb() was not catching the error returned by ldb_dn_add_base_fmt() due to the unescaped '#' character, causing the returned dn to be that of the parent key, not the potential new key. Additionally, Windows expects a return value of WERR_BADFILE when a key does not exist, but WERR_NOT_FOUND was being returned instead. Correcting the building of the dn and the providing the expected return value allows new key creation to succeed. When attempting to delete a key, Windows passes the complete path to the key, not just the name of the child key to be deleted. Using reg_path_to_ldb() to build the correct dn allows key deletion to succeed. (This used to be commit d57792d67b865ef43e7f21640b158862627f4b45) --- source4/lib/registry/ldb.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 17fac4abb2..edfb1f2e59 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -168,7 +168,13 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, else keyname = mypath; if(strlen(keyname)) { - ldb_dn_add_base_fmt(ret, "key=%s", keyname); + if (!ldb_dn_add_base_fmt(ret, "key=%s", + reg_ldb_escape(local_ctx, + keyname))) + { + talloc_free(local_ctx); + return NULL; + } } if(begin) { @@ -430,18 +436,18 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key(const struct hive_key *key, const char *child) +static WERROR ldb_del_key(const struct hive_key *key, const char *name) { int ret; struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); - struct ldb_dn *childdn; + struct ldb_dn *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - childdn = ldb_dn_copy(parentkd->ldb, parentkd->dn); - ldb_dn_add_child_fmt(childdn, "key=%s", child); + ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - ret = ldb_delete(parentkd->ldb, childdn); + ret = ldb_delete(parentkd->ldb, ldap_path); - talloc_free(childdn); + talloc_free(mem_ctx); if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; -- cgit From b5ba4910120e5350e48927cc0f5f06742ee02eb8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 03:00:00 +0100 Subject: registry: Avoid mapping registry return codes: return the right value in the first place. (This used to be commit 434e4857cec17d6d9e8983e151c170eed59fc6d1) --- source4/lib/registry/local.c | 2 +- source4/lib/registry/samba.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index fa59f25596..3e463100c9 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -140,7 +140,7 @@ WERROR local_get_predefined_key(struct registry_context *ctx, } if (mp == NULL) - return WERR_NOT_FOUND; + return WERR_BADFILE; *key = reg_import_hive_key(ctx, mp->key, mp->path.predefined_key, diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 02f3363bab..599385e73c 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -42,7 +42,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, error = reg_open_hive(ctx, location, auth_info, creds, lp_ctx, &hive); - if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) + if (W_ERROR_EQUAL(error, WERR_BADFILE)) error = reg_open_ldb_file(ctx, location, auth_info, creds, lp_ctx, &hive); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 59e31f55dc..06783e6a75 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -53,7 +53,7 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, WERROR error; error = reg_get_predefined_key(rctx, 1337, &root); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting predefined key failed"); return true; } -- cgit From 55ad09a01b31f2d2c9503f744b519e089f9f936b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 03:37:06 +0100 Subject: registry: Use correct return values. (This used to be commit 98ebdbe52fd615ea62a3caa17acfe8bb31b8f85d) --- source4/lib/registry/dir.c | 4 ++-- source4/lib/registry/hive.c | 2 +- source4/lib/registry/ldb.c | 35 ++++++++++++++++++++++++++++------- source4/lib/registry/patchfile.c | 14 +++++++------- source4/lib/registry/regf.c | 22 +++++++++++----------- source4/lib/registry/tests/hive.c | 6 +++--- source4/lib/registry/tests/registry.c | 2 +- 7 files changed, 53 insertions(+), 32 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 87d76e5eb7..27cae8c490 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -64,7 +64,7 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) if (rmdir(child) == 0) ret = WERR_OK; else if (errno == ENOENT) - ret = WERR_NOT_FOUND; + ret = WERR_BADFILE; else ret = WERR_GENERAL_FAILURE; @@ -339,7 +339,7 @@ static WERROR reg_dir_del_value (struct hive_key *key, const char *name) if (unlink(path) < 0) { talloc_free(path); if (errno == ENOENT) - return WERR_NOT_FOUND; + return WERR_BADFILE; return WERR_GENERAL_FAILURE; } talloc_free(path); diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index bbe510772c..5d56a30b3e 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -41,7 +41,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, fd = open(location, O_RDWR); if (fd == -1) { if (errno == ENOENT) - return WERR_NOT_FOUND; + return WERR_BADFILE; return WERR_BADFILE; } diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index edfb1f2e59..262859f64b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -337,7 +337,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); talloc_free(res); - return WERR_NOT_FOUND; + return WERR_BADFILE; } newkd = talloc_zero(mem_ctx, struct ldb_key_data); @@ -400,7 +400,7 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, struct security_descriptor *sd, struct hive_key **newkey) { - const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; struct ldb_message *msg; struct ldb_key_data *newkd; int ret; @@ -433,6 +433,10 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, *newkey = (struct hive_key *)newkd; + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + return WERR_OK; } @@ -450,12 +454,16 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name) talloc_free(mem_ctx); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + return WERR_OK; } @@ -478,12 +486,16 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) talloc_free(childdn); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); return WERR_FOOBAR; } + /* reset cache */ + talloc_free(kd->values); + kd->values = NULL; + return WERR_OK; } @@ -521,6 +533,10 @@ static WERROR ldb_set_value(struct hive_key *parent, return WERR_FOOBAR; } + /* reset cache */ + talloc_free(kd->values); + kd->values = NULL; + talloc_free(mem_ctx); return WERR_OK; } @@ -537,17 +553,23 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + if (kd->subkeys == NULL) { + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + } + + if (kd->values == NULL) { + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + } + /* FIXME */ if (classname != NULL) *classname = NULL; if (num_subkeys != NULL) { - W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); *num_subkeys = kd->subkey_count; } if (num_values != NULL) { - W_ERROR_NOT_OK_RETURN(cache_values(kd)); *num_values = kd->value_count; } @@ -557,7 +579,6 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (max_subkeynamelen != NULL) { int i; struct ldb_message_element *el; - W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); *max_subkeynamelen = 0; diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index d859bc3134..fa1367bbd2 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -82,11 +82,11 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (W_ERROR_IS_OK(error2)) continue; } else { - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_BADFILE; t2 = NULL; } - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -132,10 +132,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, continue; } else { t1 = NULL; - error2 = WERR_NOT_FOUND; + error2 = WERR_BADFILE; } - if (!W_ERROR_EQUAL(error2, WERR_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -238,14 +238,14 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, struct registry_key *r1 = NULL, *r2 = NULL; error = reg_get_predefined_key(ctx1, i, &r1); if (!W_ERROR_IS_OK(error) && - !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); } error = reg_get_predefined_key(ctx2, i, &r2); if (!W_ERROR_IS_OK(error) && - !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); } @@ -356,7 +356,7 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, /* Open key */ error = reg_open_key_abs(ctx, ctx, path, &tmp); - if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + if (W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Error opening key '%s'\n", path)); return error; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 475ec7bb5d..15b60745f0 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -870,7 +870,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -905,7 +905,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -942,7 +942,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "ri", 2)) { struct ri_block ri; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -1022,7 +1022,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, } talloc_free(pull); if (!key_off) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else { DEBUG(0, ("Unknown subkey list type.\n")); return WERR_GENERAL_FAILURE; @@ -1419,7 +1419,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } li.key_count--; @@ -1464,7 +1464,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } lf.key_count--; @@ -1510,7 +1510,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(0, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } lh.key_count--; @@ -1548,7 +1548,7 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) uint32_t i; if (nk->values_offset == -1) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } values = hbin_get(regf, nk->values_offset); @@ -1572,7 +1572,7 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) } } if (!found_offset) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else { nk->num_values--; values.length = (nk->num_values)*4; @@ -1608,14 +1608,14 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) if (parent_nk->subkeys_offset == -1) { DEBUG(4, ("Subkey list is empty, this key cannot contain subkeys.\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } /* Find the key */ if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, (struct hive_key **)&key))) { DEBUG(2, ("Key '%s' not found\n", name)); - return WERR_NOT_FOUND; + return WERR_BADFILE; } if (key->nk->subkeys_offset != -1 || diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index f72b7d6bf3..4d27e83a74 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -31,7 +31,7 @@ static bool test_del_nonexistant_key(struct torture_context *tctx, { const struct hive_key *root = (const struct hive_key *)test_data; WERROR error = hive_key_del(root, "bla"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "invalid return code"); return true; @@ -134,7 +134,7 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "reg_key_del"); error = hive_key_del(root, "Nested Key"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "reg_key_del"); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "reg_key_del"); return true; } @@ -218,7 +218,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value"); error = hive_key_del_value(subkey, "Answer"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "deleting value"); return true; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 06783e6a75..7d14b3a412 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -204,7 +204,7 @@ static bool test_del_key(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "Delete key"); error = reg_key_del(root, "Polen"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "Delete missing key"); return true; -- cgit