[SCM] Samba Shared Repository - branch v4-23-test updated

Jule Anger janger at samba.org
Fri Aug 22 13:12:01 UTC 2025


The branch, v4-23-test has been updated
       via  93cb60fe642 third_party:quic_ko_wrapper Fix compilation with clang-20
       via  e69828e8de5 third_party:quic Fix compilation with clang-20
       via  d43c632b632 third_party: fix libquic build on older systems
       via  8d50eb1938a libads: change netlogon_pings() behaviour wrt to min_servers parameter
       via  0dc0860f3a6 libads: reverse termination condition in netlogon_pings_done()
       via  e412ceaa8e9 idmap_ad: add and use ldap_timeout and fix LDAP server failover
       via  e03f233e920 tldap: use tevent_req_set_endtime() to terminate LDAP searches
       via  a0b8de88f85 winbindd: use find_domain_from_name_noinit() in find_dns_domain_name()
       via  02e2933d081 libads: fix get_kdc_ip_string()
      from  224d4f69abe WHATSNEW: add Per-share profiling stats

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-23-test


- Log -----------------------------------------------------------------
commit 93cb60fe64258e739c9c517672b6725df86e7993
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Aug 15 09:38:07 2025 +1200

    third_party:quic_ko_wrapper Fix compilation with clang-20
    
    Rework the code to remove the non portable variable length array in the union.
    Based on the code in wrap_msghdr_add_cmsghdr().
    
    NOTE: this removes the 64 bit alignment, which I think should be ok.
    
    ./../third_party/quic_ko_wrapper/quic_ko_wrapper.c:3523:11: error:
       fields must have a constant size: 'variable length array in structure'
       extension will never be supported
      3523 |                 uint8_t cmbuf[cmspace];
           |                         ^
    1 error generated.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15896
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Björn Baumbach <bb at sernet.de>
    Autobuild-Date(master): Wed Aug 20 15:04:34 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 26065e1f1ee111f5ddfb64782638492af65aeb95)
    
    Autobuild-User(v4-23-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-23-test): Fri Aug 22 13:11:45 UTC 2025 on atb-devel-224

commit e69828e8de5dd68f0e3694430bd7893b0cf672fb
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Aug 15 09:33:24 2025 +1200

    third_party:quic Fix compilation with clang-20
    
    Add -Wno-error=format-nonliteral so that quic builds with clang 20
    
    ../../third_party/quic/libquic/handshake.c:106:35: error:
       format string is not a string literal [-Werror,-Wformat-nonliteral]
      106 |         rc = vsnprintf(msg, sizeof(msg), fmt, arg);
          |                                          ^~~
    ../../third_party/quic/libquic/handshake.c:135:35: error:
       format string is not a string literal [-Werror,-Wformat-nonliteral]
      135 |         rc = vsnprintf(msg, sizeof(msg), fmt, arg);
          |                                          ^~~
    ../../third_party/quic/libquic/handshake.c:164:35: error:
       format string is not a string literal [-Werror,-Wformat-nonliteral]
      164 |         rc = vsnprintf(msg, sizeof(msg), fmt, arg);
          |                                          ^~~
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15896
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit de7932ea8d12348208f50f7b050b826d236ea597)

commit d43c632b632991afc04871e8d68943e1f4ff7471
Author: Björn Baumbach <bb at sernet.de>
Date:   Fri Aug 8 17:31:34 2025 +0200

    third_party: fix libquic build on older systems
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15896
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 149933854f39b4628b14abc5dcd57e73e2a0a637)

commit 8d50eb1938a26e7d8a81e56acc64365473b0e9fc
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Jul 24 12:59:30 2025 +0200

    libads: change netlogon_pings() behaviour wrt to min_servers parameter
    
    Currently if a caller passes min_servers=X with X>1, netlogon_pings() will fail
    if it can't contact X DCs. This is not really what we want. What we want is: we
    want at least one DC, and up to X.
    
    Change implemenentation in that sense and rename the min_servers argument to
    wanted_servers to express this behaviour change.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Wed Aug 13 19:31:10 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 85dd55a5fef0049660126bdcd48abfa1c48da259)

commit 0dc0860f3a615b45371889abeeee663d23f27ed0
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Jul 24 12:55:30 2025 +0200

    libads: reverse termination condition in netlogon_pings_done()
    
    No change in behaviour, prepares for upcoming change and minimizes its diff.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 6643d1fb3375903e2857e5bff33b39a4562c5a4d)

commit e412ceaa8e9087d7afa486aae8b8426d28debc62
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Jul 24 15:49:19 2025 +0200

    idmap_ad: add and use ldap_timeout and fix LDAP server failover
    
    The key parts are:
    
    1. If an LDAP search fails with the hardcoded fatal error, remove the
    retry. That would only retry the query against the same server, taken
    from the DCINFO cache key. Instead, force a DC rediscovery.
    
    2. Set a default ldap_timeout and pass it to tldap_search(). This
    avoids tldap_search() hanging forever on a stale TCP connection.
    
    3. The LDAP server idmap_ad is using is not necessarily the same DC
    we're using for RPC, so in case we learn about a dead DC, put it in
    the negative-conn-cache.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 4d69ec473b7be763399c9787eda8e659a1582184)

commit e03f233e92054a2f86017b2bdaed58a8466092cf
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jul 21 06:44:22 2025 +0200

    tldap: use tevent_req_set_endtime() to terminate LDAP searches
    
    Needed to detect unresponsive LDAP servers, otherwise we might be sitting up to
    924.6 seconds after sending a request before the kernel notifies us of a broken
    connection.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 4e79fe13325385ef4fe37baeec8656c9b332de19)

commit a0b8de88f8581c3753594cd4367056ad84e9e90f
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Jul 22 19:16:14 2025 +0200

    winbindd: use find_domain_from_name_noinit() in find_dns_domain_name()
    
    Avoid triggering a connection to a DC of a trusted domain.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 9ad2e59a464bb472da2071c61a254547b6497625)

commit 02e2933d081748705d94008837f23e3f2f4d1b57
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Jul 22 19:22:31 2025 +0200

    libads: fix get_kdc_ip_string()
    
    Correctly handle the interaction between optionally passed in DC via
    pss and DC lookup.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 23f100f67c0586a940e91e9e1e6f42b804401322)

-----------------------------------------------------------------------

Summary of changes:
 source3/lib/tldap.c                           |  5 +++
 source3/libads/cldap.c                        |  2 +-
 source3/libads/kerberos.c                     | 18 +++++++---
 source3/libads/ldap.c                         |  2 +-
 source3/libads/netlogon_ping.c                | 32 ++++++++++-------
 source3/libads/netlogon_ping.h                |  4 +--
 source3/libsmb/dsgetdcname.c                  |  2 +-
 source3/winbindd/idmap_ad.c                   | 33 ++++++++++++-----
 source3/winbindd/wb_queryuser.c               | 10 +++++-
 source3/winbindd/wb_sids2xids.c               | 12 ++++++-
 source3/winbindd/wb_xids2sids.c               | 10 +++++-
 source3/winbindd/winbindd_cm.c                | 52 +++++++++++++++++++++++++++
 source3/winbindd/winbindd_proto.h             |  1 +
 source3/winbindd/winbindd_util.c              |  2 +-
 source4/libnet/libnet_site.c                  |  2 +-
 source4/torture/rpc/lsa.c                     |  2 +-
 third_party/quic/libquic_handshake_wrapper.c  |  2 ++
 third_party/quic/wscript                      | 11 +++++-
 third_party/quic_ko_wrapper/quic_ko_wrapper.c |  9 ++---
 19 files changed, 166 insertions(+), 45 deletions(-)
 create mode 100644 third_party/quic/libquic_handshake_wrapper.c


Changeset truncated at 500 lines:

diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index f89306d2acd..7b1d04064e2 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -1905,6 +1905,11 @@ struct tevent_req *tldap_search_send(TALLOC_CTX *mem_ctx,
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
+	if (timelimit != 0) {
+		struct timeval end;
+		end = timeval_current_ofs(timelimit * 1.5F, 0);
+		tevent_req_set_endtime(subreq, ev, end);
+	}
 	tevent_req_set_callback(subreq, tldap_search_done, req);
 	return req;
 
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
index 96d602d9feb..fdb78454141 100644
--- a/source3/libads/cldap.c
+++ b/source3/libads/cldap.c
@@ -69,7 +69,7 @@ static bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
 			.acct_ctrl = -1,
 			.required_flags = required_flags,
 		},
-		1,				    /* min_servers */
+		1,				    /* wanted_servers */
 		timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
 		&responses);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index c1f3f3ce356..d8325201b2f 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -1180,10 +1180,12 @@ static char *get_kdc_ip_string(char *mem_ctx,
 	DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
 	if (num_dcs == 0) {
 		/*
-		 * We do not have additional KDCs, but we have the one passed
-		 * in via `pss`. So just use that one and leave.
+		 * We do not have additional KDCs, but if we have one passed
+		 * in via `pss` just use that one, otherwise fail
 		 */
-		result = talloc_move(mem_ctx, &kdc_str);
+		if (pss != NULL) {
+			result = talloc_move(mem_ctx, &kdc_str);
+		}
 		goto out;
 	}
 
@@ -1223,14 +1225,20 @@ static char *get_kdc_ip_string(char *mem_ctx,
 					.acct_ctrl = -1,
 					.required_flags = DS_KDC_REQUIRED,
 				},
-				MIN(num_dcs, 3),	   /* min_servers */
+				MIN(num_dcs, 3),	   /* wanted_servers */
 				timeval_current_ofs(3, 0), /* timeout */
 				&responses);
 	TALLOC_FREE(dc_addrs2);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_DEBUG("netlogon_pings failed: %s\n", nt_errstr(status));
-		result = talloc_move(mem_ctx, &kdc_str);
+		/*
+		 * netlogon_pings() failed, but if we have one passed
+		 * in via `pss` just just use that one, otherwise fail
+		 */
+		if (pss != NULL) {
+			result = talloc_move(mem_ctx, &kdc_str);
+		}
 		goto out;
 	}
 
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index af467cfe390..49fa1d47298 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -501,7 +501,7 @@ again:
 					.required_flags = ads->config.flags |
 							  DS_ONLY_LDAP_NEEDED,
 				},
-				1,	 /* min_servers */
+				1,	 /* wanted_servers */
 				endtime, /* timeout */
 				&responses);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libads/netlogon_ping.c b/source3/libads/netlogon_ping.c
index 22f5a56b395..c65244dd876 100644
--- a/source3/libads/netlogon_ping.c
+++ b/source3/libads/netlogon_ping.c
@@ -588,7 +588,7 @@ struct netlogon_pings_state {
 
 	struct tsocket_address **servers;
 	size_t num_servers;
-	size_t min_servers;
+	size_t wanted_servers;
 	struct timeval timeout;
 	enum client_netlogon_ping_protocol proto;
 	uint32_t required_flags;
@@ -610,7 +610,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
 				       struct tsocket_address **servers,
 				       size_t num_servers,
 				       struct netlogon_ping_filter filter,
-				       size_t min_servers,
+				       size_t wanted_servers,
 				       struct timeval timeout)
 {
 	struct tevent_req *req = NULL;
@@ -626,7 +626,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
 	state->proto = proto;
 	state->servers = servers;
 	state->num_servers = num_servers;
-	state->min_servers = min_servers;
+	state->wanted_servers = wanted_servers;
 	state->timeout = timeout;
 	state->required_flags = filter.required_flags;
 
@@ -685,7 +685,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
 	}
 	state->filter = filter_str;
 
