s4:registry library - fix up "reg_ldb_set_value"
authorMatthias Dieter Wallnöfer <mwallnoefer@yahoo.de>
Sat, 6 Mar 2010 18:36:01 +0000 (19:36 +0100)
committerMatthias Dieter Wallnöfer <mwallnoefer@yahoo.de>
Sat, 6 Mar 2010 18:59:04 +0000 (19:59 +0100)
The previous logic was wrong since it tried to add empty data in some cases
which always ended in an error. This problem should be fixed with the new logic.

source4/lib/registry/ldb.c

index df06798f74fc9486d7c0194aab05ea6bd33b5743..d8a786cf8a87ae915d1c85275e7e5ac52577d243 100644 (file)
@@ -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) {