The branch, v4-23-stable has been updated
via 9e8dc8c1609 VERSION: Disable GIT_SNAPSHOT for the 4.23.3 release.
via ac5c8fea8ee WHATSNEW: Add release notes for Samba 4.23.3.
via 3f2c2537347 s3:script: Avoid UnicodeDecodeError for
samba-log-parser processing whole directory
via 74001ee99f0 vfs_recycle: Make recycle:touch/touch_mtime work again
if recycle:keeptree is set
via ad4bbed0563 vfs_recycle: Fix trailing whitespace in vfs_recycle.c
via 633a74d3d60 selftest: Add a test for
recycle:touch,touch_mtime,keeptree
via 5ca842bc6c0 mdssvc: add support for parsing date ranges
via f7c01ed4a74 mdssvc: add a test for parsing Spotlight date ranges
via 6b87f2133d6 mdssvc: reduce a log level to DEBUG
via b6cb1d223db ctdb-scripts: Avoid failing updateip when IP is not
assigned
via 8f1032fb959 ctdb-scripts: Avoid printing a message if no connections
via c49aa8718a3 ctdb-tests: Add an event script unit test for updateip
via 1b084f149a0 ctdb-daemon: Fix a crash due to a failed updateip
via 6d2cf012b41 smbd: only increment lease epoch if a lease was granted
via 1757b5ae5ae smbtorture: add test "smb2.lease.lease-epoch"
via 2dfa5168417 mdssvc: call mangle_reset_cache()
via 76257068f6e mdssvc: implement elasticsearch:default_fields
via 39d2fcb2401 mdssvc: fix filtering by share path prefix
via e554174d6b3 mdssvc: fix running test command manually
via fda3bc7f2ce vfs_fruit: ignore Set-ACL requests with zero ACEs
via d5d6d5f5bbe smbd: hang directory pattern matching case sensitivity
on the pathname
via 04d9de20394 smbd: hang posix brl per-handle check on the pathname
via 8fb5d5dde4c vfs_fruit: add option "fruit:posix_opens = yes|no"
(default: yes)
via 2ed0f530269 smbtorture: add test vfs.fruit.case_insensitive_find
via 2ad0cafc89d smbtorture: add test vfs.fruit.readonly-exclusive-lock
via aee9fcf8297 smbd: don't use sticky write times on POSIX handles
via 195499a86fc smbtorture: fix locking offset in
test_fruit_locking_conflict()
via 97002261e50 VERSION: Bump version up to Samba 4.23.3...
from beb9001eecf VERSION: Disable GIT_SNAPSHOT for the 4.23.2 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-23-stable
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
VERSION | 2 +-
WHATSNEW.txt | 55 ++++++-
ctdb/config/events/legacy/10.interface.script | 17 +-
ctdb/config/functions | 4 +
ctdb/server/ctdb_takeover.c | 10 +-
.../UNIT/eventscripts/10.interface.updateip.001.sh | 16 ++
docs-xml/manpages/vfs_fruit.8.xml | 33 ++++
.../smbdotconf/misc/elasticsearchdefaultfields.xml | 19 +++
python/samba/tests/blackbox/mdsearch.py | 18 ++-
python/samba/tests/dcerpc/mdssvc.py | 54 ++++++-
selftest/target/Samba3.pm | 3 +
source3/include/vfs.h | 18 +++
source3/modules/vfs_fruit.c | 49 +++++-
source3/modules/vfs_recycle.c | 6 +-
source3/rpc_server/mdssvc/es_parser.y | 17 +-
source3/rpc_server/mdssvc/es_parser_test.c | 3 -
source3/rpc_server/mdssvc/mdssvc_es.c | 58 ++++---
source3/rpc_server/mdssvc/mdssvc_es.h | 1 +
source3/rpc_server/mdssvc/test_mdsparser_es.c | 118 +++++++-------
source3/rpc_server/rpcd_mdssvc.c | 3 +
source3/script/samba-log-parser | 14 +-
source3/script/tests/test_recycle.sh | 37 +++++
source3/smbd/dir.c | 2 +-
source3/smbd/dosmode.c | 3 +
source3/smbd/open.c | 5 +-
source3/smbd/smb2_lock.c | 16 +-
source4/torture/smb2/lease.c | 99 ++++++++++++
source4/torture/vfs/fruit.c | 179 ++++++++++++++++++++-
28 files changed, 743 insertions(+), 116 deletions(-)
create mode 100755 ctdb/tests/UNIT/eventscripts/10.interface.updateip.001.sh
create mode 100644 docs-xml/smbdotconf/misc/elasticsearchdefaultfields.xml
Changeset truncated at 500 lines:
diff --git a/VERSION b/VERSION
index 84abed24c83..f35f7ab0abb 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=23
-SAMBA_VERSION_RELEASE=2
+SAMBA_VERSION_RELEASE=3
########################################################
# If a official release has a serious bug #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 4d729e939a3..a143f1c084c 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,55 @@
+ ==============================
+ Release Notes for Samba 4.23.3
+ November 07, 2025
+ ==============================
+
+
+This is the latest stable release of the Samba 4.23 release series.
+
+
+Changes since 4.23.2
+--------------------
+
+o Ralph Boehme <[email protected]>
+ * BUG 15926: Samba 4.22 breaks Time Machine.
+ * BUG 15927: Spotlight search restriction for shares incomplete and default
+ search searches in too many attributes.
+ * BUG 15930: Searching for numbers doesn't work with Spotlight.
+ * BUG 15931: rpcd_mdssvc may crash because name mangling is not initialized.
+ * BUG 15933: Only increment lease epoch if a lease was granted.
+
+o Pavel Filipenský <[email protected]>
+ * BUG 15940: vfs_recycle does not update mtime.
+ * BUG 15943: samba-log-parser fails with UnicodeDecodeError: 'utf-8' codec
+ can't decode byte.
+
+o Martin Schwenke <[email protected]>
+ * BUG 15935: Crash in ctdbd on failed updateip.
+
+
+#######################################
+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.23.2
October 15, 2025
@@ -44,8 +96,7 @@ database (https://bugzilla.samba.org/).
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
==============================
Release Notes for Samba 4.23.1
September 26, 2025
diff --git a/ctdb/config/events/legacy/10.interface.script
b/ctdb/config/events/legacy/10.interface.script
index cb7c958ec95..5eaefd7fa86 100755
--- a/ctdb/config/events/legacy/10.interface.script
+++ b/ctdb/config/events/legacy/10.interface.script
@@ -78,6 +78,11 @@ get_iface_ip_maskbits()
"$ip" "$maskbits" "$_maskbits_in"
fi
else
+ if [ "$_iface_in" = "__none__" ]; then
+ echo "WARNING: Unable to determine interface for IP
${ip}"
+ iface="$_iface_in"
+ return
+ fi
die "ERROR: Unable to determine interface for IP ${ip}"
fi
}
@@ -214,10 +219,14 @@ updateip)
exit 0
fi
- ip_block "$ip" "$oiface"
-
- delete_ip_from_iface "$oiface" "$ip" "$maskbits" 2>/dev/null
- delete_ip_from_iface "$niface" "$ip" "$maskbits" 2>/dev/null
+ # Behave more like takeip when the IP is not assigned. No
+ # need for a similar condition around ip_unblock()s because
+ # they will silently fail.
+ if [ "$oiface" != "__none__" ]; then
+ ip_block "$ip" "$oiface"
+ delete_ip_from_iface "$oiface" "$ip" "$maskbits" >/dev/null 2>&1
+ fi
+ delete_ip_from_iface "$niface" "$ip" "$maskbits" >/dev/null 2>&1
add_ip_to_iface "$niface" "$ip" "$maskbits" || {
ip_unblock "$ip" "$oiface"
diff --git a/ctdb/config/functions b/ctdb/config/functions
index 1d80c61e5f2..f5194237843 100755
--- a/ctdb/config/functions
+++ b/ctdb/config/functions
@@ -630,6 +630,10 @@ tickle_tcp_connections()
_conns=$(get_tcp_connections_for_ip "$_ip" |
awk '{ print $1, $2 ; print $2, $1 }')
+ if [ -z "$_conns" ]; then
+ return
+ fi
+
echo "$_conns" | awk '{ print "Tickle TCP connection", $1, $2 }'
echo "$_conns" | ctdb tickle
}
diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c
index 60f60e29ffc..cbf8d0a5b10 100644
--- a/ctdb/server/ctdb_takeover.c
+++ b/ctdb/server/ctdb_takeover.c
@@ -617,7 +617,15 @@ static void ctdb_do_updateip_callback(struct ctdb_context
*ctdb, int status,
*/
ctdb_vnn_unassign_iface(ctdb, state->vnn);
state->vnn->iface = state->old;
- state->vnn->iface->references++;
+ /*
+ * state->old (above) can be NULL if the IP wasn't
+ * recorded as held by this node but the system thinks
+ * the IP was assigned. In that case, a move could
+ * still be desirable..
+ */
+ if (state->vnn->iface != NULL) {
+ state->vnn->iface->references++;
+ }
ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
talloc_free(state);
diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.updateip.001.sh
b/ctdb/tests/UNIT/eventscripts/10.interface.updateip.001.sh
new file mode 100755
index 00000000000..e9567a8d114
--- /dev/null
+++ b/ctdb/tests/UNIT/eventscripts/10.interface.updateip.001.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "error - update a non-existent ip"
+
+setup
+
+public_address=$(ctdb_get_1_public_address)
+ip="${public_address% *}"
+ip="${ip#* }"
+
+ok "WARNING: Unable to determine interface for IP ${ip}"
+# Want separate words from public_address: interface IP maskbits
+# shellcheck disable=SC2086
+simple_test "__none__" $public_address
diff --git a/docs-xml/manpages/vfs_fruit.8.xml
b/docs-xml/manpages/vfs_fruit.8.xml
index 9e27030b660..13748c110fb 100644
--- a/docs-xml/manpages/vfs_fruit.8.xml
+++ b/docs-xml/manpages/vfs_fruit.8.xml
@@ -426,6 +426,39 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>fruit:posix_opens = yes | no</term>
+ <listitem>
+
+ <para>When <parameter>fruit:posix_opens</parameter> is set to
+ <parameter>yes</parameter>, vfs_fruit will internally translate
+ all filesystem semantics to use POSIX behaviour instead of Windows
+ behaviour. As Macs are closer to POSIX than Windows with regard
+ to filesystem semantics, this improves access semantics for
+ a lot of corner cases.</para>
+ <para>The default is <emphasis>yes</emphasis>.</para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>fruit:ignore_zero_aces = yes | no</term>
+ <listitem>
+
+ <para>When <parameter>fruit:ignore_zero_aces</parameter> is
+ enabled, attempts to modify filesystem permissions fail if the ACL
+ sent over the wire contains no ACEs. This is completely valid
+ client behaviour, but it means subsequently no further access is
+ possible to the file, unless permissions get fixed by an
+ administrator.</para>
+ <para>This problematic behaviour has been reported for latest
+ macOS versions and this new option allows to work around
+ it.</para>
+ <para>The default is <emphasis>yes</emphasis>.</para>
+
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/docs-xml/smbdotconf/misc/elasticsearchdefaultfields.xml
b/docs-xml/smbdotconf/misc/elasticsearchdefaultfields.xml
new file mode 100644
index 00000000000..9230e9280b7
--- /dev/null
+++ b/docs-xml/smbdotconf/misc/elasticsearchdefaultfields.xml
@@ -0,0 +1,19 @@
+<samba:parameter name="elasticsearch:default_fields"
+ context="G"
+ type="string"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+ <description>
+ <para>
+ Default attributes in Elasticsearch to query when receiving a Spotlight
+ query that searches in the special attribute "*". This is the default
used
+ by macOS clients when searching from the Finder.
+ </para>
+ <para>
+ This option expects a list of Elasticsearch attributes separated by
+ comma where each attributes must be enclosed in double quotes.
+ </para>
+ </description>
+
+ <value type="default">"file.filename", "content"</value>
+ <value type="example">"foo", "bar"</value>
+</samba:parameter>
diff --git a/python/samba/tests/blackbox/mdsearch.py
b/python/samba/tests/blackbox/mdsearch.py
index 8d67090e182..a2e6eb09029 100644
--- a/python/samba/tests/blackbox/mdsearch.py
+++ b/python/samba/tests/blackbox/mdsearch.py
@@ -102,8 +102,22 @@ class MdfindBlackboxTests(BlackboxTestCase):
json_in = r'''{
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
- "query_string": {
- "query": "(samba*) AND path.real.fulltext:\"%BASEPATH%\""
+ "bool": {
+ "filter": [
+ {
+ "prefix": {
+ "path.real": "%BASEPATH%/"
+ }
+ }
+ ],
+ "must": [
+ {
+ "query_string": {
+ "query": "samba*",
+ "fields": ["file.filename", "content"]
+ }
+ }
+ ]
}
}
}'''
diff --git a/python/samba/tests/dcerpc/mdssvc.py
b/python/samba/tests/dcerpc/mdssvc.py
index cd256548b91..40005ff1824 100644
--- a/python/samba/tests/dcerpc/mdssvc.py
+++ b/python/samba/tests/dcerpc/mdssvc.py
@@ -133,8 +133,22 @@ class MdssvcTests(RpcInterfaceTestCase):
exp_json_query = r'''{
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
- "query_string": {
- "query": "(samba*) AND path.real.fulltext:\"%BASEPATH%\""
+ "bool": {
+ "filter": [
+ {
+ "prefix": {
+ "path.real": "%BASEPATH%/"
+ }
+ }
+ ],
+ "must": [
+ {
+ "query_string": {
+ "query": "samba*",
+ "fields": ["file.filename", "content"]
+ }
+ }
+ ]
}
}
}'''
@@ -165,8 +179,22 @@ class MdssvcTests(RpcInterfaceTestCase):
exp_json_query = r'''{
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
- "query_string": {
- "query": "(file.filename:x\\+x OR file.filename:x\\*x OR
file.filename:x=x OR file.filename:x'x OR file.filename:x\\?x OR
file.filename:x\\ x OR file.filename:x\\(x OR file.filename:x\\\"x OR
file.filename:x\\\\x) AND path.real.fulltext:\"%BASEPATH%\""
+ "bool": {
+ "filter": [
+ {
+ "prefix": {
+ "path.real": "%BASEPATH%/"
+ }
+ }
+ ],
+ "must": [
+ {
+ "query_string": {
+ "query": "file.filename:x\\+x OR file.filename:x\\*x OR
file.filename:x=x OR file.filename:x'x OR file.filename:x\\?x OR
file.filename:x\\ x OR file.filename:x\\(x OR file.filename:x\\\"x OR
file.filename:x\\\\x",
+ "fields": ["file.filename", "content"]
+ }
+ }
+ ]
}
}
}'''
@@ -207,8 +235,22 @@ class MdssvcTests(RpcInterfaceTestCase):
exp_json_query = r'''{
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
- "query_string": {
- "query": "(*samba*) AND path.real.fulltext:\"%BASEPATH%\""
+ "bool": {
+ "filter": [
+ {
+ "prefix": {
+ "path.real": "%BASEPATH%/"
+ }
+ }
+ ],
+ "must": [
+ {
+ "query_string": {
+ "query": "*samba*",
+ "fields": ["file.filename", "content"]
+ }
+ }
+ ]
}
}
}'''
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 6ea64ff3525..6f17d659d96 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -3718,6 +3718,9 @@ sub provision($$)
path = $recycle_shrdir
vfs objects = recycle
recycle : repository = .trash
+ recycle : keeptree = yes
+ recycle : touch = yes
+ recycle : touch_mtime = yes
recycle : exclude = *.tmp
recycle : directory_mode = 755
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 75b81648108..e87a0d923e5 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -462,6 +462,15 @@ typedef struct files_struct {
bool lock_failure_seen : 1;
bool encryption_required : 1;
bool fstat_before_close : 1;
+ /*
+ * For POSIX clients struct files_struct.fsp_flags.posix_open
+ * and struct smb_filename.flags SMB_FILENAME_POSIX_PATH will
+ * always be set to the same value.
+ *
+ * For macOS clients vfs_fruit with fruit:posix_open=yes, we
+ * deliberately set both flags to fsp_flags.posix_open=true
+ * while SMB_FILENAME_POSIX_PATH will not be set.
+ */
bool posix_open : 1;
bool posix_append : 1;
bool ntcreatex_deny_dos : 1;
@@ -889,6 +898,15 @@ struct smb_filename {
struct fsp_smb_fname_link *fsp_link;
};
+/*
+ * For POSIX clients struct files_struct.fsp_flags.posix_open
+ * and struct smb_filename.flags SMB_FILENAME_POSIX_PATH will
+ * always be set to the same value.
+ *
+ * For macOS clients vfs_fruit with fruit:posix_open=yes, we
+ * deliberately set both flags to fsp_flags.posix_open=true
+ * while SMB_FILENAME_POSIX_PATH will not be set.
+ */
#define SMB_FILENAME_POSIX_PATH 0x01
enum vfs_translate_direction {
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 1b72eeec534..302d90ce997 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -125,6 +125,7 @@ struct fruit_config_data {
bool use_aapl; /* config from smb.conf */
bool use_copyfile;
bool readdir_attr_enabled;
+ bool posix_opens;
bool unix_info_enabled;
bool copyfile_enabled;
bool veto_appledouble;
@@ -136,6 +137,7 @@ struct fruit_config_data {
bool wipe_intentionally_left_blank_rfork;
bool delete_empty_adfiles;
bool validate_afpinfo;
+ bool ignore_zero_aces;
/*
* Additional options, all enabled by default,
@@ -339,6 +341,14 @@ static int init_fruit_config(vfs_handle_struct *handle)
config->use_copyfile = lp_parm_bool(-1, FRUIT_PARAM_TYPE_NAME,
"copyfile", false);
+ config->posix_opens = lp_parm_bool(
+ SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME, "posix_opens", true);
+
+ config->ignore_zero_aces = lp_parm_bool(SNUM(handle->conn),
+ FRUIT_PARAM_TYPE_NAME,
+ "ignore_zero_aces",
+ true);
+
config->aapl_zero_file_id =
lp_parm_bool(SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME,
"zero_file_id", true);
@@ -1754,16 +1764,27 @@ static int fruit_openat(vfs_handle_struct *handle,
files_struct *fsp,
const struct vfs_open_how *how)
{
+ struct fruit_config_data *config = NULL;
int fd;
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
if (!is_named_stream(smb_fname)) {
- return SMB_VFS_NEXT_OPENAT(handle,
- dirfsp,
- smb_fname,
- fsp,
- how);
+ fd = SMB_VFS_NEXT_OPENAT(handle,
+ dirfsp,
+ smb_fname,
+ fsp,
+ how);
+ if (fd == -1) {
+ return -1;
+ }
+ if (config->posix_opens && global_fruit_config.nego_aapl) {
+ fsp->fsp_flags.posix_open = true;
+ }
+ return fd;
}
if ((how->resolve & ~VFS_OPEN_HOW_WITH_BACKUP_INTENT) != 0) {
@@ -1798,7 +1819,13 @@ static int fruit_openat(vfs_handle_struct *handle,
DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
/* Prevent reopen optimisation */
+ if (fd == -1) {
+ return -1;
+ }
fsp->fsp_flags.have_proc_fds = false;
+ if (config->posix_opens && global_fruit_config.nego_aapl) {
+ fsp->fsp_flags.posix_open = true;
+ }
return fd;
}
@@ -4605,6 +4632,7 @@ static NTSTATUS fruit_fset_nt_acl(vfs_handle_struct
*handle,
uint32_t security_info_sent,
const struct security_descriptor *orig_psd)
{
+ struct fruit_config_data *config = NULL;
NTSTATUS status;
bool do_chmod;
mode_t ms_nfs_mode = 0;
@@ -4612,6 +4640,10 @@ static NTSTATUS fruit_fset_nt_acl(vfs_handle_struct
*handle,
struct security_descriptor *psd = NULL;
uint32_t orig_num_aces = 0;
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data,
+ return NT_STATUS_UNSUCCESSFUL);
--
Samba Shared Repository