From 78d69a9eebe080aa2bcdf62be8360b581dd1e5f0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Wed, 2 Jul 2025 21:59:48 +0200 Subject: [PATCH] s3-winbindd: Fix internal winbind dsgetdcname calls w.r.t. domain name MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 2560c9b3224816ffd371a62103f65b3aca301ad5) Autobuild-User(v4-22-test): Jule Anger Autobuild-Date(v4-22-test): Mon Jul 7 15:43:22 UTC 2025 on atb-devel-224 --- source3/winbindd/wb_queryuser.c | 17 +++++++++++++---- source3/winbindd/wb_sids2xids.c | 17 +++++++++++++---- source3/winbindd/wb_xids2sids.c | 12 +++++++++--- source3/winbindd/winbindd_dual.c | 6 +++++- source3/winbindd/winbindd_proto.h | 1 + source3/winbindd/winbindd_util.c | 19 +++++++++++++++++++ 6 files changed, 60 insertions(+), 12 deletions(-) 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 614727aceb9..622d50c2b91 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -532,6 +532,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; @@ -604,8 +605,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 5d428ef2845..08e1c11f29b 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 48f4c9a67cb..ceb6a3136fb 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -2230,3 +2230,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; +} -- 2.47.2