-	for (i = 0; i < min_servers; i++) {
+	for (i = 0; i < wanted_servers; i++) {
 		state->reqs[i] = netlogon_ping_send(state->reqs,
 						    state->ev,
 						    state->servers[i],
@@ -699,7 +699,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
 					netlogon_pings_done,
 					req);
 	}
-	state->num_sent = min_servers;
+	state->num_sent = wanted_servers;
 	if (state->num_sent < state->num_servers) {
 		/*
 		 * After 100 milliseconds fire the next one
@@ -818,21 +818,27 @@ static void netlogon_pings_done(struct tevent_req *subreq)
 		}
 	}
 
-	if (state->num_good_received >= state->min_servers) {
+	if (state->num_good_received >= state->wanted_servers) {
 		tevent_req_done(req);
 		return;
 	}
-	if (state->num_received == state->num_servers) {
+	if (state->num_received < state->num_servers) {
 		/*
-		 * Everybody replied, but we did not get enough good
-		 * answers (see above)
+		 * Wait for more answers
 		 */
-		tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+		return;
+	}
+	if (state->num_good_received == 1) {
+		/* We require at least one DC */
+		tevent_req_done(req);
 		return;
 	}
 	/*
-	 * Wait for more answers
+	 * Everybody replied, but we did not get a single good
+	 * answers (see above)
 	 */
+	tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+	return;
 }
 
 NTSTATUS netlogon_pings_recv(struct tevent_req *req,
@@ -856,7 +862,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
 			struct tsocket_address **servers,
 			int num_servers,
 			struct netlogon_ping_filter filter,
-			int min_servers,
+			int wanted_servers,
 			struct timeval timeout,
 			struct netlogon_samlogon_response ***responses)
 {
@@ -875,7 +881,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
 				  servers,
 				  num_servers,
 				  filter,
-				  min_servers,
+				  wanted_servers,
 				  timeout);
 	if (req == NULL) {
 		goto fail;
diff --git a/source3/libads/netlogon_ping.h b/source3/libads/netlogon_ping.h
index d50c0a47936..6063c4e8a28 100644
--- a/source3/libads/netlogon_ping.h
+++ b/source3/libads/netlogon_ping.h
@@ -45,7 +45,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
 				       struct tsocket_address **servers,
 				       size_t num_servers,
 				       struct netlogon_ping_filter filter,
-				       size_t min_servers,
+				       size_t wanted_servers,
 				       struct timeval timeout);
 NTSTATUS netlogon_pings_recv(struct tevent_req *req,
 			     TALLOC_CTX *mem_ctx,
@@ -55,7 +55,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
 			struct tsocket_address **servers,
 			int num_servers,
 			struct netlogon_ping_filter filter,
-			int min_servers,
+			int wanted_servers,
 			struct timeval timeout,
 			struct netlogon_samlogon_response ***responses);
 
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 695f0c38d85..97633317903 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -871,7 +871,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
 			.domain = domain_name,
 			.required_flags = flags,
 		},
