1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-04 08:22:08 +03:00

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 commit is contained in:
Jeremy Allison
2004-10-16 03:04:40 +00:00
committed by Gerald (Jerry) Carter
parent c3e87f9fa5
commit 6ae417f12c
2 changed files with 43 additions and 18 deletions

View File

@ -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);

View File

@ -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;
}
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",
/*
* Only allow delete on close for writable shares.
*/
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);