r3323: more warning reductions
[bbaumbach/samba-autobuild/.git] / source4 / lib / ldb / ldb_ldap / ldb_ldap.c
index 510f28a45ef7fadf0bad14c57acc76b94a3f2e17..9ac51b26fe31192e7a418dff25e4d5ae21d7f91d 100644 (file)
@@ -77,18 +77,55 @@ static int lldb_close(struct ldb_context *ldb)
                ret = -1;
        }
 
+       ldb_set_alloc(ldb, NULL, NULL);
+
        if (lldb->options) {
                for (i=0;lldb->options[i];i++) {
-                       free(lldb->options[i]);
+                       ldb_free(ldb, lldb->options[i]);
                }
-               free(lldb->options);
+               ldb_free(ldb, lldb->options);
        }
-       free(lldb);
+       ldb_free(ldb, lldb);
        free(ldb);
 
        return ret;
 }
 
+/*
+  rename a record
+*/
+static int lldb_rename(struct ldb_context *ldb, const char *olddn, const char *newdn)
+{
+       struct lldb_private *lldb = ldb->private_data;
+       int ret = 0;
+       char *newrdn, *p;
+       const char *parentdn = "";
+
+       /* ignore ltdb specials */
+       if (olddn[0] == '@' ||newdn[0] == '@') {
+               return 0;
+       }
+
+       newrdn = ldb_strdup(ldb, newdn);
+       if (!newrdn) {
+               return -1;
+       }
+
+       p = strchr(newrdn, ',');
+       if (p) {
+               *p++ = '\0';
+               parentdn = p;
+       }
+
+       lldb->last_rc = ldap_rename_s(lldb->ldap, olddn, newrdn, parentdn, 1, NULL, NULL);
+       ldb_free(ldb, newrdn);
+       if (lldb->last_rc != LDAP_SUCCESS) {
+               ret = -1;
+       }
+
+       return ret;
+}
+
 /*
   delete a record
 */
@@ -96,6 +133,11 @@ static int lldb_delete(struct ldb_context *ldb, const char *dn)
 {
        struct lldb_private *lldb = ldb->private_data;
        int ret = 0;
+
+       /* ignore ltdb specials */
+       if (dn[0] == '@') {
+               return 0;
+       }
        
        lldb->last_rc = ldap_delete_s(lldb->ldap, dn);
        if (lldb->last_rc != LDAP_SUCCESS) {
@@ -110,19 +152,19 @@ static int lldb_delete(struct ldb_context *ldb, const char *dn)
 */
 static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
 {
-       int i, j;
-       free(msg->dn);
+       unsigned int i, j;
+       ldb_free(ldb, msg->dn);
        for (i=0;i<msg->num_elements;i++) {
-               free(msg->elements[i].name);
+               ldb_free(ldb, msg->elements[i].name);
                for (j=0;j<msg->elements[i].num_values;j++) {
                        if (msg->elements[i].values[j].data) {
-                               free(msg->elements[i].values[j].data);
+                               ldb_free(ldb, msg->elements[i].values[j].data);
                        }
                }
-               free(msg->elements[i].values);
+               ldb_free(ldb, msg->elements[i].values);
        }
-       if (msg->elements) free(msg->elements);
-       free(msg);
+       if (msg->elements) ldb_free(ldb, msg->elements);
+       ldb_free(ldb, msg);
        return 0;
 }
 
@@ -137,7 +179,7 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
                        return -1;
                }
        }
-       free(res);
+       ldb_free(ldb, res);
        return 0;
 }
 
@@ -145,7 +187,8 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
 /*
   add a single set of ldap message values to a ldb_message
 */
