Skip to content
Snippets Groups Projects
Commit e12af2ad authored by Nick Mathewson's avatar Nick Mathewson :game_die:
Browse files

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.
parent 747f368c
No related branches found
No related tags found
No related merge requests found
......@@ -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.
*/
......
......@@ -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);
......
......@@ -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 */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment