diff options
Diffstat (limited to 'source4/lib/registry')
-rw-r--r-- | source4/lib/registry/dir.c | 6 | ||||
-rw-r--r-- | source4/lib/registry/hive.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/ldb.c | 109 | ||||
-rw-r--r-- | source4/lib/registry/local.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/patchfile.c | 20 | ||||
-rw-r--r-- | source4/lib/registry/regf.c | 24 | ||||
-rw-r--r-- | source4/lib/registry/samba.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/tests/hive.c | 10 | ||||
-rw-r--r-- | source4/lib/registry/tests/registry.c | 20 |
9 files changed, 125 insertions, 70 deletions
diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index a13e3753b7..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; @@ -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 */ @@ -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 259315cc39..262859f64b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -111,6 +111,15 @@ 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; + + 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) { @@ -159,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) { @@ -293,7 +308,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); @@ -322,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); @@ -385,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; @@ -400,8 +415,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 < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + return WERR_ALREADY_EXISTS; + } + + if (ret != LDB_SUCCESS) { + DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } @@ -414,29 +433,37 @@ 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; } -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; - } else if (ret < 0) { + 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; } @@ -447,19 +474,28 @@ 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); talloc_free(childdn); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_NOT_FOUND; - } else if (ret < 0) { + 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; } @@ -475,18 +511,32 @@ 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 < 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; } + /* reset cache */ + talloc_free(kd->values); + kd->values = NULL; + talloc_free(mem_ctx); return WERR_OK; } @@ -503,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; } @@ -523,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/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/patchfile.c b/source4/lib/registry/patchfile.c index b6ad7dfb10..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_DEST_NOT_FOUND; + error2 = WERR_BADFILE; } - 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); @@ -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; @@ -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 9b126cc808..15b60745f0 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; } @@ -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/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/hive.c b/source4/lib/registry/tests/hive.c index 22b4785222..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; } @@ -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,10 +215,10 @@ 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, + 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 75fbe1cbea..7d14b3a412 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; } @@ -195,16 +195,16 @@ 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"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + error = reg_key_del(root, "Polen"); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "Delete missing key"); return true; @@ -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; |