-static int lldb_add_msg_attr(struct ldb_message *msg, 
+static int lldb_add_msg_attr(struct ldb_context *ldb,
+                            struct ldb_message *msg, 
                             const char *attr, struct berval **bval)
 {
        int count, i;
@@ -157,8 +200,8 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
                return -1;
        }
 
-       el = realloc_p(msg->elements, struct ldb_message_element, 
-                      msg->num_elements + 1);
+       el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, 
+                          msg->num_elements + 1);
        if (!el) {
                errno = ENOMEM;
                return -1;
@@ -168,7 +211,7 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
 
        el = &msg->elements[msg->num_elements];
 
-       el->name = strdup(attr);
+       el->name = ldb_strdup(ldb, attr);
        if (!el->name) {
                errno = ENOMEM;
                return -1;
@@ -176,14 +219,14 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
        el->flags = 0;
 
        el->num_values = 0;
-       el->values = malloc_array_p(struct ldb_val, count);
+       el->values = ldb_malloc_array_p(ldb, struct ldb_val, count);
        if (!el->values) {
                errno = ENOMEM;
                return -1;
        }
 
        for (i=0;i<count;i++) {
-               el->values[i].data = malloc(bval[i]->bv_len);
+               el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len);
                if (!el->values[i].data) {
                        return -1;
                }
@@ -202,14 +245,16 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
 */
 static int lldb_search(struct ldb_context *ldb, const char *base,
                       enum ldb_scope scope, const char *expression,
-                      const char **attrs, struct ldb_message ***res)
+                      const char * const *attrs, struct ldb_message ***res)
 {
        struct lldb_private *lldb = ldb->private_data;
        int count, msg_count;
        LDAPMessage *ldapres, *msg;
 
        lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope, 
-                                     expression, attrs, 0, &ldapres);
+                                     expression, 
+                                     discard_const_p(char *, attrs), 
+                                     0, &ldapres);
        if (lldb->last_rc != LDAP_SUCCESS) {
                return -1;
        }
@@ -220,7 +265,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
                return count;
        }
 
-       (*res) = malloc_array_p(struct ldb_message *, count+1);
+       (*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1);
        if (! *res) {
                ldap_msgfree(ldapres);
                errno = ENOMEM;
@@ -240,11 +285,11 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
 
                if (msg_count == count) {
                        /* hmm, got too many? */
-                       fprintf(stderr,"Too many messages?!\n");
+                       ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
                        break;
                }
 
-               (*res)[msg_count] = malloc_p(struct ldb_message);
+               (*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message);
                if (!(*res)[msg_count]) {
                        goto failed;
                }
@@ -255,7 +300,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
                        goto failed;
                }
 
-               (*res)[msg_count]->dn = strdup(dn);
+               (*res)[msg_count]->dn = ldb_strdup(ldb, dn);
                ldap_memfree(dn);
                if (!(*res)[msg_count]->dn) {
                        goto failed;
@@ -264,7 +309,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
 
                (*res)[msg_count]->num_elements = 0;
                (*res)[msg_count]->elements = NULL;
-               (*res)[msg_count]->private = NULL;
+               (*res)[msg_count]->private_data = NULL;
 
                /* loop over all attributes */
                for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
@@ -274,7 +319,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
                        bval = ldap_get_values_len(lldb->ldap, msg, attr);
 
                        if (bval) {
-                               lldb_add_msg_attr((*res)[msg_count], attr, bval);
+                               lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
                                ldap_value_free_len(bval);
                        }                                         
                        
@@ -298,7 +343,7 @@ failed:
 /*
   free a set of mods from lldb_msg_to_mods()
 */
-static void lldb_mods_free(LDAPMod **mods)
+static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods)
 {
        int i, j;
 
@@ -307,13 +352,13 @@ static void lldb_mods_free(LDAPMod **mods)
        for (i=0;mods[i];i++) {
                if (mods[i]->mod_vals.modv_bvals) {
                        for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) {
-                               free(mods[i]->mod_vals.modv_bvals[j]);
+                               ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]);
                        }
-                       free(mods[i]->mod_vals.modv_bvals);
+                       ldb_free(ldb, mods[i]->mod_vals.modv_bvals);
                }
-               free(mods[i]);
+               ldb_free(ldb, mods[i]);
        }
-       free(mods);
+       ldb_free(ldb, mods);
 }
 
 
@@ -321,13 +366,15 @@ static void lldb_mods_free(LDAPMod **mods)
   convert a ldb_message structure to a list of LDAPMod structures
   ready for ldap_add() or ldap_modify()
 */
-static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
+static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
+                                 const struct ldb_message *msg, int use_flags)
 {
        LDAPMod **mods;
-       int i, j, num_mods = 0;
+       unsigned int i, j;
+       int num_mods = 0;
 
        /* allocate maximum number of elements needed */
-       mods = malloc_array_p(LDAPMod *, msg->num_elements+1);
+       mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
        if (!mods) {
                errno = ENOMEM;
                return NULL;
@@ -337,7 +384,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
        for (i=0;i<msg->num_elements;i++) {
                const struct ldb_message_element *el = &msg->elements[i];
 
-               mods[num_mods] = malloc_p(LDAPMod);
+               mods[num_mods] = ldb_malloc_p(ldb, LDAPMod);
                if (!mods[num_mods]) {
                        goto failed;
                }
@@ -357,14 +404,15 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
                        }
                }
                mods[num_mods]->mod_type = el->name;
-               mods[num_mods]->mod_vals.modv_bvals = malloc_array_p(struct berval *, 
-                                                                    1+el->num_values);
+               mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb, 
+                                                                        struct berval *,
+                                                                        1+el->num_values);
                if (!mods[num_mods]->mod_vals.modv_bvals) {
                        goto failed;
                }
 
                for (j=0;j<el->num_values;j++) {
-                       mods[num_mods]->mod_vals.modv_bvals[j] = malloc_p(struct berval);
+                       mods[num_mods]->mod_vals.modv_bvals[j] = ldb_malloc_p(ldb, struct berval);
                        if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
                                goto failed;
                        }
