2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
2005-01-30 03:54:57 +03:00
2003-08-13 05:53:07 +04:00
Main SMB server routines
2005-01-30 03:54:57 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 2005
2003-08-13 05:53:07 +04:00
Copyright ( C ) Martin Pool 2002
Copyright ( C ) Jelmer Vernooij 2002
Copyright ( C ) James J Myers 2003 < myersjj @ samba . org >
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 2 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2005-02-03 14:56:03 +03:00
# include "lib/events/events.h"
2005-01-18 13:10:35 +03:00
# include "version.h"
2004-11-02 05:57:18 +03:00
# include "lib/cmdline/popt_common.h"
2005-01-30 03:54:57 +03:00
# include "system/dir.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2005-10-27 09:33:49 +04:00
# include "system/kerberos.h"
2005-12-26 21:48:23 +03:00
# include "smb_build.h"
2005-12-28 00:11:09 +03:00
# include "registry/registry.h"
2005-12-28 01:51:30 +03:00
# include "ntvfs/ntvfs.h"
2003-08-13 05:53:07 +04:00
2005-01-30 03:54:57 +03:00
/*
2005-07-10 12:06:28 +04:00
recursively delete a directory tree
2005-01-30 03:54:57 +03:00
*/
2005-07-10 12:06:28 +04:00
static void recursive_delete ( const char * path )
2003-08-13 05:53:07 +04:00
{
2005-01-30 03:54:57 +03:00
DIR * dir ;
struct dirent * de ;
2003-08-13 05:53:07 +04:00
2005-01-30 03:54:57 +03:00
dir = opendir ( path ) ;
if ( ! dir ) {
return ;
2003-08-13 05:53:07 +04:00
}
2005-01-30 03:54:57 +03:00
for ( de = readdir ( dir ) ; de ; de = readdir ( dir ) ) {
2005-07-10 12:06:28 +04:00
char * fname ;
struct stat st ;
if ( strcmp ( de - > d_name , " . " ) = = 0 | |
strcmp ( de - > d_name , " .. " ) = = 0 ) {
continue ;
}
fname = talloc_asprintf ( path , " %s/%s " , path , de - > d_name ) ;
if ( stat ( fname , & st ) ! = 0 ) {
continue ;
}
if ( S_ISDIR ( st . st_mode ) ) {
recursive_delete ( fname ) ;
talloc_free ( fname ) ;
continue ;
}
if ( unlink ( fname ) ! = 0 ) {
DEBUG ( 0 , ( " Unabled to delete '%s' - %s \n " ,
fname , strerror ( errno ) ) ) ;
smb_panic ( " unable to cleanup tmp files " ) ;
2005-01-30 03:54:57 +03:00
}
2005-07-10 12:06:28 +04:00
talloc_free ( fname ) ;
2003-08-13 05:53:07 +04:00
}
2005-01-30 03:54:57 +03:00
closedir ( dir ) ;
2005-07-10 12:06:28 +04:00
}
/*
cleanup temporary files . This is the new alternative to
TDB_CLEAR_IF_FIRST . Unfortunately TDB_CLEAR_IF_FIRST is not
efficient on unix systems due to the lack of scaling of the byte
range locking system . So instead of putting the burden on tdb to
cleanup tmp files , this function deletes them .
*/
static void cleanup_tmp_files ( void )
{
char * path ;
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
path = smbd_tmp_path ( mem_ctx , NULL ) ;
2005-01-30 03:54:57 +03:00
2005-07-10 12:06:28 +04:00
recursive_delete ( path ) ;
2005-01-30 03:54:57 +03:00
talloc_free ( mem_ctx ) ;
}
2003-08-13 05:53:07 +04:00
2005-01-30 03:54:57 +03:00
/*
setup signal masks
*/
static void setup_signals ( void )
{
2003-08-13 05:53:07 +04:00
/* we are never interested in SIGPIPE */
BlockSignals ( True , SIGPIPE ) ;
# if defined(SIGFPE)
/* we are never interested in SIGFPE */
BlockSignals ( True , SIGFPE ) ;
# endif
2005-12-15 19:53:20 +03:00
/* We are no longer interested in USR1 */
BlockSignals ( True , SIGUSR1 ) ;
2003-08-13 05:53:07 +04:00
# if defined(SIGUSR2)
/* We are no longer interested in USR2 */
BlockSignals ( True , SIGUSR2 ) ;
# endif
/* POSIX demands that signals are inherited. If the invoking process has
* these signals masked , we will have problems , as we won ' t recieve them . */
BlockSignals ( False , SIGHUP ) ;
BlockSignals ( False , SIGTERM ) ;
2005-01-30 03:54:57 +03:00
2005-12-15 19:53:20 +03:00
/* as we don't handle on this signals yet, we need to ignore them,
* instead of terminating */
CatchSignal ( SIGHUP , SIG_IGN ) ;
}
2005-01-30 03:54:57 +03:00
2005-05-17 10:20:54 +04:00
/*
handle io on stdin
*/
static void server_stdin_handler ( struct event_context * event_ctx , struct fd_event * fde ,
uint16_t flags , void * private )
{
2005-12-15 21:08:25 +03:00
const char * binary_name = private ;
2005-05-17 10:20:54 +04:00
uint8_t c ;
if ( read ( 0 , & c , 1 ) = = 0 ) {
2005-12-15 21:08:25 +03:00
DEBUG ( 0 , ( " %s: EOF on stdin - terminating \n " , binary_name ) ) ;
2005-05-17 10:20:54 +04:00
exit ( 0 ) ;
}
}
2005-06-12 04:17:23 +04:00
/*
die if the user selected maximum runtime is exceeded
*/
static void max_runtime_handler ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private )
{
2005-12-15 21:08:25 +03:00
const char * binary_name = private ;
DEBUG ( 0 , ( " %s: maximum runtime exceeded - terminating \n " , binary_name ) ) ;
2005-06-12 04:17:23 +04:00
exit ( 0 ) ;
}
2005-01-30 03:54:57 +03:00
/*
main server .
*/
2005-12-15 21:08:25 +03:00
static int binary_smbd_main ( const char * binary_name , int argc , const char * argv [ ] )
2005-01-30 03:54:57 +03:00
{
BOOL interactive = False ;
int opt ;
poptContext pc ;
2005-12-26 19:46:55 +03:00
init_module_fn static_init [ ] = STATIC_SERVER_SERVICE_MODULES ;
init_module_fn * shared_init ;
2005-01-30 03:54:57 +03:00
struct event_context * event_ctx ;
NTSTATUS status ;
const char * model = " standard " ;
2005-06-12 04:17:23 +04:00
int max_runtime = 0 ;
2005-01-30 03:54:57 +03:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{ " interactive " , ' i ' , POPT_ARG_VAL , & interactive , True ,
" Run interactive (not a daemon) " , NULL } ,
{ " model " , ' M ' , POPT_ARG_STRING , & model , True ,
" Select process model " , " MODEL " } ,
2005-06-12 04:17:23 +04:00
{ " maximum-runtime " , 0 , POPT_ARG_INT , & max_runtime , True ,
2005-12-15 21:08:25 +03:00
" set maximum runtime of the server process, till autotermination " , " seconds " } ,
2005-06-13 12:12:39 +04:00
POPT_COMMON_SAMBA
2005-01-30 03:54:57 +03:00
POPT_COMMON_VERSION
POPT_TABLEEND
} ;
2005-12-15 21:08:25 +03:00
pc = poptGetContext ( binary_name , argc , argv , long_options , 0 ) ;
2005-01-30 03:54:57 +03:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) /* noop */ ;
poptFreeContext ( pc ) ;
2005-12-16 13:21:05 +03:00
setup_logging ( binary_name , interactive ? DEBUG_STDOUT : DEBUG_FILE ) ;
2005-01-30 03:54:57 +03:00
setup_signals ( ) ;
2003-08-13 05:53:07 +04:00
/* we want total control over the permissions on created files,
so set our umask to 0 */
umask ( 0 ) ;
2005-12-15 21:08:25 +03:00
DEBUG ( 0 , ( " %s version %s started. \n " , binary_name , SAMBA_VERSION_STRING ) ) ;
2005-01-14 04:32:56 +03:00
DEBUGADD ( 0 , ( " Copyright Andrew Tridgell and the Samba Team 1992-2005 \n " ) ) ;
2003-08-13 05:53:07 +04:00
2004-07-14 01:04:56 +04:00
if ( sizeof ( uint16_t ) < 2 | | sizeof ( uint32_t ) < 4 | | sizeof ( uint64_t ) < 8 ) {
2003-08-13 05:53:07 +04:00
DEBUG ( 0 , ( " ERROR: Samba is not configured correctly for the word size on your machine \n " ) ) ;
exit ( 1 ) ;
}
2004-07-14 01:04:56 +04:00
2005-01-30 03:54:57 +03:00
if ( ! interactive ) {
2003-08-13 05:53:07 +04:00
DEBUG ( 3 , ( " Becoming a daemon. \n " ) ) ;
2005-01-30 03:54:57 +03:00
become_daemon ( True ) ;
2003-08-13 05:53:07 +04:00
}
2005-01-30 03:54:57 +03:00
cleanup_tmp_files ( ) ;
2005-02-10 09:36:30 +03:00
if ( ! directory_exist ( lp_lockdir ( ) ) ) {
2003-08-13 05:53:07 +04:00
mkdir ( lp_lockdir ( ) , 0755 ) ;
}
2005-12-15 21:08:25 +03:00
pidfile_create ( binary_name ) ;
2005-01-30 03:54:57 +03:00
/* Do *not* remove this, until you have removed
* passdb / secrets . c , and proved that Samba still builds . . . */
/* Setup the SECRETS subsystem */
if ( ! secrets_init ( ) ) {
exit ( 1 ) ;
2003-08-13 05:53:07 +04:00
}
2005-01-30 03:54:57 +03:00
smbd_init_subsystems ;
2004-04-19 15:21:50 +04:00
2005-12-27 00:58:31 +03:00
registry_init ( ) ; /* FIXME: maybe run this in the initialization function
of the winreg RPC server instead ? */
ntptr_init ( ) ; /* FIXME: maybe run this in the initialization function
of the spoolss RPC server instead ? */
ntvfs_init ( ) ; /* FIXME: maybe run this in the initialization functions
of the SMB [ , 2 ] server instead ? */
process_model_init ( ) ;
2005-12-26 19:46:55 +03:00
shared_init = load_samba_modules ( NULL , " service " ) ;
run_init_functions ( static_init ) ;
run_init_functions ( shared_init ) ;
talloc_free ( shared_init ) ;
2005-01-30 03:54:57 +03:00
/* the event context is the top level structure in smbd. Everything else
should hang off that */
event_ctx = event_context_init ( NULL ) ;
2005-01-14 04:32:56 +03:00
2005-06-07 12:33:17 +04:00
if ( interactive ) {
/* catch EOF on stdin */
2005-06-11 06:50:47 +04:00
# ifdef SIGTTIN
signal ( SIGTTIN , SIG_IGN ) ;
# endif
2005-06-07 12:33:17 +04:00
event_add_fd ( event_ctx , event_ctx , 0 , EVENT_FD_READ ,
2005-12-15 21:08:25 +03:00
server_stdin_handler ,
discard_const ( binary_name ) ) ;
2005-06-07 12:33:17 +04:00
}
2005-05-17 10:20:54 +04:00
2005-06-12 04:17:23 +04:00
if ( max_runtime ) {
event_add_timed ( event_ctx , event_ctx ,
timeval_current_ofs ( max_runtime , 0 ) ,
2005-12-15 21:08:25 +03:00
max_runtime_handler ,
discard_const ( binary_name ) ) ;
2005-06-12 04:17:23 +04:00
}
2005-12-15 21:08:25 +03:00
DEBUG ( 0 , ( " %s: using '%s' process model \n " , binary_name , model ) ) ;
2005-01-30 03:54:57 +03:00
status = server_service_startup ( event_ctx , model , lp_server_services ( ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Starting Services failed - %s \n " , nt_errstr ( status ) ) ) ;
2004-07-14 01:04:56 +04:00
return 1 ;
}
2003-08-13 05:53:07 +04:00
2005-01-30 03:54:57 +03:00
/* wait for events - this is where smbd sits for most of its
life */
event_loop_wait ( event_ctx ) ;
2005-01-14 04:32:56 +03:00
2005-01-30 03:54:57 +03:00
/* as everything hangs off this event context, freeing it
should initiate a clean shutdown of all services */
talloc_free ( event_ctx ) ;
2005-01-14 04:32:56 +03:00
return 0 ;
2004-07-14 01:04:56 +04:00
}
int main ( int argc , const char * argv [ ] )
{
2005-12-15 21:08:25 +03:00
return binary_smbd_main ( " smbd " , argc , argv ) ;
2003-08-13 05:53:07 +04:00
}