mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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:
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user