@@ -378,7 +426,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
        return mods;
 
 failed:
-       lldb_mods_free(mods);
+       lldb_mods_free(ldb, mods);
        return NULL;
 }
 
@@ -392,14 +440,19 @@ static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg)
        LDAPMod **mods;
        int ret = 0;
 
-       mods = lldb_msg_to_mods(msg, 0);
+       /* ignore ltdb specials */
+       if (msg->dn[0] == '@') {
+               return 0;
+       }
+
+       mods = lldb_msg_to_mods(ldb, msg, 0);
 
        lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
        if (lldb->last_rc != LDAP_SUCCESS) {
                ret = -1;
        }
 
-       lldb_mods_free(mods);
+       lldb_mods_free(ldb, mods);
 
        return ret;
 }
@@ -414,14 +467,19 @@ static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
        LDAPMod **mods;
        int ret = 0;
 
-       mods = lldb_msg_to_mods(msg, 1);
+       /* ignore ltdb specials */
+       if (msg->dn[0] == '@') {
+               return 0;
+       }
+
+       mods = lldb_msg_to_mods(ldb, msg, 1);
 
        lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
        if (lldb->last_rc != LDAP_SUCCESS) {
                ret = -1;
        }
 
-       lldb_mods_free(mods);
+       lldb_mods_free(ldb, mods);
 
        return ret;
 }
@@ -444,6 +502,7 @@ static const struct ldb_backend_ops lldb_ops = {
        lldb_add,
        lldb_modify,
        lldb_delete,
+       lldb_rename,
        lldb_errstring
 };
 
@@ -457,17 +516,17 @@ struct ldb_context *lldb_connect(const char *url,
 {
        struct ldb_context *ldb = NULL;
        struct lldb_private *lldb = NULL;
-       int i;
+       int i, version = 3;
 
-       ldb = malloc_p(struct ldb_context);
+       ldb = calloc(1, sizeof(struct ldb_context));
        if (!ldb) {
                errno = ENOMEM;
                goto failed;
        }
 
-       lldb = malloc_p(struct lldb_private);
+       lldb = ldb_malloc_p(ldb, struct lldb_private);
        if (!lldb) {
-               free(ldb);
+               ldb_free(ldb, ldb);
                errno = ENOMEM;
                goto failed;
        }
@@ -480,6 +539,11 @@ struct ldb_context *lldb_connect(const char *url,
                goto failed;
        }
 
+       lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
+       if (lldb->last_rc != LDAP_SUCCESS) {
+               goto failed;
+       }
+
        ldb->ops = &lldb_ops;
        ldb->private_data = lldb;
 
@@ -488,14 +552,14 @@ struct ldb_context *lldb_connect(const char *url,
                   on the caller keeping it around (it might be dynamic) */
                for (i=0;options[i];i++) ;
 
-               lldb->options = malloc_array_p(char *, i+1);
+               lldb->options = ldb_malloc_array_p(ldb, char *, i+1);
                if (!lldb->options) {
                        goto failed;
                }
                
                for (i=0;options[i];i++) {
                        lldb->options[i+1] = NULL;
-                       lldb->options[i] = strdup(options[i]);
+                       lldb->options[i] = ldb_strdup(ldb, options[i]);
                        if (!lldb->options[i]) {
                                goto failed;
                        }
@@ -507,14 +571,14 @@ struct ldb_context *lldb_connect(const char *url,
 failed:
        if (lldb && lldb->options) {
                for (i=0;lldb->options[i];i++) {
-                       free(lldb->options[i]);
+                       ldb_free(ldb, lldb->options[i]);
                }
-               free(lldb->options);
+               ldb_free(ldb, lldb->options);
        }
        if (lldb && lldb->ldap) {
                ldap_unbind(lldb->ldap);
        }
-       if (lldb) free(lldb);
+       ldb_free(ldb, lldb);
        if (ldb) free(ldb);
        return NULL;
 }