Browse Source

- fixed a bug in the id switching code -- setgid has to happen before
setuid, because after we setuid we don't have the priviledges we
need to setgid anymore, duh. merged switch_user() and
switch_group() into switch_id(), since that code has to be wound
together.

- return -1 from switch_id() if it's not defined to do anything else.

- moved daemoinize(), write_pidfile(), and switch_id() from main.c to
util.c


svn:r656

Steven Hazel 20 years ago
parent
commit
4139c1c86a
3 changed files with 95 additions and 88 deletions
  1. 88 0
      src/common/util.c
  2. 4 0
      src/common/util.h
  3. 3 88
      src/or/main.c

+ 88 - 0
src/common/util.c

@@ -547,3 +547,91 @@ get_uname(void)
   return uname_result;
 }
       
+void daemonize(void) {
+#ifndef MS_WINDOWS
+  /* Fork; parent exits. */
+  if (fork())
+    exit(0);
+
+  /* Create new session; make sure we never get a terminal */
+  setsid();
+  if (fork())
+    exit(0);
+
+  chdir("/");
+  umask(000);
+
+  fclose(stdin);
+  fclose(stdout);
+  fclose(stderr);
+#endif
+}
+
+void write_pidfile(char *filename) {
+#ifndef MS_WINDOWS
+  FILE *pidfile;
+
+  if ((pidfile = fopen(filename, "w")) == NULL) {
+    log_fn(LOG_WARN, "unable to open %s for writing: %s", filename,
+           strerror(errno));
+  } else {
+    fprintf(pidfile, "%d", getpid());
+    fclose(pidfile);
+  }
+#endif
+}
+
+int switch_id(char *user, char *group) {
+#ifndef MS_WINDOWS
+  int status;
+  struct passwd *pw = NULL;
+  struct group *gr = NULL;
+
+  if (user) {
+    pw = getpwnam(user);
+    if (pw == NULL) {
+      log_fn(LOG_ERR,"User '%s' not found.", user);
+      return -1;
+    }
+  }
+
+  /* switch the group first, while we still have the priveledges to do so */
+  if (group) {
+    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;
+    }
+  } else if (user) {
+    status = setgid(pw->pw_gid);
+    if (status != 0) {
+      log_fn(LOG_ERR,"Error setting GID: %s", strerror(errno));
+      return -1;
+    }
+  }
+
+  /* now that the group is switched, we can switch users and lose
+     priviledges */
+  if (user) {
+    status = setuid(pw->pw_uid);
+    if (status != 0) {
+      log_fn(LOG_ERR,"Error setting UID: %s", strerror(errno));
+      return -1;
+    }
+  }
+
+  return 0;
+#endif
+
+  log_fn(LOG_ERR, 
+         "User '%s' specified, but switching users is not supported.", 
+         user);
+
+  return -1;
+}

+ 4 - 0
src/common/util.h

@@ -64,6 +64,10 @@ int tor_socketpair(int family, int type, int protocol, int fd[2]);
 
 const char *get_uname(void);
 
+void daemonize(void);
+void write_pidfile(char *filename);
+int switch_id(char *user, char *group);
+
 /* For stupid historical reasons, windows sockets have an independent set of 
  * errnos which they use as the fancy strikes them.
  */

+ 3 - 88
src/or/main.c

@@ -746,85 +746,6 @@ static void dumpstats(int severity) {
            (int) (stats_n_bytes_read/stats_n_seconds_reading));
 }
 
-void daemonize(void) {
-#ifndef MS_WINDOWS
-  /* Fork; parent exits. */
-  if (fork())
-    exit(0);
-
-  /* Create new session; make sure we never get a terminal */
-  setsid();
-  if (fork())
-    exit(0);
-
-  chdir("/");
-  umask(000);
-
-  fclose(stdin);
-  fclose(stdout);
-  fclose(stderr);
-#endif
-}
-
-void write_pidfile(char *filename) {
-#ifndef MS_WINDOWS
-  FILE *pidfile;
-
-  if ((pidfile = fopen(filename, "w")) == NULL) {
-    log_fn(LOG_WARN, "unable to open %s for writing: %s", filename,
-           strerror(errno));
-  } else {
-    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[]) {
 
   /* give it somewhere to log to initially */
@@ -849,15 +770,9 @@ 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) {
+  /* now that we've written the pid file, we can switch the user and group. */
+  if(options.User || options.Group) {
+    if(switch_id(options.User, options.Group) != 0) {
       return -1;
     }
   }