From 85e6880233c114450f6a0cc9e655e8c14c8af80a Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 9 Apr 2010 10:15:51 +0000 Subject: Make opentracker's user runtime configurable. Also add more debug output to aid finding problems. --- opentracker.c | 29 ++++++++++++++++++++++------- opentracker.conf.sample | 10 ++++++++-- 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 @@ #include #include #include +#include /* Libowfat */ #include "socket.h" @@ -41,6 +42,7 @@ volatile int g_opentracker_running = 1; int g_self_pipe[2]; static char * g_serverdir; +static char * g_serveruser; static void panic( const char *routine ) { fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); @@ -72,7 +74,7 @@ static void defaul_signal_handlers( void ) { sigaddset (&signal_mask, SIGHUP); sigaddset (&signal_mask, SIGINT); sigaddset (&signal_mask, SIGALRM); - pthread_sigmask (SIG_BLOCK, &signal_mask, NULL); + pthread_sigmask (SIG_BLOCK, &signal_mask, NULL); } static void install_signal_handlers( void ) { @@ -88,11 +90,11 @@ static void install_signal_handlers( void ) { sigaddset (&signal_mask, SIGINT); sigaddset (&signal_mask, SIGALRM); - pthread_sigmask (SIG_UNBLOCK, &signal_mask, NULL); + pthread_sigmask (SIG_UNBLOCK, &signal_mask, NULL); } static void usage( char *name ) { - fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-A ip] [-f config] [-s livesyncport]" + fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip] [-f config] [-s livesyncport]" #ifdef WANT_ACCESSLIST_BLACK " [-b blacklistfile]" #elif defined ( WANT_ACCESSLIST_WHITE ) @@ -111,6 +113,7 @@ static void help( char *name ) { HELPLINE("-P port","specify udp port to bind to (default: 6969, you may specify more than one)"); HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); + HELPLINE("-u user","specify user under whose priviliges opentracker should run (default: \"nobody\")"); HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); #ifdef WANT_ACCESSLIST_BLACK HELPLINE("-b file","specify blacklist file."); @@ -382,6 +385,8 @@ int parse_configfile( char * config_filename ) { /* Scan for commands */ if(!byte_diff(p,15,"tracker.rootdir" ) && isspace(p[15])) { set_config_option( &g_serverdir, p+16 ); + } else if(!byte_diff(p,12,"tracker.user" ) && isspace(p[12])) { + set_config_option( &g_serveruser, p+13 ); } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { uint16_t tmpport = 6969; if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error; @@ -473,11 +478,18 @@ void load_state(const char * const state_filename ) { fclose( state_filehandle ); } -int drop_privileges (const char * const serverdir) { +int drop_privileges ( const char * const serveruser, const char * const serverdir ) { struct passwd *pws = NULL; +#ifdef _DEBUG + if( !geteuid() ) + fprintf( stderr, "Dropping to user %s.\n", serveruser ); + if( serverdir ) + fprintf( stderr, "ch%s'ing to directory %s.\n", geteuid() ? "dir" : "root", serverdir ); +#endif + /* Grab pws entry before chrooting */ - pws = getpwnam( "nobody" ); + pws = getpwnam( serveruser ); endpwent(); if( geteuid() == 0 ) { @@ -490,7 +502,9 @@ int drop_privileges (const char * const serverdir) { if(chdir("/")) panic("chdir() failed after chrooting: "); + /* If we can't find server user, revert to nobody's default uid */ if( !pws ) { + fprintf( stderr, "Warning: Could not get password entry for %s. Reverting to uid -2.\n", serveruser ); setegid( (gid_t)-2 ); setgid( (gid_t)-2 ); setuid( (uid_t)-2 ); seteuid( (uid_t)-2 ); } @@ -525,7 +539,7 @@ int main( int argc, char **argv ) { #endif while( scanon ) { - switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:l:v" + switch( getopt( argc, argv, ":i:p:A:P:d:u:r:s:f:l:v" #ifdef WANT_ACCESSLIST_BLACK "b:" #elif defined( WANT_ACCESSLIST_WHITE ) @@ -553,6 +567,7 @@ int main( int argc, char **argv ) { livesync_bind_mcast( serverip, tmpport); break; #endif case 'd': set_config_option( &g_serverdir, optarg ); break; + case 'u': set_config_option( &g_serveruser, optarg ); break; case 'r': set_config_option( &g_redirecturl, optarg ); break; case 'l': load_state( optarg ); break; case 'A': @@ -578,7 +593,7 @@ int main( int argc, char **argv ) { ot_try_bind( serverip, 6969, FLAG_UDP ); } - if( drop_privileges( g_serverdir ) == -1 ) + if( drop_privileges( g_serveruser ? g_serveruser : "nobody", g_serverdir ) == -1 ) panic( "drop_privileges failed, exiting. Last error"); 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 @@ # batchsync.cluster.admin_ip 10.1.1.1 # -# V) Control directory where opentracker will chdir to. So all black/white -# list files may be put in that directory (shell option -d). +# V) Control privilege drop behaviour. +# Put in the directory opentracker will chroot/chdir to. All black/white +# list files must be put in that directory (shell option -d). +# # # tracker.rootdir /usr/local/etc/opentracker # +# Tell opentracker which user to setuid to. +# +# tracker.user nobody +# # VI) opentracker can be told to answer to a "GET / HTTP"-request with a # redirect to another location (shell option -r). diff --git a/ot_http.c b/ot_http.c index 22fb68f..e364809 100644 --- a/ot_http.c +++ b/ot_http.c @@ -347,6 +347,7 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c unsigned long long numwants[201]; #endif +#if defined( WANT_KEEPALIVE ) || defined( WANT_IP_FROM_PROXY ) static char* http_header( char *data, size_t byte_count, char *header ) { size_t i; long sl = strlen( header ); @@ -359,6 +360,7 @@ static char* http_header( char *data, size_t byte_count, char *header ) { } return 0; } +#endif static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "event", 3 }, { "numwant", 4 }, { "compact", 5 }, { "compact6", 5 }, { "info_hash", 6 }, #ifdef WANT_IP_FROM_QUERY_STRING -- cgit v1.2.3