1
0
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:
Jeremy Allison
-
parent 20a4167599
commit a58d0f91f9
5 changed files with 184 additions and 83 deletions

View File

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