[or-cvs] added User and Group options -- if you set them, tor will t...

Steven Hazel sah at seul.org
Wed Oct 22 06:03:13 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home/sah/tor/src/or

Modified Files:
	or.h main.c config.c 
Log Message:
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.


Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.170
retrieving revision 1.171
diff -u -d -r1.170 -r1.171
--- or.h	21 Oct 2003 09:48:17 -0000	1.170
+++ or.h	22 Oct 2003 06:03:11 -0000	1.171
@@ -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 @@
    char *ExitPolicy;
    char *SocksBindAddress;
    char *ORBindAddress;
+   char *User;
+   char *Group;
    double CoinWeight;
    int ORPort;
    int SocksPort;

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- main.c	21 Oct 2003 09:48:17 -0000	1.139
+++ main.c	22 Oct 2003 06:03:11 -0000	1.140
@@ -599,7 +599,7 @@
                         (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 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 write_pidfile(char *filename) {
+#ifndef MS_WINDOWS
   FILE *pidfile;
 
   if ((pidfile = fopen(filename, "w")) == NULL) {
@@ -776,6 +777,52 @@
     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[]) {
@@ -801,6 +848,19 @@
 
   /* 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: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- config.c	21 Oct 2003 09:48:17 -0000	1.61
+++ config.c	22 Oct 2003 06:03:11 -0000	1.62
@@ -162,6 +162,8 @@
     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) ||



More information about the tor-commits mailing list