aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in2
-rw-r--r--src/or/config.c2
-rw-r--r--src/or/main.c68
-rw-r--r--src/or/or.h8
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;