The branch, v4-22-stable has been updated
via 356fafd5fa3 VERSION: Disable GIT_SNAPSHOT for the 4.22.4 release.
via 99b0baadbb4 WHATSNEW: Add release notes for Samba 4.22.4.
via a31301e4f03 winbindd: use find_domain_from_name_noinit() in
find_dns_domain_name()
via 8f00ba25bc6 libads: fix get_kdc_ip_string()
via 4725af8a4c3 libads: change netlogon_pings() behaviour wrt to
min_servers parameter
via 0a1f0d01417 libads: reverse termination condition in
netlogon_pings_done()
via 5e685641fcc idmap_ad: add and use ldap_timeout and fix LDAP server
failover
via e4420f35c67 tldap: use tevent_req_set_endtime() to terminate LDAP
searches
via 58aa90b34be vfs: Fix vfs_streams_depot's fstatat
via a35b91ffd39 vfs_virsufilter: Fix the invocation of
SMB_VFS_NEXT_CONNECT
via 5f93ef723df ctdb: Fix a stuck cluster lock holder after a delayed
leader bcast
via af6d23f9891 smbd: fix mode being sent to possibly_set_archive
via 33647976766 s3:utils: Allow ROLE_IPA_DC to allow to use Kerberos in
gensec
via 00adb3104e7 s3:netlogon: IPA DC is the PDC as well - allow
ROLE_IPA_DC in _netr_DsRGetForestTrustInformation()
via d14fa6eb96a docs-xml: Make smb.conf 'server role' value consistent
with ROLE_IPA_DC in libparam
via fe8eafc289d s3:winbindd: Resolve dc name using CLDAP also for
ROLE_IPA_DC
via 25f5debf01e s3-net: fix "net ads kerberos" krb5ccname handling
via b17dec31068 s3-selftest: add tests for "net ads kerberos" commands
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
via e119cb0b484 libads: fix get_kdc_ip_string() ...
via f186da9fabf Add check for the GPO link to have at least two
attributes separated by semicolumn. Allows to handle empty links.
via 69cccd4c18c WHATSNEW: fix typo
via ef1a5896a11 VERSION: Bump version up to Samba 4.22.4...
from 70eeb722062 VERSION: Disable GIT_SNAPSHOT for the 4.22.3 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-22-stable
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
VERSION | 2 +-
WHATSNEW.txt | 75 +++++++++++-
ctdb/server/ctdb_recoverd.c | 1 +
docs-xml/smbdotconf/security/serverrole.xml | 2 +-
python/samba/gp/gpclass.py | 4 +-
selftest/knownfail | 1 -
source3/lib/tldap.c | 5 +
source3/libads/cldap.c | 2 +-
source3/libads/kerberos.c | 39 ++++++-
source3/libads/ldap.c | 48 +++++---
source3/libads/netlogon_ping.c | 45 +++++---
source3/libads/netlogon_ping.h | 4 +-
source3/libsmb/conncache.c | 8 +-
source3/libsmb/dsgetdcname.c | 8 +-
source3/libsmb/namequery.c | 25 +++-
source3/modules/vfs_streams_depot.c | 16 ++-
source3/modules/vfs_virusfilter.c | 7 +-
source3/rpc_server/netlogon/srv_netlog_nt.c | 5 +-
source3/script/tests/test_net_ads_kerberos.sh | 158 ++++++++++++++++++++++++++
source3/selftest/tests.py | 12 ++
source3/smbd/open.c | 2 +-
source3/utils/net.c | 15 +++
source3/utils/net.h | 1 +
source3/utils/net_ads.c | 6 +-
source3/utils/ntlm_auth.c | 6 +-
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 | 58 +++++++++-
source3/winbindd/winbindd_pam.c | 96 +++++++++++++++-
source3/winbindd/winbindd_proto.h | 5 +
source3/winbindd/winbindd_util.c | 2 +-
source4/libnet/libnet_site.c | 2 +-
source4/torture/rpc/lsa.c | 2 +-
35 files changed, 647 insertions(+), 80 deletions(-)
create mode 100755 source3/script/tests/test_net_ads_kerberos.sh
Changeset truncated at 500 lines:
diff --git a/VERSION b/VERSION
index 171017d023a..ba090b498d4 100644
--- a/VERSION
+++ b/VERSION
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the
Samba Team 1992-2025"
########################################################
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 --git a/WHATSNEW.txt b/WHATSNEW.txt
index 57d9133b43f..fcbc3a8b524 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,73 @@
+ ==============================
+ 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 <[email protected]>
+ * 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 <[email protected]>
+ * BUG 15840: kinit command is failing with Missing cache Error.
+
+o Pavel Filipenský <[email protected]>
+ * BUG 15891: Figuring out the DC name from IP address fails and breaks
+ fork_domain_child().
+
+o Volker Lendecke <[email protected]>
+ * BUG 15816: vfs_streams_depot fstatat broken.
+ * BUG 15892: Delayed leader broadcast can block ctdb forever.
+
+o Stefan Metzmacher <[email protected]>
+ * BUG 14981: netr_LogonSamLogonEx returns NR_STATUS_ACCESS_DENIED with
+ SysvolReady=0.
+
+o Rabinarayan Panigrahi <[email protected]>
+ * BUG 15663: Apparently there is a conflict between shadow_copy2 module and
+ virusfilter (action quarantine).
+
+o Aleksandr Sharov <[email protected]>
+ * BUG 15877: Fix handling of empty GPO link.
+
+o Srinivas Rao V <[email protected]>
+ * 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 @@ o Stefan Metzmacher <[email protected]>
calls like netr_DsRGetDCName.
o Andreas Schneider <[email protected]>
- * 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 @@ database (https://bugzilla.samba.org/).
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
==============================
Release Notes for Samba 4.22.2
June 05, 2025
diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index 11644868e46..edc89754c2c 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/server/ctdb_recoverd.c
@@ -1902,6 +1902,7 @@ static void cluster_lock_election(struct ctdb_recoverd
*rec)
* attempt to retake it. This provides stability.
*/
if (cluster_lock_held(rec)) {
+ rec->leader = rec->pnn;
goto done;
}
diff --git a/docs-xml/smbdotconf/security/serverrole.xml
b/docs-xml/smbdotconf/security/serverrole.xml
index 4ea4e4751ee..40244e125ce 100644
--- a/docs-xml/smbdotconf/security/serverrole.xml
+++ b/docs-xml/smbdotconf/security/serverrole.xml
@@ -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 --git a/python/samba/gp/gpclass.py b/python/samba/gp/gpclass.py
index d86aacec138..07b4fb3e7bd 100644
--- a/python/samba/gp/gpclass.py
+++ b/python/samba/gp/gpclass.py
@@ -673,8 +673,10 @@ class GP_LINK:
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 --git a/selftest/knownfail b/selftest/knownfail
index 103a0bb1d76..ab2d79d7114 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -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 --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index db06e9f1282..11bf28ad4e4 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -1895,6 +1895,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 75803500d31..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,21 +1225,50 @@ 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));
+ /*
+ * 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 --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 016402d5ca6..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)) {
@@ -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..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
@@ -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);
@@ -811,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,
@@ -849,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)
{
@@ -868,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,
--
Samba Shared Repository