From 4d8a60f617f941ff6481bcfbac73d7ed69e43daa Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 01:50:33 +0100 Subject: When Windows initially creates a new value, the value name is "New Value #1". The '#' character was causing problems, as it was not being escaped for the dn, but the failure returned by ldb_dn_add_child_fmt() was not being caught. This was causing the new value to be added on the parent key, not the current key. When attempting to delete the new value (now on the parent key) the same escaping error was returned by ldb_dn_add_child_fmt(), causing the delete to delete the key and not the value. When attempting to rename a value, Windows first tries to ensure the new name does not already exist. When a value does not exist, Windows expects a return value of WERR_BADFILE, but WERR_NOT_FOUND was being returned instead. Providing the WERR_BADFILE that Windows expects allows values to be renamed. (This used to be commit 94fb39cfd967455ce5a554720c1c7e6183f91056) --- source4/lib/registry/ldb.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index d87bc6cf8e..884aed1579 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -112,6 +112,16 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, } +static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, value); + val.length = strlen(value); + + return ldb_dn_escape_value(mem_ctx, val); +} + static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { @@ -447,7 +457,12 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) struct ldb_dn *childdn; childdn = ldb_dn_copy(kd->ldb, kd->dn); - ldb_dn_add_child_fmt(childdn, "value=%s", child); + if (!ldb_dn_add_child_fmt(childdn, "value=%s", + reg_ldb_escape(childdn, child))) + { + talloc_free(childdn); + return WERR_FOOBAR; + } ret = ldb_delete(kd->ldb, childdn); @@ -475,7 +490,12 @@ static WERROR ldb_set_value(struct hive_key *parent, msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data); msg->dn = ldb_dn_copy(msg, kd->dn); - ldb_dn_add_child_fmt(msg->dn, "value=%s", name); + if (!ldb_dn_add_child_fmt(msg->dn, "value=%s", + reg_ldb_escape(mem_ctx, name))) + { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } ret = ldb_add(kd->ldb, msg); if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { -- cgit