r20269: merge -r20264:20267 from SAMBA_3_0_24
[jra/samba/.git] / source3 / lib / ldb / common / ldb_msg.c
index 809d965745bb5f56e179952a7a6e6bdd98bc2ccd..bf217d2787f3f38292da1149e1584a1543a31153 100644 (file)
 #include "includes.h"
 #include "ldb/include/includes.h"
 
+void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f);
+int ldb_msg_element_compare_name(struct ldb_message_element *el1, 
+                                struct ldb_message_element *el2);
+
 /*
   create a new ldb_message in a given memory context (NULL for top level)
 */
@@ -119,7 +123,10 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v)
 /*
   add an empty element to a message
 */
-int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
+int ldb_msg_add_empty( struct ldb_message *msg,
+                       const char *attr_name,
+                       int flags,
+                       struct ldb_message_element **return_el)
 {
        struct ldb_message_element *els;
 
@@ -146,6 +153,10 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
        msg->elements = els;
        msg->num_elements++;
 
+       if (return_el) {
+               *return_el = &els[msg->num_elements-1];
+       }
+
        return LDB_SUCCESS;
 }
 
@@ -156,7 +167,7 @@ int ldb_msg_add(struct ldb_message *msg,
                const struct ldb_message_element *el, 
                int flags)
 {
-       if (ldb_msg_add_empty(msg, el->name, flags) != 0) {
+       if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
@@ -171,18 +182,19 @@ int ldb_msg_add(struct ldb_message *msg,
 */
 int ldb_msg_add_value(struct ldb_message *msg, 
                      const char *attr_name,
-                     const struct ldb_val *val)
+                     const struct ldb_val *val,
+                     struct ldb_message_element **return_el)
 {
        struct ldb_message_element *el;
        struct ldb_val *vals;
+       int ret;
 
        el = ldb_msg_find_element(msg, attr_name);
        if (!el) {
-               ldb_msg_add_empty(msg, attr_name, 0);
-               el = ldb_msg_find_element(msg, attr_name);
-       }
-       if (!el) {
-               return LDB_ERR_OPERATIONS_ERROR;
+               ret = ldb_msg_add_empty(msg, attr_name, 0, &el);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
        }
 
        vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1);
@@ -194,6 +206,10 @@ int ldb_msg_add_value(struct ldb_message *msg,
        el->values[el->num_values] = *val;
        el->num_values++;
 
+       if (return_el) {
+               *return_el = el;
+       }
+
        return LDB_SUCCESS;
 }
 
@@ -206,10 +222,10 @@ int ldb_msg_add_steal_value(struct ldb_message *msg,
                            struct ldb_val *val)
 {
        int ret;
-       ret = ldb_msg_add_value(msg, attr_name, val);
+       struct ldb_message_element *el;
+
+       ret = ldb_msg_add_value(msg, attr_name, val, &el);
        if (ret == LDB_SUCCESS) {
-               struct ldb_message_element *el;
-               el = ldb_msg_find_element(msg, attr_name);
                talloc_steal(el->values, val->data);
        }
        return ret;
@@ -229,10 +245,10 @@ int ldb_msg_add_string(struct ldb_message *msg,
 
        if (val.length == 0) {
                /* allow empty strings as non-existant attributes */
-               return 0;
+               return LDB_SUCCESS;
        }
 
-       return ldb_msg_add_value(msg, attr_name, &val);
+       return ldb_msg_add_value(msg, attr_name, &val, NULL);
 }
 
 /*
@@ -576,7 +592,7 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
                if (!el) {
                        if (ldb_msg_add_empty(mod, 
                                              msg1->elements[i].name,
-                                             LDB_FLAG_MOD_DELETE) != 0) {
+                                             LDB_FLAG_MOD_DELETE, NULL) != 0) {
                                return NULL;
                        }
                }
@@ -596,11 +612,6 @@ int ldb_msg_sanity_check(struct ldb_context *ldb,
                ldb_set_errstring(ldb, "ldb message lacks a DN!");
                return LDB_ERR_INVALID_DN_SYNTAX;
        }
-       if (msg->dn->comp_num == 0) {
-               /* root dse has empty dn */
-               ldb_set_errstring(ldb, "DN on new ldb message is '' (not permitted)!");
-               return LDB_ERR_ENTRY_ALREADY_EXISTS;
-       }
 
        /* basic syntax checks */
        for (i = 0; i < msg->num_elements; i++) {
@@ -647,7 +658,7 @@ const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs)
 
 /*
   copy an attribute list. This only copies the array, not the elements
-  (ie. the elements are left as the same pointers)
+  (ie. the elements are left as the same pointers).  The new attribute is added to the list.
 */
 const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr)
 {
@@ -730,6 +741,18 @@ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
        }
 }
 
+/*
+  remove the specified element in a search result
+*/
+void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el)
+{
+       int n = (el - msg->elements);
+       if (n != msg->num_elements-1) {
+               memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+       }
+       msg->num_elements--;
+}
+
 /*
   return a LDAP formatted time string
 */