r17714: fix compiler warnings
[kamenim/samba.git] / source4 / lib / ldb / common / ldb_msg.c
index f4a49e47ce1516c0e6b33b1a5559609666684842..b42c4fe6024c225b8931ae8417758a635f83453b 100644 (file)
  */
 
 #include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_errors.h"
-#include "ldb/include/ldb_private.h"
-#include <time.h>
+#include "ldb/include/includes.h"
 
 /*
   create a new ldb_message in a given memory context (NULL for top level)
@@ -126,6 +123,10 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
 {
        struct ldb_message_element *els;
 
+       if (! ldb_valid_attr_name(attr_name)) {
+               return -1;
+       }
+
        els = talloc_realloc(msg, msg->elements, 
                             struct ldb_message_element, msg->num_elements+1);
        if (!els) {
@@ -138,6 +139,7 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
        els[msg->num_elements].flags = flags;
        els[msg->num_elements].name = talloc_strdup(els, attr_name);
        if (!els[msg->num_elements].name) {
+               errno = ENOMEM;
                return -1;
        }
 
@@ -196,6 +198,24 @@ int ldb_msg_add_value(struct ldb_message *msg,
 }
 
 
+/*
+  add a value to a message, stealing it into the 'right' place
+*/
+int ldb_msg_add_steal_value(struct ldb_message *msg, 
+                           const char *attr_name,
+                           struct ldb_val *val)
+{
+       int ret;
+       ret = ldb_msg_add_value(msg, attr_name, val);
+       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;
+}
+
+
 /*
   add a string element to a message
 */
@@ -210,6 +230,20 @@ int ldb_msg_add_string(struct ldb_message *msg,
        return ldb_msg_add_value(msg, attr_name, &val);
 }
 
+/*
+  add a string element to a message, stealing it into the 'right' place
+*/
+int ldb_msg_add_steal_string(struct ldb_message *msg, 
+                            const char *attr_name, char *str)
+{
+       struct ldb_val val;
+
+       val.data = (uint8_t *)str;
+       val.length = strlen(str);
+
+       return ldb_msg_add_steal_value(msg, attr_name, &val);
+}
+
 /*
   add a printf formatted element to a message
 */
@@ -229,7 +263,7 @@ int ldb_msg_add_fmt(struct ldb_message *msg,
        val.data   = (uint8_t *)str;
        val.length = strlen(str);
 
-       return ldb_msg_add_value(msg, attr_name, &val);
+       return ldb_msg_add_steal_value(msg, attr_name, &val);
 }
 
 /*
@@ -277,9 +311,9 @@ const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const
        return &el->values[0];
 }
 
-int ldb_msg_find_int(const struct ldb_message *msg, 
-                    const char *attr_name,
-                    int default_value)
+int ldb_msg_find_attr_as_int(const struct ldb_message *msg, 
+                            const char *attr_name,
+                            int default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -288,9 +322,9 @@ int ldb_msg_find_int(const struct ldb_message *msg,
        return strtol((const char *)v->data, NULL, 0);
 }
 
-unsigned int ldb_msg_find_uint(const struct ldb_message *msg, 
-                              const char *attr_name,
-                              unsigned int default_value)
+unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, 
+                                      const char *attr_name,
+                                      unsigned int default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -299,9 +333,9 @@ unsigned int ldb_msg_find_uint(const struct ldb_message *msg,
        return strtoul((const char *)v->data, NULL, 0);
 }
 
-int64_t ldb_msg_find_int64(const struct ldb_message *msg, 
-                          const char *attr_name,
-                          int64_t default_value)
+int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, 
+                                  const char *attr_name,
+                                  int64_t default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -310,9 +344,9 @@ int64_t ldb_msg_find_int64(const struct ldb_message *msg,
        return strtoll((const char *)v->data, NULL, 0);
 }
 
-uint64_t ldb_msg_find_uint64(const struct ldb_message *msg, 
-                            const char *attr_name,
-                            uint64_t default_value)
+uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, 
+                                    const char *attr_name,
+                                    uint64_t default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -321,9 +355,9 @@ uint64_t ldb_msg_find_uint64(const struct ldb_message *msg,
        return strtoull((const char *)v->data, NULL, 0);
 }
 
-double ldb_msg_find_double(const struct ldb_message *msg, 
-                          const char *attr_name,
-                          double default_value)
+double ldb_msg_find_attr_as_double(const struct ldb_message *msg, 
+                                  const char *attr_name,
+                                  double default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -332,9 +366,26 @@ double ldb_msg_find_double(const struct ldb_message *msg,
        return strtod((const char *)v->data, NULL);
 }
 
-const char *ldb_msg_find_string(const struct ldb_message *msg, 
-                               const char *attr_name,
-                               const char *default_value)
+int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, 
+                             const char *attr_name,
+                             int default_value)
+{
+       const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
+       if (!v || !v->data) {
+               return default_value;
+       }
+       if (strcasecmp((const char *)v->data, "FALSE") == 0) {
+               return 0;
+       }
+       if (strcasecmp((const char *)v->data, "TRUE") == 0) {
+               return 1;
+       }
+       return default_value;
+}
+
+const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, 
+                                       const char *attr_name,
+                                       const char *default_value)
 {
        const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
        if (!v || !v->data) {
@@ -343,6 +394,19 @@ const char *ldb_msg_find_string(const struct ldb_message *msg,
        return (const char *)v->data;
 }
 
+struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx,
+                                      const struct ldb_message *msg,
+                                      const char *attr_name)
+{
+       const struct ldb_val *v;
+
+       v = ldb_msg_find_ldb_val(msg, attr_name);
+       if (!v || !v->data) {
+               return NULL;
+       }
+       return ldb_dn_explode(mem_ctx, (const char *)v->data);
+}
+
 /*
   sort the elements of a message by name
 */
