tldap talloc_realloc
[metze/samba/wip.git] / source3 / lib / tldap.c
index c8f3af7982b799f4b4e3fff3ad740b9bf58eedd4..d039f9548af8f83958694fc165a61509609011f7 100644 (file)
 */
 
 #include "includes.h"
+#include "tldap.h"
+#include "../lib/util/asn1.h"
+#include "../lib/tsocket/tsocket.h"
+#include "../lib/util/tevent_unix.h"
+
+static int tldap_simple_recv(struct tevent_req *req);
 
 bool tevent_req_is_ldap_error(struct tevent_req *req, int *perr)
 {
@@ -183,7 +189,7 @@ bool tldap_context_setattr(struct tldap_context *ld,
        struct tldap_ctx_attribute *tmp, *attr;
        char *tmpname;
        int num_attrs;
-       void **pptr = (void **)_pptr;
+       void **pptr = (void **)discard_const_p(void,_pptr);
 
        attr = tldap_context_findattr(ld, name);
        if (attr != NULL) {
@@ -418,7 +424,7 @@ static struct tevent_req *tldap_msg_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       state->iov.iov_base = blob.data;
+       state->iov.iov_base = (void *)blob.data;
        state->iov.iov_len = blob.length;
 
        subreq = tstream_writev_queue_send(state, ev, ld->conn, ld->outgoing,
@@ -468,7 +474,7 @@ static void tldap_msg_unset_pending(struct tevent_req *req)
         * No NULL check here, we're shrinking by sizeof(void *), and
         * talloc_realloc just adjusts the size for this.
         */
-       ld->pending = talloc_realloc(NULL, ld->pending, struct tevent_req *,
+       ld->pending = talloc_realloc(ld, ld->pending, struct tevent_req *,
                                     num_pending - 1);
        return;
 }
@@ -505,7 +511,7 @@ static bool tldap_msg_set_pending(struct tevent_req *req)
        }
 
        /*
-        * We're the first ones, add the read_ldap request that waits for the
+        * We're the first one, add the read_ldap request that waits for the
         * answer from the server
         */
        subreq = read_ldap_send(ld->pending, state->ev, ld->conn);
@@ -535,7 +541,7 @@ static void tldap_msg_sent(struct tevent_req *subreq)
        }
 
        if (!tldap_msg_set_pending(req)) {
-               tevent_req_nomem(NULL, req);
+               tevent_req_oom(req);
                return;
        }
 }
@@ -554,7 +560,6 @@ static void tldap_msg_received(struct tevent_req *subreq)
                subreq, struct tldap_context);
        struct tevent_req *req;
        struct tldap_msg_state *state;
-       struct tevent_context *ev;
        struct asn1_data *data;
        uint8_t *inbuf;
        ssize_t received;
@@ -613,8 +618,6 @@ static void tldap_msg_received(struct tevent_req *subreq)
        state->inbuf = talloc_move(state, &inbuf);
        state->data = talloc_move(state, &data);
 
-       ev = state->ev;
-
        talloc_set_destructor(req, NULL);
        tldap_msg_unset_pending(req);
        num_pending = talloc_array_length(ld->pending);
@@ -733,6 +736,11 @@ static void tldap_save_msg(struct tldap_context *ld, struct tevent_req *req)
 static char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob)
 {
        char *result = talloc_array(mem_ctx, char, blob.length+1);
+
+       if (result == NULL) {
+               return NULL;
+       }
+
        memcpy(result, blob.data, blob.length);
        result[blob.length] = '\0';
        return result;
@@ -740,13 +748,21 @@ static char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob)
 
 static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
                                         struct asn1_data *data,
-                                        char **result)
+                                        char **presult)
 {
        DATA_BLOB string;
+       char *result;
        if (!asn1_read_OctetString(data, mem_ctx, &string))
                return false;
-       *result = blob2string_talloc(mem_ctx, string);
+
+       result = blob2string_talloc(mem_ctx, string);
+
        data_blob_free(&string);
+
+       if (result == NULL) {
+               return false;
+       }
+       *presult = result;
        return true;
 }
 
