mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
Fixed delete on close bug. Added core dump code to winbindd.
Jeremy. (This used to be commit a58d0f91f9ee7354c01a9c20cfe178d5dc02142d)
This commit is contained in:
parent
d2e279ecf2
commit
d05bbf0422
@ -23,6 +23,8 @@
|
||||
|
||||
#include "winbindd.h"
|
||||
|
||||
extern pstring debugf;
|
||||
|
||||
/* List of all connected clients */
|
||||
|
||||
struct winbindd_cli_state *client_list;
|
||||
@ -53,6 +55,57 @@ static BOOL reload_services_file(BOOL test)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#if DUMP_CORE
|
||||
|
||||
/**************************************************************************** **
|
||||
Prepare to dump a core file - carefully!
|
||||
**************************************************************************** */
|
||||
|
||||
static BOOL dump_core(void)
|
||||
{
|
||||
char *p;
|
||||
pstring dname;
|
||||
pstrcpy( dname, debugf );
|
||||
if ((p=strrchr(dname,'/')))
|
||||
*p=0;
|
||||
pstrcat( dname, "/corefiles" );
|
||||
mkdir( dname, 0700 );
|
||||
sys_chown( dname, getuid(), getgid() );
|
||||
chmod( dname, 0700 );
|
||||
if ( chdir(dname) )
|
||||
return( False );
|
||||
umask( ~(0700) );
|
||||
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
#ifdef RLIMIT_CORE
|
||||
{
|
||||
struct rlimit rlp;
|
||||
getrlimit( RLIMIT_CORE, &rlp );
|
||||
rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
|
||||
setrlimit( RLIMIT_CORE, &rlp );
|
||||
getrlimit( RLIMIT_CORE, &rlp );
|
||||
DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DEBUG(0,("Dumping core in %s\n",dname));
|
||||
abort();
|
||||
return( True );
|
||||
} /* dump_core */
|
||||
#endif
|
||||
|
||||
/**************************************************************************** **
|
||||
Handle a fault..
|
||||
**************************************************************************** */
|
||||
|
||||
static void fault_quit(void)
|
||||
{
|
||||
#if DUMP_CORE
|
||||
dump_core();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void winbindd_status(void)
|
||||
{
|
||||
struct winbindd_cli_state *tmp;
|
||||
@ -672,7 +725,6 @@ struct winbindd_state server_state; /* Server state information */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern pstring global_myname;
|
||||
extern pstring debugf;
|
||||
int accept_sock;
|
||||
BOOL interactive = False;
|
||||
int opt, new_debuglevel = -1;
|
||||
@ -682,6 +734,7 @@ int main(int argc, char **argv)
|
||||
|
||||
CatchSignal(SIGUSR1, SIG_IGN);
|
||||
|
||||
fault_setup((void (*)(void *))fault_quit );
|
||||
snprintf(debugf, sizeof(debugf), "%s/log.winbindd", dyn_LOGFILEBASE);
|
||||
|
||||
/* Initialise for running in non-root mode */
|
||||
@ -735,6 +788,10 @@ int main(int argc, char **argv)
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
|
||||
DEBUGADD( 1, ( "Copyright The Samba Team 2000-2001\n" ) );
|
||||
|
||||
if (!reload_services_file(False)) {
|
||||
DEBUG(0, ("error opening config file\n"));
|
||||
exit(1);
|
||||
|
@ -119,8 +119,7 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
|
||||
|
||||
/* Skip own domain */
|
||||
|
||||
if (strequal(domain->name, lp_workgroup()))
|
||||
continue;
|
||||
if (strequal(domain->name, lp_workgroup())) continue;
|
||||
|
||||
/* Add domain to list */
|
||||
|
||||
|
@ -330,7 +330,7 @@ static int map_create_disposition( uint32 create_disposition)
|
||||
Utility function to map share modes.
|
||||
****************************************************************************/
|
||||
|
||||
static int map_share_mode( BOOL *pstat_open_only, char *fname,
|
||||
static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_options,
|
||||
uint32 desired_access, uint32 share_access, uint32 file_attributes)
|
||||
{
|
||||
int smb_open_mode = -1;
|
||||
@ -423,6 +423,13 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
|
||||
DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = %x\n", smb_open_mode));
|
||||
}
|
||||
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
/* Implicit delete access requested... */
|
||||
smb_open_mode |= DELETE_ACCESS_REQUESTED;
|
||||
smb_open_mode |= DELETE_ON_CLOSE_FLAG;
|
||||
DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = %x\n", smb_open_mode));
|
||||
}
|
||||
|
||||
/* Add in the requested share mode. */
|
||||
switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
|
||||
case FILE_SHARE_READ:
|
||||
@ -650,7 +657,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
||||
*/
|
||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||
|
||||
if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access,
|
||||
if((smb_open_mode = map_share_mode(&stat_open_only, fname, create_options, desired_access,
|
||||
share_access,
|
||||
file_attributes)) == -1) {
|
||||
END_PROFILE(SMBntcreateX);
|
||||
@ -681,7 +688,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
||||
if(create_options & FILE_DIRECTORY_FILE) {
|
||||
oplock_request = 0;
|
||||
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
@ -749,7 +756,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
||||
}
|
||||
|
||||
oplock_request = 0;
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
@ -1157,7 +1164,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
||||
* and the share access.
|
||||
*/
|
||||
|
||||
if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
|
||||
if((smb_open_mode = map_share_mode( &stat_open_only, fname, create_options, desired_access,
|
||||
share_access, file_attributes)) == -1)
|
||||
return ERROR_DOS(ERRDOS,ERRbadaccess);
|
||||
|
||||
@ -1190,7 +1197,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
||||
* CreateDirectory() call.
|
||||
*/
|
||||
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
@ -1226,7 +1233,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
||||
}
|
||||
|
||||
oplock_request = 0;
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||
fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
|
@ -618,6 +618,7 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
|
||||
int deny_mode = GET_DENY_MODE(share_mode);
|
||||
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
|
||||
BOOL delete_access_requested = GET_DELETE_ACCESS_REQUESTED(share_mode);
|
||||
BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
|
||||
BOOL file_existed = VALID_STAT(*psbuf);
|
||||
BOOL fcbopen = False;
|
||||
SMB_DEV_T dev = 0;
|
||||
@ -905,6 +906,17 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
|
||||
|
||||
set_share_mode(fsp, port, oplock_request);
|
||||
|
||||
if (delete_on_close) {
|
||||
NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
|
||||
|
||||
if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
|
||||
unlock_share_entry_fsp(fsp);
|
||||
fd_close(conn,fsp);
|
||||
file_free(fsp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_share_entry_fsp(fsp);
|
||||
|
||||
conn->num_files_open++;
|
||||
@ -1019,11 +1031,12 @@ int close_file_fchmod(files_struct *fsp)
|
||||
****************************************************************************/
|
||||
|
||||
files_struct *open_directory(connection_struct *conn, char *fname,
|
||||
SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action)
|
||||
SMB_STRUCT_STAT *psbuf, int share_mode, int smb_ofun, mode_t unixmode, int *action)
|
||||
{
|
||||
extern struct current_user current_user;
|
||||
BOOL got_stat = False;
|
||||
files_struct *fsp = file_new(conn);
|
||||
BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
|
||||
|
||||
if(!fsp)
|
||||
return NULL;
|
||||
@ -1126,6 +1139,14 @@ files_struct *open_directory(connection_struct *conn, char *fname,
|
||||
fsp->conn = conn;
|
||||
string_set(&fsp->fsp_name,fname);
|
||||
|
||||
if (delete_on_close) {
|
||||
NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
|
||||
|
||||
if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
|
||||
file_free(fsp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
conn->num_files_open++;
|
||||
|
||||
return fsp;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user