diff options
author | Jeremy Allison <jra@samba.org> | 2004-10-16 03:04:40 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:52:59 -0500 |
commit | 2efbc238d4f32e810f42393ea2f1f022030d97c5 (patch) | |
tree | ce575e08882febb73ca85ad59417cb2c47711d54 /source3/smbd | |
parent | 9e4b000b1265c22a975877da6b1945925f680698 (diff) | |
download | samba-2efbc238d4f32e810f42393ea2f1f022030d97c5.tar.gz samba-2efbc238d4f32e810f42393ea2f1f022030d97c5.tar.bz2 samba-2efbc238d4f32e810f42393ea2f1f022030d97c5.zip |
r3002: Fix for bug #1886 - prevent delete on close being set
for readonly files (and return the correct error code).
We now pass the Samba4 test suite on this.
Jeremy.
(This used to be commit 6ae417f12cc6f8d2ad00bea27ce0a20242f76325)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/open.c | 16 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 45 |
2 files changed, 43 insertions, 18 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 6d559ac828..55970493fa 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1409,9 +1409,17 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", } if (delete_on_close) { - NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close); + uint32 dosmode = existing_dos_mode; + NTSTATUS result; + + if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) { + dosmode = new_dos_mode; + } + result = set_delete_on_close_internal(fsp, delete_on_close, dosmode); if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) { + uint8 u_e_c; + uint32 u_e_code; /* Remember to delete the mode we just added. */ if (add_share_mode) { del_share_mode(fsp, NULL); @@ -1419,6 +1427,10 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", unlock_share_entry_fsp(fsp); fd_close(conn,fsp); file_free(fsp); + ntstatus_to_dos(result, &u_e_c, &u_e_code); + unix_ERR_ntstatus = result; + unix_ERR_class = u_e_c; + unix_ERR_code = u_e_code; return NULL; } } @@ -1651,7 +1663,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST string_set(&fsp->fsp_name,fname); if (delete_on_close) { - NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close); + NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close, 0); if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) { file_free(fsp); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 31a74ae482..9b1f2aa210 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2811,25 +2811,38 @@ static int call_trans2qfilepathinfo(connection_struct *conn, open_file_shared. JRA. ****************************************************************************/ -NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close) +NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode) { - /* - * Only allow delete on close for writable shares. - */ + if (delete_on_close) { + /* + * Only allow delete on close for writable files. + */ - if (delete_on_close && !CAN_WRITE(fsp->conn)) { - DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n", + if (dosmode & aRONLY) { + DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n", fsp->fsp_name )); - return NT_STATUS_ACCESS_DENIED; - } - /* - * Only allow delete on close for files/directories opened with delete intent. - */ + return NT_STATUS_CANNOT_DELETE; + } + + /* + * Only allow delete on close for writable shares. + */ - if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) { - DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n", + if (!CAN_WRITE(fsp->conn)) { + DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n", fsp->fsp_name )); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; + } + + /* + * Only allow delete on close for files/directories opened with delete intent. + */ + + if (!(fsp->desired_access & DELETE_ACCESS)) { + DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; + } } if(fsp->is_directory) { @@ -2866,7 +2879,7 @@ NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close) return NT_STATUS_ACCESS_DENIED; if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) { - DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n", + DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n", fsp->fsp_name )); unlock_share_entry_fsp(fsp); return NT_STATUS_ACCESS_DENIED; @@ -3286,7 +3299,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, if (fsp == NULL) return(UNIXERROR(ERRDOS,ERRbadfid)); - status = set_delete_on_close_internal(fsp, delete_on_close); + status = set_delete_on_close_internal(fsp, delete_on_close, dosmode); if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) return ERROR_NT(status); |