-		1, /* min_servers */
+		1, /* wanted_servers */
 		timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
 		&responses);
 
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c
index 38e902b8292..0644b844df1 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -50,6 +50,7 @@ struct idmap_ad_context {
 
 	bool unix_primary_group;
 	bool unix_nss_info;
+	int ldap_timeout;
 
 	struct ldb_context *ldb;
 	struct ldb_dn **deny_ous;
@@ -576,6 +577,8 @@ static NTSTATUS idmap_ad_context_create(TALLOC_CTX *mem_ctx,
 		domname, "unix_primary_group", false);
 	ctx->unix_nss_info = idmap_config_bool(
 		domname, "unix_nss_info", false);
+	ctx->ldap_timeout = idmap_config_int(
+		domname, "ldap_timeout", 10);
 
 	schema_mode = idmap_config_const_string(
 		domname, "schema_mode", "rfc2307");
@@ -742,7 +745,7 @@ static NTSTATUS idmap_ad_query_user(struct idmap_domain *domain,
 
 	rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
 			  attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
-			  0, 0, 0, talloc_tos(), &msgs);
+			  ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
 	if (!TLDAP_RC_IS_SUCCESS(rc)) {
 		return NT_STATUS_LDAP(TLDAP_RC_V(rc));
 	}
@@ -815,13 +818,17 @@ static NTSTATUS idmap_ad_query_user_retry(struct idmap_domain *domain,
 {
 	const NTSTATUS status_server_down =
 		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+	const NTSTATUS status_timeout =
+		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
 	NTSTATUS status;
 
 	status = idmap_ad_query_user(domain, info);
 
-	if (NT_STATUS_EQUAL(status, status_server_down)) {
+	if (NT_STATUS_EQUAL(status, status_server_down) ||
+	    NT_STATUS_EQUAL(status, status_timeout))
+	{
 		TALLOC_FREE(domain->private_data);
-		status = idmap_ad_query_user(domain, info);
+		return NT_STATUS_HOST_UNREACHABLE;
 	}
 
 	return status;
@@ -978,7 +985,7 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom,
 
 	rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
 			  attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
-			  0, 0, 0, talloc_tos(), &msgs);
+			  ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
 	if (!TLDAP_RC_IS_SUCCESS(rc)) {
 		return NT_STATUS_LDAP(TLDAP_RC_V(rc));
 	}
@@ -1142,7 +1149,7 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom,
 
 	rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
 			  attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
-			  0, 0, 0, talloc_tos(), &msgs);
+			  ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
 	if (!TLDAP_RC_IS_SUCCESS(rc)) {
 		return NT_STATUS_LDAP(TLDAP_RC_V(rc));
 	}
@@ -1249,13 +1256,17 @@ static NTSTATUS idmap_ad_unixids_to_sids_retry(struct idmap_domain *dom,
 {
 	const NTSTATUS status_server_down =
 		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+	const NTSTATUS status_timeout =
+		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
 	NTSTATUS status;
 
 	status = idmap_ad_unixids_to_sids(dom, ids);
 
-	if (NT_STATUS_EQUAL(status, status_server_down)) {
+	if (NT_STATUS_EQUAL(status, status_server_down) ||
+	    NT_STATUS_EQUAL(status, status_timeout))
+	{
 		TALLOC_FREE(dom->private_data);
-		status = idmap_ad_unixids_to_sids(dom, ids);
+		return NT_STATUS_HOST_UNREACHABLE;
 	}
 
 	return status;
@@ -1266,13 +1277,17 @@ static NTSTATUS idmap_ad_sids_to_unixids_retry(struct idmap_domain *dom,
 {
 	const NTSTATUS status_server_down =
 		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+	const NTSTATUS status_timeout =
+		NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
 	NTSTATUS status;
 
 	status = idmap_ad_sids_to_unixids(dom, ids);
 
-	if (NT_STATUS_EQUAL(status, status_server_down)) {
+	if (NT_STATUS_EQUAL(status, status_server_down) ||
+	    NT_STATUS_EQUAL(status, status_timeout))
+	{
 		TALLOC_FREE(dom->private_data);
-		status = idmap_ad_sids_to_unixids(dom, ids);
+		return NT_STATUS_HOST_UNREACHABLE;
 	}
 
 	return status;
diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c
index db8e946ba71..0f318f8b631 100644
--- a/source3/winbindd/wb_queryuser.c
+++ b/source3/winbindd/wb_queryuser.c
@@ -279,6 +279,7 @@ static void wb_queryuser_done(struct tevent_req *subreq)
 	NTSTATUS status, result;
 	bool need_group_name = false;
 	const char *tmpl = NULL;
+	uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
 
 	status = dcerpc_wbint_GetNssInfo_recv(subreq, info, &result);
 	TALLOC_FREE(subreq);
@@ -287,6 +288,13 @@ static void wb_queryuser_done(struct tevent_req *subreq)
 		return;
 	}
 
+	if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+		winbind_idmap_add_failed_connection_entry(info->domain_name);
+		/* Trigger DC lookup and reconnect below */
+		result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+		dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+	}
+
 	if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
 	    !state->tried_dclookup) {
 		const char *domain_name = find_dns_domain_name(
@@ -301,7 +309,7 @@ static void wb_queryuser_done(struct tevent_req *subreq)
 					     domain_name,
 					     NULL,
 					     NULL,
-					     DS_RETURN_DNS_NAME);
+					     dsgetdcname_flags);
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index 03e5e7e0258..f5ff9223034 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -598,6 +598,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
 	NTSTATUS status, result;
 	const struct wbint_TransIDArray *src = NULL;
 	struct wbint_TransIDArray *dst = NULL;
+	uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
 	uint32_t si;
 
 	status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result);
@@ -608,6 +609,15 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
 		return;
 	}
 
+	if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+		struct lsa_DomainInfo *d =
+			&state->idmap_doms.domains[state->dom_index];
+		winbind_idmap_add_failed_connection_entry(d->name.string);
+		/* Trigger DC lookup and reconnect below */
+		result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+		dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+	}
+
 	if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
 	    !state->tried_dclookup) {
 
@@ -627,7 +637,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
 					     domain_name,
 					     NULL,
 					     NULL,
-					     DS_RETURN_DNS_NAME);
+					     dsgetdcname_flags);
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
index 6fcf524d94f..0384740d17d 100644
--- a/source3/winbindd/wb_xids2sids.c
+++ b/source3/winbindd/wb_xids2sids.c
@@ -130,6 +130,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
 	struct wb_xids2sids_dom_state *state = tevent_req_data(
 		req, struct wb_xids2sids_dom_state);
 	const struct wb_parent_idmap_config_dom *dom_map = state->dom_map;
