X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fngircd.c;h=89b2f7f8b0362406c0bbb2909bb77a52bc389f4a;hp=8fbdba3f78ab017aa1bdb32848ab1fb2cadc3b1b;hb=112102b10ce991340ba56e272e32bc50a73e1b05;hpb=e9b0ec9148ac8579eca9c4c387a6daa1a1c94b98 diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 8fbdba3f..89b2f7f8 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2004 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2005 by Alexander Barton (alex@barton.de) * * 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 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: ngircd.c,v 1.83 2004/01/19 21:54:59 alex Exp $"; +static char UNUSED id[] = "$Id: ngircd.c,v 1.88 2005/02/04 14:24:21 alex Exp $"; #include "imp.h" #include @@ -31,13 +31,13 @@ static char UNUSED id[] = "$Id: ngircd.c,v 1.83 2004/01/19 21:54:59 alex Exp $"; #include #include +#include "defines.h" #include "resolve.h" #include "conn.h" #include "client.h" #include "channel.h" #include "conf.h" #include "cvs-version.h" -#include "defines.h" #include "lists.h" #include "log.h" #include "parse.h" @@ -57,6 +57,9 @@ LOCAL VOID Signal_Handler PARAMS(( INT Signal )); LOCAL VOID Show_Version PARAMS(( VOID )); LOCAL VOID Show_Help PARAMS(( VOID )); +LOCAL VOID Pidfile_Create PARAMS(( LONG )); +LOCAL VOID Pidfile_Delete PARAMS(( VOID )); + GLOBAL int main( int argc, const char *argv[] ) @@ -228,6 +231,38 @@ main( int argc, const char *argv[] ) while( ! NGIRCd_SignalQuit ) { + /* Initialize global variables */ + NGIRCd_Start = time( NULL ); + (VOID)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start )); + + NGIRCd_SignalRehash = FALSE; + NGIRCd_SignalRestart = FALSE; + NGIRCd_SignalQuit = FALSE; + + /* Initialize modules, part I */ + Log_Init( ); + Conf_Init( ); + + if( Conf_Chroot[0] ) + { + /* Chroot */ + if( chdir( Conf_Chroot ) != 0 ) Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno )); + + if( chroot( Conf_Chroot ) != 0 ) Log( LOG_ERR, "Can't change root directory to \"%s\": %s", Conf_Chroot, strerror( errno )); + else Log( LOG_INFO, "Changed root and working directory to \"%s\".", Conf_Chroot ); + } + + if( Conf_GID != 0 ) + { + /* Set new group ID */ + if( setgid( Conf_GID ) != 0 ) Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno )); + } + if( Conf_UID != 0 ) + { + /* Set new user ID */ + if( setuid( Conf_UID ) != 0 ) Log( LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror( errno )); + } + /* In der Regel wird ein Sub-Prozess ge-fork()'t, der * nicht mehr mit dem Terminal verbunden ist. Mit der * Option "--nodaemon" kann dies (z.B. zum Debuggen) @@ -252,18 +287,33 @@ main( int argc, const char *argv[] ) (VOID)setsid( ); chdir( "/" ); } - - /* Globale Variablen initialisieren */ - NGIRCd_Start = time( NULL ); - (VOID)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start )); - NGIRCd_SignalRehash = FALSE; - NGIRCd_SignalRestart = FALSE; - NGIRCd_SignalQuit = FALSE; - /* Module initialisieren */ - Log_Init( ); + /* Create PID file */ + pid = (LONG) getpid( ); + Pidfile_Create( pid ); + + /* Show user, group, and PID of the running daemon */ + pwd = getpwuid( getuid( )); grp = getgrgid( getgid( )); + Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.", pwd ? pwd->pw_name : "unknown", (LONG)getuid( ), grp ? grp->gr_name : "unknown", (LONG)getgid( ), pid); + + /* Change working directory to home directory of the user + * we are running as (when not running chroot()'ed!) */ + if( Conf_UID != 0 && ! Conf_Chroot[0] ) + { + struct passwd *pwd; + + pwd = getpwuid( Conf_UID ); + if( pwd != NULL ) + { + if( chdir( pwd->pw_dir ) == 0 ) Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir ); + else Log( LOG_ERR, "Can't change working directory to \"%s\": %s", pwd->pw_dir, strerror( errno )); + } + else Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID ); + } + + /* Initialize modules, part II: these functions are eventually + * called with already dropped privileges ... */ Resolve_Init( ); - Conf_Init( ); Lists_Init( ); Channel_Init( ); Client_Init( ); @@ -272,28 +322,11 @@ main( int argc, const char *argv[] ) #endif Conn_Init( ); - /* Wenn als root ausgefuehrt und eine andere UID - * konfiguriert ist, jetzt zu dieser wechseln */ - if( getuid( ) == 0 ) - { - if( Conf_GID != 0 ) - { - /* Neue Group-ID setzen */ - if( setgid( Conf_GID ) != 0 ) Log( LOG_ERR, "Can't change Group-ID to %u: %s", Conf_GID, strerror( errno )); - } - if( Conf_UID != 0 ) - { - /* Neue User-ID setzen */ - if( setuid( Conf_UID ) != 0 ) Log( LOG_ERR, "Can't change User-ID to %u: %s", Conf_UID, strerror( errno )); - } - } - - /* User, Gruppe und Prozess-ID des Daemon ausgeben */ - pwd = getpwuid( getuid( )); grp = getgrgid( getgid( )); - Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.", pwd ? pwd->pw_name : "unknown", (LONG)getuid( ), grp ? grp->gr_name : "unknown", (LONG)getgid( ), (LONG)getpid( )); - - /* stderr in "Error-File" umlenken */ - Log_InitErrorfile( ); + /* Redirect stderr handle to "error file" for debugging. + * But don't try to write in the chroot jail, since it's more + * secure to have a chroot dir not writable by the daemon. + */ + if( ! Conf_Chroot[0] ) Log_InitErrorfile( ); /* Signal-Handler initialisieren */ Initialize_Signal_Handler( ); @@ -324,6 +357,7 @@ main( int argc, const char *argv[] ) { Log( LOG_ALERT, "Server isn't listening on a single port!" ); Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); + Pidfile_Delete( ); exit( 1 ); } @@ -339,6 +373,8 @@ main( int argc, const char *argv[] ) Channel_Exit( ); Lists_Exit( ); Log_Exit( ); + + Pidfile_Delete( ); } return 0; @@ -534,7 +570,7 @@ LOCAL VOID Show_Version( VOID ) { puts( NGIRCd_Version( )); - puts( "Copyright (c)2001-2004 by Alexander Barton ()." ); + puts( "Copyright (c)2001-2005 by Alexander Barton ()." ); puts( "Homepage: \n" ); puts( "This is free software; see the source for copying conditions. There is NO" ); puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ); @@ -559,4 +595,47 @@ Show_Help( VOID ) } /* Show_Help */ +LOCAL VOID +Pidfile_Delete( VOID ) +{ + /* Pidfile configured? */ + if( ! Conf_PidFile[0] ) return; + +#ifdef DEBUG + Log( LOG_DEBUG, "Removing PID file (%s) ...", Conf_PidFile ); +#endif + + if( unlink( Conf_PidFile )) + Log( LOG_ERR, "Error unlinking PID file (%s): %s", Conf_PidFile, strerror( errno )); +} /* Pidfile_Delete */ + + +LOCAL VOID +Pidfile_Create( LONG pid ) +{ + FILE *pidf; + + /* Pidfile configured? */ + if( ! Conf_PidFile[0] ) return; + + pidf = fopen( Conf_PidFile, "w" ); + +#ifdef DEBUG + Log( LOG_DEBUG, "Creating PID file (%s) ...", Conf_PidFile ); +#endif + + if( ! pidf ) + { + Log( LOG_ERR, "Error writing PID file (%s): %s", Conf_PidFile, strerror( errno )); + return; + } + + if( fprintf( pidf, "%ld\n", pid ) < 0 ) + Log( LOG_ERR, "Can't write PID file (%s): %s", Conf_PidFile, strerror( errno )); + + if( fclose(pidf) != 0 ) + Log( LOG_ERR, "Error closing PID file (%s): %s", Conf_PidFile, strerror( errno )); +} /* Pidfile_Create */ + + /* -eof- */