diff options
author | Steven Hazel <sah@freehaven.net> | 2003-10-22 11:21:29 +0000 |
---|---|---|
committer | Steven Hazel <sah@freehaven.net> | 2003-10-22 11:21:29 +0000 |
commit | 4139c1c86a92a90bde1c006a592bc7e894755140 (patch) | |
tree | e9c13ebc4eb28d01adcbcb99d1050a8c4a32a4f6 | |
parent | c78d5d7d30e94b190deef5fd721f966abceb1e18 (diff) | |
download | tor-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.c | 88 | ||||
-rw-r--r-- | src/common/util.h | 4 | ||||
-rw-r--r-- | src/or/main.c | 91 |
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; } } |