From 3afde5db59c8aeb90b1a6eebe37c2be6283ac972 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 31 Aug 2021 17:04:56 +0200 Subject: [PATCH 1/2] winbindd: call wb_parent_idmap_setup_send() in wb_queryuser_send() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14804 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit 39c2ec72cb77945c3eb611fb1d7d7e9aad52bdfd) --- source3/winbindd/wb_queryuser.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c index 9db51909c02..f5bc96f03f6 100644 --- a/source3/winbindd/wb_queryuser.c +++ b/source3/winbindd/wb_queryuser.c @@ -25,10 +25,12 @@ struct wb_queryuser_state { struct tevent_context *ev; - struct wbint_userinfo *info; + struct wbint_userinfo *info; + const struct wb_parent_idmap_config *idmap_cfg; bool tried_dclookup; }; +static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq); static void wb_queryuser_got_uid(struct tevent_req *subreq); static void wb_queryuser_got_domain(struct tevent_req *subreq); static void wb_queryuser_got_dc(struct tevent_req *subreq); @@ -60,13 +62,35 @@ struct tevent_req *wb_queryuser_send(TALLOC_CTX *mem_ctx, sid_copy(&info->user_sid, user_sid); + subreq = wb_parent_idmap_setup_send(state, state->ev); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_queryuser_idmap_setup_done, req); + return req; +} + +static void wb_queryuser_idmap_setup_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_queryuser_state *state = tevent_req_data( + req, struct wb_queryuser_state); + NTSTATUS status; + + status = wb_parent_idmap_setup_recv(subreq, &state->idmap_cfg); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + subreq = wb_sids2xids_send( state, state->ev, &state->info->user_sid, 1); if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); + return; } tevent_req_set_callback(subreq, wb_queryuser_got_uid, req); - return req; + return; } static void wb_queryuser_got_uid(struct tevent_req *subreq) -- 2.31.1 From f46790b525ec91a0a1aef2c2ff2ab06c6cf5fc07 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 20 Aug 2021 15:04:49 +0200 Subject: [PATCH 2/2] winbind: ensure wb_parent_idmap_setup_send() gets called in winbindd_allocate_uid_send() 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 Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Thu Sep 2 15:20:06 UTC 2021 on sn-devel-184 (cherry picked from commit d0f6d54354b02f5591706814fbd1e4844788fdfa) --- source3/winbindd/winbindd_allocate_uid.c | 44 +++++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/winbindd_allocate_uid.c b/source3/winbindd/winbindd_allocate_uid.c index 69ce61c872e..64711f1b661 100644 --- a/source3/winbindd/winbindd_allocate_uid.c +++ b/source3/winbindd/winbindd_allocate_uid.c @@ -22,9 +22,11 @@ #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) -- 2.31.1