Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Jul 17 18:26:27 UTC 2026 on atb-devel-224
Ralph Boehme [Fri, 17 Jul 2026 09:24:08 +0000 (11:24 +0200)]
WHATSNEW: SMB3 Persistent Handles
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Jul 17 11:21:41 UTC 2026 on atb-devel-224
It's likely a real bug that needs to be investigated, but we're
running out of time for the 4.25 merge windows, so let's pave over it
and fix it later.
Marking as flapping is not sufficient as the test leaves ctdb
non-functional when failing.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Tue, 2 Dec 2025 15:09:32 +0000 (16:09 +0100)]
smbtorture: add test "smb2.persistent-open.deleteonclose-twice"
Verifies cleanup of stale delete-on-close token. This only works against Samba
where we have to implement DoC token expiration instead of fully deleting the
file (and the token).
1. Open file with PH an handle-timeout of 1s
2. Open file a second time with PH an handle-timeout of 10s
3. Set Doc on handle from (1)
4. Set Doc on handle from (2)
5. Disconnect
6. Sleep 2s, handle from (1) should expire, scavenger should not
cleanup DoC token as that is from (3)
7. Reconnect session and handle from (3)
8. Close file, should now get removed as Doc should still be set
9. Verify file is gone
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
This uses the same basic test as smb2.persistent-open.reconnect-contended, but
instead of doing a simple TCP disconnect from TALLOC_FREE()ing the smb2_tree, we
use the ctdb failover hooks.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
smb2.persistent-open.deleteonclose-reconnect verifies reconnecting or expiring a
Persistent Handle with delete-on-close pending:
1a. SMB2-CREATE + PH + initial-delete-on-close, or
1b. SMB2-CREATE + PH + SMB2-SETINFO(delete-on-close), then
2. Disconnect TCP
3. Reconnect TCP and handle
4. SMB2-CLOSE -> should delete the file
5. Try to open -> should fail with NT_STATUS_OBJECT_NAME_NOT_FOUND
The test smb2.persistent-open.deleteonclose-expire fails against Samba, but
works againt Windows. The reason is current lack of support for accessing our
VFS from the scavenger. Note that the same problem applies to Durable Handles,
not just Persistent Handles.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Mon, 25 Aug 2025 09:56:48 +0000 (11:56 +0200)]
smbtorture: add test "smb2.persistent-open.timeout_5"
Verify that a disconnected Persistent Handle with a timeout of 5 seconds is
reaped by the scavenger after the timeout expires, so another client can then
open the file.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Thu, 25 Sep 2025 14:59:54 +0000 (16:59 +0200)]
smbtorture: add test "smb2.persistent-open.reconnect-contended-oplock"
Persistent Handles together with oplocks are broken on Windows: eg oplocks are
"silently" downgraded from B to S when reconnecting a PH, instead of sending an
oplock break with the downgraded oplock level (cf --option=torture:subtest=7).
Samba doesn't grant Persistent Handles with oplocks at all, only with
leases or without an oplock or lease.
Skip these tests altogether, they're merely kept for historical
reference and in case this subject needs furthter exploration in the
future.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Thu, 25 Sep 2025 14:49:22 +0000 (16:49 +0200)]
smbtorture: add test "smb2.persistent-open.reconnect-contended-two"
Same as smb2.persistent-open.reconnect-contended, but with two Persistent
Handles sharing the same lease key.
Note that some tests are failing against Windows as Windows is strangely failing
to reconnect the second handle. This is being discussed with Microsoft:
Ralph Boehme [Sun, 24 Aug 2025 19:56:38 +0000 (21:56 +0200)]
smbtorture: add test "smb2.persistent-open.reconnect-contended"
This tests trying to open a file with a disconnected persistent handle
with various different lease levels, sharemodes and create disposition
combinations.
The client then disconnects and we try to open (contend) the now disconnected
Persistent Handle from the first client. This will either fail with
NT_STATUS_FILE_NOT_AVAILABLE or trigger a lease break which gets dispatched once
the first client reconnects.
The client must always be able to reconnect the disconnected open and the server
guarantees that any operations which break W or H leases are blocked.
The bottom line being:
* incompatible opens without H-lease are blocked with
NT_STATUS_FILE_NOT_AVAILABLE
* incompatible opens with a H lease trigger a lease break and are deferred until
the first client reconnects the handle
* in addition to that, if the file has byterange locks the lease must include
W, otherwise contending opens are also blocked with NT_STATUS_FILE_NOT_AVAILABLE
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Mon, 25 Aug 2025 16:48:20 +0000 (18:48 +0200)]
smbd: fail replay operation on handle that has been used
Using a handle, eg processing an SMB2_WRITE operation, removes the replay cache
record associated with open.
If the handle is a Persistent Handle, the replay must fail with
NT_STATUS_FILE_NOT_AVAILABLE in this case, whereas for a Durable Handle without
persistency, the replay would be handled as a new create.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Wed, 26 Feb 2025 16:55:57 +0000 (17:55 +0100)]
smbd: check for Persistent Handles in smbXsrv_open_global_verify_record()
Return NT_STATUS_REMOTE_DISCONNECT for a Persistent Handle if the process
doesn't exist, same error response as for a Durable Handle where the server_id
is found to be set to the special disconnected id a few lines above.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Mon, 1 Dec 2025 16:48:24 +0000 (17:48 +0100)]
scavenger: clean up stale delete-on-close tokens in the scavenger
Currently we discard Durable Handles when processing a client disconnect that
have delete-on-close set, which will then also clean up the delete-on-close
token.
This is going to change for Persistent Handles, so we have to prepare for
cleaning up delete-on-close tokens in the scavenger.
Windows takes it one step further and the file gets actually deleted: on Windows
delete-on-close in set at the FSA layer so when the scavenger closes the handle,
the filesystem will just follow standard delete-on-close processing and delete
the file.
For Samba this is hard to implement in the scavenger, as it would need to be
extended to be able talk to the Samba VFS to delete the file, so we merely
remove the stale delete-token and without deleting the file.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Factor out reset_delete_on_close_lck_internal() and then make the
existing reset_delete_on_close_lck() a wrapper around it.
No change in behaviour for reset_delete_on_close_lck().
reset_delete_on_close_lck_open_id() receives the open_persistent_id from the
smbXsrv_open_global.tdb as an additional parameter
A later commit will use reset_delete_on_close_lck_open_id() in the open
scavenging code to ensure the delete token is only removed if the open-id
matches.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Tue, 25 Nov 2025 14:58:27 +0000 (15:58 +0100)]
scavenger: update scavenger_add_timer() for Persistent Handles
With Persistent Handles global->disconnect_time might be 0 if a process or node
crashed and global->server_id won't be set to the special disconnected id.
Due to a race there might the open record might already be gone, so handle that
as well to still allow cleanup of locking.tdb and brlock.tdb records.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Fri, 29 Aug 2025 13:44:16 +0000 (15:44 +0200)]
s3/brlock: update brlock cleanup for Persistent Handles
Durable Handles don't allow byte-range locks from other opens on a file, but
Persistent Handles do allow this. Adapt brl_cleanup_disconnected() to
deal with locks from different handles.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Thu, 6 Nov 2025 13:40:41 +0000 (14:40 +0100)]
smbd: adjust get_lease_type() for Persistent Handles
If the lease record was lost due to a node outage, just return
SMB2_LEASE_NONE. Note that e->protect will only be set to true for Persistent
Handles and if the handle is currently disconnected.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Mon, 1 Dec 2025 17:03:46 +0000 (18:03 +0100)]
scavenger: pass individual args not fsp to scavenger_schedule_disconnected()
In preperation of calling scavenger_schedule_disconnected() from a
function where we don't have an fsp.
Not having an fsp also means not having access to the open record via
fsp->op->global to fetch the timeout values. Hence in the scavenger in
scavenger_add_timer() we use smbXsrv_open_global_lookup() to fetch the open
record with the timeout values.
No change in behaviour.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Sun, 30 Nov 2025 14:31:10 +0000 (15:31 +0100)]
smbd: restrict leases on CA and SO shares when filling tcon->smb_max_lease_mask
This adds the following paremetric options
smb3 ca:max lease mask = RWH (default:R, set to RWH in selftest on testshare)
smb3 ca so:max lease mask = RWH (default:R)
For now keep them as "internal" undocumented parametric options. If we learn
about real world usecases in the future, we can then look into turning them into
documented options.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Sat, 6 Dec 2025 15:26:17 +0000 (16:26 +0100)]
smbd: checking for disconnected Persistent Handles
The core of blocking access to disconnect Persistent Handles:
MS-SMB2 3.3.5.9 Receiving an SMB2 CREATE Request:
If Connection.Dialect belongs to the SMB 3.x dialect family and the request
does not contain SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context or
SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context, the server MUST look
up an existing open in the GlobalOpenTable where Open.FileName matches the
file name in the Buffer field of the request. If an Open entry is found, and
if all the following conditions are satisfied, the server SHOULD<300> fail the
request with STATUS_FILE_NOT_AVAILABLE:
- Open.IsPersistent is TRUE
- Open.Connection is NULL
If the disconnected handle has an H lease (or WH lease in case the file has
byterange locks), and the contending open triggers a lease break, we have to
"save" the lease break until the handle is reconnected.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>
Ralph Boehme [Tue, 17 Sep 2019 16:47:52 +0000 (09:47 -0700)]
s3/locking: update share_entry_stale_pid() check for Persistent Handles
Disconnected Persistent Handles are NOT "stale" and must be preserved. But while
we're at it to check if the handle is connected or not, remember this
information so we can check this later in the open code.
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Anoop C S <anoopcs@samba.org>