]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
added User and Group options -- if you set them, tor will try to
authorSteven Hazel <sah@freehaven.net>
Wed, 22 Oct 2003 06:03:11 +0000 (06:03 +0000)
committerSteven Hazel <sah@freehaven.net>
Wed, 22 Oct 2003 06:03:11 +0000 (06:03 +0000)
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

configure.in
src/or/config.c
src/or/main.c
src/or/or.h

index 33d9484167386bc07a40be793962d5be7c4da682..7933cf767852dc590e1d7aec240f38e23f12a31b 100644 (file)
@@ -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
 
index 8bc0e17ffa22e99b0aed977fa342530f1b0007a0..c049b681fc8abb25e61c728f4787e52f59a53006 100644 (file)
@@ -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) ||
index a7bd83adf1b9c465978a33e83a56f5691bdb7951..1d6511f521a30a43871d3bae9a53fb58174e4119 100644 (file)
@@ -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();
 
index 85ce9092b81da2ddf3408540b0b0fe5f3c656ede..bc96e0869223dc028c9015e3afb693a513470276 100644 (file)
 #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;