From: Stefan Metzmacher Date: Fri, 7 Feb 2025 12:57:45 +0000 (+0100) Subject: winbindd: use struct winbindd_domain_ref in struct wbint_bh_raw_call_state X-Git-Tag: tevent-0.17.0~841 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddf3a523d406efeb33e9e0ed1953d7dd16d01e7a;p=thirdparty%2Fsamba.git winbindd: use struct winbindd_domain_ref in struct wbint_bh_raw_call_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. Note this is most likely not really needed because the requests are in the domain or child tevent queue, before the domain will be free'ed. But we better use the winbindd_domain_ref in all async state! Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source3/winbindd/winbindd_dual_ndr.c b/source3/winbindd/winbindd_dual_ndr.c index 2d452385572..a1ce38c8bd1 100644 --- a/source3/winbindd/winbindd_dual_ndr.c +++ b/source3/winbindd/winbindd_dual_ndr.c @@ -71,7 +71,7 @@ static uint32_t wbint_bh_set_timeout(struct dcerpc_binding_handle *h, } struct wbint_bh_raw_call_state { - struct winbindd_domain *domain; + struct winbindd_domain_ref domain; uint32_t opnum; DATA_BLOB in_data; struct winbindd_request request; @@ -104,7 +104,7 @@ static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } - state->domain = hs->domain; + winbindd_domain_ref_set(&state->domain, hs->domain); state->opnum = opnum; state->in_data.data = discard_const_p(uint8_t, in_data); state->in_data.length = in_length; @@ -115,11 +115,11 @@ static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - if ((state->domain != NULL) - && wcache_fetch_ndr(state, state->domain, state->opnum, + if ((hs->domain != NULL) + && wcache_fetch_ndr(state, hs->domain, state->opnum, &state->in_data, &state->out_data)) { DBG_DEBUG("Got opnum %"PRIu32" for domain %s from cache\n", - state->opnum, state->domain->name); + state->opnum, hs->domain->name); tevent_req_done(req); return tevent_req_post(req, ev); } @@ -188,6 +188,8 @@ static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq) tevent_req_data(req, struct wbint_bh_raw_call_state); int ret, err; + struct winbindd_domain *domain = NULL; + bool valid; ret = wb_domain_request_recv(subreq, state, &state->response, &err); TALLOC_FREE(subreq); @@ -205,8 +207,16 @@ static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq) return; } - if (state->domain != NULL) { - wcache_store_ndr(state->domain, state->opnum, + valid = winbindd_domain_ref_get(&state->domain, &domain); + if (!valid) { + /* + * winbindd_domain_ref_get() already generated + * a debug message for the stale domain! + * + * Just don't fill the cache + */ + } else { + wcache_store_ndr(domain, state->opnum, &state->in_data, &state->out_data); }