From: Günther Deschner Date: Wed, 2 Jul 2025 19:59:48 +0000 (+0200) Subject: s3-winbindd: Fix internal winbind dsgetdcname calls w.r.t. domain name X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2560c9b3224816ffd371a62103f65b3aca301ad5;p=thirdparty%2Fsamba.git s3-winbindd: Fix internal winbind dsgetdcname calls w.r.t. domain name when winbind calls to dsgetdcname internally, make sure to prefer the DNS domain name if we have it. Makes DNS lookups much more likely to succeed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876 Guenther Signed-off-by: Guenther Deschner Reviewed-by: Andreas Schneider Reviewed-by: Ralph Boehme Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Mon Jul 7 10:44:37 UTC 2025 on atb-devel-224 --- diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c index c2758f1b76a..db8e946ba71 100644 --- a/source3/winbindd/wb_queryuser.c +++ b/source3/winbindd/wb_queryuser.c @@ -289,10 +289,19 @@ static void wb_queryuser_done(struct tevent_req *subreq) if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) && !state->tried_dclookup) { - D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling wb_dsgetdcname_send()\n"); - subreq = wb_dsgetdcname_send( - state, state->ev, state->info->domain_name, NULL, NULL, - DS_RETURN_DNS_NAME); + const char *domain_name = find_dns_domain_name( + state->info->domain_name); + + D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling " + "wb_dsgetdcname_send(%s)\n", + domain_name); + + subreq = wb_dsgetdcname_send(state, + state->ev, + domain_name, + NULL, + NULL, + DS_RETURN_DNS_NAME); if (tevent_req_nomem(subreq, req)) { return; } diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c index f0f6c23fc20..03e5e7e0258 100644 --- a/source3/winbindd/wb_sids2xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -612,13 +612,22 @@ static void wb_sids2xids_done(struct tevent_req *subreq) !state->tried_dclookup) { struct lsa_DomainInfo *d; + const char *domain_name = NULL; - D_DEBUG("Domain controller not found. Calling wb_dsgetdcname_send() to get it.\n"); d = &state->idmap_doms.domains[state->dom_index]; - subreq = wb_dsgetdcname_send( - state, state->ev, d->name.string, NULL, NULL, - DS_RETURN_DNS_NAME); + domain_name = find_dns_domain_name(d->name.string); + + D_DEBUG("Domain controller not found. Calling " + "wb_dsgetdcname_send(%s) to get it.\n", + domain_name); + + subreq = wb_dsgetdcname_send(state, + state->ev, + domain_name, + NULL, + NULL, + DS_RETURN_DNS_NAME); if (tevent_req_nomem(subreq, req)) { return; } diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c index 86bd7f9deab..6fcf524d94f 100644 --- a/source3/winbindd/wb_xids2sids.c +++ b/source3/winbindd/wb_xids2sids.c @@ -143,9 +143,15 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq) if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) && !state->tried_dclookup) { - subreq = wb_dsgetdcname_send( - state, state->ev, state->dom_map->name, NULL, NULL, - DS_RETURN_DNS_NAME); + const char *domain_name = find_dns_domain_name( + state->dom_map->name); + + subreq = wb_dsgetdcname_send(state, + state->ev, + domain_name, + NULL, + NULL, + DS_RETURN_DNS_NAME); if (tevent_req_nomem(subreq, req)) { return; } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 57e76884416..ccea44acf18 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -548,6 +548,7 @@ static void wb_domain_request_trigger(struct tevent_req *req, struct wb_domain_request_state *state = tevent_req_data( req, struct wb_domain_request_state); struct winbindd_domain *domain = state->domain; + const char *domain_name = NULL; struct tevent_req *subreq = NULL; size_t shortest_queue_length; @@ -623,8 +624,11 @@ static void wb_domain_request_trigger(struct tevent_req *req, * which is indicated by DS_RETURN_DNS_NAME. * For NT4 domains we still get the netbios name. */ + + domain_name = find_dns_domain_name(state->domain->name); + subreq = wb_dsgetdcname_send(state, state->ev, - state->domain->name, + domain_name, NULL, /* domain_guid */ NULL, /* site_name */ DS_RETURN_DNS_NAME); /* flags */ diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 6d11a41d815..3734ab49086 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -608,6 +608,7 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, struct dom_sid **sids, uint32_t *num_sids); bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr, struct unixid **pxids, uint32_t *pnum_xids); +const char *find_dns_domain_name(const char *domain_name); /* The following definitions come from winbindd/winbindd_wins.c */ diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 05466177600..954d01928b2 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -2673,3 +2673,22 @@ fail: TALLOC_FREE(xids); return false; } + +/** + * Helper to extract the DNS Domain Name from a struct winbindd_domain + */ +const char *find_dns_domain_name(const char *domain_name) +{ + struct winbindd_domain *wbdom = NULL; + + wbdom = find_domain_from_name(domain_name); + if (wbdom == NULL) { + return domain_name; + } + + if (wbdom->active_directory && wbdom->alt_name != NULL) { + return wbdom->alt_name; + } + + return wbdom->name; +}