aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Hazel <sah@freehaven.net>2003-10-22 11:21:29 +0000
committerSteven Hazel <sah@freehaven.net>2003-10-22 11:21:29 +0000
commit4139c1c86a92a90bde1c006a592bc7e894755140 (patch)
treee9c13ebc4eb28d01adcbcb99d1050a8c4a32a4f6
parentc78d5d7d30e94b190deef5fd721f966abceb1e18 (diff)
downloadtor-4139c1c86a92a90bde1c006a592bc7e894755140.tar
tor-4139c1c86a92a90bde1c006a592bc7e894755140.tar.gz
- 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
-rw-r--r--src/common/util.c88
-rw-r--r--src/common/util.h4
-rw-r--r--src/or/main.c91
3 files changed, 95 insertions, 88 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 098b20157..1db8989a3 100644
--- a/src/common/util.c
+++ b/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;
+}
diff --git a/src/common/util.h b/src/common/util.h
index 3df098c68..15893f160 100644
--- a/src/common/util.h
+++ b/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.
*/
diff --git a/src/or/main.c b/src/or/main.c
index 1d6511f52..eed0d4c48 100644
--- a/src/or/main.c
+++ b/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;
}
}