From 137eb666b8350347212940dd56b41c5892b27f51 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Feb 2025 13:57:45 +0100 Subject: [PATCH] winbindd: use struct winbindd_domain_ref in struct winbindd_domain_info_state In the next commits it will be possible that struct winbindd_domain instances become stale because trusted domains were reloaded. That means aync state structure should not use pointers to 'struct winbindd_domain' as they can become stale! Instead they should use 'struct winbindd_domain_ref domain' in the async state and use winbindd_domain_ref_set/get() to manage the 'struct winbindd_domain' pointer. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_domain_info.c | 40 ++++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/source3/winbindd/winbindd_domain_info.c b/source3/winbindd/winbindd_domain_info.c index 5b3c46a9de5..78dc180124b 100644 --- a/source3/winbindd/winbindd_domain_info.c +++ b/source3/winbindd/winbindd_domain_info.c @@ -24,7 +24,7 @@ #include "librpc/gen_ndr/ndr_winbind_c.h" struct winbindd_domain_info_state { - struct winbindd_domain *domain; + struct winbindd_domain_ref domain; uint32_t in; uint32_t out; }; @@ -39,6 +39,7 @@ struct tevent_req *winbindd_domain_info_send( { struct tevent_req *req, *subreq; struct winbindd_domain_info_state *state; + struct winbindd_domain *domain = NULL; req = tevent_req_create(mem_ctx, &state, struct winbindd_domain_info_state); @@ -49,17 +50,18 @@ struct tevent_req *winbindd_domain_info_send( DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid, cli->request->domain_name)); - state->domain = find_domain_from_name_noinit( + domain = find_domain_from_name_noinit( cli->request->domain_name); - if (state->domain == NULL) { + if (domain == NULL) { DEBUG(3, ("Did not find domain [%s]\n", cli->request->domain_name)); tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); return tevent_req_post(req, ev); } + winbindd_domain_ref_set(&state->domain, domain); - if (state->domain->initialized) { + if (domain->initialized) { tevent_req_done(req); return tevent_req_post(req, ev); } @@ -72,7 +74,7 @@ struct tevent_req *winbindd_domain_info_send( state->out = 0; subreq = dcerpc_wbint_Ping_send(state, global_event_context(), - dom_child_handle(state->domain), + dom_child_handle(domain), state->in, &state->out); if (tevent_req_nomem(subreq, req)) { @@ -90,6 +92,8 @@ static void winbindd_domain_info_done(struct tevent_req *subreq) struct winbindd_domain_info_state *state = tevent_req_data( req, struct winbindd_domain_info_state); NTSTATUS status, result; + struct winbindd_domain *domain = NULL; + bool valid; status = dcerpc_wbint_Ping_recv(subreq, state, &result); TALLOC_FREE(subreq); @@ -105,9 +109,19 @@ static void winbindd_domain_info_done(struct tevent_req *subreq) return; } - if (!state->domain->initialized) { + valid = winbindd_domain_ref_get(&state->domain, &domain); + if (!valid) { + /* + * winbindd_domain_ref_get() already generated + * a debug message for the stale domain! + */ + tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); + return; + } + + if (!domain->initialized) { DBG_INFO("dcerpc_wbint_Ping did not initialize domain %s\n", - state->domain->name); + domain->name); tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -120,7 +134,8 @@ NTSTATUS winbindd_domain_info_recv(struct tevent_req *req, { struct winbindd_domain_info_state *state = tevent_req_data( req, struct winbindd_domain_info_state); - struct winbindd_domain *domain = state->domain; + struct winbindd_domain *domain = NULL; + bool valid; NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { @@ -129,6 +144,15 @@ NTSTATUS winbindd_domain_info_recv(struct tevent_req *req, return status; } + valid = winbindd_domain_ref_get(&state->domain, &domain); + if (!valid) { + /* + * winbindd_domain_ref_get() already generated + * a debug message for the stale domain! + */ + return NT_STATUS_NO_SUCH_DOMAIN; + } + fstrcpy(response->data.domain_info.name, domain->name); fstrcpy(response->data.domain_info.alt_name, domain->alt_name); sid_to_fstring(response->data.domain_info.sid, &domain->sid); -- 2.47.2