diff options
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | src/or/config.c | 2 | ||||
-rw-r--r-- | src/or/main.c | 68 | ||||
-rw-r--r-- | src/or/or.h | 8 |
4 files changed, 75 insertions, 5 deletions
diff --git a/configure.in b/configure.in index 33d948416..7933cf767 100644 --- a/configure.in +++ b/configure.in @@ -130,7 +130,7 @@ LIBS="$saved_LIBS -lcrypto -lssl" dnl The warning message here is no longer strictly accurate. -AC_CHECK_HEADERS(unistd.h string.h signal.h netdb.h ctype.h poll.h sys/stat.h sys/poll.h sys/types.h sys/fcntl.h sys/ioctl.h sys/socket.h sys/time.h netinet/in.h arpa/inet.h errno.h assert.h time.h, , AC_MSG_WARN(some headers were not found, compilation may fail)) +AC_CHECK_HEADERS(unistd.h string.h signal.h netdb.h ctype.h poll.h sys/stat.h sys/poll.h sys/types.h sys/fcntl.h sys/ioctl.h sys/socket.h sys/time.h netinet/in.h arpa/inet.h errno.h assert.h time.h pwd.h grp.h, , AC_MSG_WARN(some headers were not found, compilation may fail)) dnl These headers are not essential 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 <time.h> #endif +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif +#ifdef HAVE_GRP_H +#include <grp.h> +#endif #ifdef HAVE_WINSOCK_H #include <winsock.h> #endif @@ -428,6 +434,8 @@ typedef struct { char *ExitPolicy; char *SocksBindAddress; char *ORBindAddress; + char *User; + char *Group; double CoinWeight; int ORPort; int SocksPort; |