2010-05-13 01:48:04 +04:00
/*
Unix SMB / CIFS implementation .
Main SMB server routines
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Martin Pool 2002
Copyright ( C ) Jelmer Vernooij 2002 - 2003
Copyright ( C ) Volker Lendecke 1993 - 2007
Copyright ( C ) Jeremy Allison 1993 - 2007
Copyright ( C ) Andrew Bartlett 2010
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2010-05-13 01:48:04 +04:00
# include "smbd/globals.h"
2011-05-02 15:21:53 +04:00
# include "ntdomain.h"
2010-12-20 13:42:17 +03:00
# include "../librpc/gen_ndr/srv_dfs.h"
# include "../librpc/gen_ndr/srv_dssetup.h"
# include "../librpc/gen_ndr/srv_echo.h"
# include "../librpc/gen_ndr/srv_eventlog.h"
# include "../librpc/gen_ndr/srv_initshutdown.h"
# include "../librpc/gen_ndr/srv_lsa.h"
# include "../librpc/gen_ndr/srv_netlogon.h"
# include "../librpc/gen_ndr/srv_ntsvcs.h"
# include "../librpc/gen_ndr/srv_samr.h"
# include "../librpc/gen_ndr/srv_spoolss.h"
# include "../librpc/gen_ndr/srv_srvsvc.h"
# include "../librpc/gen_ndr/srv_svcctl.h"
# include "../librpc/gen_ndr/srv_winreg.h"
# include "../librpc/gen_ndr/srv_wkssvc.h"
2011-02-22 12:28:29 +03:00
# include "printing/notify.h"
2011-02-22 21:24:31 +03:00
# include "printing.h"
2011-02-25 01:05:57 +03:00
# include "serverid.h"
2011-12-15 14:51:20 +04:00
# include "messages.h"
2012-07-20 03:36:18 +04:00
# include "../lib/util/pidfile.h"
2010-12-20 13:42:17 +03:00
2010-05-13 01:48:04 +04:00
static struct files_struct * log_writeable_file_fn (
struct files_struct * fsp , void * private_data )
{
bool * found = ( bool * ) private_data ;
char * path ;
if ( ! fsp - > can_write ) {
return NULL ;
}
if ( ! ( * found ) ) {
DEBUG ( 0 , ( " Writable files open at exit: \n " ) ) ;
* found = true ;
}
path = talloc_asprintf ( talloc_tos ( ) , " %s/%s " , fsp - > conn - > connectpath ,
smb_fname_str_dbg ( fsp - > fsp_name ) ) ;
if ( path = = NULL ) {
DEBUGADD ( 0 , ( " <NOMEM> \n " ) ) ;
}
DEBUGADD ( 0 , ( " %s \n " , path ) ) ;
TALLOC_FREE ( path ) ;
return NULL ;
}
/****************************************************************************
Exit the server .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Reasons for shutting down a server process. */
enum server_exit_reason { SERVER_EXIT_NORMAL , SERVER_EXIT_ABNORMAL } ;
static void exit_server_common ( enum server_exit_reason how ,
2012-05-22 15:18:06 +04:00
const char * reason ) _NORETURN_ ;
2010-05-13 01:48:04 +04:00
static void exit_server_common ( enum server_exit_reason how ,
2012-05-22 15:18:06 +04:00
const char * reason )
2010-05-13 01:48:04 +04:00
{
2012-05-24 15:46:11 +04:00
struct smbXsrv_connection * conn = global_smbXsrv_connection ;
struct smbd_server_connection * sconn = NULL ;
2012-05-31 17:28:11 +04:00
struct messaging_context * msg_ctx = server_messaging_context ( ) ;
2012-05-24 15:46:11 +04:00
if ( conn ! = NULL ) {
sconn = conn - > sconn ;
}
2010-05-13 01:48:04 +04:00
if ( ! exit_firsttime )
exit ( 0 ) ;
exit_firsttime = false ;
change_to_root_user ( ) ;
if ( sconn & & sconn - > smb1 . negprot . auth_context ) {
2010-07-17 02:23:55 +04:00
TALLOC_FREE ( sconn - > smb1 . negprot . auth_context ) ;
2010-05-13 01:48:04 +04:00
}
if ( sconn ) {
2012-05-22 15:18:06 +04:00
NTSTATUS status ;
2010-09-27 05:53:00 +04:00
if ( lp_log_writeable_files_on_exit ( ) ) {
bool found = false ;
files_forall ( sconn , log_writeable_file_fn , & found ) ;
}
2012-05-22 15:18:06 +04:00
/*
* Note : this is a no - op for smb2 as
* conn - > tcon_table is empty
*/
status = smb1srv_tcon_disconnect_all ( conn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Server exit (%s) \n " ,
( reason ? reason : " normal exit " ) ) ) ;
DEBUG ( 0 , ( " exit_server_common: "
" smb1srv_tcon_disconnect_all() failed (%s) - "
" triggering cleanup \n " , nt_errstr ( status ) ) ) ;
how = SERVER_EXIT_ABNORMAL ;
reason = " smb1srv_tcon_disconnect_all failed " ;
}
status = smbXsrv_session_logoff_all ( conn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Server exit (%s) \n " ,
( reason ? reason : " normal exit " ) ) ) ;
DEBUG ( 0 , ( " exit_server_common: "
" smbXsrv_session_logoff_all() failed (%s) - "
" triggering cleanup \n " , nt_errstr ( status ) ) ) ;
how = SERVER_EXIT_ABNORMAL ;
reason = " smbXsrv_session_logoff_all failed " ;
}
change_to_root_user ( ) ;
2010-05-13 01:48:04 +04:00
}
/* 3 second timeout. */
2012-05-31 17:28:11 +04:00
print_notify_send_messages ( msg_ctx , 3 ) ;
2010-05-13 01:48:04 +04:00
/* delete our entry in the serverid database. */
2010-07-04 15:46:48 +04:00
if ( am_parent ) {
/*
* For children the parent takes care of cleaning up
*/
2012-05-31 17:28:11 +04:00
serverid_deregister ( messaging_server_id ( msg_ctx ) ) ;
2010-07-04 15:46:48 +04:00
}
2010-05-13 01:48:04 +04:00
# ifdef WITH_DFS
if ( dcelogin_atmost_once ) {
dfs_unlogin ( ) ;
}
# endif
# ifdef USE_DMAPI
/* Destroy Samba DMAPI session only if we are master smbd process */
if ( am_parent ) {
if ( ! dmapi_destroy_session ( ) ) {
DEBUG ( 0 , ( " Unable to close Samba DMAPI session \n " ) ) ;
}
}
# endif
2010-12-20 13:42:17 +03:00
if ( am_parent ) {
rpc_wkssvc_shutdown ( ) ;
rpc_dssetup_shutdown ( ) ;
2011-01-04 18:53:33 +03:00
# ifdef DEVELOPER
2010-12-20 13:42:17 +03:00
rpc_rpcecho_shutdown ( ) ;
2011-01-04 18:53:33 +03:00
# endif
2010-12-20 13:42:17 +03:00
rpc_netdfs_shutdown ( ) ;
rpc_initshutdown_shutdown ( ) ;
rpc_eventlog_shutdown ( ) ;
rpc_ntsvcs_shutdown ( ) ;
rpc_svcctl_shutdown ( ) ;
rpc_spoolss_shutdown ( ) ;
rpc_srvsvc_shutdown ( ) ;
rpc_winreg_shutdown ( ) ;
rpc_netlogon_shutdown ( ) ;
rpc_samr_shutdown ( ) ;
rpc_lsarpc_shutdown ( ) ;
}
2010-05-13 01:48:04 +04:00
/*
* we need to force the order of freeing the following ,
* because smbd_msg_ctx is not a talloc child of smbd_server_conn .
*/
sconn = NULL ;
2012-05-24 15:46:11 +04:00
conn = NULL ;
TALLOC_FREE ( global_smbXsrv_connection ) ;
2010-06-10 19:54:00 +04:00
server_messaging_context_free ( ) ;
server_event_context_free ( ) ;
2010-06-11 00:17:35 +04:00
TALLOC_FREE ( smbd_memcache_ctx ) ;
2010-05-13 01:48:04 +04:00
2011-07-04 19:55:54 +04:00
locking_end ( ) ;
printing_end ( ) ;
2010-05-13 01:48:04 +04:00
if ( how ! = SERVER_EXIT_NORMAL ) {
DEBUGSEP ( 0 ) ;
DEBUG ( 0 , ( " Abnormal server exit: %s \n " ,
reason ? reason : " no explanation provided " ) ) ;
DEBUGSEP ( 0 ) ;
log_stack_trace ( ) ;
dump_core ( ) ;
2012-05-31 23:35:04 +04:00
/* Notreached. */
exit ( 1 ) ;
2010-05-13 01:48:04 +04:00
} else {
DEBUG ( 3 , ( " Server exit (%s) \n " ,
( reason ? reason : " normal exit " ) ) ) ;
if ( am_parent ) {
2012-07-20 03:36:18 +04:00
pidfile_unlink ( lp_piddir ( ) , " smbd " ) ;
2010-05-13 01:48:04 +04:00
}
gencache_stabilize ( ) ;
}
2012-05-31 23:35:04 +04:00
exit ( 0 ) ;
2010-05-13 01:48:04 +04:00
}
void exit_server ( const char * const explanation )
{
exit_server_common ( SERVER_EXIT_ABNORMAL , explanation ) ;
}
void exit_server_cleanly ( const char * const explanation )
{
exit_server_common ( SERVER_EXIT_NORMAL , explanation ) ;
}