From baa4727b243ff2dfb78d3dd5fd29c8e9a3667c56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Dec 2009 18:06:40 -0800 Subject: [PATCH] Remove unneeded argument from can_set_delete_on_close(). Ensure can_set_delete_on_close() is correctly called before any setting of the disposition bit (clean up the do_unlink() call). Jeremy. (cherry picked from commit dfcc4115ddc7c3bf7a69d7eb747c096cd217b8a6) --- source3/include/proto.h | 3 +-- source3/locking/locking.c | 11 ++--------- source3/modules/onefs_open.c | 4 ++-- source3/smbd/open.c | 4 ++-- source3/smbd/reply.c | 30 +++++++++++------------------- source3/smbd/trans2.c | 9 +++++---- 6 files changed, 23 insertions(+), 38 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index f389a5f5076..7a7d4f904f4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3486,8 +3486,7 @@ bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp); void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid); bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp); bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp); -NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, - uint32 dosmode); +NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode); void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok); void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok); bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok); diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5a6fdf081eb..26018f90db9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1307,18 +1307,11 @@ bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) } /**************************************************************************** - Deal with the internal needs of setting the delete on close flag. Note that - as the tdb locking is recursive, it is safe to call this from within - open_file_ntcreate. JRA. + Check if setting delete on close is allowed on this fsp. ****************************************************************************/ -NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, - uint32 dosmode) +NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode) { - if (!delete_on_close) { - return NT_STATUS_OK; - } - /* * Only allow delete on close for writable files. */ diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index fd12fff58ca..b96c4b6afbb 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -1328,7 +1328,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, /* Handle strange delete on close create semantics. */ if (create_options & FILE_DELETE_ON_CLOSE) { - status = can_set_delete_on_close(fsp, True, new_dos_attributes); + status = can_set_delete_on_close(fsp, new_dos_attributes); if (!NT_STATUS_IS_OK(status)) { /* Remember to delete the mode we just added. */ @@ -1686,7 +1686,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, * always to be honored on close... See test 19 in Samba4 BASE-DELETE. */ if (create_options & FILE_DELETE_ON_CLOSE) { - status = can_set_delete_on_close(fsp, True, 0); + status = can_set_delete_on_close(fsp, 0); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) { TALLOC_FREE(lck); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 72f6a008183..fd3c6103e9f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2171,7 +2171,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, /* Handle strange delete on close create semantics. */ if (create_options & FILE_DELETE_ON_CLOSE) { - status = can_set_delete_on_close(fsp, True, new_dos_attributes); + status = can_set_delete_on_close(fsp, new_dos_attributes); if (!NT_STATUS_IS_OK(status)) { /* Remember to delete the mode we just added. */ @@ -2634,7 +2634,7 @@ static NTSTATUS open_directory(connection_struct *conn, /* For directories the delete on close bit at open time seems always to be honored on close... See test 19 in Samba4 BASE-DELETE. */ if (create_options & FILE_DELETE_ON_CLOSE) { - status = can_set_delete_on_close(fsp, True, 0); + status = can_set_delete_on_close(fsp, 0); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) { TALLOC_FREE(lck); file_free(req, fsp); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 682f56ff33e..101635fb504 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2454,24 +2454,6 @@ static NTSTATUS do_unlink(connection_struct *conn, return NT_STATUS_OBJECT_NAME_INVALID; #endif /* JRATEST */ - /* Fix for bug #3035 from SATOH Fumiyasu - - On a Windows share, a file with read-only dosmode can be opened with - DELETE_ACCESS. But on a Samba share (delete readonly = no), it - fails with NT_STATUS_CANNOT_DELETE error. - - This semantic causes a problem that a user can not - rename a file with read-only dosmode on a Samba share - from a Windows command prompt (i.e. cmd.exe, but can rename - from Windows Explorer). - */ - - if (!lp_delete_readonly(SNUM(conn))) { - if (fattr & aRONLY) { - return NT_STATUS_CANNOT_DELETE; - } - } - /* On open checks the open itself will check the share mode, so don't do it here as we'll get it wrong. */ @@ -2500,6 +2482,16 @@ static NTSTATUS do_unlink(connection_struct *conn, return status; } + status = can_set_delete_on_close(fsp, fattr); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + nt_errstr(status))); + close_file(req, fsp, NORMAL_CLOSE); + return status; + } + /* The set is across all open files on this dev/inode pair. */ if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) { close_file(req, fsp, NORMAL_CLOSE); @@ -6084,7 +6076,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, */ if (create_options & FILE_DELETE_ON_CLOSE) { - status = can_set_delete_on_close(fsp, True, 0); + status = can_set_delete_on_close(fsp, 0); if (NT_STATUS_IS_OK(status)) { /* Note that here we set the *inital* delete on close flag, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 3b4a4b70d39..ca2ff60162d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5737,10 +5737,11 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn, (unsigned int)dosmode, (unsigned int)delete_on_close )); - status = can_set_delete_on_close(fsp, delete_on_close, dosmode); - - if (!NT_STATUS_IS_OK(status)) { - return status; + if (delete_on_close) { + status = can_set_delete_on_close(fsp, dosmode); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } /* The set is across all open files on this dev/inode pair. */ -- 2.11.4.GIT