mirror of
https://github.com/samba-team/samba.git
synced 2025-12-02 00:23:50 +03:00
Fixed delete on close bug. Added core dump code to winbindd.
Jeremy.
This commit is contained in:
@@ -1671,6 +1671,90 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
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_shared. JRA.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
|
||||
{
|
||||
/*
|
||||
* Only allow delete on close for files/directories opened with delete intent.
|
||||
*/
|
||||
|
||||
if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
|
||||
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) {
|
||||
fsp->directory_delete_on_close = 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 if(fsp->stat_open) {
|
||||
|
||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Reply to a TRANS2_SETFILEINFO (set file info by fileid).
|
||||
****************************************************************************/
|
||||
@@ -1931,6 +2015,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
|
||||
{
|
||||
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
|
||||
NTSTATUS status;
|
||||
|
||||
if (tran_call != TRANSACT2_SETFILEINFO)
|
||||
return ERROR_DOS(ERRDOS,ERRunknownlevel);
|
||||
@@ -1938,78 +2023,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
if (fsp == NULL)
|
||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||
|
||||
/*
|
||||
* Only allow delete on close for files/directories opened with delete intent.
|
||||
*/
|
||||
|
||||
if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
|
||||
DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
|
||||
fsp->fsp_name ));
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
if(fsp->is_directory) {
|
||||
fsp->directory_delete_on_close = delete_on_close;
|
||||
DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
} else if(fsp->stat_open) {
|
||||
|
||||
DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %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,("call_trans2setfilepathinfo: %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 ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
|
||||
if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
|
||||
DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
|
||||
fsp->fsp_name ));
|
||||
unlock_share_entry_fsp(fsp);
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user