The branch, v4-22-test has been updated
via 4a05b06b12a s3/libsmb: check the negative-conn-cache in
resolve_ads()
via a7eaa61f728 s3/libsmb: check command in
make_dc_info_from_cldap_reply()
via 02080bdbf69 libads: check for if DCs are in paused state when
processing CLDAP replies
via 10c00de2616 s3/libads: get rid of additional loop calling
add_failed_connection_entry()
via a77d376ab5a s3:libads: let get_kdc_ip_string() check for a
blacklisted server name
via 213af0ed20b s3:libads: let cldap_ping_list() check for a
blacklisted server name
via 04c938d82b7 winbindd: blacklist servers returning
ACCESS_DENIED/authoritative=0
via 48ce6782a97 winbindd: always use
winbind_add_failed_connection_entry() wrapper
via f7b28aa9cb4 s3:conncache: improve debugging for the negative
connection cache
from e119cb0b484 libads: fix get_kdc_ip_string() ...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-22-test
- Log -----------------------------------------------------------------
commit 4a05b06b12a5640655e83914b92065c627762122
Author: Ralph Boehme <[email protected]>
Date: Thu Jul 3 18:42:04 2025 +0200
s3/libsmb: check the negative-conn-cache in resolve_ads()
This way we throw away blacklisted servers right away when learning about
them
from the DNS SRV query.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
Autobuild-User(master): Günther Deschner <[email protected]>
Autobuild-Date(master): Wed Jul 30 10:10:21 UTC 2025 on atb-devel-224
(cherry picked from commit c1ee6fe9a489a8923d607e14d26768935a398849)
Autobuild-User(v4-22-test): Jule Anger <[email protected]>
Autobuild-Date(v4-22-test): Thu Aug 7 13:50:32 UTC 2025 on atb-devel-224
commit a7eaa61f728f73a4eaa458a1bd5c5129ac8eb31f
Author: Ralph Boehme <[email protected]>
Date: Wed Jul 2 18:49:51 2025 +0200
s3/libsmb: check command in make_dc_info_from_cldap_reply()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit 5217bd1a2334825fed32f40c57f72464d126aac0)
commit 02080bdbf6929c3e06092a49b7bf31e65b90d972
Author: Ralph Boehme <[email protected]>
Date: Thu Jul 3 12:50:53 2025 +0200
libads: check for if DCs are in paused state when processing CLDAP replies
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit d3000d7df09de724694aa0682b9750b8c7767514)
commit 10c00de2616b4fcb056a1c1f1300a08226a46d8c
Author: Ralph Boehme <[email protected]>
Date: Tue Jul 1 18:19:32 2025 +0200
s3/libads: get rid of additional loop calling add_failed_connection_entry()
Just call add_failed_connection_entry() in the initial loop at all places
where
we have a "bad" result.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit a397801598eef4b0381a64a37af1845e9e85a50f)
commit a77d376ab5ac36ee0786d6d01b448665c9ad156c
Author: Stefan Metzmacher <[email protected]>
Date: Tue Jul 4 18:07:51 2023 +0200
s3:libads: let get_kdc_ip_string() check for a blacklisted server name
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Stefan Metzmacher <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit 63051a2dcbe3a4a07f029e0c18aa90bd3f56b0a4)
commit 213af0ed20bdd97157c8a08e6959d76c5f9d27aa
Author: Stefan Metzmacher <[email protected]>
Date: Wed Feb 16 13:09:14 2022 +0100
s3:libads: let cldap_ping_list() check for a blacklisted server name
If we black listed a server we should not use it even if
it responses to CLDAP requests.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Pair-Programmed-With: Ralph Boehme <[email protected]>
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit 08c8760ad9706b62755e35acaa121647344a4c9e)
commit 04c938d82b7c772529816f47240310fd7f769798
Author: Stefan Metzmacher <[email protected]>
Date: Wed Feb 16 14:23:16 2022 +0100
winbindd: blacklist servers returning ACCESS_DENIED/authoritative=0
https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Stefan Metzmacher <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit ce80451f3af4418d1c83be009b58b3824c071cae)
commit 48ce6782a974ef6f983579ecf1dadebd741f71b2
Author: Stefan Metzmacher <[email protected]>
Date: Wed Feb 16 14:18:50 2022 +0100
winbindd: always use winbind_add_failed_connection_entry() wrapper
We should not use add_failed_connection_entry() directly.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Stefan Metzmacher <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit 7fed75c495ead8f476c805b91cc6624ebf933427)
commit f7b28aa9cb4ffceff9ac5ffd650a172476d233a2
Author: Stefan Metzmacher <[email protected]>
Date: Wed Feb 16 14:18:20 2022 +0100
s3:conncache: improve debugging for the negative connection cache
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14981
Signed-off-by: Stefan Metzmacher <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
(cherry picked from commit 613ac83fb7666f5b132187d5587053e0d7dcd46d)
-----------------------------------------------------------------------
Summary of changes:
source3/libads/kerberos.c | 22 +++++++++
source3/libads/ldap.c | 46 ++++++++++++++-----
source3/libads/netlogon_ping.c | 13 ++++--
source3/libsmb/conncache.c | 8 ++--
source3/libsmb/dsgetdcname.c | 6 +++
source3/libsmb/namequery.c | 25 ++++++++--
source3/winbindd/winbindd_cm.c | 2 +-
source3/winbindd/winbindd_pam.c | 96 ++++++++++++++++++++++++++++++++++++++-
source3/winbindd/winbindd_proto.h | 4 ++
9 files changed, 196 insertions(+), 26 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 145bc36cdb2..c1f3f3ce356 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -1235,10 +1235,32 @@ static char *get_kdc_ip_string(char *mem_ctx,
}
for (i=0; i<num_dcs; i++) {
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX *cldap_reply = NULL;
+ char addr[INET6_ADDRSTRLEN];
+
if (responses[i] == NULL) {
continue;
}
+ if (responses[i]->ntver != NETLOGON_NT_VERSION_5EX) {
+ continue;
+ }
+
+ print_sockaddr(addr, sizeof(addr), &dc_addrs[i]);
+
+ cldap_reply = &responses[i]->data.nt5_ex;
+
+ if (cldap_reply->pdc_dns_name != NULL) {
+ status = check_negative_conn_cache(
+ realm,
+ cldap_reply->pdc_dns_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* propagate blacklisting from name to ip */
+ add_failed_connection_entry(realm, addr,
status);
+ continue;
+ }
+ }
+
/* Append to the string - inefficient but not done often. */
talloc_asprintf_addbuf(&kdc_str,
"\t\tkdc = %s\n",
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 016402d5ca6..af467cfe390 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -518,21 +518,53 @@ again:
struct NETLOGON_SAM_LOGON_RESPONSE_EX *cldap_reply = NULL;
char server[INET6_ADDRSTRLEN];
+ print_sockaddr(server, sizeof(server), &req_sa_list[i]->u.ss);
+
if (responses[i] == NULL) {
+ add_failed_connection_entry(
+ domain,
+ server,
+ NT_STATUS_INVALID_NETWORK_RESPONSE);
continue;
}
- print_sockaddr(server, sizeof(server), &req_sa_list[i]->u.ss);
-
if (responses[i]->ntver != NETLOGON_NT_VERSION_5EX) {
DBG_NOTICE("realm=[%s] nt_version mismatch: 0x%08x for
%s\n",
ads->server.realm,
responses[i]->ntver, server);
+ add_failed_connection_entry(
+ domain,
+ server,
+ NT_STATUS_INVALID_NETWORK_RESPONSE);
continue;
}
cldap_reply = &responses[i]->data.nt5_ex;
+ if (cldap_reply->pdc_dns_name != NULL) {
+ status = check_negative_conn_cache(
+ domain,
+ cldap_reply->pdc_dns_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * only use the server if it's not black listed
+ * by name
+ */
+ DBG_NOTICE("realm=[%s] server=[%s][%s] "
+ "black listed: %s\n",
+ ads->server.realm,
+ server,
+ cldap_reply->pdc_dns_name,
+ nt_errstr(status));
+ /* propagate blacklisting from name to ip */
+ add_failed_connection_entry(domain,
+ server,
+ status);
+ retry = true;
+ continue;
+ }
+ }
+
/* Returns ok only if it matches the correct server type */
ok = ads_fill_cldap_reply(ads,
false,
@@ -571,16 +603,6 @@ again:
}
}
- /* keep track of failures as all were not suitable */
- for (i = 0; i < num_requests; i++) {
- char server[INET6_ADDRSTRLEN];
-
- print_sockaddr(server, sizeof(server), &req_sa_list[i]->u.ss);
-
- add_failed_connection_entry(domain, server,
- NT_STATUS_UNSUCCESSFUL);
- }
-
status = NT_STATUS_NO_LOGON_SERVERS;
DBG_WARNING("realm[%s] no valid response "
"num_requests[%zu] for count[%zu] - %s\n",
diff --git a/source3/libads/netlogon_ping.c b/source3/libads/netlogon_ping.c
index c94af8fbc57..22f5a56b395 100644
--- a/source3/libads/netlogon_ping.c
+++ b/source3/libads/netlogon_ping.c
@@ -787,23 +787,30 @@ static void netlogon_pings_done(struct tevent_req *subreq)
state->num_received += 1;
if (NT_STATUS_IS_OK(status)) {
+ enum netlogon_command cmd;
uint32_t ret_flags;
- bool ok;
+ bool ok = true;
switch (response->ntver) {
case NETLOGON_NT_VERSION_5EX:
ret_flags = response->data.nt5_ex.server_type;
+ cmd = response->data.nt5_ex.command;
+ ok &= !(cmd == LOGON_SAM_LOGON_PAUSE_RESPONSE ||
+ cmd == LOGON_SAM_LOGON_PAUSE_RESPONSE_EX);
break;
case NETLOGON_NT_VERSION_5:
ret_flags = response->data.nt5.server_type;
+ cmd = response->data.nt5.command;
+ ok &= !(cmd == LOGON_SAM_LOGON_PAUSE_RESPONSE ||
+ cmd == LOGON_SAM_LOGON_PAUSE_RESPONSE_EX);
break;
default:
ret_flags = 0;
break;
}
- ok = check_cldap_reply_required_flags(ret_flags,
- state->required_flags);
+ ok &= check_cldap_reply_required_flags(ret_flags,
+ state->required_flags);
if (ok) {
state->responses[i] = talloc_move(state->responses,
&response);
diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c
index 7310b508a3b..353c1e8f930 100644
--- a/source3/libsmb/conncache.c
+++ b/source3/libsmb/conncache.c
@@ -147,8 +147,9 @@ NTSTATUS check_negative_conn_cache( const char *domain,
const char *server)
if (gencache_get(key, talloc_tos(), &value, NULL))
result = negative_conn_cache_valuedecode(value);
done:
- DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
- "server %s\n", NT_STATUS_V(result), domain, server));
+ DBG_PREFIX(NT_STATUS_IS_OK(result) ? DBGLVL_DEBUG : DBGLVL_INFO,
+ ("returning result %s for domain %s "
+ "server %s\n", nt_errstr(result), domain, server));
TALLOC_FREE(key);
TALLOC_FREE(value);
return result;
@@ -187,7 +188,8 @@ void add_failed_connection_entry(const char *domain, const
char *server,
if (gencache_set(key, value,
time(NULL) + FAILED_CONNECTION_CACHE_TIMEOUT))
DEBUG(9,("add_failed_connection_entry: added domain %s (%s) "
- "to failed conn cache\n", domain, server ));
+ "to failed conn cache %s\n", domain, server,
+ nt_errstr(result)));
else
DEBUG(1,("add_failed_connection_entry: failed to add "
"domain %s (%s) to failed conn cache\n",
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 6bbe4e0b4ad..695f0c38d85 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -755,6 +755,12 @@ static NTSTATUS make_dc_info_from_cldap_reply(
char addr[INET6_ADDRSTRLEN];
+ if (r->command == LOGON_SAM_LOGON_PAUSE_RESPONSE ||
+ r->command == LOGON_SAM_LOGON_PAUSE_RESPONSE_EX)
+ {
+ return NT_STATUS_NETLOGON_NOT_STARTED;
+ }
+
if (sa != NULL) {
print_sockaddr(addr, sizeof(addr), &sa->u.ss);
dc_address = addr;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index a54ca2f74d3..0b762af64af 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -2617,6 +2617,14 @@ static NTSTATUS resolve_ads(TALLOC_CTX *ctx,
for(i = 0; i < numdcs; i++) {
/* Copy all the IP addresses from the SRV response */
size_t j;
+
+ status = check_negative_conn_cache(name, dcs[i].hostname);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("Skipping blacklisted server [%s] "
+ "for domain [%s]", dcs[i].hostname, name);
+ continue;
+ }
+
for (j = 0; j < dcs[i].num_ips; j++) {
char addr[INET6_ADDRSTRLEN];
@@ -2625,12 +2633,19 @@ static NTSTATUS resolve_ads(TALLOC_CTX *ctx,
continue;
}
+ print_sockaddr(addr,
+ sizeof(addr),
+ &srv_addrs[num_srv_addrs]);
+
DBG_DEBUG("SRV lookup %s got IP[%zu] %s\n",
- name,
- j,
- print_sockaddr(addr,
- sizeof(addr),
- &srv_addrs[num_srv_addrs]));
+ name, j, addr);
+
+ status = check_negative_conn_cache(name, addr);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("Skipping blacklisted server [%s] "
+ "for domain [%s]", addr, name);
+ continue;
+ }
num_srv_addrs++;
}
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 741761f606b..bff3a9ce4f9 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -320,7 +320,7 @@ void set_domain_online_request(struct winbindd_domain
*domain)
Add -ve connection cache entries for domain and realm.
****************************************************************/
-static void winbind_add_failed_connection_entry(
+void winbind_add_failed_connection_entry(
const struct winbindd_domain *domain,
const char *server,
NTSTATUS result)
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 450030fcbf1..406dd37c671 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1641,6 +1641,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct
winbindd_domain *domain,
{
int attempts = 0;
int netr_attempts = 0;
+ int invalid_servers = 0;
bool retry = false;
bool valid_result = false;
NTSTATUS result;
@@ -1709,10 +1710,9 @@ static NTSTATUS winbind_samlogon_retry_loop(struct
winbindd_domain *domain,
DEBUG(3, ("This is the third problem for this "
"particular call, adding DC to the "
"negative cache list: %s %s\n",
domain->name, domain->dcname));
- add_failed_connection_entry(domain->name,
+ winbind_add_failed_connection_entry(domain,
domain->dcname,
result);
- saf_delete(domain->name);
}
/* Only allow 3 retries */
@@ -1802,6 +1802,98 @@ static NTSTATUS winbind_samlogon_retry_loop(struct
winbindd_domain *domain,
&validation);
}
+ /*
+ * MS-NRPC 3.5.4.5.1 NetrLogonSamLogonEx (Opnum 39) says:
+ * ...
+ *
+ * Authoritative: ...
+ * This Boolean value indicates whether the validation
+ * information is final. This field is necessary because
+ * the request might be forwarded through multiple servers.
+ *
+ * The value TRUE indicates that the validation information
+ * is an authoritative response and MUST remain unchanged.
+ *
+ * The value FALSE indicates that the validation information
+ * is not an authoritative response and that the client can
+ * resend the request to another server.
+ *
+ * ...
+ * If the server cannot service the request due to an
+ * implementation-specific condition, the server
+ * returns STATUS_ACCESS_DENIED.
+ * ...
+ *
+ * One reason for this is that SysvolReady is still 0 in
+ *
HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters
+ * It means there are problems with sysvol replication.
+ *
+ * The response looks like this:
+ *
+ * netr_LogonSamLogonEx: struct netr_LogonSamLogonEx
+ * out: struct netr_LogonSamLogonEx
+ * validation : *
+ * validation : union
netr_Validation(case 6)
+ * sam6 : NULL
+ * authoritative : *
+ * authoritative : 0x00 (0)
+ * flags : *
+ * flags : 0x00000000 (0)
+ * 0:
NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT
+ * 0:
NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP
+ * 0:
NETLOGON_SAMLOGON_FLAG_RODC_TO_OTHER_DOMAIN
+ * 0: NETLOGON_SAMLOGON_FLAG_RODC_NTLM_REQUEST
+ * result : NT_STATUS_ACCESS_DENIED
+ *
+ * In that case we'll mark the dc as broken and retry.
+ * In order to prevent a fallback to a local user due to
+ * authoritative=0, we reset authoritative=1 and continue
+ * with NT_STATUS_NETLOGON_NOT_STARTED.
+ *
+ * In the end we may result in NT_STATUS_NO_LOGON_SERVERS
+ * if we never reach 'valid_result = true'.
+ * This matches what windows does. In a chain of transitive
+ * trusts the ACCESS_DENIED/authoritative=0 is not propagated
+ * instead of NT_STATUS_NO_LOGON_SERVERS/authoritative=1 is
+ * passed along the chain if there's no other DC is available.
+ */
+ if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
+ *authoritative == 0)
+ {
+ reset_cm_connection_on_error(
+ domain,
+ netlogon_pipe->binding_handle,
+ result);
+
+ *authoritative = true;
+ result = NT_STATUS_NETLOGON_NOT_STARTED;
+ DBG_WARNING("sam_logon[%s\\%s] returned ACCESS_DENIED "
+ "authoritative=0.\n"
+ "The DC may have set SysvolReady=0 in "
+ "HKLM\\SYSTEM\\CurrentControlSet\\Services"
+ "\\Netlogon\\Parameters\n"
+ "%s: Adding DC to the negative cache list: "
+ "%s %s\n",
+ domainname,
+ username,
+ nt_errstr(result),
+ domain->name,
+ domain->dcname);
+
+ winbind_add_failed_connection_entry(domain,
+ domain->dcname,
+ result);
+
+ /* Only allow 3 retries */
+ if (invalid_servers < 3) {
+ DBG_NOTICE("Retry another server\n");
+ invalid_servers++;
+ retry = true;
+ continue;
+ }
+ break;
+ }
+
/*
* we increment this after the "feature negotiation"
* for can_do_samlogon_ex and can_do_validation6
diff --git a/source3/winbindd/winbindd_proto.h
b/source3/winbindd/winbindd_proto.h
index 08e1c11f29b..cf18266628c 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -206,6 +206,10 @@ void winbind_msg_domain_online(struct messaging_context
*msg_ctx,
void set_domain_offline(struct winbindd_domain *domain);
void set_domain_online_request(struct winbindd_domain *domain);
+void winbind_add_failed_connection_entry(
+ const struct winbindd_domain *domain,
+ const char *server,
+ NTSTATUS result);
struct cli_credentials;
NTSTATUS winbindd_get_trust_credentials(struct winbindd_domain *domain,
--
Samba Shared Repository