]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
winbindd: use struct winbindd_domain_ref in struct winbindd_list_users_domstate
authorStefan Metzmacher <metze@samba.org>
Fri, 7 Feb 2025 12:57:45 +0000 (13:57 +0100)
committerRalph Boehme <slow@samba.org>
Sat, 8 Feb 2025 15:26:38 +0000 (15:26 +0000)
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 <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/winbindd/winbindd_list_users.c

index 8630672c323e641f245e09ce04ee135abc94e450..298917e8df864bcd1fcb1ba9e5c60abe6fb95aed 100644 (file)
@@ -24,7 +24,7 @@
 
 struct winbindd_list_users_domstate {
        struct tevent_req *subreq;
-       struct winbindd_domain *domain;
+       struct winbindd_domain_ref domain;
        char *users;
 };
 
@@ -85,21 +85,31 @@ struct tevent_req *winbindd_list_users_send(TALLOC_CTX *mem_ctx,
        }
 
        if (request->domain_name[0] != '\0') {
-               state->domains[0].domain = find_domain_from_name_noinit(
+               domain = find_domain_from_name_noinit(
                        request->domain_name);
-               if (state->domains[0].domain == NULL) {
+               if (domain == NULL) {
                        tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
                        return tevent_req_post(req, ev);
                }
+               winbindd_domain_ref_set(&state->domains[0].domain, domain);
        } else {
                i = 0;
                for (domain = domain_list(); domain; domain = domain->next) {
-                       state->domains[i++].domain = domain;
+                       winbindd_domain_ref_set(&state->domains[i++].domain,
+                                               domain);
                }
        }
 
        for (i=0; i<state->num_domains; i++) {
                struct winbindd_list_users_domstate *d = &state->domains[i];
+               bool valid;
+
+               /*
+                * We set the ref a few lines above, it must be valid!
+                */
+               valid = winbindd_domain_ref_get(&d->domain, &domain);
+               SMB_ASSERT(valid);
+
                /*
                 * Use "state" as a talloc memory context since it has type
                 * "struct tevent_req". This is needed to make tevent call depth
@@ -107,7 +117,7 @@ struct tevent_req *winbindd_list_users_send(TALLOC_CTX *mem_ctx,
                 * After calling wb_query_user_list_send(), re-parent back to
                 * "state->domains" to make TALLOC_FREE(state->domains) working.
                 */
-               d->subreq = wb_query_user_list_send(state, ev, d->domain);
+               d->subreq = wb_query_user_list_send(state, ev, domain);
                d->subreq = talloc_reparent(state, state->domains, d->subreq);
                if (tevent_req_nomem(d->subreq, req)) {
                        TALLOC_FREE(state->domains);