From: Stefan Metzmacher Date: Fri, 7 Feb 2025 12:57:45 +0000 (+0100) Subject: winbindd: use struct winbindd_domain_ref in struct getpwent_state X-Git-Tag: tevent-0.17.0~839 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=886168753498cc5a16c9800f7b206d49000d3830;p=thirdparty%2Fsamba.git winbindd: use struct winbindd_domain_ref in struct getpwent_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 --- diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c index f000c64a17e..334ee9bec71 100644 --- a/source3/winbindd/wb_next_pwent.c +++ b/source3/winbindd/wb_next_pwent.c @@ -38,22 +38,37 @@ static void wb_next_pwent_send_do(struct tevent_req *req, { struct tevent_req *subreq; struct dom_sid_buf buf, buf1; + struct winbindd_domain *domain = NULL; + bool valid; + + valid = winbindd_domain_ref_get(&state->gstate->domain, + &domain); + if (!valid) { + /* + * winbindd_domain_ref_get() already generated + * a debug message for the stale domain! + */ + tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); + return; + } if (state->gstate->next_user >= state->gstate->rids.num_rids) { + TALLOC_FREE(state->gstate->rids.rids); state->gstate->rids.num_rids = 0; - state->gstate->domain = wb_next_domain(state->gstate->domain); - if (state->gstate->domain == NULL) { + domain = wb_next_domain(domain); + winbindd_domain_ref_set(&state->gstate->domain, domain); + if (domain == NULL) { tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); return; } D_DEBUG("Query user RID list for domain %s.\n", - state->gstate->domain->name); + domain->name); subreq = dcerpc_wbint_QueryUserRidList_send( state, state->ev, - dom_child_handle(state->gstate->domain), + dom_child_handle(domain), &state->gstate->rids); if (tevent_req_nomem(subreq, req)) { return; @@ -63,12 +78,12 @@ static void wb_next_pwent_send_do(struct tevent_req *req, return; } - sid_compose(&state->next_sid, &state->gstate->domain->sid, + sid_compose(&state->next_sid, &domain->sid, state->gstate->rids.rids[state->gstate->next_user]); D_DEBUG("Get pw for SID %s composed from domain SID %s and RID %"PRIu32".\n", dom_sid_str_buf(&state->next_sid, &buf), - dom_sid_str_buf(&state->gstate->domain->sid, &buf1), + dom_sid_str_buf(&domain->sid, &buf1), state->gstate->rids.rids[state->gstate->next_user]); subreq = wb_getpwsid_send(state, state->ev, &state->next_sid, state->pw); @@ -116,10 +131,24 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq) &result); TALLOC_FREE(subreq); if (any_nt_status_not_ok(status, result, &status)) { + struct winbindd_domain *domain = NULL; + bool valid; + + valid = winbindd_domain_ref_get(&state->gstate->domain, + &domain); + if (!valid) { + /* + * winbindd_domain_ref_get() already generated + * a debug message for the stale domain! + */ + tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); + return; + } + /* Ignore errors here, just log it */ D_DEBUG("query_user_list for domain %s returned %s\n", - state->gstate->domain->name, - nt_errstr(status)); + domain->name, + nt_errstr(status)); state->gstate->rids.num_rids = 0; } diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 144fd466e6e..fb6e10b02d1 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -97,7 +97,7 @@ bool _winbindd_domain_ref_get(struct winbindd_domain_ref *ref, _winbindd_domain_ref_get(__ref, __domain, __location__, __func__) struct getpwent_state { - struct winbindd_domain *domain; + struct winbindd_domain_ref domain; uint32_t next_user; struct wbint_RidArray rids; };