static void exit_server_common(enum server_exit_reason how, const char *reason) { struct smbXsrv_client *client = global_smbXsrv_client; struct smbXsrv_connection *xconn = NULL; struct smbd_server_connection *sconn = NULL; struct messaging_context *msg_ctx = server_messaging_context(); if (client != NULL) { sconn = client->sconn; /* * Here we typically have just one connection */ xconn = client->connections; } if (!exit_firsttime) exit(0); exit_firsttime = false; change_to_root_user(); if (xconn != NULL) { /* * This is typically the disconnect for the only * (or with multi-channel last) connection of the client */ if (NT_STATUS_IS_OK(xconn->transport.status)) { switch (how) { case SERVER_EXIT_ABNORMAL: xconn->transport.status = NT_STATUS_INTERNAL_ERROR; break; case SERVER_EXIT_NORMAL: xconn->transport.status = NT_STATUS_LOCAL_DISCONNECT; break; } } TALLOC_FREE(xconn->smb1.negprot.auth_context); } change_to_root_user(); if (sconn != NULL) { if (lp_log_writeable_files_on_exit()) { bool found = false; files_forall(sconn, log_writeable_file_fn, &found); } } change_to_root_user(); if (xconn != NULL) { NTSTATUS status; /* * Note: this is a no-op for smb2 as * conn->tcon_table is empty */ status = smb1srv_tcon_disconnect_all(xconn); 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))); } status = smbXsrv_session_logoff_all(xconn); 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))); } } change_to_root_user(); /* 3 second timeout. */ print_notify_send_messages(msg_ctx, 3); #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 if (am_parent) { rpc_wkssvc_shutdown(); rpc_dssetup_shutdown(); #ifdef DEVELOPER rpc_rpcecho_shutdown(); #endif 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(); } /* * we need to force the order of freeing the following, * because smbd_msg_ctx is not a talloc child of smbd_server_conn. */ if (client != NULL) { struct smbXsrv_connection *next; for (; xconn != NULL; xconn = next) { next = xconn->next; DLIST_REMOVE(client->connections, xconn); talloc_free(xconn); DO_PROFILE_INC(disconnect); } TALLOC_FREE(client->sconn); } sconn = NULL; xconn = NULL; client = NULL; netlogon_creds_cli_close_global_db(); TALLOC_FREE(global_smbXsrv_client); smbprofile_dump(); server_messaging_context_free(); server_event_context_free(); TALLOC_FREE(smbd_memcache_ctx); locking_end(); printing_end(); if (how != SERVER_EXIT_NORMAL) { smb_panic(reason); /* Notreached. */ exit(1); } else { DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { pidfile_unlink(lp_pid_directory(), "smbd"); } gencache_stabilize(); } exit(0); }
static void exit_server_common(enum server_exit_reason how, const char *reason) { struct smbXsrv_connection *conn = global_smbXsrv_connection; struct smbd_server_connection *sconn = NULL; struct messaging_context *msg_ctx = server_messaging_context(); if (conn != NULL) { sconn = conn->sconn; } if (!exit_firsttime) exit(0); exit_firsttime = false; change_to_root_user(); if (sconn) { NTSTATUS status; if (NT_STATUS_IS_OK(sconn->status)) { switch (how) { case SERVER_EXIT_ABNORMAL: sconn->status = NT_STATUS_INTERNAL_ERROR; break; case SERVER_EXIT_NORMAL: sconn->status = NT_STATUS_LOCAL_DISCONNECT; break; } } TALLOC_FREE(sconn->smb1.negprot.auth_context); if (lp_log_writeable_files_on_exit()) { bool found = false; files_forall(sconn, log_writeable_file_fn, &found); } /* * 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(); } /* 3 second timeout. */ print_notify_send_messages(msg_ctx, 3); /* delete our entry in the serverid database. */ if (am_parent) { /* * For children the parent takes care of cleaning up */ serverid_deregister(messaging_server_id(msg_ctx)); } #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 if (am_parent) { rpc_wkssvc_shutdown(); rpc_dssetup_shutdown(); #ifdef DEVELOPER rpc_rpcecho_shutdown(); #endif 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(); } /* * 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; conn = NULL; TALLOC_FREE(global_smbXsrv_connection); server_messaging_context_free(); server_event_context_free(); TALLOC_FREE(smbd_memcache_ctx); locking_end(); printing_end(); if (how != SERVER_EXIT_NORMAL) { smb_panic(reason); /* Notreached. */ exit(1); } else { DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { pidfile_unlink(lp_pid_directory(), "smbd"); } gencache_stabilize(); } exit(0); }
static void exit_server_common(enum server_exit_reason how, const char *const reason) { struct smbd_server_connection *sconn = smbd_server_conn; if (!exit_firsttime) exit(0); exit_firsttime = false; change_to_root_user(); if (sconn && sconn->smb1.negprot.auth_context) { TALLOC_FREE(sconn->smb1.negprot.auth_context); } if (sconn) { if (lp_log_writeable_files_on_exit()) { bool found = false; files_forall(sconn, log_writeable_file_fn, &found); } (void)conn_close_all(sconn); invalidate_all_vuids(sconn); } /* 3 second timeout. */ print_notify_send_messages(sconn->msg_ctx, 3); /* delete our entry in the serverid database. */ if (am_parent) { /* * For children the parent takes care of cleaning up */ serverid_deregister(sconn_server_id(sconn)); } #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 if (am_parent) { rpc_wkssvc_shutdown(); #ifdef ACTIVE_DIRECTORY rpc_dssetup_shutdown(); #endif #ifdef DEVELOPER rpc_rpcecho_shutdown(); #endif #ifdef DFS_SUPPORT rpc_netdfs_shutdown(); #endif rpc_initshutdown_shutdown(); #ifdef EXTRA_SERVICES rpc_eventlog_shutdown(); rpc_svcctl_shutdown(); rpc_ntsvcs_shutdown(); #endif #ifdef PRINTER_SUPPORT rpc_spoolss_shutdown(); #endif rpc_srvsvc_shutdown(); #ifdef WINREG_SUPPORT rpc_winreg_shutdown(); #endif #ifdef NETLOGON_SUPPORT rpc_netlogon_shutdown(); #endif #ifdef SAMR_SUPPORT rpc_samr_shutdown(); #endif #ifdef LSA_SUPPORT rpc_lsarpc_shutdown(); #endif } /* * 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; TALLOC_FREE(smbd_server_conn); server_messaging_context_free(); server_event_context_free(); TALLOC_FREE(smbd_memcache_ctx); locking_end(); printing_end(); 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(); /* Notreached. */ exit(1); } else { DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { pidfile_unlink(); } gencache_stabilize(); } exit(0); }