The branch, v4-22-test has been updated
via 78d69a9eebe s3-winbindd: Fix internal winbind dsgetdcname calls
w.r.t. domain name
via b197ce8c6f1 s3:winbindd: avoid using any netlogon call to get a dc
name
from 7501696d552 lib:util: Disable logging to syslog for startup messages
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-22-test
- Log -----------------------------------------------------------------
commit 78d69a9eebe080aa2bcdf62be8360b581dd1e5f0
Author: Günther Deschner <[email protected]>
Date: Wed Jul 2 21:59:48 2025 +0200
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 <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Autobuild-User(master): Ralph Böhme <[email protected]>
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 <[email protected]>
Autobuild-Date(v4-22-test): Mon Jul 7 15:43:22 UTC 2025 on atb-devel-224
commit b197ce8c6f155e7d7dd3bd7a9b77172553eb78f7
Author: Stefan Metzmacher <[email protected]>
Date: Fri May 9 09:38:41 2025 +0200
s3:winbindd: avoid using any netlogon call to get a dc name
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
Signed-off-by: Stefan Metzmacher <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
(cherry picked from commit f86a4bf6848ade2db7229d182576db3320c3ece7)
-----------------------------------------------------------------------
Summary of changes:
source3/winbindd/wb_queryuser.c | 17 +++-
source3/winbindd/wb_sids2xids.c | 17 +++-
source3/winbindd/wb_xids2sids.c | 12 ++-
source3/winbindd/winbindd_cm.c | 150 -----------------------------------
source3/winbindd/winbindd_dual.c | 6 +-
source3/winbindd/winbindd_dual_srv.c | 105 ++----------------------
source3/winbindd/winbindd_proto.h | 1 +
source3/winbindd/winbindd_util.c | 19 +++++
8 files changed, 65 insertions(+), 262 deletions(-)
Changeset truncated at 500 lines:
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_cm.c b/source3/winbindd/winbindd_cm.c
index 420ea961876..741761f606b 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -475,140 +475,6 @@ static bool cm_is_ipc_credentials(struct cli_credentials
*creds)
return ret;
}
-static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
- fstring dcname,
- struct sockaddr_storage *dc_ss,
- uint32_t request_flags)
-{
- struct winbindd_domain *our_domain = NULL;
- struct rpc_pipe_client *netlogon_pipe = NULL;
- NTSTATUS result;
- WERROR werr;
- TALLOC_CTX *mem_ctx;
- unsigned int orig_timeout;
- const char *tmp = NULL;
- const char *p;
- struct dcerpc_binding_handle *b;
-
- /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
- * moment.... */
-
- if (IS_DC) {
- return False;
- }
-
- if (domain->primary) {
- return False;
- }
-
- our_domain = find_our_domain();
-
- if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
- return False;
- }
-
- result = cm_connect_netlogon(our_domain, &netlogon_pipe);
- if (!NT_STATUS_IS_OK(result)) {
- talloc_destroy(mem_ctx);
- return False;
- }
-
- b = netlogon_pipe->binding_handle;
-
- /* This call can take a long time - allow the server to time out.
- 35 seconds should do it. */
-
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
-
- if (our_domain->active_directory) {
- struct netr_DsRGetDCNameInfo *domain_info = NULL;
-
- /*
- * TODO request flags are not respected in the server
- * (and in some cases, like REQUIRE_PDC, causes an error)
- */
- result = dcerpc_netr_DsRGetDCName(b,
- mem_ctx,
- our_domain->dcname,
- domain->name,
- NULL,
- NULL,
-
request_flags|DS_RETURN_DNS_NAME,
- &domain_info,
- &werr);
- if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
- tmp = talloc_strdup(
- mem_ctx, domain_info->dc_unc);
- if (tmp == NULL) {
- DBG_ERR("talloc_strdup failed for dc_unc[%s]\n",
- domain_info->dc_unc);
- talloc_destroy(mem_ctx);
- return false;
- }
- if (domain->alt_name == NULL) {
- domain->alt_name = talloc_strdup(domain,
-
domain_info->domain_name);
- if (domain->alt_name == NULL) {
- DBG_ERR("talloc_strdup failed for "
-
"domain_info->domain_name[%s]\n",
- domain_info->domain_name);
- talloc_destroy(mem_ctx);
- return false;
- }
- }
- if (domain->forest_name == NULL) {
- domain->forest_name = talloc_strdup(domain,
-
domain_info->forest_name);
- if (domain->forest_name == NULL) {
- DBG_ERR("talloc_strdup failed for "
-
"domain_info->forest_name[%s]\n",
- domain_info->forest_name);
- talloc_destroy(mem_ctx);
- return false;
- }
- }
- }
- } else {
- result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
- our_domain->dcname,
- domain->name,
- &tmp,
- &werr);
- }
-
- /* And restore our original timeout. */
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
- nt_errstr(result)));
- talloc_destroy(mem_ctx);
- return false;
- }
-
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
- win_errstr(werr)));
- talloc_destroy(mem_ctx);
- return false;
- }
-
- /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
- p = strip_hostname(tmp);
-
- fstrcpy(dcname, p);
-
- talloc_destroy(mem_ctx);
-
- DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
-
- if (!resolve_name(dcname, dc_ss, 0x20, true)) {
- return False;
- }
-
- return True;
-}
-
/**
* Helper function to assemble trust password and account name
*/
@@ -1307,24 +1173,8 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct
winbindd_domain *domain,
struct samba_sockaddr *sa_list = NULL;
size_t salist_size = 0;
size_t i;
- bool is_our_domain;
enum security_types sec = (enum security_types)lp_security();
- is_our_domain = strequal(domain->name, lp_workgroup());
-
- /* If not our domain, get the preferred DC, by asking our primary DC */
- if ( !is_our_domain
- && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
- && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
- num_dcs) )
- {
- char addr[INET6_ADDRSTRLEN];
- print_sockaddr(addr, sizeof(addr), &ss);
- DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
- dcname, addr));
- return True;
- }
-
if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
char *sitename = NULL;
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_dual_srv.c
b/source3/winbindd/winbindd_dual_srv.c
index 2572588f6d1..e59c42dbcda 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -660,106 +660,11 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p,
NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName
*r)
{
- struct winbindd_domain *domain = wb_child_domain();
- struct rpc_pipe_client *netlogon_pipe;
- struct netr_DsRGetDCNameInfo *dc_info;
- NTSTATUS status;
- WERROR werr;
- unsigned int orig_timeout;
- struct dcerpc_binding_handle *b;
- bool retry = false;
- bool try_dsrgetdcname = false;
-
- if (domain == NULL) {
- return dsgetdcname(p->mem_ctx, global_messaging_context(),
- r->in.domain_name, r->in.domain_guid,
- r->in.site_name ? r->in.site_name : "",
- r->in.flags,
- r->out.dc_info);
- }
-
- if (domain->active_directory) {
- try_dsrgetdcname = true;
- }
-
-reconnect:
- status = cm_connect_netlogon(domain, &netlogon_pipe);
-
- reset_cm_connection_on_error(domain, NULL, status);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
- return status;
- }
-
- b = netlogon_pipe->binding_handle;
-
- /* This call can take a long time - allow the server to time out.
- 35 seconds should do it. */
-
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
-
- if (try_dsrgetdcname) {
- status = dcerpc_netr_DsRGetDCName(b,
- p->mem_ctx, domain->dcname,
- r->in.domain_name, NULL, r->in.domain_guid,
- r->in.flags, r->out.dc_info, &werr);
- if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
- goto done;
- }
- if (!retry &&
- reset_cm_connection_on_error(domain, NULL, status))
- {
- retry = true;
- goto reconnect;
- }
- try_dsrgetdcname = false;
- retry = false;
- }
-
- /*
- * Fallback to less capable methods
- */
-
- dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo);
- if (dc_info == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if (r->in.flags & DS_PDC_REQUIRED) {
- status = dcerpc_netr_GetDcName(b,
- p->mem_ctx, domain->dcname,
- r->in.domain_name, &dc_info->dc_unc, &werr);
- } else {
- status = dcerpc_netr_GetAnyDCName(b,
- p->mem_ctx, domain->dcname,
- r->in.domain_name, &dc_info->dc_unc, &werr);
- }
-
- if (!retry && reset_cm_connection_on_error(domain, b, status)) {
- retry = true;
- goto reconnect;
- }
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
- nt_errstr(status)));
- goto done;
- }
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
- win_errstr(werr)));
- status = werror_to_ntstatus(werr);
- goto done;
- }
-
- *r->out.dc_info = dc_info;
- status = NT_STATUS_OK;
-
-done:
- /* And restore our original timeout. */
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
-
- return status;
+ return dsgetdcname(p->mem_ctx, global_messaging_context(),
+ r->in.domain_name, r->in.domain_guid,
+ r->in.site_name ? r->in.site_name : "",
+ r->in.flags,
+ r->out.dc_info);
}
NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)
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;
+}
--
Samba Shared Repository