[RFC PATCH samba] smbd: deny rename if the destination has non-POSIX opens

ChenXiaoSong chenxiaosong at chenxiaosong.com
Wed Aug 5 13:31:45 UTC 2026


From: ChenXiaoSong <chenxiaosong at kylinos.cn>

Check the destination share mode entries with
has_other_nonposix_opens() before replacing it, and return
NT_STATUS_ACCESS_DENIED if a non-POSIX open exists.

Signed-off-by: ChenXiaoSong <chenxiaosong at kylinos.cn>
---
 source3/smbd/smb2_reply.c | 48 +++++++++------------------------------
 1 file changed, 11 insertions(+), 37 deletions(-)

diff --git a/source3/smbd/smb2_reply.c b/source3/smbd/smb2_reply.c
index 6bdc02c2374..c3da096205e 100644
--- a/source3/smbd/smb2_reply.c
+++ b/source3/smbd/smb2_reply.c
@@ -1312,31 +1312,6 @@ static void notify_rename(struct connection_struct *conn,
 	TALLOC_FREE(parent_dir_dst);
 }
 
-struct rename_check_open_state {
-	struct files_struct *dst_fsp;
-	struct file_id fileid;
-};
-
-static struct files_struct *rename_check_open_fn(struct files_struct *fsp,
-						 void *private_data)
-{
-	struct rename_check_open_state *state = private_data;
-
-	if (fsp == state->dst_fsp) {
-		return NULL;
-	}
-
-	if (!fsp->fsp_flags.is_fsa) {
-		return NULL;
-	}
-
-	if (!file_id_equal(&fsp->file_id, &state->fileid)) {
-		return NULL;
-	}
-
-	return fsp;
-}
-
 /****************************************************************************
  Rename an open file - given an fsp.
 ****************************************************************************/
@@ -1483,11 +1458,9 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 	}
 
 	if (VALID_STAT(smb_fname_dst->st)) {
-
-		struct rename_check_open_state check_state = {
-			.dst_fsp = smb_fname_dst->fsp,
-		};
-		struct files_struct *found_open = NULL;
+		struct file_id fileid;
+		struct share_mode_lock *dst_lck = NULL;
+		bool has_other_open = false;
 
 		if (!replace_if_exists) {
 			DBG_NOTICE("dest exists doing rename "
@@ -1498,13 +1471,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 			goto out;
 		}
 
-		check_state.fileid = vfs_file_id_from_sbuf(conn,
-							   &smb_fname_dst->st);
-
-		found_open = files_forall(conn->sconn,
-					  rename_check_open_fn,
-					  &check_state);
-		if (found_open != NULL) {
+		fileid = vfs_file_id_from_sbuf(conn, &smb_fname_dst->st);
+		dst_lck = fetch_share_mode_unlocked(ctx, fileid);
+		if (dst_lck != NULL) {
+			has_other_open = has_other_nonposix_opens(
+				dst_lck, smb_fname_dst->fsp);
+			TALLOC_FREE(dst_lck);
+		}
+		if (has_other_open) {
 			DBG_NOTICE("Target file open\n");
 			status = NT_STATUS_ACCESS_DENIED;
 			goto out;
-- 
2.54.0




More information about the samba-technical mailing list