From b1eca56b77ba1316eb23587341319fbbe2bc6560 Mon Sep 17 00:00:00 2001 From: Steven Hazel Date: Wed, 22 Oct 2003 06:03:11 +0000 Subject: added User and Group options -- if you set them, tor will try to setuid and setgid respectively, and die if it can't. (If the User option is set, tor will setgid to the user's gid as well.) This happens after the pidfile is created, so that in cases where tor needs to be root to work with the pidfile, it will at least be able to create it, although it won't be able to delete it. That sucks, but it's somewhat better than not being able to create the pidfile in the first place. svn:r652 --- src/or/config.c | 2 ++ src/or/main.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/or/or.h | 8 +++++++ 3 files changed, 74 insertions(+), 4 deletions(-) (limited to 'src/or') diff --git a/src/or/config.c b/src/or/config.c index 8bc0e17ff..c049b681f 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -162,6 +162,8 @@ static void config_assign(or_options_t *options, struct config_line *list) { config_compare(list, "ExitPolicy", CONFIG_TYPE_STRING, &options->ExitPolicy) || config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) || config_compare(list, "ORBindAddress", CONFIG_TYPE_STRING, &options->ORBindAddress) || + config_compare(list, "User", CONFIG_TYPE_STRING, &options->User) || + config_compare(list, "Group", CONFIG_TYPE_STRING, &options->Group) || /* int options */ config_compare(list, "MaxConn", CONFIG_TYPE_INT, &options->MaxConn) || diff --git a/src/or/main.c b/src/or/main.c index a7bd83adf..1d6511f52 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -599,7 +599,7 @@ static int do_main_loop(void) { (uint16_t) options.DirPort); for(;;) { -#ifndef MS_WIN32 /* do signal stuff only on unix */ +#ifndef MS_WINDOWS /* do signal stuff only on unix */ if(please_dumpstats) { /* prefer to log it at INFO, but make sure we always see it */ dumpstats(options.loglevel>LOG_INFO ? options.loglevel : LOG_INFO); @@ -670,14 +670,14 @@ static int do_main_loop(void) { static void catch(int the_signal) { -#ifndef MS_WIN32 /* do signal stuff only on unix */ +#ifndef MS_WINDOWS /* do signal stuff only on unix */ switch(the_signal) { // case SIGABRT: case SIGTERM: case SIGINT: log(LOG_ERR,"Catching signal %d, exiting cleanly.", the_signal); - /* we don't care if there was an error when we unlink, - nothing we could do about it anyways */ + /* we don't care if there was an error when we unlink, nothing + we could do about it anyways */ unlink(options.PidFile); exit(0); case SIGHUP: @@ -767,6 +767,7 @@ void daemonize(void) { } void write_pidfile(char *filename) { +#ifndef MS_WINDOWS FILE *pidfile; if ((pidfile = fopen(filename, "w")) == NULL) { @@ -776,6 +777,52 @@ void write_pidfile(char *filename) { fprintf(pidfile, "%d", getpid()); fclose(pidfile); } +#endif +} + +int switch_user(char *user) { +#ifndef MS_WINDOWS + int status; + struct passwd *pw = NULL; + + pw = getpwnam(user); + if(pw == NULL) { + log_fn(LOG_ERR,"User '%s' not found.", user); + return -1; + } + status = setuid(pw->pw_uid); + if (status != 0) { + log_fn(LOG_ERR,"Error setting UID: %s", strerror(errno)); + return -1; + } + status = setgid(pw->pw_gid); + if (status != 0) { + log_fn(LOG_ERR,"Error setting GID: %s", strerror(errno)); + return -1; + } + + return 0; +#endif +} + +int switch_group(char *group) { +#ifndef MS_WINDOWS + int status; + struct group *gr = NULL; + + gr = getgrnam(group); + if(gr == NULL) { + log_fn(LOG_ERR,"Group '%s' not found.", group); + return -1; + } + status = setgid(gr->gr_gid); + if (status != 0) { + log_fn(LOG_ERR,"Error setting GID: %s", strerror(errno)); + return -1; + } + + return 0; +#endif } int tor_main(int argc, char *argv[]) { @@ -802,6 +849,19 @@ int tor_main(int argc, char *argv[]) { /* write our pid to the pid file */ write_pidfile(options.PidFile); + /* now that we've written the pid file, we can switch the user and group */ + if(options.User) { + if(switch_user(options.User) != 0) { + return -1; + } + } + + if(options.Group) { + if(switch_group(options.Group) != 0) { + return -1; + } + } + if(options.RunAsDaemon) daemonize(); diff --git a/src/or/or.h b/src/or/or.h index 85ce9092b..bc96e0869 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -72,6 +72,12 @@ #ifdef HAVE_TIME_H #include #endif +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif #ifdef HAVE_WINSOCK_H #include #endif @@ -428,6 +434,8 @@ typedef struct { char *ExitPolicy; char *SocksBindAddress; char *ORBindAddress; + char *User; + char *Group; double CoinWeight; int ORPort; int SocksPort; -- cgit v1.2.3