aboutsummaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorJérémy Bobbio <lunar@debian.org>2011-06-14 12:18:32 -0400
committerNick Mathewson <nickm@torproject.org>2011-06-14 12:18:32 -0400
commit54d7d31cba84232b50fef4287951b2c4bfa746c2 (patch)
tree3edfea998d447846a8e5cf14b850d38eb0da7450 /src/common/util.c
parentf30327449009a7f00b0f5c2bd09a7eff615df3dd (diff)
downloadtor-54d7d31cba84232b50fef4287951b2c4bfa746c2.tar
tor-54d7d31cba84232b50fef4287951b2c4bfa746c2.tar.gz
Make ControlSocketsGroupWritable work with User.
Original message from bug3393: check_private_dir() to ensure that ControlSocketsGroupWritable is safe to use. Unfortunately, check_private_dir() only checks against the currently running user… which can be root until privileges are dropped to the user and group configured by the User config option. The attached patch fixes the issue by adding a new effective_user argument to check_private_dir() and updating the callers. It might not be the best way to fix the issue, but it did in my tests. (Code by lunar; changelog by nickm)
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 6f323dd20..36aa9ccef 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1677,15 +1677,20 @@ file_status(const char *fname)
* is group-readable, but in all cases we create the directory mode 0700.
* If CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions
* if they are too permissive: we just return -1.
+ * When effective_user is not NULL, check permissions against the given user and
+ * its primary group.
*/
int
-check_private_dir(const char *dirname, cpd_check_t check)
+check_private_dir(const char *dirname, cpd_check_t check, const char *effective_user)
{
int r;
struct stat st;
char *f;
#ifndef MS_WINDOWS
int mask;
+ struct passwd *pw = NULL;
+ uid_t running_uid;
+ gid_t running_gid;
#endif
tor_assert(dirname);
@@ -1724,33 +1729,47 @@ check_private_dir(const char *dirname, cpd_check_t check)
return -1;
}
#ifndef MS_WINDOWS
- if (st.st_uid != getuid()) {
+ if (effective_user) {
+ /* Lookup the user and group information, if we have a problem, bail out. */
+ pw = getpwnam(effective_user);
+ if (pw == NULL) {
+ log_warn(LD_CONFIG, "Error setting configured user: %s not found", effective_user);
+ return -1;
+ }
+ running_uid = pw->pw_uid;
+ running_gid = pw->pw_gid;
+ } else {
+ running_uid = getuid();
+ running_gid = getgid();
+ }
+
+ if (st.st_uid != running_uid) {
struct passwd *pw = NULL;
char *process_ownername = NULL;
- pw = getpwuid(getuid());
+ pw = getpwuid(running_uid);
process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
pw = getpwuid(st.st_uid);
log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
"%s (%d). Perhaps you are running Tor as the wrong user?",
- dirname, process_ownername, (int)getuid(),
+ dirname, process_ownername, (int)running_uid,
pw ? pw->pw_name : "<unknown>", (int)st.st_uid);
tor_free(process_ownername);
return -1;
}
- if ((check & CPD_GROUP_OK) && st.st_gid != getgid()) {
+ if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
struct group *gr;
char *process_groupname = NULL;
- gr = getgrgid(getgid());
+ gr = getgrgid(running_gid);
process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup("<unknown>");
gr = getgrgid(st.st_gid);
log_warn(LD_FS, "%s is not owned by this group (%s, %d) but by group "
"%s (%d). Are you running Tor as the wrong user?",
- dirname, process_groupname, (int)getgid(),
+ dirname, process_groupname, (int)running_gid,
gr ? gr->gr_name : "<unknown>", (int)st.st_gid);
tor_free(process_groupname);