]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25717 winbind: ensure wb_parent_idmap_setup_send() gets called in winbindd_a...
authorRalph Boehme <slow@samba.org>
Fri, 20 Aug 2021 13:04:49 +0000 (15:04 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:09 +0000 (10:52 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804
RN: winbindd can crash because idmap child state is not fully initialized

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Thu Sep  2 15:20:06 UTC 2021 on sn-devel-184

(cherry picked from commit d0f6d54354b02f5591706814fbd1e4844788fdfa)

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556

(cherry picked from commit 446f89510f2e55a551e2975a6cbf01c6a023ba0c)

source3/winbindd/winbindd_allocate_uid.c

index 69ce61c872e70def55b7d12d2768ded2aeafcba6..64711f1b66117bfa6f1b992a4ca311d0e261b210 100644 (file)
 #include "librpc/gen_ndr/ndr_winbind_c.h"
 
 struct winbindd_allocate_uid_state {
+       struct tevent_context *ev;
        uint64_t uid;
 };
 
+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq);
 static void winbindd_allocate_uid_done(struct tevent_req *subreq);
 
 struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx,
@@ -34,25 +36,57 @@ struct tevent_req *winbindd_allocate_uid_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req, *subreq;
        struct winbindd_allocate_uid_state *state;
-       struct dcerpc_binding_handle *child_binding_handle = NULL;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct winbindd_allocate_uid_state);
        if (req == NULL) {
                return NULL;
        }
+        state->ev = ev;
 
        DEBUG(3, ("allocate_uid\n"));
 
-       child_binding_handle = idmap_child_handle();
+       subreq = wb_parent_idmap_setup_send(state, ev);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_allocate_uid_initialized, req);
+       return req;
+}
+
+static void winbindd_allocate_uid_initialized(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct dcerpc_binding_handle *child_binding_handle = NULL;
+       struct winbindd_allocate_uid_state *state = tevent_req_data(
+               req, struct winbindd_allocate_uid_state);
+       const struct wb_parent_idmap_config *cfg = NULL;
+       NTSTATUS status;
+
+       status = wb_parent_idmap_setup_recv(subreq, &cfg);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       if (cfg->num_doms == 0) {
+               /*
+                * idmap_tdb also returns UNSUCCESSFUL if a range is full
+                */
+               tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
+               return;
+       }
+
+        child_binding_handle = idmap_child_handle();
 
-       subreq = dcerpc_wbint_AllocateUid_send(state, ev, child_binding_handle,
+        subreq = dcerpc_wbint_AllocateUid_send(state,
+                                              state->ev,
+                                               child_binding_handle,
                                               &state->uid);
        if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
+               return;
        }
        tevent_req_set_callback(subreq, winbindd_allocate_uid_done, req);
-       return req;
 }
 
 static void winbindd_allocate_uid_done(struct tevent_req *subreq)