diff options
| author | erdgeist <> | 2010-04-09 10:15:51 +0000 |
|---|---|---|
| committer | erdgeist <> | 2010-04-09 10:15:51 +0000 |
| commit | 85e6880233c114450f6a0cc9e655e8c14c8af80a (patch) | |
| tree | c1ed7c868a57a792a2f51a211ff3000958ea7cb1 | |
| parent | fc48cbed012c2b7a4eaa8611c6cfb42628a5c622 (diff) | |
Make opentracker's user runtime configurable. Also add more debug output to aid finding problems.
| -rw-r--r-- | opentracker.c | 29 | ||||
| -rw-r--r-- | opentracker.conf.sample | 10 | ||||
| -rw-r--r-- | ot_http.c | 2 |
3 files changed, 32 insertions, 9 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 ); |
diff --git a/opentracker.conf.sample b/opentracker.conf.sample index 9cad622..f5d88d3 100644 --- a/opentracker.conf.sample +++ b/opentracker.conf.sample | |||
| @@ -79,11 +79,17 @@ | |||
| 79 | # batchsync.cluster.admin_ip 10.1.1.1 | 79 | # batchsync.cluster.admin_ip 10.1.1.1 |
| 80 | # | 80 | # |
| 81 | 81 | ||
| 82 | # V) Control directory where opentracker will chdir to. So all black/white | 82 | # V) Control privilege drop behaviour. |
| 83 | # list files may be put in that directory (shell option -d). | 83 | # Put in the directory opentracker will chroot/chdir to. All black/white |
| 84 | # list files must be put in that directory (shell option -d). | ||
| 85 | # | ||
| 84 | # | 86 | # |
| 85 | # tracker.rootdir /usr/local/etc/opentracker | 87 | # tracker.rootdir /usr/local/etc/opentracker |
| 86 | # | 88 | # |
| 89 | # Tell opentracker which user to setuid to. | ||
| 90 | # | ||
| 91 | # tracker.user nobody | ||
| 92 | # | ||
| 87 | 93 | ||
| 88 | # VI) opentracker can be told to answer to a "GET / HTTP"-request with a | 94 | # VI) opentracker can be told to answer to a "GET / HTTP"-request with a |
| 89 | # redirect to another location (shell option -r). | 95 | # redirect to another location (shell option -r). |
| @@ -347,6 +347,7 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c | |||
| 347 | unsigned long long numwants[201]; | 347 | unsigned long long numwants[201]; |
| 348 | #endif | 348 | #endif |
| 349 | 349 | ||
| 350 | #if defined( WANT_KEEPALIVE ) || defined( WANT_IP_FROM_PROXY ) | ||
| 350 | static char* http_header( char *data, size_t byte_count, char *header ) { | 351 | static char* http_header( char *data, size_t byte_count, char *header ) { |
| 351 | size_t i; | 352 | size_t i; |
| 352 | long sl = strlen( header ); | 353 | long sl = strlen( header ); |
| @@ -359,6 +360,7 @@ static char* http_header( char *data, size_t byte_count, char *header ) { | |||
| 359 | } | 360 | } |
| 360 | return 0; | 361 | return 0; |
| 361 | } | 362 | } |
| 363 | #endif | ||
| 362 | 364 | ||
| 363 | static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "event", 3 }, { "numwant", 4 }, { "compact", 5 }, { "compact6", 5 }, { "info_hash", 6 }, | 365 | static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "event", 3 }, { "numwant", 4 }, { "compact", 5 }, { "compact6", 5 }, { "info_hash", 6 }, |
| 364 | #ifdef WANT_IP_FROM_QUERY_STRING | 366 | #ifdef WANT_IP_FROM_QUERY_STRING |