+	uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
 	NTSTATUS status, result;
 	size_t i;
 	size_t dom_sid_idx;
@@ -140,6 +141,13 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
 		return;
 	}
 
+	if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+		winbind_idmap_add_failed_connection_entry(dom_map->name);
+		/* Trigger DC lookup and reconnect below */
+		result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+		dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+	}
+
 	if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
 	    !state->tried_dclookup) {
 
@@ -151,7 +159,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
 					     domain_name,
 					     NULL,
 					     NULL,
-					     DS_RETURN_DNS_NAME);
+					     dsgetdcname_flags);
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index f45bb6cda99..3963881ca45 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -90,6 +90,8 @@
 #include "lib/global_contexts.h"
 #include "librpc/gen_ndr/ndr_winbind_c.h"
 #include "libsmb/smbsock_connect.h"
+#include "source3/libsmb/namequery.h"
+#include "source3/libsmb/dsgetdcname.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -338,6 +340,56 @@ void winbind_add_failed_connection_entry(
 	winbindd_unset_locator_kdc_env(domain);
 }
 
+void winbind_idmap_add_failed_connection_entry(const char *_domain_name)
+{
+	struct netr_DsRGetDCNameInfo *dcinfo = NULL;
+	const char *dc_unc = NULL;
+	const char *dc_address = NULL;
+	char *domain_name = NULL;
+	struct winbindd_domain *domain = NULL;
+	NTSTATUS failed_status = NT_STATUS_HOST_UNREACHABLE;
+	NTSTATUS status;
+
+	domain_name = talloc_strdup_upper(talloc_tos(), _domain_name);
+	if (domain_name == NULL) {
+		DBG_ERR("talloc_strdup_upper failed\n");
+		return;
+	}
+
+	status = wb_dsgetdcname_gencache_get(talloc_tos(), domain_name, &dcinfo);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_DEBUG("Missing DC cache for domain '%s'\n", domain_name);
+		goto done;
+	}
+
+	dc_unc = dcinfo->dc_unc;
+	while (dc_unc[0] == '\\') {
+		dc_unc++;
+	}
+	dc_address = dcinfo->dc_address;
+	while (dc_address[0] == '\\') {
+		dc_address++;
+	}
+
+	add_failed_connection_entry(domain_name, dc_unc, failed_status);
+	add_failed_connection_entry(domain_name, dc_address, failed_status);
+
+	domain = find_domain_from_name_noinit(domain_name);
+	if (domain == NULL) {
+		goto done;
+	}
+	if (domain->alt_name == NULL) {
+		goto done;
+	}
+
+	add_failed_connection_entry(domain->alt_name, dc_unc, failed_status);
+	add_failed_connection_entry(domain->alt_name, dc_address, failed_status);
+
+done:
+	TALLOC_FREE(domain_name);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list