From b409d4120f9ae451f93a2322267c0f346531d9f3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 15:16:40 +0000 Subject: r24667: Finally merge the registry improvements that Wilco Baan Hofman and I have been working on for at least half a year now. Contains the following improvements: * proper layering (finally!) for the registry library. Distinction is now made between 'real' backends (local, remote, wine, etc) and the low-level hive backends (regf, creg, ldb, ...) that are only used by the local registry backend * tests for all important hive and registry operations * re-enable RPC-WINREG tests (still needs more work though, as some return values aren't checked yet) * write support for REGF files * dir backend now supports setting/reading values, creating keys * support for storing security descriptors * remove CREG backend as it was incomplete, didn't match the data model and wasn't used at all anyway * support for parsing ADM files as used by the policy editor (see lib/policy) * support for parsing PREG files (format used by .POL files) * new streaming interface for registry diffs (improves speed and memory usage for regdiff/regpatch significantly) ... and fixes a large number of bugs in the registry code (This used to be commit 7a1eec6358bc863dfc671c542b7185d3e39d7b5a) --- source4/lib/registry/ldb.c | 501 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 source4/lib/registry/ldb.c (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c new file mode 100644 index 0000000000..8ee4d9f932 --- /dev/null +++ b/source4/lib/registry/ldb.c @@ -0,0 +1,501 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "registry.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "db_wrap.h" +#include "librpc/gen_ndr/winreg.h" + +static struct hive_operations reg_backend_ldb; + +struct ldb_key_data +{ + struct hive_key key; + struct ldb_context *ldb; + struct ldb_dn *dn; + struct ldb_message **subkeys, **values; + int subkey_count, value_count; +}; + +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, + uint32_t *type, DATA_BLOB *data) +{ + const struct ldb_val *val; + if (name != NULL) + *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + + if (type != NULL) + *type = ldb_msg_find_attr_as_uint(msg, "type", 0); + val = ldb_msg_find_ldb_val(msg, "data"); + + switch (*type) + { + case REG_SZ: + case REG_EXPAND_SZ: + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + val->data, val->length, (void **)&data->data); + break; + + case REG_DWORD: { + uint32_t tmp = strtoul((char *)val->data, NULL, 0); + *data = data_blob_talloc(mem_ctx, &tmp, 4); + } + break; + + default: + *data = data_blob_talloc(mem_ctx, val->data, val->length); + break; + } +} + +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, + TALLOC_CTX *mem_ctx, const char *name, + uint32_t type, DATA_BLOB data) +{ + struct ldb_val val; + struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); + char *type_s; + + ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name)); + + switch (type) { + case REG_SZ: + case REG_EXPAND_SZ: + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + (void *)data.data, data.length, (void **)&val.data); + ldb_msg_add_value(msg, "data", &val, NULL); + break; + + case REG_DWORD: + ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + break; + default: + ldb_msg_add_value(msg, "data", &data, NULL); + } + + + type_s = talloc_asprintf(mem_ctx, "%u", type); + ldb_msg_add_string(msg, "type", type_s); + + return msg; +} + + +static int reg_close_ldb_key(struct ldb_key_data *key) +{ + if (key->subkeys != NULL) { + talloc_free(key->subkeys); + key->subkeys = NULL; + } + + if (key->values != NULL) { + talloc_free(key->values); + key->values = NULL; + } + return 0; +} + +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, + const struct hive_key *from, + const char *path, const char *add) +{ + TALLOC_CTX *local_ctx; + struct ldb_dn *ret; + char *mypath = talloc_strdup(mem_ctx, path); + char *begin; + struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data); + struct ldb_context *ldb = kd->ldb; + + local_ctx = talloc_new(mem_ctx); + + if (add) { + ret = ldb_dn_new(mem_ctx, ldb, add); + } else { + ret = ldb_dn_new(mem_ctx, ldb, NULL); + } + if (!ldb_dn_validate(ret)) { + talloc_free(ret); + talloc_free(local_ctx); + return NULL; + } + + while (mypath) { + char *keyname; + + begin = strrchr(mypath, '\\'); + + if (begin) keyname = begin + 1; + else keyname = mypath; + + if(strlen(keyname)) { + ldb_dn_add_base_fmt(ret, "key=%s", keyname); + } + + if(begin) { + *begin = '\0'; + } else { + break; + } + } + + ldb_dn_add_base(ret, kd->dn); + + talloc_free(local_ctx); + + return ret; +} + +static WERROR cache_subkeys(struct ldb_key_data *kd) +{ + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + + kd->subkey_count = res->count; + kd->subkeys = talloc_steal(kd, res->msgs); + talloc_free(res); + + return WERR_OK; +} + +static WERROR cache_values(struct ldb_key_data *kd) +{ + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + kd->value_count = res->count; + kd->values = talloc_steal(kd, res->msgs); + talloc_free(res); + return WERR_OK; +} + + +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) +{ + struct ldb_message_element *el; + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + + /* Do a search if necessary */ + if (kd->subkeys == NULL) { + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + } + + if (idx >= kd->subkey_count) + return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(kd->subkeys[idx], "key"); + SMB_ASSERT(el != NULL); + SMB_ASSERT(el->num_values != 0); + + if (name != NULL) + *name = talloc_strdup(mem_ctx, (char *)el->values[0].data); + + if (classname != NULL) + *classname = NULL; /* TODO: Store properly */ + + if (last_mod_time != NULL) + *last_mod_time = 0; /* TODO: we need to add this to the + ldb backend properly */ + + return WERR_OK; +} + +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, int idx, + const char **name, uint32_t *data_type, DATA_BLOB *data) +{ + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + + /* Do the search if necessary */ + if (kd->values == NULL) { + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + } + + if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; + + reg_ldb_unpack_value(mem_ctx, kd->values[idx], + name, data_type, data); + + return WERR_OK; +} + +static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, + const char *name, uint32_t *data_type, DATA_BLOB *data) +{ + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + char *query = talloc_asprintf(mem_ctx, "(value=%s)", name); + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res); + + talloc_free(query); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + + if (res->count == 0) + return WERR_NOT_FOUND; + + reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); + + return WERR_OK; +} + +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, + const char *name, struct hive_key **key) +{ + struct ldb_result *res; + struct ldb_dn *ldap_path; + int ret; + struct ldb_key_data *newkd; + struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data); + struct ldb_context *c = kd->ldb; + + ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL); + + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error opening key '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + return WERR_FOOBAR; + } else if (res->count == 0) { + DEBUG(0, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + talloc_free(res); + return WERR_NOT_FOUND; + } + + newkd = talloc_zero(mem_ctx, struct ldb_key_data); + newkd->key.ops = ®_backend_ldb; + newkd->ldb = talloc_reference(newkd, kd->ldb); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); + + *key = (struct hive_key *)newkd; + + talloc_free(res); + + return WERR_OK; +} + +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k) +{ + struct ldb_key_data *kd; + struct ldb_context *wrap; + + if (location == NULL) + return WERR_INVALID_PARAM; + + wrap = ldb_wrap_connect(parent_ctx, location, session_info, + credentials, 0, NULL); + + if (wrap == NULL) { + DEBUG(1, (__FILE__": unable to connect\n")); + return WERR_FOOBAR; + } + + ldb_set_debug_stderr(wrap); + + kd = talloc_zero(parent_ctx, struct ldb_key_data); + kd->key.ops = ®_backend_ldb; + kd->ldb = talloc_reference(kd, wrap); + talloc_set_destructor (kd, reg_close_ldb_key); + kd->dn = ldb_dn_new(kd, wrap, "hive=NONE"); + + *k = (struct hive_key *)kd; + + return WERR_OK; +} + +static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sd, + struct hive_key **newkey) +{ + const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_message *msg; + struct ldb_key_data *newkd; + int ret; + + msg = ldb_msg_new(mem_ctx); + + msg->dn = reg_path_to_ldb(msg, parent, name, NULL); + + ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); + if (classname != NULL) + ldb_msg_add_string(msg, "classname", 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))); + return WERR_FOOBAR; + } + + DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn))); + + newkd = talloc_zero(mem_ctx, struct ldb_key_data); + newkd->ldb = talloc_reference(newkd, parentkd->ldb); + newkd->key.ops = ®_backend_ldb; + newkd->dn = talloc_steal(newkd, msg->dn); + + *newkey = (struct hive_key *)newkd; + + return WERR_OK; +} + +static WERROR ldb_del_key (const struct hive_key *key, const char *child) +{ + int ret; + struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(parentkd->ldb, parentkd->dn); + ldb_dn_add_child_fmt(childdn, "key=%s", child); + + ret = ldb_delete(parentkd->ldb, childdn); + + talloc_free(childdn); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return WERR_NOT_FOUND; + } else if (ret < 0) { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_del_value (struct hive_key *key, const char *child) +{ + int ret; + struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(kd->ldb, kd->dn); + ldb_dn_add_child_fmt(childdn, "value=%s", child); + + ret = ldb_delete(kd->ldb, childdn); + + talloc_free(childdn); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return WERR_NOT_FOUND; + } else if (ret < 0) { + DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_set_value(struct hive_key *parent, + const char *name, uint32_t type, + const DATA_BLOB data) +{ + struct ldb_message *msg; + struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data); + int ret; + TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); + + 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); + + 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; + } + } + + talloc_free(mem_ctx); + return WERR_OK; +} + +static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) +{ + struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + + /* 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; + } + + if (last_change_time != NULL) + *last_change_time = 0; + + return WERR_OK; +} + +static struct hive_operations reg_backend_ldb = { + .name = "ldb", + .add_key = ldb_add_key, + .del_key = ldb_del_key, + .get_key_by_name = ldb_open_key, + .enum_value = ldb_get_value_by_id, + .enum_key = ldb_get_subkey_by_id, + .set_value = ldb_set_value, + .get_value_by_name = ldb_get_value, + .delete_value = ldb_del_value, + .get_key_info = ldb_get_key_info, +}; -- cgit From 6ca139026956916a4a956dd36d10d7f5a72272b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 22:12:02 +0000 Subject: r24684: Be a bit less verbose (This used to be commit 7a7af62dc4485d832436ed39dfba41b417ec2b10) --- source4/lib/registry/ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 8ee4d9f932..8a34fa7a54 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -295,11 +295,11 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error opening key '%s': %s\n", + DEBUG(3, ("Error opening key '%s': %s\n", ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { - DEBUG(0, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); talloc_free(res); return WERR_NOT_FOUND; } -- cgit From 033c2c07a3a080922a35cc674163b1768d0ff227 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Sep 2007 16:17:12 +0000 Subject: r24898: Fix LOCAL-REGISTRY, do not silently ignore testcase setup failures. (This used to be commit 527ea7fccf4ace9cd9cbacf49820ecd208b8d570) --- source4/lib/registry/ldb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 8a34fa7a54..5ecbfa0407 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -327,8 +327,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, location, session_info, - credentials, 0, NULL); + wrap = ldb_wrap_connect(parent_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { DEBUG(1, (__FILE__": unable to connect\n")); -- cgit From 2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 18:52:55 +0000 Subject: r25446: Merge some changes I made on the way home from SFO: 2007-09-29 More higher-level passing around of lp_ctx. 2007-09-29 Fix warning. 2007-09-29 Pass loadparm contexts on a higher level. 2007-09-29 Avoid using global loadparm context. (This used to be commit 3468952e771ab31f90b6c374ade01c5550810f42) --- source4/lib/registry/ldb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 5ecbfa0407..e9daf31f9b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -23,6 +23,7 @@ #include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" static struct hive_operations reg_backend_ldb; @@ -317,9 +318,9 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, } WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **k) + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k) { struct ldb_key_data *kd; struct ldb_context *wrap; @@ -327,7 +328,8 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, location, session_info, credentials, 0, NULL); + wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + location, session_info, credentials, 0, NULL); if (wrap == NULL) { DEBUG(1, (__FILE__": unable to connect\n")); -- cgit From cc8f4eb3cd9b3bc4e3f3d61bfad240147e8a4e5e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 6 Oct 2007 00:17:44 +0000 Subject: r25544: Cleanup some more indents in lib/registry. Guenther (This used to be commit 0d9826dc54057db2cfebcb806e5442c4dcf60daa) --- source4/lib/registry/ldb.c | 154 +++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 68 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index e9daf31f9b..4a6ef65bc4 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Jelmer Vernooij 2004-2007. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,7 +27,7 @@ static struct hive_operations reg_backend_ldb; -struct ldb_key_data +struct ldb_key_data { struct hive_key key; struct ldb_context *ldb; @@ -36,12 +36,15 @@ struct ldb_key_data int subkey_count, value_count; }; -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, - uint32_t *type, DATA_BLOB *data) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char **name, uint32_t *type, + DATA_BLOB *data) { const struct ldb_val *val; if (name != NULL) - *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + *name = talloc_strdup(mem_ctx, + ldb_msg_find_attr_as_string(msg, "value", + NULL)); if (type != NULL) *type = ldb_msg_find_attr_as_uint(msg, "type", 0); @@ -51,8 +54,9 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, - val->data, val->length, (void **)&data->data); + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + val->data, val->length, + (void **)&data->data); break; case REG_DWORD: { @@ -67,9 +71,10 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c } } -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, - TALLOC_CTX *mem_ctx, const char *name, - uint32_t type, DATA_BLOB data) +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, + TALLOC_CTX *mem_ctx, + const char *name, + uint32_t type, DATA_BLOB data) { struct ldb_val val; struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); @@ -80,13 +85,17 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, - (void *)data.data, data.length, (void **)&val.data); + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + (void *)data.data, + data.length, + (void **)&val.data); ldb_msg_add_value(msg, "data", &val, NULL); break; case REG_DWORD: - ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + ldb_msg_add_string(msg, "data", + talloc_asprintf(mem_ctx, "0x%x", + IVAL(data.data, 0))); break; default: ldb_msg_add_value(msg, "data", &data, NULL); @@ -94,7 +103,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(msg, "type", type_s); + ldb_msg_add_string(msg, "type", type_s); return msg; } @@ -103,20 +112,20 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { - talloc_free(key->subkeys); + talloc_free(key->subkeys); key->subkeys = NULL; } if (key->values != NULL) { - talloc_free(key->values); + talloc_free(key->values); key->values = NULL; } return 0; } -static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, - const struct hive_key *from, - const char *path, const char *add) +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, + const struct hive_key *from, + const char *path, const char *add) { TALLOC_CTX *local_ctx; struct ldb_dn *ret; @@ -173,7 +182,8 @@ static WERROR cache_subkeys(struct ldb_key_data *kd) ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -190,10 +200,12 @@ static WERROR cache_values(struct ldb_key_data *kd) struct ldb_result *res; int ret; - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } kd->value_count = res->count; @@ -203,11 +215,11 @@ static WERROR cache_values(struct ldb_key_data *kd) } -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, - const struct hive_key *k, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { struct ldb_message_element *el; struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -215,21 +227,21 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, /* Do a search if necessary */ if (kd->subkeys == NULL) { W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); - } + } - if (idx >= kd->subkey_count) + if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; el = ldb_msg_find_element(kd->subkeys[idx], "key"); SMB_ASSERT(el != NULL); SMB_ASSERT(el->num_values != 0); - + if (name != NULL) *name = talloc_strdup(mem_ctx, (char *)el->values[0].data); if (classname != NULL) *classname = NULL; /* TODO: Store properly */ - + if (last_mod_time != NULL) *last_mod_time = 0; /* TODO: we need to add this to the ldb backend properly */ @@ -237,8 +249,9 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, int idx, - const char **name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -247,16 +260,18 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, W_ERROR_NOT_OK_RETURN(cache_values(kd)); } - if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; + if (idx >= kd->value_count) + return WERR_NO_MORE_ITEMS; - reg_ldb_unpack_value(mem_ctx, kd->values[idx], - name, data_type, data); + reg_ldb_unpack_value(mem_ctx, kd->values[idx], + name, data_type, data); return WERR_OK; } -static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, - const char *name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, + const char *name, uint32_t *data_type, + DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); struct ldb_context *c = kd->ldb; @@ -269,7 +284,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, talloc_free(query); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -281,8 +297,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, return WERR_OK; } -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, - const char *name, struct hive_key **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, + const char *name, struct hive_key **key) { struct ldb_result *res; struct ldb_dn *ldap_path; @@ -296,11 +312,12 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(3, ("Error opening key '%s': %s\n", - ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + DEBUG(3, ("Error opening key '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { - DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + DEBUG(3, ("Key '%s' not found\n", + ldb_dn_get_linearized(ldap_path))); talloc_free(res); return WERR_NOT_FOUND; } @@ -308,7 +325,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, newkd = talloc_zero(mem_ctx, struct ldb_key_data); newkd->key.ops = ®_backend_ldb; newkd->ldb = talloc_reference(newkd, kd->ldb); - newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); *key = (struct hive_key *)newkd; @@ -317,7 +334,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, return WERR_OK; } -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct hive_key **k) @@ -325,10 +342,10 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct ldb_key_data *kd; struct ldb_context *wrap; - if (location == NULL) + if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + wrap = ldb_wrap_connect(parent_ctx, global_loadparm, location, session_info, credentials, 0, NULL); if (wrap == NULL) { @@ -349,10 +366,10 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *sd, - struct hive_key **newkey) +static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sd, + struct hive_key **newkey) { const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; struct ldb_message *msg; @@ -365,13 +382,14 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); if (classname != NULL) - ldb_msg_add_string(msg, "classname", talloc_strdup(mem_ctx, classname)); + ldb_msg_add_string(msg, "classname", + 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))); return WERR_FOOBAR; - } + } DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn))); @@ -385,7 +403,7 @@ 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 *child) { int ret; struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); @@ -431,9 +449,9 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value(struct hive_key *parent, - const char *name, uint32_t type, - const DATA_BLOB data) +static WERROR ldb_set_value(struct hive_key *parent, + const char *name, uint32_t type, + const DATA_BLOB data) { struct ldb_message *msg; struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data); @@ -454,17 +472,17 @@ static WERROR ldb_set_value(struct hive_key *parent, return WERR_FOOBAR; } } - + talloc_free(mem_ctx); return WERR_OK; } -static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); -- cgit From ca0b72a1fdb7bd965065e833df34662afef0423e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Nov 2007 20:12:00 +0100 Subject: r26003: Split up DB_WRAP, as first step in an attempt to sanitize dependencies. (This used to be commit 56dfcb4f2f8e74c9d8b2fe3a0df043781188a555) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 4a6ef65bc4..fdd4c27599 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -21,7 +21,7 @@ #include "registry.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "db_wrap.h" +#include "ldb_wrap.h" #include "librpc/gen_ndr/winreg.h" #include "param/param.h" -- cgit From cb7c72a0ef9a8e6d145ead6286e54ec50ddf3988 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:58:04 +0100 Subject: r26263: Don't assume CH_UNIX is CH_UTF8. (This used to be commit 69157be9b180e4d82a66257afb5f774ef16cea89) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index fdd4c27599..6ce422049b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); -- cgit From 39ee38d9c1aabf4db065b433d067d0da053d7d61 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 17:52:23 +0100 Subject: r26316: Use contexts for conversion functions. (This used to be commit f6420d933b5b011d428974f3a2a57edf19e6f482) --- source4/lib/registry/ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 6ce422049b..0e556da9e2 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -54,7 +54,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + val.length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); -- cgit From d891c0c74a03d797aed1c5ac0329fd9d1d78da63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:09 +0100 Subject: r26429: Avoid use of global_smb_iconv_convenience. (This used to be commit d37136b7abfbba75ef2e5ab855eb3382b9648b8c) --- source4/lib/registry/ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0e556da9e2..11fa066a35 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -54,7 +54,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + val.length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); -- cgit From 96a200511e884a88dcf48fa5b313b2cddb2df566 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 00:27:31 +0100 Subject: r26443: Remove global_loadparm instances. (This used to be commit 8242c696235d1bfb402b5c276a57f36d93610545) --- source4/lib/registry/ldb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 11fa066a35..873e291d5b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -337,6 +337,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **k) { struct ldb_key_data *kd; -- cgit From 45015eda2421253f858f0a4500a57c2855f9686c Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 14 Dec 2007 10:38:26 +0100 Subject: r26451: Janitorial: fix warnings in lib/registry/ This does not fix the discarded qualifier warnings in tests, as the test data is currently passed as const. Jelmer wants to provide a test function that passes non-const test data, thus allowing for a cleaner way to fix those warnings. (This used to be commit 46dfa63d4f7381c5c6ce3f4b8b0bd9aa9e16950c) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 873e291d5b..78acc3150b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -249,7 +249,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k, int idx, const char **name, uint32_t *data_type, DATA_BLOB *data) { -- cgit From 12a513b47b1a1f2adeb2cb2a10ac36d02dd44065 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:16 +0100 Subject: r26518: Fix provision of registry using Python. (This used to be commit 12eb38e553993b2726a803af4ae9c05229d6ebe4) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 78acc3150b..c9697ddb4c 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -346,7 +346,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + wrap = ldb_wrap_connect(parent_ctx, lp_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { -- cgit From 47f6bbf8cf5bdd03c72c59d00e3e1eab8895590e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 14:11:29 -0600 Subject: r26689: registry: Return max_subkeynamelen, max_valnamelen and max_valbufsize in getkeyinfo(). (This used to be commit b06896d2378e536f5044dbe500a5232a89d6d0b5) --- source4/lib/registry/ldb.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index c9697ddb4c..1e345ba9f3 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -41,16 +41,19 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, DATA_BLOB *data) { const struct ldb_val *val; + uint32_t value_type; + if (name != NULL) *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + value_type = ldb_msg_find_attr_as_uint(msg, "type", 0); if (type != NULL) - *type = ldb_msg_find_attr_as_uint(msg, "type", 0); + *type = value_type; val = ldb_msg_find_ldb_val(msg, "data"); - switch (*type) + switch (value_type) { case REG_SZ: case REG_EXPAND_SZ: @@ -483,7 +486,10 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); @@ -504,6 +510,46 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (last_change_time != NULL) *last_change_time = 0; + if (max_subkeynamelen != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + + *max_subkeynamelen = 0; + + for (i = 0; i < kd->subkey_count; i++) { + el = ldb_msg_find_element(kd->subkeys[i], "key"); + *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length); + } + } + + if (max_valnamelen != NULL || max_valbufsize != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + + if (max_valbufsize != NULL) + *max_valbufsize = 0; + + if (max_valnamelen != NULL) + *max_valnamelen = 0; + + for (i = 0; i < kd->value_count; i++) { + if (max_valnamelen != NULL) { + el = ldb_msg_find_element(kd->values[i], "value"); + *max_valnamelen = MAX(*max_valnamelen, el->values[0].length); + } + + if (max_valbufsize != NULL) { + DATA_BLOB data; + reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, + NULL, &data); + *max_valbufsize = MAX(*max_valbufsize, data.length); + talloc_free(data.data); + } + } + } + return WERR_OK; } -- cgit From 83a7d865e41e56ee7ad6c732f743df51a418168e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 23:41:55 -0600 Subject: r26692: registry: Treat key and value names case-insensitively. (This used to be commit 9fc5f098e01145db5b01efb0bf22cdddf0213d20) --- source4/lib/registry/ldb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 1e345ba9f3..259315cc39 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -345,6 +345,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, { struct ldb_key_data *kd; struct ldb_context *wrap; + struct ldb_message *attrs_msg; if (location == NULL) return WERR_INVALID_PARAM; @@ -357,6 +358,15 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_FOOBAR; } + attrs_msg = ldb_msg_new(wrap); + W_ERROR_HAVE_NO_MEMORY(attrs_msg); + attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES"); + W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn); + ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE"); + ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE"); + + ldb_add(wrap, attrs_msg); + ldb_set_debug_stderr(wrap); kd = talloc_zero(parent_ctx, struct ldb_key_data); -- cgit 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/ldb.c') 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/ldb.c') 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/ldb.c') 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/ldb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry/ldb.c') 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; } -- 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/ldb.c') 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 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/ldb.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry/ldb.c') 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; -- cgit From 7a402da97eb12fbcae3ad86171562623ba52a116 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 17:18:51 +0100 Subject: registry: Fix warning. (This used to be commit dad809030478a85ac13a73bce9c07314792f01c2) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 262859f64b..0c8a55396e 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, struct security_descriptor *sd, struct hive_key **newkey) { - struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent); struct ldb_message *msg; struct ldb_key_data *newkd; int ret; -- cgit From 10169a203019445e6d325a5c1559de3c73782237 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:54:24 +0100 Subject: Remove more global_loadparm instance.s (This used to be commit a1280252ce924df69d911e597b7f65d8038abef9) --- source4/lib/registry/ldb.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0c8a55396e..dfd368ea80 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -36,7 +36,9 @@ struct ldb_key_data int subkey_count, value_count; }; -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct ldb_message *msg, const char **name, uint32_t *type, DATA_BLOB *data) { @@ -57,7 +59,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, iconv_convenience, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -281,7 +283,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k, if (idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - reg_ldb_unpack_value(mem_ctx, kd->values[idx], + reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), kd->values[idx], name, data_type, data); return WERR_OK; @@ -310,7 +312,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, if (res->count == 0) return WERR_BADFILE; - reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); + reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), res->msgs[0], NULL, data_type, data); return WERR_OK; } @@ -607,7 +609,9 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (max_valbufsize != NULL) { DATA_BLOB data; - reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, + reg_ldb_unpack_value(mem_ctx, + lp_iconv_convenience(global_loadparm), + kd->values[i], NULL, NULL, &data); *max_valbufsize = MAX(*max_valbufsize, data.length); talloc_free(data.data); -- cgit From 7dac0598ec6edb63f15a7cce7c231f56f9ab7f7d Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 16 Feb 2008 15:08:28 -0600 Subject: registry: Implement recursive deletes for ldb-backed registry. When deleting a registry key that contains subkeys or values, Windows performs a recursive deletion that removes any subkeys or values. This update makes deletes for an ldb-backed registry consistent with Windows. Under ldb, the deletion is done using an explicit transaction. If an error occurs during the deletion the entire transaction is cancelled, leaving the registry as it was before the deletions started. (This used to be commit ca796c8fb10598674a5eef31d15863e79bcf3db8) --- source4/lib/registry/ldb.c | 143 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 27 deletions(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0c8a55396e..31b78d8246 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -440,33 +440,6 @@ 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 *name) -{ - int ret; - struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); - struct ldb_dn *ldap_path; - TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - - ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - - ret = ldb_delete(parentkd->ldb, ldap_path); - - talloc_free(mem_ctx); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - 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; -} - static WERROR ldb_del_value (struct hive_key *key, const char *child) { int ret; @@ -499,6 +472,122 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } +static WERROR ldb_del_key(const struct hive_key *key, const char *name) +{ + int i, ret; + struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); + struct ldb_context *c = parentkd->ldb; + struct ldb_result *res_keys; + struct ldb_result *res_vals; + WERROR werr; + struct hive_key *hk; + + /* Verify key exists by opening it */ + werr = ldb_open_key(mem_ctx, key, name, &hk); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(mem_ctx); + return werr; + } + + ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); + if (!ldap_path) { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for subkeys */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(key=*)", NULL, &res_keys); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for values */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res_vals); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Start an explicit transaction */ + ret = ldb_transaction_start(c); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + if (res_keys->count || res_vals->count) + { + /* Delete any subkeys */ + for (i = 0; i < res_keys->count; i++) + { + werr = ldb_del_key(hk, ldb_msg_find_attr_as_string( + res_keys->msgs[i], + "key", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + + /* Delete any values */ + for (i = 0; i < res_vals->count; i++) + { + werr = ldb_del_value(hk, ldb_msg_find_attr_as_string( + res_vals->msgs[i], + "value", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + } + + /* Delete the key itself */ + ret = ldb_delete(c, ldap_path); + + if (ret != LDB_SUCCESS) + { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Commit the transaction */ + ret = ldb_transaction_commit(c); + + if (ret != LDB_SUCCESS) + { + DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + talloc_free(mem_ctx); + + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + + return WERR_OK; +} + static WERROR ldb_set_value(struct hive_key *parent, const char *name, uint32_t type, const DATA_BLOB data) -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/lib/registry/ldb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry/ldb.c') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index a764ca6235..a8a9ed597e 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -357,6 +357,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **k) { @@ -367,7 +368,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, lp_ctx, + wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { -- cgit