/*
* 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
#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 <assert.h>
#include <pwd.h>
#include <grp.h>
+#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"
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[] )
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)
(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( );
#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( );
{
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 );
}
Channel_Exit( );
Lists_Exit( );
Log_Exit( );
+
+ Pidfile_Delete( );
}
return 0;
Show_Version( VOID )
{
puts( NGIRCd_Version( ));
- puts( "Copyright (c)2001-2004 by Alexander Barton (<alex@barton.de>)." );
+ puts( "Copyright (c)2001-2005 by Alexander Barton (<alex@barton.de>)." );
puts( "Homepage: <http://arthur.ath.cx/~alex/ngircd/>\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." );
} /* 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- */