|
@@ -1678,15 +1678,20 @@ file_status(const char *fname)
|
|
* is group-readable, but in all cases we create the directory mode 0700.
|
|
* 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 CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions
|
|
* if they are too permissive: we just return -1.
|
|
* 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
|
|
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;
|
|
int r;
|
|
struct stat st;
|
|
struct stat st;
|
|
char *f;
|
|
char *f;
|
|
#ifndef MS_WINDOWS
|
|
#ifndef MS_WINDOWS
|
|
int mask;
|
|
int mask;
|
|
|
|
+ struct passwd *pw = NULL;
|
|
|
|
+ uid_t running_uid;
|
|
|
|
+ gid_t running_gid;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
tor_assert(dirname);
|
|
tor_assert(dirname);
|
|
@@ -1725,33 +1730,47 @@ check_private_dir(const char *dirname, cpd_check_t check)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
#ifndef MS_WINDOWS
|
|
#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;
|
|
struct passwd *pw = NULL;
|
|
char *process_ownername = NULL;
|
|
char *process_ownername = NULL;
|
|
|
|
|
|
- pw = getpwuid(getuid());
|
|
|
|
|
|
+ pw = getpwuid(running_uid);
|
|
process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
|
|
process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
|
|
|
|
|
|
pw = getpwuid(st.st_uid);
|
|
pw = getpwuid(st.st_uid);
|
|
|
|
|
|
log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
|
|
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?",
|
|
"%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);
|
|
pw ? pw->pw_name : "<unknown>", (int)st.st_uid);
|
|
|
|
|
|
tor_free(process_ownername);
|
|
tor_free(process_ownername);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- if ((check & CPD_GROUP_OK) && st.st_gid != getgid()) {
|
|
|
|
|
|
+ if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
|
|
struct group *gr;
|
|
struct group *gr;
|
|
char *process_groupname = NULL;
|
|
char *process_groupname = NULL;
|
|
- gr = getgrgid(getgid());
|
|
|
|
|
|
+ gr = getgrgid(running_gid);
|
|
process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup("<unknown>");
|
|
process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup("<unknown>");
|
|
gr = getgrgid(st.st_gid);
|
|
gr = getgrgid(st.st_gid);
|
|
|
|
|
|
log_warn(LD_FS, "%s is not owned by this group (%s, %d) but by group "
|
|
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?",
|
|
"%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);
|
|
gr ? gr->gr_name : "<unknown>", (int)st.st_gid);
|
|
|
|
|
|
tor_free(process_groupname);
|
|
tor_free(process_groupname);
|