summaryrefslogtreecommitdiff
path: root/source4/lib/registry
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/registry')
-rw-r--r--source4/lib/registry/ldb.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c
index df06798f74..d8a786cf8a 100644
--- a/source4/lib/registry/ldb.c
+++ b/source4/lib/registry/ldb.c
@@ -700,13 +700,14 @@ static WERROR ldb_set_value(struct hive_key *parent,
{
struct ldb_message *msg;
struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
+ unsigned int i;
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);
-
- if (strlen(name) > 0) {
+
+ if (name[0] != '\0') {
/* For a default value, we add/overwrite the attributes to/of the hive.
For a normal value, we create a new child. */
if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
@@ -717,14 +718,27 @@ static WERROR ldb_set_value(struct hive_key *parent,
}
}
- ret = ldb_add(kd->ldb, msg);
- if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- unsigned int i;
- for (i = 0; i < msg->num_elements; i++) {
- if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE)
- msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+ /* Try first a "modify" and if this doesn't work do try an "add" */
+ for (i = 0; i < msg->num_elements; i++) {
+ if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) {
+ msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
}
- ret = ldb_modify(kd->ldb, msg);
+ }
+ ret = ldb_modify(kd->ldb, msg);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ i = 0;
+ while (i < msg->num_elements) {
+ if (msg->elements[i].flags == LDB_FLAG_MOD_DELETE) {
+ ldb_msg_remove_element(msg, &msg->elements[i]);
+ } else {
+ ++i;
+ }
+ }
+ ret = ldb_add(kd->ldb, msg);
+ }
+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ /* ignore this -> the value didn't exist and also now doesn't */
+ ret = LDB_SUCCESS;
}
if (ret != LDB_SUCCESS) {