mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Fix delete on close semantics to match W2K. I (think:-) I understand it now :-).
Thanks to Nir Livni <nirl@cyber-ark.com> for giving me the test case to track it down. Jeremy.
This commit is contained in:
parent
041a1dd543
commit
41894489e8
@ -145,6 +145,22 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
||||
*/
|
||||
|
||||
lock_share_entry_fsp(fsp);
|
||||
|
||||
if (fsp->delete_on_close) {
|
||||
|
||||
/*
|
||||
* Modify the share mode entry for all files open
|
||||
* on this device and inode to tell other smbds we have
|
||||
* changed the delete on close flag. The last closer will delete the file
|
||||
* if flag is set.
|
||||
*/
|
||||
|
||||
NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close);
|
||||
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
|
||||
DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n",
|
||||
fsp->fsp_name ));
|
||||
}
|
||||
|
||||
share_entry_count = del_share_mode(fsp, &share_entry);
|
||||
|
||||
DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
|
||||
|
@ -2101,62 +2101,42 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
|
||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
} else {
|
||||
|
||||
files_struct *iterate_fsp;
|
||||
|
||||
/*
|
||||
* Modify the share mode entry for all files open
|
||||
* on this device and inode to tell other smbds we have
|
||||
* changed the delete on close flag. This will be noticed
|
||||
* in the close code, the last closer will delete the file
|
||||
* if flag is set.
|
||||
*/
|
||||
|
||||
DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
|
||||
|
||||
if (lock_share_entry_fsp(fsp) == False)
|
||||
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",
|
||||
fsp->fsp_name ));
|
||||
unlock_share_entry_fsp(fsp);
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the lock.
|
||||
*/
|
||||
|
||||
unlock_share_entry_fsp(fsp);
|
||||
|
||||
/*
|
||||
* Go through all files we have open on the same device and
|
||||
* inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
|
||||
* Other smbd's that have this file open will look in the share_mode on close.
|
||||
* take care of this (rare) case in close_file(). See the comment there.
|
||||
* NB. JRA. We don't really need to do this anymore - all should be taken
|
||||
* care of in the share_mode changes in the tdb.
|
||||
*/
|
||||
|
||||
for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
|
||||
iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
|
||||
fsp->delete_on_close = delete_on_close;
|
||||
|
||||
/*
|
||||
* Set the delete on close flag in the fsp.
|
||||
*/
|
||||
fsp->delete_on_close = delete_on_close;
|
||||
|
||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Sets the delete on close flag over all share modes on this file.
|
||||
Modify the share mode entry for all files open
|
||||
on this device and inode to tell other smbds we have
|
||||
changed the delete on close flag. This will be noticed
|
||||
in the close code, the last closer will delete the file
|
||||
if flag is set.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
|
||||
{
|
||||
DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
|
||||
|
||||
if (lock_share_entry_fsp(fsp) == False)
|
||||
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",
|
||||
fsp->fsp_name ));
|
||||
unlock_share_entry_fsp(fsp);
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
unlock_share_entry_fsp(fsp);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Returns true if this pathname is within the share, and thus safe.
|
||||
****************************************************************************/
|
||||
@ -2531,6 +2511,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
|
||||
status = set_delete_on_close_internal(fsp, delete_on_close);
|
||||
|
||||
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
|
||||
return ERROR_NT(status);
|
||||
|
||||
/* The set is across all open files on this dev/inode pair. */
|
||||
status =set_delete_on_close_over_all(fsp, delete_on_close);
|
||||
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
|
||||
return ERROR_NT(status);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user