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 /src/common/util.c | |
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
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 88 |
1 files changed, 88 insertions, 0 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; +} |