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

ChenXiaoSong <[email protected]>
Newsgroups org.kernel.vger.linux-cifs
Message-ID <[email protected]>
From: ChenXiaoSong <[email protected]>

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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.