#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"
struct ldb_key_data
{
- const char *dn;
+ const struct ldb_dn *dn;
struct ldb_message **subkeys, **values;
int subkey_count, value_count;
};
-static int ldb_free_hive (void *_hive)
+static int ldb_free_hive (struct registry_hive *hive)
{
- struct registry_hive *hive = _hive;
talloc_free(hive->backend_data);
+ hive->backend_data = NULL;
return 0;
}
-static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, void **data, int *len)
+static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, DATA_BLOB *data)
{
const struct ldb_val *val;
- *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL));
- *type = ldb_msg_find_uint(msg, "type", 0);
+ *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", 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:
- *len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, data);
+ data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data);
break;
- case REG_DWORD_LE:
- *len = 4;
- *data = talloc(mem_ctx, uint32_t);
- SIVAL(*data, 0, strtol(val->data, NULL, 0));
+ case REG_DWORD: {
+ uint32_t tmp = strtoul((char *)val->data, NULL, 0);
+ *data = data_blob_talloc(mem_ctx, &tmp, 4);
+ }
break;
default:
- *data = talloc_memdup(mem_ctx, val->data, val->length);
- *len = val->length;
+ *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, void *data, int len)
+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(ctx, msg, "value", talloc_strdup(mem_ctx, name));
+ 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, data, len, &val.data);
- ldb_msg_add_value(ctx, msg, "data", &val);
+ 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);
break;
- case REG_DWORD_LE:
- ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data, 0)));
+
+ case REG_DWORD:
+ ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0)));
break;
default:
- val.length = len;
- val.data = data;
- ldb_msg_add_value(ctx, msg, "data", &val);
+ ldb_msg_add_value(msg, "data", &data);
}
type_s = talloc_asprintf(mem_ctx, "%u", type);
- ldb_msg_add_string(ctx, msg, "type", type_s);
+ ldb_msg_add_string(msg, "type", type_s);
return msg;
}
-static int reg_close_ldb_key (void *data)
+static int reg_close_ldb_key(struct registry_key *key)
{
- struct registry_key *key = data;
- struct ldb_key_data *kd = key->backend_data;
- struct ldb_context *c = key->hive->backend_data;
+ struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data);
+/* struct ldb_context *c = key->hive->backend_data; */
if (kd->subkeys) {
- ldb_search_free(c, kd->subkeys);
+ talloc_free(kd->subkeys);
kd->subkeys = NULL;
}
if (kd->values) {
- ldb_search_free(c, kd->values);
+ talloc_free(kd->values);
kd->values = NULL;
}
return 0;
}
-static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, const char *path, const char *add)
+static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry_key *from, const char *path, const char *add)
{
- char *ret = talloc_strdup(mem_ctx, "");
+ TALLOC_CTX *local_ctx;
+ struct ldb_dn *ret = ldb_dn_new(mem_ctx);
char *mypath = talloc_strdup(mem_ctx, path);
char *begin;
- struct ldb_key_data *kd = from->backend_data;
+ struct ldb_key_data *kd = talloc_get_type(from->backend_data, struct ldb_key_data);
- if(add)
- ret = talloc_asprintf_append(ret, "%s", add);
+ local_ctx = talloc_new(mem_ctx);
+
+ if (add)
+ ret = ldb_dn_compose(local_ctx, ret, ldb_dn_explode(mem_ctx, add));
while(mypath) {
char *keyname;
+
begin = strrchr(mypath, '\\');
- if(begin) keyname = begin + 1;
+ if (begin) keyname = begin + 1;
else keyname = mypath;
- if(strlen(keyname))
- ret = talloc_asprintf_append(ret, "key=%s,", keyname);
-
+ if(strlen(keyname)) {
+ struct ldb_dn *base;
+
+ base = ldb_dn_build_child(local_ctx, "key", keyname, NULL);
+ ret = ldb_dn_compose(local_ctx, ret, base);
+ }
+
if(begin) {
*begin = '\0';
} else {
}
}
- ret = talloc_asprintf_append(ret, "%s", kd->dn);
+ ret = ldb_dn_compose(mem_ctx, ret, kd->dn);
+
+ talloc_free(local_ctx);
return ret;
}
-static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey)
+static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **subkey)
{
- struct ldb_context *c = k->hive->backend_data;
+ struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context);
struct ldb_message_element *el;
- struct ldb_key_data *kd = k->backend_data, *newkd;
+ struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data);
+ struct ldb_key_data *newkd;
/* Do a search if necessary */
if (kd->subkeys == NULL) {
- kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &kd->subkeys);
+ struct ldb_result *res;
+ int ret;
+
+ ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res);
- if(kd->subkey_count < 0) {
- DEBUG(0, ("Error getting subkeys for '%s': %s\n", kd->dn, ldb_errstring(c)));
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c)));
return WERR_FOOBAR;
}
+
+ kd->subkey_count = res->count;
+ kd->subkeys = talloc_steal(kd, res->msgs);
+ talloc_free(res);
}
if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS;
*subkey = talloc(mem_ctx, struct registry_key);
talloc_set_destructor(*subkey, reg_close_ldb_key);
- (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data);
+ (*subkey)->name = talloc_strdup(mem_ctx, (char *)el->values[0].data);
(*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data);
- newkd->dn = talloc_strdup(mem_ctx, kd->subkeys[idx]->dn);
+ (*subkey)->last_mod = 0; /* TODO: we need to add this to the
+ ldb backend properly */
+ newkd->dn = ldb_dn_copy(mem_ctx, kd->subkeys[idx]->dn);
return WERR_OK;
}
-static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value)
+static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value)
{
- struct ldb_context *c = k->hive->backend_data;
- struct ldb_key_data *kd = k->backend_data;
+ struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context);
+ struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data);
/* Do the search if necessary */
if (kd->values == NULL) {
- kd->value_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&kd->values);
+ struct ldb_result *res;
+ int ret;
+
+ ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res);
- if(kd->value_count < 0) {
- DEBUG(0, ("Error getting values for '%s': %s\n", kd->dn, ldb_errstring(c)));
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c)));
return WERR_FOOBAR;
}
+ kd->value_count = res->count;
+ kd->values = talloc_steal(kd, res->msgs);
+ talloc_free(res);
}
if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS;
*value = talloc(mem_ctx, struct registry_value);
- reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data_blk, &(*value)->data_len);
+ reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data);
return WERR_OK;
}
-static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key)
+static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key)
{
- struct ldb_context *c = h->hive->backend_data;
- struct ldb_message **msg;
- char *ldap_path;
+ struct ldb_context *c = talloc_get_type(h->hive->backend_data, struct ldb_context);
+ struct ldb_result *res;
+ struct ldb_dn *ldap_path;
int ret;
struct ldb_key_data *newkd;
ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
- ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg);
+ ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res);
- if(ret == 0) {
- return WERR_NO_MORE_ITEMS;
- } else if(ret < 0) {
- DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c)));
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c)));
return WERR_FOOBAR;
+ } else if (res->count == 0) {
+ return WERR_BADFILE;
}
*key = talloc(mem_ctx, struct registry_key);
talloc_set_destructor(*key, reg_close_ldb_key);
(*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name);
(*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data);
- newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn);
+ newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
- ldb_search_free(c, msg);
+ talloc_free(res);
return WERR_OK;
}
struct ldb_context *wrap;
if (!hive->location) return WERR_INVALID_PARAM;
- wrap = ldb_wrap_connect(hive, hive->location, 0, NULL);
+
+ wrap = ldb_wrap_connect(hive, hive->location, hive->session_info, hive->credentials, 0, NULL);
if(!wrap) {
DEBUG(1, ("ldb_open_hive: unable to connect\n"));
talloc_set_destructor (hive, ldb_free_hive);
(*k)->name = talloc_strdup(*k, "");
(*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data);
- kd->dn = talloc_strdup(*k, "hive=");
+ kd->dn = ldb_dn_explode(*k, "hive=NONE");
return WERR_OK;
}
-static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sd, struct registry_key **newkey)
+static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sd, struct registry_key **newkey)
{
- struct ldb_context *ctx = parent->hive->backend_data;
+ struct ldb_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context);
struct ldb_message *msg;
struct ldb_key_data *newkd;
int ret;
msg->dn = reg_path_to_ldb(msg, parent, name, NULL);
- ldb_msg_add_string(ctx, msg, "key", talloc_strdup(mem_ctx, name));
+ ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name));
ret = ldb_add(ctx, msg);
if (ret < 0) {
- DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data)));
+ DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx)));
return WERR_FOOBAR;
}
return WERR_OK;
}
-static WERROR ldb_del_key (struct registry_key *key, const char *child)
+static WERROR ldb_del_key (const struct registry_key *key, const char *child)
{
+ struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context);
int ret;
- struct ldb_key_data *kd = key->backend_data;
- char *childdn = talloc_asprintf(NULL, "key=%s,%s", child, kd->dn);
+ struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data);
+ struct ldb_dn *childdn = ldb_dn_build_child(ctx, "key", child, kd->dn);
- ret = ldb_delete(key->hive->backend_data, childdn);
+ ret = ldb_delete(ctx, childdn);
talloc_free(childdn);
if (ret < 0) {
- DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data)));
+ DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(ctx)));
return WERR_FOOBAR;
}
return WERR_OK;
}
-static WERROR ldb_del_value (struct registry_key *key, const char *child)
+static WERROR ldb_del_value (const struct registry_key *key, const char *child)
{
int ret;
- struct ldb_key_data *kd = key->backend_data;
- char *childdn = talloc_asprintf(NULL, "value=%s,%s", child, kd->dn);
+ struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context);
+ struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data);
+ struct ldb_dn *childdn = ldb_dn_build_child(ctx, "value", child, kd->dn);
- ret = ldb_delete(key->hive->backend_data, childdn);
+ ret = ldb_delete(ctx, childdn);
talloc_free(childdn);
if (ret < 0) {
- DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data)));
+ DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(ctx)));
return WERR_FOOBAR;
}
return WERR_OK;
}
-static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32_t type, void *data, int len)
+static WERROR ldb_set_value (const struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data)
{
- struct ldb_context *ctx = parent->hive->backend_data;
+ struct ldb_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context);
struct ldb_message *msg;
- struct ldb_key_data *kd = parent->backend_data;
+ struct ldb_key_data *kd = talloc_get_type(parent->backend_data, struct ldb_key_data);
int ret;
TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
- msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data, len);
+ msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data);
- msg->dn = talloc_asprintf(mem_ctx, "value=%s,%s", name, kd->dn);
+ msg->dn = ldb_dn_build_child(msg, "value", name, kd->dn);
ret = ldb_add(ctx, msg);
if (ret < 0) {
ret = ldb_modify(ctx, msg);
if (ret < 0) {
- DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data)));
+ DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx)));
talloc_free(mem_ctx);
return WERR_FOOBAR;
}