]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:tldap: avoid using talloc_tos()
authorStefan Metzmacher <metze@samba.org>
Tue, 11 Feb 2025 14:33:35 +0000 (15:33 +0100)
committerVolker Lendecke <vl@samba.org>
Thu, 13 Feb 2025 12:14:36 +0000 (12:14 +0000)
Async code should never use it without
creating its own stackframe!

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/lib/tldap.c
source3/lib/tldap_util.c

index db06e9f1282f58a94c995a5d60652c212b253a04..ef6937a85ef6d14886c71e835e00cfcc828e249b 100644 (file)
@@ -703,6 +703,7 @@ static int tldap_msg_msgid(struct tevent_req *req)
 
 static void tldap_msg_received(struct tevent_req *subreq)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        struct tldap_context *ld = tevent_req_callback_data(
                subreq, struct tldap_context);
        struct tevent_req *req;
@@ -718,7 +719,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
        uint8_t type;
        bool ok;
 
-       received = read_ldap_recv(subreq, talloc_tos(), &inbuf, &err);
+       received = read_ldap_recv(subreq, frame, &inbuf, &err);
        TALLOC_FREE(subreq);
        ld->read_req = NULL;
        if (received == -1) {
@@ -726,7 +727,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
                goto fail;
        }
 
-       data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
+       data = asn1_init(frame, ASN1_MAX_TREE_DEPTH);
        if (data == NULL) {
                /*
                 * We have to disconnect all, we can't tell which of
@@ -757,8 +758,8 @@ static void tldap_msg_received(struct tevent_req *subreq)
                        "tldap_msg_received: got msgid 0 of "
                        "type %"PRIu8", disconnecting\n",
                        type);
-               tldap_context_disconnect(ld, TLDAP_SERVER_DOWN);
-               return;
+               status = TLDAP_SERVER_DOWN;
+               goto fail;
        }
 
        num_pending = talloc_array_length(ld->pending);
@@ -791,6 +792,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
 
  done:
        if (num_pending == 0) {
+               TALLOC_FREE(frame);
                return;
        }
 
@@ -801,10 +803,12 @@ static void tldap_msg_received(struct tevent_req *subreq)
                goto fail;
        }
        tevent_req_set_callback(ld->read_req, tldap_msg_received, ld);
+       TALLOC_FREE(frame);
        return;
 
  fail:
        tldap_context_disconnect(ld, status);
+       TALLOC_FREE(frame);
 }
 
 static TLDAPRC tldap_msg_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
@@ -1415,13 +1419,16 @@ static bool tldap_unescape_inplace(char *value, size_t *val_len)
 
 static bool tldap_push_filter_basic(struct tldap_context *ld,
                                    struct asn1_data *data,
+                                   TALLOC_CTX *tmpctx,
                                    const char **_s);
 static bool tldap_push_filter_substring(struct tldap_context *ld,
                                        struct asn1_data *data,
+                                       TALLOC_CTX *tmpctx,
                                        const char *val,
                                        const char **_s);
 static bool tldap_push_filter_int(struct tldap_context *ld,
                                  struct asn1_data *data,
+                                 TALLOC_CTX *tmpctx,
                                  const char **_s)
 {
        const char *s = *_s;
@@ -1453,7 +1460,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
                tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: NOT\n");
                if (!asn1_push_tag(data, TLDAP_FILTER_NOT)) return false;
                s++;
-               ret = tldap_push_filter_int(ld, data, &s);
+               ret = tldap_push_filter_int(ld, data, tmpctx, &s);
                if (!ret) {
                        return false;
                }
@@ -1472,7 +1479,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
                return false;
 
        default:
-               ret = tldap_push_filter_basic(ld, data, &s);
+               ret = tldap_push_filter_basic(ld, data, tmpctx, &s);
                if (!ret) {
                        return false;
                }
@@ -1489,7 +1496,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
        }
 
        while (*s) {
-               ret = tldap_push_filter_int(ld, data, &s);
+               ret = tldap_push_filter_int(ld, data, tmpctx, &s);
                if (!ret) {
                        return false;
                }
@@ -1520,9 +1527,9 @@ done:
 
 static bool tldap_push_filter_basic(struct tldap_context *ld,
                                    struct asn1_data *data,
+                                   TALLOC_CTX *tmpctx,
                                    const char **_s)
 {
-       TALLOC_CTX *tmpctx = talloc_tos();
        const char *s = *_s;
        const char *e;
        const char *eq;
@@ -1693,7 +1700,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
                        /* substring */
                        if (!asn1_push_tag(data, TLDAP_FILTER_SUB)) return false;
                        if (!asn1_write_OctetString(data, s, e - s)) return false;
-                       ret = tldap_push_filter_substring(ld, data, val, &s);
+                       ret = tldap_push_filter_substring(ld, data, tmpctx, val, &s);
                        if (!ret) {
                                return false;
                        }
@@ -1731,10 +1738,10 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
 
 static bool tldap_push_filter_substring(struct tldap_context *ld,
                                        struct asn1_data *data,
+                                       TALLOC_CTX *tmpctx,
                                        const char *val,
                                        const char **_s)
 {
-       TALLOC_CTX *tmpctx = talloc_tos();
        bool initial = true;
        const char *star;
        char *chunk;
@@ -1830,15 +1837,18 @@ static bool tldap_push_filter(struct tldap_context *ld,
                              struct asn1_data *data,
                              const char *filter)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        const char *s = filter;
        bool ret;
 
-       ret = tldap_push_filter_int(ld, data, &s);
+       ret = tldap_push_filter_int(ld, data, frame, &s);
        if (ret && *s) {
                tldap_debug(ld, TLDAP_DEBUG_ERROR,
                            "Incomplete or malformed filter\n");
+               TALLOC_FREE(frame);
                return false;
        }
+       TALLOC_FREE(frame);
        return ret;
 }
 
index 89aea4c6a692c14883701471eb8ceb95a269358a..bc0b2e75689e05cc43008fdaadc2e3d02f95db39 100644 (file)
@@ -179,7 +179,7 @@ bool tldap_add_mod_blobs(TALLOC_CTX *mem_ctx,
        }
 
        if ((i == num_mods) && (talloc_array_length(mods) < num_mods + 1)) {
-               mods = talloc_realloc(talloc_tos(), mods, struct tldap_mod,
+               mods = talloc_realloc(mem_ctx, mods, struct tldap_mod,
                                      num_mods+1);
                if (mods == NULL) {
                        return false;
@@ -196,17 +196,19 @@ bool tldap_add_mod_str(TALLOC_CTX *mem_ctx,
                       struct tldap_mod **pmods, int *pnum_mods,
                       int mod_op, const char *attrib, const char *str)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        DATA_BLOB utf8;
        bool ret;
 
-       if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF8, str,
+       if (!convert_string_talloc(frame, CH_UNIX, CH_UTF8, str,
                                   strlen(str), &utf8.data, &utf8.length)) {
+               TALLOC_FREE(frame);
                return false;
        }
 
        ret = tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods, mod_op, attrib,
                                  &utf8, 1);
-       TALLOC_FREE(utf8.data);
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -287,24 +289,25 @@ bool tldap_make_mod_blob(struct tldap_message *existing, TALLOC_CTX *mem_ctx,
 
 static int compare_utf8_blobs(const DATA_BLOB *d1, const DATA_BLOB *d2)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        char *s1, *s2;
        size_t s1len, s2len;
        int ret;
 
-       if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX, d1->data,
+       if (!convert_string_talloc(frame, CH_UTF8, CH_UNIX, d1->data,
                                   d1->length, &s1, &s1len)) {
                /* can't do much here */
+               TALLOC_FREE(frame);
                return 0;
        }
-       if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX, d2->data,
+       if (!convert_string_talloc(frame, CH_UTF8, CH_UNIX, d2->data,
                                   d2->length, &s2, &s2len)) {
                /* can't do much here */
-               TALLOC_FREE(s1);
+               TALLOC_FREE(frame);
                return 0;
        }
        ret = strcasecmp_m(s1, s2);
-       TALLOC_FREE(s2);
-       TALLOC_FREE(s1);
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -312,16 +315,18 @@ bool tldap_make_mod_fmt(struct tldap_message *existing, TALLOC_CTX *mem_ctx,
                        struct tldap_mod **pmods, int *pnum_mods,
                        const char *attrib, const char *fmt, ...)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        va_list ap;
        char *newval;
        bool ret;
        DATA_BLOB blob = data_blob_null;
 
        va_start(ap, fmt);
-       newval = talloc_vasprintf(talloc_tos(), fmt, ap);
+       newval = talloc_vasprintf(frame, fmt, ap);
        va_end(ap);
 
        if (newval == NULL) {
+               TALLOC_FREE(frame);
                return false;
        }
 
@@ -331,7 +336,7 @@ bool tldap_make_mod_fmt(struct tldap_message *existing, TALLOC_CTX *mem_ctx,
        }
        ret = tldap_make_mod_blob_int(existing, mem_ctx, pmods, pnum_mods,
                                      attrib, blob, compare_utf8_blobs);
-       TALLOC_FREE(newval);
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -355,11 +360,13 @@ TLDAPRC tldap_search_va(struct tldap_context *ld, const char *base, int scope,
                        TALLOC_CTX *mem_ctx, struct tldap_message ***res,
                        const char *fmt, va_list ap)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        char *filter;
        TLDAPRC rc;
 
-       filter = talloc_vasprintf(talloc_tos(), fmt, ap);
+       filter = talloc_vasprintf(frame, fmt, ap);
        if (filter == NULL) {
+               TALLOC_FREE(frame);
                return TLDAP_NO_MEMORY;
        }
 
@@ -368,7 +375,7 @@ TLDAPRC tldap_search_va(struct tldap_context *ld, const char *base, int scope,
                          NULL /*sctrls*/, 0, NULL /*cctrls*/, 0,
                          0 /*timelimit*/, 0 /*sizelimit*/, 0 /*deref*/,
                          mem_ctx, res);
-       TALLOC_FREE(filter);
+       TALLOC_FREE(frame);
        return rc;
 }
 
@@ -390,13 +397,15 @@ TLDAPRC tldap_search_fmt(struct tldap_context *ld, const char *base, int scope,
 bool tldap_pull_uint64(struct tldap_message *msg, const char *attr,
                       uint64_t *presult)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        char *str;
        uint64_t result;
        int error = 0;
 
-       str = tldap_talloc_single_attribute(msg, attr, talloc_tos());
+       str = tldap_talloc_single_attribute(msg, attr, frame);
        if (str == NULL) {
                DEBUG(10, ("Could not find attribute %s\n", attr));
+               TALLOC_FREE(frame);
                return false;
        }
 
@@ -404,11 +413,11 @@ bool tldap_pull_uint64(struct tldap_message *msg, const char *attr,
        if (error != 0) {
                DBG_DEBUG("Attribute conversion failed (%s)\n",
                          strerror(error));
-               TALLOC_FREE(str);
+               TALLOC_FREE(frame);
                return false;
        }
 
-       TALLOC_FREE(str);
+       TALLOC_FREE(frame);
        *presult = result;
        return true;
 }
@@ -784,7 +793,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
 
        TALLOC_FREE(state->cookie.data);
 
-       asn1 = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
+       asn1 = asn1_init(state, ASN1_MAX_TREE_DEPTH);
        if (tevent_req_nomem(asn1, req)) {
                return;
        }