[Pkg-samba-maint] Bug#1111794: trixie-pu: package samba/2:4.22.4+dfsg-1~deb13u1
Michael Tokarev
mjt at tls.msk.ru
Fri Aug 22 05:28:36 BST 2025
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: samba at packages.debian.org
Control: affects -1 + src:samba
User: release.debian.org at packages.debian.org
Usertags: pu
[ Reason ]
There's a new upstream stable/bugfix release from the samba team,
4.22.4, with multiple bugfixes.
During previous debian stable series we kept samba updated with
upstream stable/bugfix releases, and it worked well.
[ Tests ]
As usual for samba releases, this release passes all upstream
automatic tests which are many. Additionally, this debian
release has been verified to work in our Active Directory
environment, as both member servers and domain controllers,
and works without regressions.
[ Risks ]
Samba stable releases has long-established proven high quality,
such updates are usually of low risk, - there was no single
breakage in many years.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
The changelog is below, first in the debdiff, with references to
the upstream bug reports for every change.
[ Other info ]
It might be easier to review individual git commits (with explanations)
instead of the resulting diff between the two upstream tarballs, - see
https://salsa.debian.org/samba-team/samba/-/commits/samba-4.22.4 (or
https://salsa.debian.org/samba-team/samba/-/commits/upstream/4.22.4+dfsg)
up to samba-4.22.3 tag.
Thanks,
/mjt
diff -Nru samba-4.22.3+dfsg/debian/changelog samba-4.22.4+dfsg/debian/changelog
--- samba-4.22.3+dfsg/debian/changelog 2025-07-17 13:52:35.000000000 +0300
+++ samba-4.22.4+dfsg/debian/changelog 2025-08-21 20:37:38.000000000 +0300
@@ -1,3 +1,37 @@
+samba (2:4.22.4+dfsg-1~deb13u1) trixie; urgency=medium
+
+ * new upstream stable/bugfix release:
+ - https://bugzilla.samba.org/show_bug.cgi?id=14981:
+ netr_LogonSamLogonEx returns NR_STATUS_ACCESS_DENIED with SysvolReady=0
+ - https://bugzilla.samba.org/show_bug.cgi?id=15663:
+ Apparently there is a conflict between shadow_copy2 module
+ and virusfilter (action quarantine)
+ - https://bugzilla.samba.org/show_bug.cgi?id=15816:
+ vfs_streams_depot fstatat broken
+ - https://bugzilla.samba.org/show_bug.cgi?id=15840:
+ kinit command is failing with Missing cache Error
+ - https://bugzilla.samba.org/show_bug.cgi?id=15844:
+ getpwuid does not shift to new DC when current DC is down
+ - https://bugzilla.samba.org/show_bug.cgi?id=15876:
+ Windows security hardening locks out schannel'ed
+ netlogon dc calls like netr_DsRGetDCName
+ - https://bugzilla.samba.org/show_bug.cgi?id=15877:
+ Fix handling of empty GPO link
+ - https://bugzilla.samba.org/show_bug.cgi?id=15880:
+ SMB ACL inheritance doesn't work for files created
+ - https://bugzilla.samba.org/show_bug.cgi?id=15881:
+ Unresponsive second DC can cause idmapping failure when using idmap_ad
+ (was libads-fix-get_kdc_ip_string.patch)
+ - https://bugzilla.samba.org/show_bug.cgi?id=15891:
+ Figuring out the DC name from IP address fails
+ and breaks fork_domain_child()
+ - https://bugzilla.samba.org/show_bug.cgi?id=15892:
+ Delayed leader broadcast can block ctdb forever
+ * libads-fix-get_kdc_ip_string.patch: remove, included upstream
+ * d/gbp.conf: debian-branch=debian/4.22
+
+ -- Michael Tokarev <mjt at tls.msk.ru> Thu, 21 Aug 2025 20:37:38 +0300
+
samba (2:4.22.3+dfsg-4) unstable; urgency=medium
* fix python3-talloc.symbols generation to not have -debian_revision
diff -Nru samba-4.22.3+dfsg/debian/gbp.conf samba-4.22.4+dfsg/debian/gbp.conf
--- samba-4.22.3+dfsg/debian/gbp.conf 2025-07-11 11:26:07.000000000 +0300
+++ samba-4.22.4+dfsg/debian/gbp.conf 2025-08-21 20:35:50.000000000 +0300
@@ -2,3 +2,4 @@
sign-tags = True
pristine-tar = True
upstream-branch = upstream_4.22
+debian-branch = debian/4.22
diff -Nru samba-4.22.3+dfsg/debian/patches/libads-fix-get_kdc_ip_string.patch samba-4.22.4+dfsg/debian/patches/libads-fix-get_kdc_ip_string.patch
--- samba-4.22.3+dfsg/debian/patches/libads-fix-get_kdc_ip_string.patch 2025-07-15 12:41:14.000000000 +0300
+++ samba-4.22.4+dfsg/debian/patches/libads-fix-get_kdc_ip_string.patch 1970-01-01 03:00:00.000000000 +0300
@@ -1,36 +0,0 @@
-From: Ralph Boehme <slow at samba.org>
-Date: Fri, 4 Jul 2025 17:50:40 +0200
-Subject: libads: fix get_kdc_ip_string() ...
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-Bug-Debian: https://bugs.debian.org/1109005
-Origin: upstream, https://gitlab.com/samba-team/samba/-/commit/88572cc8f629a737a1d5b33d5800f3692895233f
-Forwarded: not-needed
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=15881
-
-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): Mon Jul 7 16:46:29 UTC 2025 on atb-devel-224
----
- source3/libads/kerberos.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
-index 75803500d31..145bc36cdb2 100644
---- a/source3/libads/kerberos.c
-+++ b/source3/libads/kerberos.c
-@@ -1230,6 +1230,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
-
- if (!NT_STATUS_IS_OK(status)) {
- DBG_DEBUG("netlogon_pings failed: %s\n", nt_errstr(status));
-+ result = talloc_move(mem_ctx, &kdc_str);
- goto out;
- }
-
---
-2.47.2
-
diff -Nru samba-4.22.3+dfsg/debian/patches/series samba-4.22.4+dfsg/debian/patches/series
--- samba-4.22.3+dfsg/debian/patches/series 2025-07-15 12:41:14.000000000 +0300
+++ samba-4.22.4+dfsg/debian/patches/series 2025-08-21 20:36:18.000000000 +0300
@@ -24,4 +24,3 @@
revert-ldb-use-hexchars_upper-from-replace.h.patch
replace-xpg-strerror.patch
add-support-for-bind-9.20.patch
-libads-fix-get_kdc_ip_string.patch
diff -Nru samba-4.22.3+dfsg/VERSION samba-4.22.4+dfsg/VERSION
--- samba-4.22.3+dfsg/VERSION 2025-07-07 19:18:35.329030000 +0300
+++ samba-4.22.4+dfsg/VERSION 2025-08-21 18:22:56.183811400 +0300
@@ -27,7 +27,7 @@
########################################################
SAMBA_VERSION_MAJOR=4
SAMBA_VERSION_MINOR=22
-SAMBA_VERSION_RELEASE=3
+SAMBA_VERSION_RELEASE=4
########################################################
# If a official release has a serious bug #
diff -Nru samba-4.22.3+dfsg/WHATSNEW.txt samba-4.22.4+dfsg/WHATSNEW.txt
--- samba-4.22.3+dfsg/WHATSNEW.txt 2025-07-07 19:18:35.329030000 +0300
+++ samba-4.22.4+dfsg/WHATSNEW.txt 2025-08-21 18:22:56.187811600 +0300
@@ -1,4 +1,74 @@
==============================
+ Release Notes for Samba 4.22.4
+ August 21, 2025
+ ==============================
+
+
+This is the latest stable release of the Samba 4.22 release series.
+
+
+Changes since 4.22.3
+--------------------
+
+o Ralph Boehme <slow at samba.org>
+ * BUG 14981: netr_LogonSamLogonEx returns NR_STATUS_ACCESS_DENIED with
+ SysvolReady=0.
+ * BUG 15844: getpwuid does not shift to new DC when current DC is down.
+ * BUG 15876: Windows security hardening locks out schannel'ed netlogon dc
+ calls like netr_DsRGetDCName-
+ * BUG 15881: Unresponsive second DC can cause idmapping failure when using
+ idmap_ad-
+
+o Günther Deschner <gd at samba.org>
+ * BUG 15840: kinit command is failing with Missing cache Error.
+
+o Pavel Filipenský <pfilipensky at samba.org>
+ * BUG 15891: Figuring out the DC name from IP address fails and breaks
+ fork_domain_child().
+
+o Volker Lendecke <vl at samba.org>
+ * BUG 15816: vfs_streams_depot fstatat broken.
+ * BUG 15892: Delayed leader broadcast can block ctdb forever.
+
+o Stefan Metzmacher <metze at samba.org>
+ * BUG 14981: netr_LogonSamLogonEx returns NR_STATUS_ACCESS_DENIED with
+ SysvolReady=0.
+
+o Rabinarayan Panigrahi <rapanigr at redhat.com>
+ * BUG 15663: Apparently there is a conflict between shadow_copy2 module and
+ virusfilter (action quarantine).
+
+o Aleksandr Sharov <asharov at redhat.com>
+ * BUG 15877: Fix handling of empty GPO link.
+
+o Srinivas Rao V <Srinivas.Rao.V at ibm.com>
+ * BUG 15880: SMB ACL inheritance doesn't work for files created.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored. All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+ ==============================
Release Notes for Samba 4.22.3
July 07, 2025
==============================
@@ -57,7 +127,7 @@
calls like netr_DsRGetDCName.
o Andreas Schneider <asn at samba.org>
- * BUG 15869: Startup messages of rpc deamons fills /var/log/messages.
+ * BUG 15869: Startup messages of rpc daemons fills /var/log/messages.
#######################################
@@ -81,8 +151,7 @@
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
==============================
Release Notes for Samba 4.22.2
June 05, 2025
diff -Nru samba-4.22.3+dfsg/ctdb/server/ctdb_recoverd.c samba-4.22.4+dfsg/ctdb/server/ctdb_recoverd.c
--- samba-4.22.3+dfsg/ctdb/server/ctdb_recoverd.c 2025-02-06 13:31:53.732143900 +0300
+++ samba-4.22.4+dfsg/ctdb/server/ctdb_recoverd.c 2025-08-21 18:22:16.455915700 +0300
@@ -1902,6 +1902,7 @@
* attempt to retake it. This provides stability.
*/
if (cluster_lock_held(rec)) {
+ rec->leader = rec->pnn;
goto done;
}
diff -Nru samba-4.22.3+dfsg/docs-xml/smbdotconf/security/serverrole.xml samba-4.22.4+dfsg/docs-xml/smbdotconf/security/serverrole.xml
--- samba-4.22.3+dfsg/docs-xml/smbdotconf/security/serverrole.xml 2025-02-06 13:31:53.920145000 +0300
+++ samba-4.22.4+dfsg/docs-xml/smbdotconf/security/serverrole.xml 2025-08-21 18:22:16.455915700 +0300
@@ -78,7 +78,7 @@
url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4
HOWTO</ulink></para>
- <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA DOMAIN CONTROLLER</emphasis></para>
+ <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA PRIMARY DOMAIN CONTROLLER</emphasis></para>
<para>This mode of operation runs Samba in a hybrid mode for IPA
domain controller, providing forest trust to Active Directory.
diff -Nru samba-4.22.3+dfsg/python/samba/gp/gpclass.py samba-4.22.4+dfsg/python/samba/gp/gpclass.py
--- samba-4.22.3+dfsg/python/samba/gp/gpclass.py 2025-02-06 13:31:54.296147300 +0300
+++ samba-4.22.4+dfsg/python/samba/gp/gpclass.py 2025-08-21 18:22:16.459915600 +0300
@@ -673,8 +673,10 @@
self.gp_opts = int(gPOptions)
def gpo_parse_gplink(self, gPLink):
+ # normally formed link looks like [LDAP://host/path;options]
+ # empty link looks like [ ]
for p in gPLink.decode().split(']'):
- if not p:
+ if not p or ';' not in p:
continue
log.debug('gpo_parse_gplink: processing link')
p = p.lstrip('[')
diff -Nru samba-4.22.3+dfsg/selftest/knownfail samba-4.22.4+dfsg/selftest/knownfail
--- samba-4.22.3+dfsg/selftest/knownfail 2025-06-05 18:38:33.750581000 +0300
+++ samba-4.22.4+dfsg/selftest/knownfail 2025-08-21 18:22:16.459915600 +0300
@@ -338,4 +338,3 @@
# We currently don't send referrals for LDAP modify of non-replicated attrs
^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.*
-
diff -Nru samba-4.22.3+dfsg/source3/lib/tldap.c samba-4.22.4+dfsg/source3/lib/tldap.c
--- samba-4.22.3+dfsg/source3/lib/tldap.c 2025-02-06 13:31:54.440148000 +0300
+++ samba-4.22.4+dfsg/source3/lib/tldap.c 2025-08-21 18:22:16.459915600 +0300
@@ -1895,6 +1895,11 @@
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 -Nru samba-4.22.3+dfsg/source3/libads/cldap.c samba-4.22.4+dfsg/source3/libads/cldap.c
--- samba-4.22.3+dfsg/source3/libads/cldap.c 2025-02-06 13:31:54.444148000 +0300
+++ samba-4.22.4+dfsg/source3/libads/cldap.c 2025-08-21 18:22:16.459915600 +0300
@@ -69,7 +69,7 @@
.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 -Nru samba-4.22.3+dfsg/source3/libads/kerberos.c samba-4.22.4+dfsg/source3/libads/kerberos.c
--- samba-4.22.3+dfsg/source3/libads/kerberos.c 2025-02-06 13:31:54.444148000 +0300
+++ samba-4.22.4+dfsg/source3/libads/kerberos.c 2025-08-21 18:22:16.459915600 +0300
@@ -1180,10 +1180,12 @@
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,21 +1225,50 @@
.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));
+ /*
+ * 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;
}
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 -Nru samba-4.22.3+dfsg/source3/libads/ldap.c samba-4.22.4+dfsg/source3/libads/ldap.c
--- samba-4.22.3+dfsg/source3/libads/ldap.c 2025-02-06 13:31:54.448148300 +0300
+++ samba-4.22.4+dfsg/source3/libads/ldap.c 2025-08-21 18:22:16.463915800 +0300
@@ -501,7 +501,7 @@
.required_flags = ads->config.flags |
DS_ONLY_LDAP_NEEDED,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
endtime, /* timeout */
&responses);
if (!NT_STATUS_IS_OK(status)) {
@@ -518,21 +518,53 @@
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 @@
}
}
- /* 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 -Nru samba-4.22.3+dfsg/source3/libads/netlogon_ping.c samba-4.22.4+dfsg/source3/libads/netlogon_ping.c
--- samba-4.22.3+dfsg/source3/libads/netlogon_ping.c 2025-02-06 13:31:54.448148300 +0300
+++ samba-4.22.4+dfsg/source3/libads/netlogon_ping.c 2025-08-21 18:22:16.463915800 +0300
@@ -588,7 +588,7 @@
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 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 @@
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 @@
}
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 @@
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
@@ -787,23 +787,30 @@
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);
@@ -811,21 +818,27 @@
}
}
- 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,
@@ -849,7 +862,7 @@
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)
{
@@ -868,7 +881,7 @@
servers,
num_servers,
filter,
- min_servers,
+ wanted_servers,
timeout);
if (req == NULL) {
goto fail;
diff -Nru samba-4.22.3+dfsg/source3/libads/netlogon_ping.h samba-4.22.4+dfsg/source3/libads/netlogon_ping.h
--- samba-4.22.3+dfsg/source3/libads/netlogon_ping.h 2025-02-06 13:31:54.448148300 +0300
+++ samba-4.22.4+dfsg/source3/libads/netlogon_ping.h 2025-08-21 18:22:16.463915800 +0300
@@ -45,7 +45,7 @@
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 @@
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 -Nru samba-4.22.3+dfsg/source3/libsmb/conncache.c samba-4.22.4+dfsg/source3/libsmb/conncache.c
--- samba-4.22.3+dfsg/source3/libsmb/conncache.c 2025-02-06 13:31:54.460148300 +0300
+++ samba-4.22.4+dfsg/source3/libsmb/conncache.c 2025-08-21 18:22:16.463915800 +0300
@@ -147,8 +147,9 @@
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 @@
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 -Nru samba-4.22.3+dfsg/source3/libsmb/dsgetdcname.c samba-4.22.4+dfsg/source3/libsmb/dsgetdcname.c
--- samba-4.22.3+dfsg/source3/libsmb/dsgetdcname.c 2025-02-06 13:31:54.460148300 +0300
+++ samba-4.22.4+dfsg/source3/libsmb/dsgetdcname.c 2025-08-21 18:22:16.463915800 +0300
@@ -755,6 +755,12 @@
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;
@@ -865,7 +871,7 @@
.domain = domain_name,
.required_flags = flags,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
&responses);
diff -Nru samba-4.22.3+dfsg/source3/libsmb/namequery.c samba-4.22.4+dfsg/source3/libsmb/namequery.c
--- samba-4.22.3+dfsg/source3/libsmb/namequery.c 2025-02-06 13:31:54.464148300 +0300
+++ samba-4.22.4+dfsg/source3/libsmb/namequery.c 2025-08-21 18:22:16.463915800 +0300
@@ -2617,6 +2617,14 @@
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 @@
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 -Nru samba-4.22.3+dfsg/source3/modules/vfs_streams_depot.c samba-4.22.4+dfsg/source3/modules/vfs_streams_depot.c
--- samba-4.22.3+dfsg/source3/modules/vfs_streams_depot.c 2025-02-06 13:31:54.488148500 +0300
+++ samba-4.22.4+dfsg/source3/modules/vfs_streams_depot.c 2025-08-21 18:22:16.463915800 +0300
@@ -678,6 +678,7 @@
{
struct smb_filename *smb_fname_stream = NULL;
struct smb_filename *base_fname = NULL;
+ struct smb_filename *full_basename = NULL;
NTSTATUS status;
int ret = -1;
@@ -696,6 +697,14 @@
goto done;
}
+ full_basename = full_path_from_dirfsp_atname(base_fname,
+ dirfsp,
+ smb_fname);
+ if (full_basename == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+
ret = SMB_VFS_NEXT_FSTATAT(
handle, dirfsp, base_fname, &base_fname->st, flags);
if (ret == -1) {
@@ -703,8 +712,11 @@
}
/* lstat the actual stream now. */
- status = stream_smb_fname(
- handle, &base_fname->st, smb_fname, &smb_fname_stream, false);
+ status = stream_smb_fname(handle,
+ &base_fname->st,
+ full_basename,
+ &smb_fname_stream,
+ false);
if (!NT_STATUS_IS_OK(status)) {
ret = -1;
errno = map_errno_from_nt_status(status);
diff -Nru samba-4.22.3+dfsg/source3/modules/vfs_virusfilter.c samba-4.22.4+dfsg/source3/modules/vfs_virusfilter.c
--- samba-4.22.3+dfsg/source3/modules/vfs_virusfilter.c 2025-02-06 13:31:54.488148500 +0300
+++ samba-4.22.4+dfsg/source3/modules/vfs_virusfilter.c 2025-08-21 18:22:16.463915800 +0300
@@ -219,6 +219,11 @@
int ret = -1;
bool ok;
+ ret = SMB_VFS_NEXT_CONNECT(handle, svc, user);
+ if (ret < 0) {
+ return ret;
+ }
+
config = talloc_zero(handle, struct virusfilter_config);
if (config == NULL) {
DBG_ERR("talloc_zero failed\n");
@@ -578,7 +583,7 @@
}
}
- return SMB_VFS_NEXT_CONNECT(handle, svc, user);
+ return 0;
}
static void virusfilter_vfs_disconnect(struct vfs_handle_struct *handle)
diff -Nru samba-4.22.3+dfsg/source3/rpc_server/netlogon/srv_netlog_nt.c samba-4.22.4+dfsg/source3/rpc_server/netlogon/srv_netlog_nt.c
--- samba-4.22.3+dfsg/source3/rpc_server/netlogon/srv_netlog_nt.c 2025-02-20 15:58:50.537505000 +0300
+++ samba-4.22.4+dfsg/source3/rpc_server/netlogon/srv_netlog_nt.c 2025-08-21 18:22:16.467915800 +0300
@@ -2655,7 +2655,10 @@
return WERR_INVALID_FLAGS;
}
- if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
+ if ((r->in.flags & DS_GFTI_UPDATE_TDO) &&
+ (lp_server_role() != ROLE_DOMAIN_PDC) &&
+ (lp_server_role() != ROLE_IPA_DC))
+ {
p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NERR_NOTPRIMARY;
}
diff -Nru samba-4.22.3+dfsg/source3/script/tests/test_net_ads_kerberos.sh samba-4.22.4+dfsg/source3/script/tests/test_net_ads_kerberos.sh
--- samba-4.22.3+dfsg/source3/script/tests/test_net_ads_kerberos.sh 1970-01-01 03:00:00.000000000 +0300
+++ samba-4.22.4+dfsg/source3/script/tests/test_net_ads_kerberos.sh 2025-08-21 18:22:16.467915800 +0300
@@ -0,0 +1,158 @@
+#!/bin/sh
+
+if [ $# -lt 5 ]; then
+ cat <<EOF
+Usage: test_net_ads_kerberos.sh USERNAME REALM PASSWORD PREFIX
+EOF
+ exit 1
+fi
+
+USERNAME="$1"
+REALM="$2"
+PASSWORD="$3"
+PREFIX="$4"
+shift 4
+ADDARGS="$*"
+
+incdir=$(dirname "$0")/../../../testprogs/blackbox
+. "$incdir"/subunit.sh
+
+mkdir -p "$PREFIX"/private
+PACFILE=$PREFIX/private/pacsave.$$
+
+KRB5CCNAME_PATH="$PREFIX/net_ads_kerberos_krb5ccache"
+rm -f "$KRB5CCNAME_PATH"
+
+KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
+
+
+#################################################
+## Test "net ads kerberos kinit" variants
+#################################################
+
+testit "net_ads_kerberos_kinit" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos kinit \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ || failed=$((failed + 1))
+
+export KRB5CCNAME="$KRB5CCNAME_PATH"
+testit "net_ads_kerberos_kinit (KRB5CCNAME env set)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos kinit \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ || failed=$((failed + 1))
+unset KRB5CCNAME
+rm -f "$KRB5CCNAME_PATH"
+
+# --use-krb5-ccache is not working
+#testit "net_ads_kerberos_kinit (with --use-krb5-ccache)" \
+# $VALGRIND $BINDIR/net ads kerberos kinit \
+# -U$USERNAME%$PASSWORD $ADDARGS \
+# --use-krb5-ccache=${KRB5CCNAME} \
+# || failed=$((failed + 1))
+
+testit "net_ads_kerberos_kinit (-P)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos kinit \
+ -P "$ADDARGS" \
+ || failed=$((failed + 1))
+
+export KRB5CCNAME="$KRB5CCNAME_PATH"
+testit "net_ads_kerberos_kinit (-P and KRB5CCNAME env set)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos kinit \
+ -P "$ADDARGS" \
+ || failed=$((failed + 1))
+unset KRB5CCNAME
+rm -f "$KRB5CCNAME_PATH"
+
+# --use-krb5-ccache is not working
+#testit "net_ads_kerberos_kinit (-P with --use-krb5-ccache)" \
+# $VALGRIND $BINDIR/net ads kerberos kinit \
+# -P $ADDARGS \
+# --use-krb5-ccache=${KRB5CCNAME} \
+# || failed=$((failed + 1))
+
+
+#################################################
+## Test "net ads kerberos renew" variants
+#################################################
+
+#testit "net_ads_kerberos_renew" \
+# $VALGRIND $BINDIR/net ads kerberos renew \
+# -U$USERNAME%$PASSWORD $ADDARGS \
+# || failed=$((failed + 1))
+#
+#export KRB5CCNAME=$KRB5CCNAME_PATH
+#testit "net_ads_kerberos_renew (KRB5CCNAME env)" \
+# $VALGRIND $BINDIR/net ads kerberos renew \
+# -U$USERNAME%$PASSWORD $ADDARGS \
+# || failed=$((failed + 1))
+#unset KRB5CCNAME
+#rm -f $KRB5CCNAME_PATH
+#
+# renew only succeeds with pre-kinit
+export KRB5CCNAME="$KRB5CCNAME_PATH"
+testit "net_ads_kerberos_kinit (KRB5CCNAME env set)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos kinit \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ || failed=$((failed + 1))
+
+testit "net_ads_kerberos_renew" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos renew \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ || failed=$((failed + 1))
+unset KRB5CCNAME
+rm -f "$KRB5CCNAME_PATH"
+
+
+#################################################
+## Test "net ads kerberos pac" variants
+#################################################
+
+testit "net_ads_kerberos_pac_dump" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos pac dump \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ || failed=$((failed + 1))
+
+testit "net_ads_kerberos_pac_dump (-P)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos pac dump \
+ -P "$ADDARGS" \
+ || failed=$((failed + 1))
+
+IMPERSONATE_PRINC="alice@$REALM"
+
+#testit "net_ads_kerberos_pac_dump (impersonate)" \
+# $VALGRIND $BINDIR/net ads kerberos pac dump \
+# -U$USERNAME%$PASSWORD \
+# impersonate=$IMPERSONATE_PRINC $ADDARGS \
+# || failed=$((failed + 1))
+
+testit "net_ads_kerberos_pac_dump (impersonate and -P)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos pac dump \
+ -P \
+ impersonate="$IMPERSONATE_PRINC" "$ADDARGS" \
+ || failed=$((failed + 1))
+
+# no clue why this doesn't work...
+#
+#testit_expect_failure "net_ads_kerberos_pac_save (without filename)"
+# $VALGRIND $BINDIR/net ads kerberos pac save \
+# -U$USERNAME%$PASSWORD $ADDARGS \
+# || failed=$((failed + 1))
+
+testit "net_ads_kerberos_pac_save" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos pac save \
+ -U"$USERNAME"%"$PASSWORD" "$ADDARGS" \
+ filename="$PACFILE" \
+ || failed=$((failed + 1))
+
+rm -f "$PACFILE"
+
+testit "net_ads_kerberos_pac_save (-P)" \
+ "$VALGRIND" "$BINDIR"/net ads kerberos pac save \
+ -P "$ADDARGS" \
+ filename="$PACFILE" \
+ || failed=$((failed + 1))
+
+rm -f "$PACFILE"
+rm -f "$KRB5CCNAME_PATH"
+
+testok "$0" "$failed"
diff -Nru samba-4.22.3+dfsg/source3/selftest/tests.py samba-4.22.4+dfsg/source3/selftest/tests.py
--- samba-4.22.3+dfsg/source3/selftest/tests.py 2025-06-05 18:38:33.758581000 +0300
+++ samba-4.22.4+dfsg/source3/selftest/tests.py 2025-08-21 18:22:16.467915800 +0300
@@ -1900,6 +1900,18 @@
"bin/samba-tool",
'$DNSNAME'])
+for auth in ["$DC_USERNAME", "$DOMAIN\\\\$DC_USERNAME", "$DC_USERNAME@$REALM" ]:
+ plantestsuite(
+ "samba3.blackbox.net_ads_kerberos (%s)" % auth,
+ "ad_member:local",
+ [os.path.join(samba3srcdir,
+ "script/tests/test_net_ads_kerberos.sh"),
+ auth,
+ '$REALM',
+ '$DC_PASSWORD',
+ '$PREFIX',
+ configuration])
+
plantestsuite("samba3.blackbox.force-user-unlink",
"maptoguest:local",
[os.path.join(samba3srcdir,
diff -Nru samba-4.22.3+dfsg/source3/smbd/open.c samba-4.22.4+dfsg/source3/smbd/open.c
--- samba-4.22.3+dfsg/source3/smbd/open.c 2025-06-05 18:38:33.766581000 +0300
+++ samba-4.22.4+dfsg/source3/smbd/open.c 2025-08-21 18:22:16.471915700 +0300
@@ -4264,7 +4264,7 @@
parent_dir_fname,
info,
new_dos_attributes,
- &smb_fname->st.st_ex_mode);
+ &unx_mode);
/* Determine sparse flag. */
if (posix_open) {
diff -Nru samba-4.22.3+dfsg/source3/utils/net.c samba-4.22.4+dfsg/source3/utils/net.c
--- samba-4.22.3+dfsg/source3/utils/net.c 2025-02-06 13:31:54.596149000 +0300
+++ samba-4.22.4+dfsg/source3/utils/net.c 2025-08-21 18:22:16.471915700 +0300
@@ -1394,6 +1394,7 @@
cli_credentials_get_principal_obtained(c->creds);
enum credentials_obtained password_obtained =
cli_credentials_get_password_obtained(c->creds);
+ char *krb5ccname = NULL;
if (principal_obtained == CRED_SPECIFIED) {
c->explicit_credentials = true;
@@ -1410,6 +1411,20 @@
GENSEC_FEATURE_NTLM_CCACHE,
CRED_SPECIFIED);
}
+
+ /* cli_credentials_get_ccache_name_obtained() would not work
+ * here, we also cannot get the content of --use-krb5-ccache= so
+ * for now at least honour the KRB5CCNAME environment variable
+ * to get 'net ads kerberos' functions to work at all - gd */
+
+ krb5ccname = getenv("KRB5CCNAME");
+ if (krb5ccname == NULL) {
+ krb5ccname = talloc_strdup(c, "MEMORY:net");
+ }
+ if (krb5ccname == NULL) {
+ exit(1);
+ }
+ c->opt_krb5_ccache = krb5ccname;
}
c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
diff -Nru samba-4.22.3+dfsg/source3/utils/net.h samba-4.22.4+dfsg/source3/utils/net.h
--- samba-4.22.3+dfsg/source3/utils/net.h 2025-02-06 13:31:54.596149000 +0300
+++ samba-4.22.4+dfsg/source3/utils/net.h 2025-08-21 18:22:16.471915700 +0300
@@ -97,6 +97,7 @@
const char *opt_witness_new_ip;
int opt_witness_new_node;
const char *opt_witness_forced_response;
+ const char *opt_krb5_ccache;
int opt_have_ip;
struct sockaddr_storage opt_dest_ip;
diff -Nru samba-4.22.3+dfsg/source3/utils/net_ads.c samba-4.22.4+dfsg/source3/utils/net_ads.c
--- samba-4.22.3+dfsg/source3/utils/net_ads.c 2025-04-17 20:12:25.674450400 +0300
+++ samba-4.22.4+dfsg/source3/utils/net_ads.c 2025-08-21 18:22:16.471915700 +0300
@@ -3036,7 +3036,7 @@
return -1;
}
- ret = smb_krb5_renew_ticket(NULL, NULL, NULL, NULL);
+ ret = smb_krb5_renew_ticket(c->opt_krb5_ccache, NULL, NULL, NULL);
if (ret) {
d_printf(_("failed to renew kerberos ticket: %s\n"),
error_message(ret));
@@ -3091,7 +3091,7 @@
0,
NULL,
NULL,
- NULL,
+ c->opt_krb5_ccache,
true,
true,
2592000, /* one month */
@@ -3272,7 +3272,7 @@
0,
NULL,
NULL,
- NULL,
+ c->opt_krb5_ccache,
true,
true,
2592000, /* one month */
diff -Nru samba-4.22.3+dfsg/source3/utils/ntlm_auth.c samba-4.22.4+dfsg/source3/utils/ntlm_auth.c
--- samba-4.22.3+dfsg/source3/utils/ntlm_auth.c 2025-02-06 13:31:54.604149000 +0300
+++ samba-4.22.4+dfsg/source3/utils/ntlm_auth.c 2025-08-21 18:22:16.475915700 +0300
@@ -1355,7 +1355,11 @@
cli_credentials_set_conf(server_credentials, lp_ctx);
- if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
+ if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC ||
+ lp_server_role() == ROLE_IPA_DC ||
+ lp_security() == SEC_ADS ||
+ USE_KERBEROS_KEYTAB)
+ {
cli_credentials_set_kerberos_state(server_credentials,
CRED_USE_KERBEROS_DESIRED,
CRED_SPECIFIED);
diff -Nru samba-4.22.3+dfsg/source3/winbindd/idmap_ad.c samba-4.22.4+dfsg/source3/winbindd/idmap_ad.c
--- samba-4.22.3+dfsg/source3/winbindd/idmap_ad.c 2025-02-06 13:31:54.612149000 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/idmap_ad.c 2025-08-21 18:22:16.475915700 +0300
@@ -50,6 +50,7 @@
bool unix_primary_group;
bool unix_nss_info;
+ int ldap_timeout;
struct ldb_context *ldb;
struct ldb_dn **deny_ous;
@@ -576,6 +577,8 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
{
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 @@
{
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 -Nru samba-4.22.3+dfsg/source3/winbindd/wb_queryuser.c samba-4.22.4+dfsg/source3/winbindd/wb_queryuser.c
--- samba-4.22.3+dfsg/source3/winbindd/wb_queryuser.c 2025-07-07 19:18:35.397030600 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/wb_queryuser.c 2025-08-21 18:22:16.475915700 +0300
@@ -279,6 +279,7 @@
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 @@
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 @@
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff -Nru samba-4.22.3+dfsg/source3/winbindd/wb_sids2xids.c samba-4.22.4+dfsg/source3/winbindd/wb_sids2xids.c
--- samba-4.22.3+dfsg/source3/winbindd/wb_sids2xids.c 2025-07-07 19:18:35.397030600 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/wb_sids2xids.c 2025-08-21 18:22:16.475915700 +0300
@@ -598,6 +598,7 @@
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 @@
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 @@
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff -Nru samba-4.22.3+dfsg/source3/winbindd/wb_xids2sids.c samba-4.22.4+dfsg/source3/winbindd/wb_xids2sids.c
--- samba-4.22.3+dfsg/source3/winbindd/wb_xids2sids.c 2025-07-07 19:18:35.397030600 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/wb_xids2sids.c 2025-08-21 18:22:16.475915700 +0300
@@ -130,6 +130,7 @@
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 @@
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 @@
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff -Nru samba-4.22.3+dfsg/source3/winbindd/winbindd_cm.c samba-4.22.4+dfsg/source3/winbindd/winbindd_cm.c
--- samba-4.22.3+dfsg/source3/winbindd/winbindd_cm.c 2025-07-07 19:18:35.401030500 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/winbindd_cm.c 2025-08-21 18:22:16.475915700 +0300
@@ -88,6 +88,8 @@
#include "lib/util/string_wrappers.h"
#include "lib/global_contexts.h"
#include "librpc/gen_ndr/ndr_winbind_c.h"
+#include "source3/libsmb/namequery.h"
+#include "source3/libsmb/dsgetdcname.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -320,7 +322,7 @@
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)
@@ -336,6 +338,56 @@
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);
+ TALLOC_FREE(dcinfo);
+}
+
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
entry set > 0, or the "Additional restrictions for anonymous
@@ -1098,7 +1150,9 @@
if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
is_ad_domain = true;
- } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+ } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC ||
+ lp_server_role() == ROLE_IPA_DC)
+ {
is_ad_domain = domain->active_directory;
}
diff -Nru samba-4.22.3+dfsg/source3/winbindd/winbindd_pam.c samba-4.22.4+dfsg/source3/winbindd/winbindd_pam.c
--- samba-4.22.3+dfsg/source3/winbindd/winbindd_pam.c 2025-02-06 13:31:54.624149000 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/winbindd_pam.c 2025-08-21 18:22:16.479915600 +0300
@@ -1641,6 +1641,7 @@
{
int attempts = 0;
int netr_attempts = 0;
+ int invalid_servers = 0;
bool retry = false;
bool valid_result = false;
NTSTATUS result;
@@ -1709,10 +1710,9 @@
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 */
@@ -1803,6 +1803,98 @@
}
/*
+ * 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 -Nru samba-4.22.3+dfsg/source3/winbindd/winbindd_proto.h samba-4.22.4+dfsg/source3/winbindd/winbindd_proto.h
--- samba-4.22.3+dfsg/source3/winbindd/winbindd_proto.h 2025-07-07 19:18:35.405030700 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/winbindd_proto.h 2025-08-21 18:22:16.479915600 +0300
@@ -206,6 +206,11 @@
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);
+void winbind_idmap_add_failed_connection_entry(const char *domain_name);
struct cli_credentials;
NTSTATUS winbindd_get_trust_credentials(struct winbindd_domain *domain,
diff -Nru samba-4.22.3+dfsg/source3/winbindd/winbindd_util.c samba-4.22.4+dfsg/source3/winbindd/winbindd_util.c
--- samba-4.22.3+dfsg/source3/winbindd/winbindd_util.c 2025-07-07 19:18:35.409030700 +0300
+++ samba-4.22.4+dfsg/source3/winbindd/winbindd_util.c 2025-08-21 18:22:56.187811600 +0300
@@ -2238,7 +2238,7 @@
{
struct winbindd_domain *wbdom = NULL;
- wbdom = find_domain_from_name(domain_name);
+ wbdom = find_domain_from_name_noinit(domain_name);
if (wbdom == NULL) {
return domain_name;
}
diff -Nru samba-4.22.3+dfsg/source4/libnet/libnet_site.c samba-4.22.4+dfsg/source4/libnet/libnet_site.c
--- samba-4.22.3+dfsg/source4/libnet/libnet_site.c 2025-02-06 13:31:54.708149700 +0300
+++ samba-4.22.4+dfsg/source4/libnet/libnet_site.c 2025-08-21 18:22:16.483915800 +0300
@@ -74,7 +74,7 @@
NETLOGON_NT_VERSION_5EX,
.acct_ctrl = -1,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
tevent_timeval_current_ofs(2, 0), /* timeout */
&responses);
diff -Nru samba-4.22.3+dfsg/source4/torture/rpc/lsa.c samba-4.22.4+dfsg/source4/torture/rpc/lsa.c
--- samba-4.22.3+dfsg/source4/torture/rpc/lsa.c 2025-02-06 13:31:55.612155000 +0300
+++ samba-4.22.4+dfsg/source4/torture/rpc/lsa.c 2025-08-21 18:22:16.483915800 +0300
@@ -4456,7 +4456,7 @@
: ACB_DOMTRUST,
.user = account,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
tevent_timeval_current_ofs(2, 0), /* timeout */
&responses);
torture_assert_ntstatus_ok(tctx, status, "netlogon_pings");
More information about the Pkg-samba-maint
mailing list