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 ); |