@@ -868,12 +884,7 @@ static void tldap_sasl_bind_done(struct tevent_req *subreq)
 
 int tldap_sasl_bind_recv(struct tevent_req *req)
 {
-       int err;
-
-       if (tevent_req_is_ldap_error(req, &err)) {
-               return err;
-       }
-       return TLDAP_SUCCESS;
+       return tldap_simple_recv(req);
 }
 
 int tldap_sasl_bind(struct tldap_context *ld,
@@ -924,10 +935,10 @@ struct tevent_req *tldap_simple_bind_send(TALLOC_CTX *mem_ctx,
        DATA_BLOB cred;
 
        if (passwd != NULL) {
-               cred.data = (uint8_t *)passwd;
+               cred.data = discard_const_p(uint8_t, passwd);
                cred.length = strlen(passwd);
        } else {
-               cred.data = (uint8_t *)"";
+               cred.data = discard_const_p(uint8_t, "");
                cred.length = 0;
        }
        return tldap_sasl_bind_send(mem_ctx, ev, ld, dn, NULL, &cred, NULL, 0,
@@ -945,10 +956,10 @@ int tldap_simple_bind(struct tldap_context *ld, const char *dn,
        DATA_BLOB cred;
 
        if (passwd != NULL) {
-               cred.data = (uint8_t *)passwd;
+               cred.data = discard_const_p(uint8_t, passwd);
                cred.length = strlen(passwd);
        } else {
-               cred.data = (uint8_t *)"";
+               cred.data = discard_const_p(uint8_t, "");
                cred.length = 0;
        }
        return tldap_sasl_bind(ld, dn, NULL, &cred, NULL, 0, NULL, 0);
@@ -957,10 +968,17 @@ int tldap_simple_bind(struct tldap_context *ld, const char *dn,
 /*****************************************************************************/
 
 /* can't use isalpha() as only a strict set is valid for LDAP */
-#define TLDAP_IS_ALPHA(c) ((((c) >= 'a') && ((c) <= 'z')) || \
-                          (((c) >= 'A') && ((c) <= 'Z')))
 
-#define TLDAP_IS_ADH(c) (TLDAP_IS_ALPHA(c) || isdigit(c) || (c) == '-')
+static bool tldap_is_alpha(char c)
+{
+       return (((c >= 'a') && (c <= 'z')) || \
+               ((c >= 'A') && (c <= 'Z')));
+}
+
+static bool tldap_is_adh(char c)
+{
+       return tldap_is_alpha(c) || isdigit(c) || (c == '-');
+}
 
 #define TLDAP_FILTER_AND  ASN1_CONTEXT(0)
 #define TLDAP_FILTER_OR   ASN1_CONTEXT(1)
@@ -992,7 +1010,7 @@ static bool tldap_is_attrdesc(const char *s, int len, bool no_tagopts)
        /* first char has stricter rules */
        if (isdigit(*s)) {
                is_oid = true;
-       } else if (!TLDAP_IS_ALPHA(*s)) {
+       } else if (!tldap_is_alpha(*s)) {
                /* bad first char */
                return false;
        }
@@ -1013,7 +1031,7 @@ static bool tldap_is_attrdesc(const char *s, int len, bool no_tagopts)
                                continue;
                        }
                } else {
-                       if (TLDAP_IS_ADH(s[i])) {
+                       if (tldap_is_adh(s[i])) {
                                continue;
                        }
                }
@@ -1073,7 +1091,7 @@ static int tldap_hex2char(const char *x)
 {
        if (isxdigit(x[0]) && isxdigit(x[1])) {
                const char h1 = x[0], h2 = x[1];
-               int c;
+               int c = 0;
 
                if (h1 >= 'a') c = h1 - (int)'a' + 10;
                else if (h1 >= 'A') c = h1 - (int)'A' + 10;
@@ -1297,7 +1315,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
        const char *dn;
        const char *rule;
        const char *star;
-       size_t type_len;
+       size_t type_len = 0;
        char *uval;
        size_t uval_len;
        bool write_octect = true;
@@ -1357,7 +1375,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
                                return false;
                        }
 
-                       if (StrnCaseCmp(dn, "dn:", 3) != 0) {
+                       if (strncasecmp_m(dn, "dn:", 3) != 0) {
                                if (rule == e) {
                                        rule = dn;
                                        dn = NULL;
@@ -1684,11 +1702,11 @@ static void tldap_search_done(struct tevent_req *subreq)
        switch (state->result->type) {
        case TLDAP_RES_SEARCH_ENTRY:
        case TLDAP_RES_SEARCH_REFERENCE:
-               tevent_req_notify_callback(req);
                if (!tldap_msg_set_pending(subreq)) {
-                       tevent_req_nomem(NULL, req);
+                       tevent_req_oom(req);
                        return;
                }
+               tevent_req_notify_callback(req);
                break;
        case TLDAP_RES_SEARCH_RESULT:
                TALLOC_FREE(subreq);
@@ -1940,8 +1958,9 @@ bool tldap_entry_dn(struct tldap_message *msg, char **dn)
        return true;
 }
 
-bool tldap_entry_attributes(struct tldap_message *msg, int *num_attributes,
-                           struct tldap_attribute **attributes)
+bool tldap_entry_attributes(struct tldap_message *msg,
+                           struct tldap_attribute **attributes,
+                           int *num_attributes)
 {
        if ((msg->dn == NULL) && (!tldap_parse_search_entry(msg))) {
                return false;
@@ -2113,7 +2132,7 @@ int tldap_add_recv(struct tevent_req *req)
 }
 
 int tldap_add(struct tldap_context *ld, const char *dn,
-             int num_attributes, struct tldap_mod *attributes,
+             struct tldap_mod *attributes, int num_attributes,
              struct tldap_control *sctrls, int num_sctrls,
              struct tldap_control *cctrls, int num_cctrls)
 {
@@ -2153,7 +2172,7 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
                                     struct tevent_context *ev,
                                     struct tldap_context *ld,
                                     const char *dn,
-                                    int num_mods, struct tldap_mod *mods,
+                                    struct tldap_mod *mods, int num_mods,
                                     struct tldap_control *sctrls,
                                     int num_sctrls,
                                     struct tldap_control *cctrls,
@@ -2213,7 +2232,7 @@ int tldap_modify_recv(struct tevent_req *req)
 }
 
 int tldap_modify(struct tldap_context *ld, const char *dn,
-                int num_mods, struct tldap_mod *mods,
+                struct tldap_mod *mods, int num_mods,
                 struct tldap_control *sctrls, int num_sctrls,
                 struct tldap_control *cctrls, int num_cctrls)
  {
@@ -2228,7 +2247,7 @@ int tldap_modify(struct tldap_context *ld, const char *dn,
                goto fail;
        }
 
-       req = tldap_modify_send(frame, ev, ld, dn, num_mods, mods,
+       req = tldap_modify_send(frame, ev, ld, dn, mods, num_mods,
                                sctrls, num_sctrls, cctrls, num_cctrls);
        if (req == NULL) {
                result = TLDAP_NO_MEMORY;
@@ -2363,6 +2382,7 @@ void tldap_msg_sctrls(struct tldap_message *msg, int *num_sctrls,
        if (msg == NULL) {
                *sctrls = NULL;
                *num_sctrls = 0;
+               return;
        }
        *sctrls = msg->res_sctrls;
        *num_sctrls = talloc_array_length(msg->res_sctrls);