diff options
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r-- | source3/smbd/reply.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 45c4b1d1df..c20daae21b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -4236,10 +4236,11 @@ static BOOL rename_path_prefix_equal(const char *src, const char *dest) NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstring newname, uint32 attrs, BOOL replace_if_exists) { - SMB_STRUCT_STAT sbuf; + SMB_STRUCT_STAT sbuf, sbuf1; pstring newname_last_component; NTSTATUS status = NT_STATUS_OK; struct share_mode_lock *lck = NULL; + BOOL dst_exists; ZERO_STRUCT(sbuf); @@ -4307,12 +4308,22 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin return NT_STATUS_OK; } - if(!replace_if_exists && vfs_object_exist(conn, newname, NULL)) { + /* + * Have vfs_object_exist also fill sbuf1 + */ + dst_exists = vfs_object_exist(conn, newname, &sbuf1); + + if(!replace_if_exists && dst_exists) { DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n", fsp->fsp_name,newname)); return NT_STATUS_OBJECT_NAME_COLLISION; } + if (file_find_di_first(file_id_sbuf(&sbuf1)) != NULL) { + DEBUG(3, ("rename_internals_fsp: Target file open\n")); + return NT_STATUS_ACCESS_DENIED; + } + /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) == -1) { |