@@ -516,18 +580,20 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb,
        return mod;
 }
 
-int ldb_msg_sanity_check(const struct ldb_message *msg)
+int ldb_msg_sanity_check(struct ldb_context *ldb, 
+                        const struct ldb_message *msg)
 {
        int i, j;
 
        /* basic check on DN */
        if (msg->dn == NULL) {
                /* TODO: return also an error string */
+               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 */
-               /* TODO: return also an error string */
+               ldb_set_errstring(ldb, "DN on new ldb message is '' (not permitted)!");
                return LDB_ERR_ENTRY_ALREADY_EXISTS;
        }
 
@@ -535,8 +601,13 @@ int ldb_msg_sanity_check(const struct ldb_message *msg)
        for (i = 0; i < msg->num_elements; i++) {
                for (j = 0; j < msg->elements[i].num_values; j++) {
                        if (msg->elements[i].values[j].length == 0) {
+                               TALLOC_CTX *mem_ctx = talloc_new(ldb);
                                /* an attribute cannot be empty */
                                /* TODO: return also an error string */
+                               ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!",
+                                                           msg->elements[i].name, 
+                                                           ldb_dn_linearize(mem_ctx, msg->dn));
+                               talloc_free(mem_ctx);
                                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                        }
                }
@@ -569,6 +640,28 @@ 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)
+*/
+const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr)
+{
+       const char **ret;
+       int i;
+       for (i=0;attrs[i];i++) /* noop */ ;
+       ret = talloc_array(mem_ctx, const char *, i+2);
+       if (ret == NULL) {
+               return NULL;
+       }
+       for (i=0;attrs[i];i++) {
+               ret[i] = attrs[i];
+       }
+       ret[i] = new_attr;
+       ret[i+1] = NULL;
+       return ret;
+}
+
+
 /*
   return 1 if an attribute is in a list of attributes, or 0 otherwise
 */
@@ -623,11 +716,13 @@ int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *rep
 void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
 {
        struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
-       int n = (el - msg->elements);
-       if (n != msg->num_elements-1) {
-               memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+       if (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--;
        }
-       msg->num_elements--;
 }
 
 /*
@@ -671,3 +766,37 @@ time_t ldb_string_to_time(const char *s)
        return timegm(&tm);
 }
 
+
+/*
+  dump a set of results to a file. Useful from within gdb
+*/
+void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f)
+{
+       int i;
+
+       for (i = 0; i < result->count; i++) {
+               struct ldb_ldif ldif;
+               fprintf(f, "# record %d\n", i+1);
+               ldif.changetype = LDB_CHANGETYPE_NONE;
+               ldif.msg = result->msgs[i];
+               ldb_ldif_write_file(ldb, f, &ldif);
+       }
+}
+
+int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value)
+{
+       struct ldb_message_element *el;
+       struct ldb_val val;
+       
+       el = ldb_msg_find_element(msg, name);
+       if (el == NULL)
+               return 0;
+
+       val.data = discard_const(value);
+       val.length = strlen(value);
+
+       if (ldb_msg_find_val(el, &val))
+               return 1;
+
+       return 0;
+}