diff options
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/opentracker.c b/opentracker.c index d0ab047..7c368b8 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <stdio.h> | 15 | #include <stdio.h> |
| 16 | #include <pwd.h> | 16 | #include <pwd.h> |
| 17 | #include <ctype.h> | 17 | #include <ctype.h> |
| 18 | #include <pthread.h> | ||
| 18 | 19 | ||
| 19 | /* Libowfat */ | 20 | /* Libowfat */ |
| 20 | #include "socket.h" | 21 | #include "socket.h" |
| @@ -41,6 +42,7 @@ volatile int g_opentracker_running = 1; | |||
| 41 | int g_self_pipe[2]; | 42 | int g_self_pipe[2]; |
| 42 | 43 | ||
| 43 | static char * g_serverdir; | 44 | static char * g_serverdir; |
| 45 | static char * g_serveruser; | ||
| 44 | 46 | ||
| 45 | static void panic( const char *routine ) { | 47 | static void panic( const char *routine ) { |
| 46 | fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); | 48 | fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); |
| @@ -72,7 +74,7 @@ static void defaul_signal_handlers( void ) { | |||
| 72 | sigaddset (&signal_mask, SIGHUP); | 74 | sigaddset (&signal_mask, SIGHUP); |
| 73 | sigaddset (&signal_mask, SIGINT); | 75 | sigaddset (&signal_mask, SIGINT); |
| 74 | sigaddset (&signal_mask, SIGALRM); | 76 | sigaddset (&signal_mask, SIGALRM); |
| 75 | pthread_sigmask (SIG_BLOCK, &signal_mask, NULL); | 77 | pthread_sigmask (SIG_BLOCK, &signal_mask, NULL); |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | static void install_signal_handlers( void ) { | 80 | static void install_signal_handlers( void ) { |
| @@ -88,11 +90,11 @@ static void install_signal_handlers( void ) { | |||
| 88 | 90 | ||
| 89 | sigaddset (&signal_mask, SIGINT); | 91 | sigaddset (&signal_mask, SIGINT); |
| 90 | sigaddset (&signal_mask, SIGALRM); | 92 | sigaddset (&signal_mask, SIGALRM); |
| 91 | pthread_sigmask (SIG_UNBLOCK, &signal_mask, NULL); | 93 | pthread_sigmask (SIG_UNBLOCK, &signal_mask, NULL); |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | static void usage( char *name ) { | 96 | static void usage( char *name ) { |
| 95 | fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-A ip] [-f config] [-s livesyncport]" | 97 | fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip] [-f config] [-s livesyncport]" |
| 96 | #ifdef WANT_ACCESSLIST_BLACK | 98 | #ifdef WANT_ACCESSLIST_BLACK |
| 97 | " [-b blacklistfile]" | 99 | " [-b blacklistfile]" |
| 98 | #elif defined ( WANT_ACCESSLIST_WHITE ) | 100 | #elif defined ( WANT_ACCESSLIST_WHITE ) |
| @@ -111,6 +113,7 @@ static void help( char *name ) { | |||
| 111 | HELPLINE("-P port","specify udp port to bind to (default: 6969, you may specify more than one)"); | 113 | HELPLINE("-P port","specify udp port to bind to (default: 6969, you may specify more than one)"); |
| 112 | HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); | 114 | HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); |
| 113 | HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); | 115 | HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); |
| 116 | HELPLINE("-u user","specify user under whose priviliges opentracker should run (default: \"nobody\")"); | ||
| 114 | HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); | 117 | HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); |
| 115 | #ifdef WANT_ACCESSLIST_BLACK | 118 | #ifdef WANT_ACCESSLIST_BLACK |
| 116 | HELPLINE("-b file","specify blacklist file."); | 119 | HELPLINE("-b file","specify blacklist file."); |
| @@ -382,6 +385,8 @@ int parse_configfile( char * config_filename ) { | |||
| 382 | /* Scan for commands */ | 385 | /* Scan for commands */ |
| 383 | if(!byte_diff(p,15,"tracker.rootdir" ) && isspace(p[15])) { | 386 | if(!byte_diff(p,15,"tracker.rootdir" ) && isspace(p[15])) { |
| 384 | set_config_option( &g_serverdir, p+16 ); | 387 | set_config_option( &g_serverdir, p+16 ); |
| 388 | } else if(!byte_diff(p,12,"tracker.user" ) && isspace(p[12])) { | ||
| 389 | set_config_option( &g_serveruser, p+13 ); | ||
| 385 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { | 390 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { |
| 386 | uint16_t tmpport = 6969; | 391 | uint16_t tmpport = 6969; |
| 387 | if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error; | 392 | if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error; |
| @@ -473,11 +478,18 @@ void load_state(const char * const state_filename ) { | |||
| 473 | fclose( state_filehandle ); | 478 | fclose( state_filehandle ); |
| 474 | } | 479 | } |
| 475 | 480 | ||
| 476 | int drop_privileges (const char * const serverdir) { | 481 | int drop_privileges ( const char * const serveruser, const char * const serverdir ) { |
| 477 | struct passwd *pws = NULL; | 482 | struct passwd *pws = NULL; |
| 478 | 483 | ||
| 484 | #ifdef _DEBUG | ||
| 485 | if( !geteuid() ) | ||
| 486 | fprintf( stderr, "Dropping to user %s.\n", serveruser ); | ||
| 487 | if( serverdir ) | ||
| 488 | fprintf( stderr, "ch%s'ing to directory %s.\n", geteuid() ? "dir" : "root", serverdir ); | ||
| 489 | #endif | ||
| 490 | |||
| 479 | /* Grab pws entry before chrooting */ | 491 | /* Grab pws entry before chrooting */ |
| 480 | pws = getpwnam( "nobody" ); | 492 | pws = getpwnam( serveruser ); |
| 481 | endpwent(); | 493 | endpwent(); |
| 482 | 494 | ||
| 483 | if( geteuid() == 0 ) { | 495 | if( geteuid() == 0 ) { |
| @@ -490,7 +502,9 @@ int drop_privileges (const char * const serverdir) { | |||
| 490 | if(chdir("/")) | 502 | if(chdir("/")) |
| 491 | panic("chdir() failed after chrooting: "); | 503 | panic("chdir() failed after chrooting: "); |
| 492 | 504 | ||
| 505 | /* If we can't find server user, revert to nobody's default uid */ | ||
| 493 | if( !pws ) { | 506 | if( !pws ) { |
| 507 | fprintf( stderr, "Warning: Could not get password entry for %s. Reverting to uid -2.\n", serveruser ); | ||
| 494 | setegid( (gid_t)-2 ); setgid( (gid_t)-2 ); | 508 | setegid( (gid_t)-2 ); setgid( (gid_t)-2 ); |
| 495 | setuid( (uid_t)-2 ); seteuid( (uid_t)-2 ); | 509 | setuid( (uid_t)-2 ); seteuid( (uid_t)-2 ); |
| 496 | } | 510 | } |
| @@ -525,7 +539,7 @@ int main( int argc, char **argv ) { | |||
| 525 | #endif | 539 | #endif |
| 526 | 540 | ||
| 527 | while( scanon ) { | 541 | while( scanon ) { |
| 528 | switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:l:v" | 542 | switch( getopt( argc, argv, ":i:p:A:P:d:u:r:s:f:l:v" |
| 529 | #ifdef WANT_ACCESSLIST_BLACK | 543 | #ifdef WANT_ACCESSLIST_BLACK |
| 530 | "b:" | 544 | "b:" |
| 531 | #elif defined( WANT_ACCESSLIST_WHITE ) | 545 | #elif defined( WANT_ACCESSLIST_WHITE ) |
| @@ -553,6 +567,7 @@ int main( int argc, char **argv ) { | |||
| 553 | livesync_bind_mcast( serverip, tmpport); break; | 567 | livesync_bind_mcast( serverip, tmpport); break; |
| 554 | #endif | 568 | #endif |
| 555 | case 'd': set_config_option( &g_serverdir, optarg ); break; | 569 | case 'd': set_config_option( &g_serverdir, optarg ); break; |
| 570 | case 'u': set_config_option( &g_serveruser, optarg ); break; | ||
| 556 | case 'r': set_config_option( &g_redirecturl, optarg ); break; | 571 | case 'r': set_config_option( &g_redirecturl, optarg ); break; |
| 557 | case 'l': load_state( optarg ); break; | 572 | case 'l': load_state( optarg ); break; |
| 558 | case 'A': | 573 | case 'A': |
| @@ -578,7 +593,7 @@ int main( int argc, char **argv ) { | |||
| 578 | ot_try_bind( serverip, 6969, FLAG_UDP ); | 593 | ot_try_bind( serverip, 6969, FLAG_UDP ); |
| 579 | } | 594 | } |
| 580 | 595 | ||
| 581 | if( drop_privileges( g_serverdir ) == -1 ) | 596 | if( drop_privileges( g_serveruser ? g_serveruser : "nobody", g_serverdir ) == -1 ) |
| 582 | panic( "drop_privileges failed, exiting. Last error"); | 597 | panic( "drop_privileges failed, exiting. Last error"); |
| 583 | 598 | ||
| 584 | g_now_seconds = time( NULL ); | 599 | g_now_seconds = time( NULL ); |
