summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c29
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;
41int g_self_pipe[2]; 42int g_self_pipe[2];
42 43
43static char * g_serverdir; 44static char * g_serverdir;
45static char * g_serveruser;
44 46
45static void panic( const char *routine ) { 47static 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
78static void install_signal_handlers( void ) { 80static 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
94static void usage( char *name ) { 96static 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
476int drop_privileges (const char * const serverdir) { 481int 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 );