s4-ldb: Refactor ldb_msg_diff() to be based on ldb_msg_diff_ex() implementatoin
authorKamen Mazdrashki <kamenim@samba.org>
Fri, 9 Jul 2010 03:53:27 +0000 (06:53 +0300)
committerKamen Mazdrashki <kamenim@samba.org>
Sat, 10 Jul 2010 20:03:13 +0000 (23:03 +0300)
This changes ldb_msg_diff() behavior in two directions:
1. resulting message is allocated in NULL TALLOC_CTX
   This way it should appear as memory leak in talloc
   reports in case the caller haven't freed the memory
2. previous implementation had a hidden leak - internal
   ldb_msg returned from ldb_msg_canonicalize() wasn't freed
   and stays attached to ldb_context for the connection lifetime

source4/lib/ldb/common/ldb_msg.c

index e54caa8..186861a 100644 (file)
@@ -590,55 +590,17 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
                                 struct ldb_message *msg1,
                                 struct ldb_message *msg2)
 {
+       int ldb_ret;
        struct ldb_message *mod;
-       struct ldb_message_element *el;
-       unsigned int i;
 
-       mod = ldb_msg_new(ldb);
-       if (mod == NULL) {
+       /* allocate mod message in NULL context
+        * so it should appear as 'leaked' in talloc reports */
+       ldb_ret = ldb_msg_diff_ex(ldb, msg1, msg2,
+                                 (TALLOC_CTX*)NULL, &mod);
+       if (ldb_ret != LDB_SUCCESS) {
                return NULL;
        }
 
-       mod->dn = msg1->dn;
-       mod->num_elements = 0;
-       mod->elements = NULL;
-
-       msg2 = ldb_msg_canonicalize(ldb, msg2);
-       if (msg2 == NULL) {
-               talloc_free(mod);
-               return NULL;
-       }
-       
-       /* look in msg2 to find elements that need to be added
-          or modified */
-       for (i=0;i<msg2->num_elements;i++) {
-               el = ldb_msg_find_element(msg1, msg2->elements[i].name);
-
-               if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) {
-                       continue;
-               }
-
-               if (ldb_msg_add(mod, 
-                               &msg2->elements[i],
-                               el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != LDB_SUCCESS) {
-                       talloc_free(mod);
-                       return NULL;
-               }
-       }
-
-       /* look in msg1 to find elements that need to be deleted */
-       for (i=0;i<msg1->num_elements;i++) {
-               el = ldb_msg_find_element(msg2, msg1->elements[i].name);
-               if (el == NULL) {
-                       if (ldb_msg_add_empty(mod, 
-                                             msg1->elements[i].name,
-                                             LDB_FLAG_MOD_DELETE, NULL) != LDB_SUCCESS) {
-                               talloc_free(mod);
-                               return NULL;
-                       }
-               }
-       }
-
        return mod;
 }