Add a pair of wrapper functions: tor_getpwnam() and tor_getpwuid()

We'll use these to deal with being unable to access the user DB
after we install the sandbox, to fix bug 11946.
This commit is contained in:
Nick Mathewson
2014-05-14 13:50:43 -04:00
parent 747f368c6d
commit e12af2adb0
3 changed files with 91 additions and 0 deletions
+83
View File
@@ -1702,6 +1702,89 @@ log_credential_status(void)
}
#endif
#ifndef _WIN32
static struct passwd *passwd_cached = NULL;
static struct passwd *
tor_passwd_dup(const struct passwd *pw)
{
struct passwd *new_pw = tor_malloc_zero(sizeof(struct passwd));
if (pw->pw_name)
new_pw->pw_name = tor_strdup(pw->pw_name);
if (pw->pw_dir)
new_pw->pw_dir = tor_strdup(pw->pw_dir);
new_pw->pw_uid = pw->pw_uid;
new_pw->pw_gid = pw->pw_gid;
return new_pw;
}
static void
tor_passwd_free(struct passwd *pw)
{
if (!pw)
return;
tor_free(pw->pw_name);
tor_free(pw->pw_dir);
tor_free(pw);
}
/** Wrapper around getpwnam() that caches result. Used so that we don't need
* to give the sandbox access to /etc/passwd. */
const struct passwd *
tor_getpwnam(const char *username)
{
struct passwd *pw;
if (username == NULL) {
tor_passwd_free(passwd_cached);
passwd_cached = NULL;
return NULL;
}
if ((pw = getpwnam(username))) {
tor_passwd_free(passwd_cached);
passwd_cached = tor_passwd_dup(pw);
log_notice(LD_GENERAL, "Caching new entry %s for %s",
passwd_cached->pw_name, username);
return pw;
}
/* Lookup failed */
if (! passwd_cached || ! passwd_cached->pw_name)
return NULL;
if (! strcmp(username, passwd_cached->pw_name))
return passwd_cached;
return NULL;
}
/** Wrapper around getpwnam() that can use cached result from
* tor_getpwnam(). Used so that we don't need to give the sandbox access to
* /etc/passwd. */
const struct passwd *
tor_getpwuid(uid_t uid)
{
struct passwd *pw;
if ((pw = getpwuid(uid))) {
return pw;
}
/* Lookup failed */
if (! passwd_cached)
return NULL;
if (uid == passwd_cached->pw_uid)
return passwd_cached;
return NULL;
}
#endif
/** Call setuid and setgid to run as <b>user</b> and switch to their
* primary group. Return 0 on success. On failure, log and return -1.
*/
+5
View File
@@ -633,6 +633,11 @@ int switch_id(const char *user);
char *get_user_homedir(const char *username);
#endif
#ifndef _WIN32
const struct passwd *tor_getpwnam(const char *username);
const struct passwd *tor_getpwuid(uid_t uid);
#endif
int get_parent_directory(char *fname);
char *make_path_absolute(char *fname);
+3
View File
@@ -2548,6 +2548,9 @@ tor_free_all(int postfork)
free_cell_pool();
if (!postfork) {
tor_tls_free_all();
#ifndef _WIN32
tor_getpwnam(NULL);
#endif
}
/* stuff in main.c */