[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Add a pair of wrapper functions: tor_getpwnam() and tor_getpwuid()
commit e12af2adb0919d0de6d6ba44462d9255f63fca5b
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed May 14 13:50:43 2014 -0400
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.
---
src/common/compat.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/common/compat.h | 5 ++++
src/or/main.c | 3 ++
3 files changed, 91 insertions(+)
diff --git a/src/common/compat.c b/src/common/compat.c
index 7a444df..9f31cce 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -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.
*/
diff --git a/src/common/compat.h b/src/common/compat.h
index 314b1aa..683c4d0 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -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);
diff --git a/src/or/main.c b/src/or/main.c
index 5532026..a2c5743 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -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 */
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits