]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/librpc: open_files.idl: updates for Persistent Handles
authorRalph Boehme <slow@samba.org>
Tue, 7 Oct 2025 16:39:33 +0000 (18:39 +0200)
committerRalph Boehme <slow@samba.org>
Fri, 17 Jul 2026 10:18:36 +0000 (10:18 +0000)
New share_mode_entry flag:
- SHARE_ENTRY_FLAG_PERSISTENT_OPEN

New share_mode_data member:
- num_persistent

New share_mode_entry members:
- create_guid
- protect

delete_token
- open_persistent_id

New vfs_default_durable_cookie members:
- initial_delete_on_close

The SHARE_ENTRY_FLAG_PERSISTENT_OPEN flag is crucially needed to modify the
behaviour of share_entry_stale_pid() and used in other places when looking at a
share_mode_entry and having to adust processing behaviour for Persistent
Handles.

num_persistent is used to track the number of Persistent Handles per
share_mode_data record, adjusting dbwrap_store() behaviour depending on its
value: if num_persistent is greater then zero, we pass DBWRAP_STORE_PERSISTENT.
Without it we would have to iterate over oll share_mode_entry's every time we
store the record.

The create_guid ties together the open state from locking.tdb and the
smbXsrv_open_global.tdb as an additional hardening to securely corolate both.

The protect boolean is an in-memory flag indicating a disconnected Persistent
Handle. We don't want to store this in the share_mode_entry on disk.

open_persistent_id in the delete_token will be used to implement scavening
delete_tokens when Persistent Handles with delete-on-close set expire. Windows
will actually delete the file, but this is not easily possible with the current
architecture of the scavenger, but we must at least correctly remove those stale
tokens.

initial_delete_on_close is used to preserve the fsp flag initial_delete_on_close
across disconnects. When reconnecting the handle, the fsp flag can be
reestablished based on the value from the cookie.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Anoop C S <anoopcs@samba.org>
source3/librpc/idl/open_files.idl
source3/locking/locking.c
source3/locking/share_mode_lock.c

index fe5012a9dbaa98a839efea9c435175b82c5d88b8..53450ee06d24f91d9942d66fb9d5bb07ec2d158c 100644 (file)
@@ -17,7 +17,8 @@ interface open_files
                SHARE_ENTRY_FLAG_POSIX_OPEN             = 0x0001,
                SHARE_ENTRY_FLAG_STREAM_BASEOPEN        = 0x0002,
                SHARE_ENTRY_FLAG_DENY_DOS               = 0x0004,
-               SHARE_ENTRY_FLAG_DENY_FCB               = 0x0008
+               SHARE_ENTRY_FLAG_DENY_FCB               = 0x0008,
+               SHARE_ENTRY_FLAG_PERSISTENT_OPEN        = 0x0010
        } share_entry_flags;
 
        typedef [enum16bit] enum {
@@ -34,6 +35,7 @@ interface open_files
                hyper           op_mid;
                share_mode_entry_op_type op_type;
                GUID            client_guid;
+               GUID            create_guid;
                smb2_lease_key  lease_key;
                uint32          access_mask;
                uint32          share_access;
@@ -48,11 +50,17 @@ interface open_files
                 * to store this share_mode_entry on disk.
                 */
                [skip] boolean8 stale;
+               /*
+                * In-memory flag indicating a disconnected Persistent Handle.
+                * We don't want to store this in the share_mode_entry on disk.
+                */
+               [skip] boolean8 protect;
        } share_mode_entry;
 
        typedef [public] struct {
                uint32          name_hash;
                smb2_lease_key  parent_lease_key;
+               hyper           open_persistent_id;
                security_token *delete_nt_token;
                security_unix_token *delete_token;
        } delete_token;
@@ -76,6 +84,7 @@ interface open_files
                [string,charset(UTF8)] char *servicepath;
                [string,charset(UTF8)] char *base_name;
                [string,charset(UTF8)] char *stream_name;
+               uint32 num_persistent;
                uint32 num_delete_tokens;
                [size_is(num_delete_tokens)] delete_token delete_tokens[];
                [skip] boolean8 not_stored;
@@ -130,6 +139,7 @@ interface open_files
                hyper initial_allocation_size;
                hyper position_information;
                boolean8 write_time_forced;
+               boolean8 initial_delete_on_close;
                vfs_default_durable_stat stat_info;
        } vfs_default_durable_cookie;
 
index cebdb311b4b4a518664a73326b5d1e0579974909..2f78bae6285c461a3c1c14559655add7fb9f34bc 100644 (file)
@@ -772,6 +772,10 @@ static bool add_delete_on_close_token(struct share_mode_data *d,
                dtl->parent_lease_key = lease->parent_lease_key;
        }
 
+       if (fsp->op != NULL) {
+               dtl->open_persistent_id = fsp->op->global->open_persistent_id;
+       }
+
        dtl->delete_nt_token = security_token_duplicate(d->delete_tokens, nt_tok);
        if (dtl->delete_nt_token == NULL) {
                return false;
@@ -896,6 +900,11 @@ void set_delete_on_close_lck(files_struct *fsp,
                                dt->parent_lease_key = lease->parent_lease_key;
                        }
 
+                       if (fsp->op != NULL) {
+                               dt->open_persistent_id =
+                                       fsp->op->global->open_persistent_id;
+                       }
+
                        TALLOC_FREE(dt->delete_nt_token);
                        dt->delete_nt_token = security_token_duplicate(dt, nt_tok);
                        SMB_ASSERT(dt->delete_nt_token != NULL);
index 4f3a4b8201d9bf1f05dbd4439b778b370d2e9288..83a961ba01d42065e8852fdba164d9dabe86fab4 100644 (file)
@@ -345,13 +345,13 @@ static struct share_mode_data *share_mode_memcache_fetch(
 }
 
 /*
- * 124 is the sizeof an ndr-encoded struct share_mode_entry_buf.
+ * 140 is the sizeof an ndr-encoded struct share_mode_entry_buf.
  * Reading/writing entries will immediately error out if this
  * size differs (push/pull is done without allocs).
  */
 
 struct share_mode_entry_buf {
-       uint8_t buf[124];
+       uint8_t buf[140];
 };
 #define SHARE_MODE_ENTRY_SIZE (sizeof(struct share_mode_entry_buf))