[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