From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 9 May 2025 09:38:41 +0200
Subject: s3:winbindd: avoid using any netlogon call to get a dc name
Forwarded: not-needed
Origin: upstream, https://gitlab.com/samba-team/samba/-/commit/f86a4bf6848ade2db7229d182576db3320c3ece7
Bug-Debian: https://bugs.debian.org/1108904

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
---
 source3/winbindd/winbindd_cm.c       | 150 ---------------------------
 source3/winbindd/winbindd_dual_srv.c | 105 +------------------
 2 files changed, 5 insertions(+), 250 deletions(-)

diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index cc0b47b0600c..15a2f60c5321 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -477,140 +477,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
  */
@@ -1297,24 +1163,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_srv.c b/source3/winbindd/winbindd_dual_srv.c
index b1809809b13e..c48ca15dd2b2 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -661,106 +661,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)
-- 
2.50.0

