summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorChristof Schmitt <cs@samba.org>2018-11-02 12:08:23 -0700
committerChristof Schmitt <cs@samba.org>2018-11-03 03:01:25 +0100
commit162a5257c48f20d3752f644e86c9e626b46436c0 (patch)
treef30abf61d327922c72ed919948e03ad2fe409ba2 /source3
parentdc9bbbe4141d8425e66fe9290ff611845f4bd1ce (diff)
downloadsamba-162a5257c48f20d3752f644e86c9e626b46436c0.tar.gz
smbd: Fix DELETE_ON_CLOSE behaviour on files with READ_ONLY attribute
MS-FSA states that a CREATE with FILE_DELETE_ON_CLOSE on an existing file with READ_ONLY attribute has to return STATUS_CANNOT_DELETE. This was missing in smbd as the check used the DOS attributes from the CREATE instead of the DOS attributes on the existing file. We need to handle the new file and existing file cases separately. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13673 Signed-off-by: Christof Schmitt <cs@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/open.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index d6359aac0c6..a323a42609e 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3280,6 +3280,18 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
request_time = fsp->open_time;
}
+ if ((create_options & FILE_DELETE_ON_CLOSE) &&
+ (flags2 & O_CREAT) &&
+ !file_existed) {
+ /* Delete on close semantics for new files. */
+ status = can_set_delete_on_close(fsp,
+ new_dos_attributes);
+ if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ return status;
+ }
+ }
+
/*
* Ensure we pay attention to default ACLs on directories if required.
*/
@@ -3732,15 +3744,17 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
/* Handle strange delete on close create semantics. */
if (create_options & FILE_DELETE_ON_CLOSE) {
+ if (!new_file_created) {
+ status = can_set_delete_on_close(fsp,
+ existing_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. */
- del_share_mode(lck, fsp);
- TALLOC_FREE(lck);
- fd_close(fsp);
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Remember to delete the mode we just added. */
+ del_share_mode(lck, fsp);
+ TALLOC_FREE(lck);
+ fd_close(fsp);
+ return status;
+ }
}
/* Note that here we set the *inital* delete on close flag,
not the regular one. The magic gets handled in close. */