From 2df09905f5540fee096d48a92cb0c42558498a12 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 2 Jan 2009 08:57:53 +0000 Subject: * opentracker now drops permissions in correct order and really chroots() if ran as root * lock passing between add_peer_to_torrent and return_peers_for_torrent is now avoided by providing a more general add_peer_to_torrent_and_return_peers function that can be used with NULL parameters to not return any peers (in sync case) * in order to keep a fast overview how many torrents opentracker maintains, every mutex_bucket_unlock operation expects an additional integer parameter that tells ot_mutex.c how many torrents have been added or removed. A function mutex_get_torrent_count has been introduced. --- opentracker.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'opentracker.c') diff --git a/opentracker.c b/opentracker.c index 61acd3f..993877a 100644 --- a/opentracker.c +++ b/opentracker.c @@ -350,8 +350,47 @@ int parse_configfile( char * config_filename ) { return bound; } -int main( int argc, char **argv ) { +int drop_privileges (const char * const serverdir) { struct passwd *pws = NULL; + + /* Grab pws entry before chrooting */ + pws = getpwnam( "nobody" ); + endpwent(); + + if( geteuid() == 0 ) { + /* Running as root: chroot and drop privileges */ + if(chroot( serverdir )) { + fprintf( stderr, "Could not chroot to %s, because: %s\n", serverdir, strerror(errno) ); + return -1; + } + + if(chdir("/")) + panic("chdir() failed after chrooting: "); + + if( !pws ) { + setegid( (gid_t)-2 ); setgid( (gid_t)-2 ); + setuid( (uid_t)-2 ); seteuid( (uid_t)-2 ); + } + else { + setegid( pws->pw_gid ); setgid( pws->pw_gid ); + setuid( pws->pw_uid ); seteuid( pws->pw_uid ); + } + + if( geteuid() == 0 || getegid() == 0 ) + panic("Still running with root privileges?!"); + } + else { + /* Normal user, just chdir() */ + if(chdir( serverdir )) { + fprintf( stderr, "Could not chroot to %s, because: %s\n", serverdir, strerror(errno) ); + return -1; + } + } + + return 0; +} + +int main( int argc, char **argv ) { char serverip[4] = {0,0,0,0}, tmpip[4]; int bound = 0, scanon = 1; uint16_t tmpport; @@ -404,16 +443,8 @@ while( scanon ) { ot_try_bind( serverip, 6969, FLAG_UDP ); } - /* Drop permissions */ - pws = getpwnam( "nobody" ); - if( !pws ) { - setegid( (gid_t)-2 ); setuid( (uid_t)-2 ); - setgid( (gid_t)-2 ); seteuid( (uid_t)-2 ); - } else { - setegid( pws->pw_gid ); setuid( pws->pw_uid ); - setgid( pws->pw_gid ); seteuid( pws->pw_uid ); - } - endpwent(); + if( drop_privileges( g_serverdir ? g_serverdir : "." ) == -1 ) + panic( "drop_privileges failed, exiting. Last error"); signal( SIGPIPE, SIG_IGN ); signal( SIGINT, signal_handler ); @@ -421,9 +452,10 @@ while( scanon ) { g_now_seconds = time( NULL ); - if( trackerlogic_init( g_serverdir ? g_serverdir : "." ) == -1 ) - panic( "Logic not started" ); + /* Init all sub systems. This call may fail with an exit() */ + trackerlogic_init( ); + /* Kick off our initial clock setting alarm */ alarm(5); server_mainloop( ); -- cgit v1.2.3