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

Reply via email to