From ae19fd4998b9ad8c956fb17d9a3eaa3fc3118e84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 23 Mar 2021 15:13:55 +0100 Subject: [PATCH] winbindd: Fix a startup race with allocate_gid If you try to allocate a GID before winbind is fully set up, idmap_child_handle() is still NULL. Add the required wb_parent_idmap_setup_send()/recv() to allocate_gid(). Bug: https://bugzilla.samba.org/show_bug.cgi?id=14678 RN: Fix a crash in winbind when allocate-gid is called early Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 2e608468595d748f506a059811231c5572976157) --- source3/winbindd/winbindd_allocate_gid.c | 43 +++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/winbindd_allocate_gid.c b/source3/winbindd/winbindd_allocate_gid.c index 85aa1369473..2841d96e5f9 100644 --- a/source3/winbindd/winbindd_allocate_gid.c +++ b/source3/winbindd/winbindd_allocate_gid.c @@ -22,9 +22,11 @@ #include "librpc/gen_ndr/ndr_winbind_c.h" struct winbindd_allocate_gid_state { + struct tevent_context *ev; uint64_t gid; }; +static void winbindd_allocate_gid_initialized(struct tevent_req *subreq); static void winbindd_allocate_gid_done(struct tevent_req *subreq); struct tevent_req *winbindd_allocate_gid_send(TALLOC_CTX *mem_ctx, @@ -34,25 +36,56 @@ struct tevent_req *winbindd_allocate_gid_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct winbindd_allocate_gid_state *state; - struct dcerpc_binding_handle *child_binding_handle = NULL; req = tevent_req_create(mem_ctx, &state, struct winbindd_allocate_gid_state); if (req == NULL) { return NULL; } + state->ev = ev; DEBUG(3, ("allocate_gid\n")); + 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_gid_initialized, req); + return req; +} + +static void winbindd_allocate_gid_initialized(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct winbindd_allocate_gid_state *state = tevent_req_data( + req, struct winbindd_allocate_gid_state); + NTSTATUS status; + const struct wb_parent_idmap_config *cfg = NULL; + struct dcerpc_binding_handle *child_binding_handle = NULL; + + 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_AllocateGid_send(state, ev, child_binding_handle, - &state->gid); + subreq = dcerpc_wbint_AllocateGid_send( + state, state->ev, child_binding_handle, &state->gid); if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); + return; } tevent_req_set_callback(subreq, winbindd_allocate_gid_done, req); - return req; } static void winbindd_allocate_gid_done(struct tevent_req *subreq) -- 2.25.1