tor  0.4.2.1-alpha-dev
userdb.c
Go to the documentation of this file.
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
12 #include "lib/fs/userdb.h"
13 
14 #ifndef _WIN32
15 #include "lib/malloc/malloc.h"
16 #include "lib/log/log.h"
17 #include "lib/log/util_bug.h"
18 
19 #include <pwd.h>
20 #include <stddef.h>
21 #include <string.h>
22 
24 static struct passwd *passwd_cached = NULL;
25 
31 static struct passwd *
32 tor_passwd_dup(const struct passwd *pw)
33 {
34  struct passwd *new_pw = tor_malloc_zero(sizeof(struct passwd));
35  if (pw->pw_name)
36  new_pw->pw_name = tor_strdup(pw->pw_name);
37  if (pw->pw_dir)
38  new_pw->pw_dir = tor_strdup(pw->pw_dir);
39  new_pw->pw_uid = pw->pw_uid;
40  new_pw->pw_gid = pw->pw_gid;
41 
42  return new_pw;
43 }
44 
45 #define tor_passwd_free(pw) \
46  FREE_AND_NULL(struct passwd, tor_passwd_free_, (pw))
47 
49 static void
50 tor_passwd_free_(struct passwd *pw)
51 {
52  if (!pw)
53  return;
54 
55  tor_free(pw->pw_name);
56  tor_free(pw->pw_dir);
57  tor_free(pw);
58 }
59 
69 const struct passwd *
70 tor_getpwnam(const char *username)
71 {
72  struct passwd *pw;
73 
74  if (username == NULL) {
75  tor_passwd_free(passwd_cached);
76  passwd_cached = NULL;
77  return NULL;
78  }
79 
80  if ((pw = getpwnam(username))) {
81  tor_passwd_free(passwd_cached);
83  log_info(LD_GENERAL, "Caching new entry %s for %s",
84  passwd_cached->pw_name, username);
85  return pw;
86  }
87 
88  /* Lookup failed */
89  if (! passwd_cached || ! passwd_cached->pw_name)
90  return NULL;
91 
92  if (! strcmp(username, passwd_cached->pw_name))
93  return passwd_cached; // LCOV_EXCL_LINE - would need to make getpwnam flaky
94 
95  return NULL;
96 }
97 
105 const struct passwd *
106 tor_getpwuid(uid_t uid)
107 {
108  struct passwd *pw;
109 
110  if ((pw = getpwuid(uid))) {
111  return pw;
112  }
113 
114  /* Lookup failed */
115  if (! passwd_cached)
116  return NULL;
117 
118  if (uid == passwd_cached->pw_uid)
119  return passwd_cached; // LCOV_EXCL_LINE - would need to make getpwnam flaky
120 
121  return NULL;
122 }
123 
126 char *
127 get_user_homedir(const char *username)
128 {
129  const struct passwd *pw;
130  tor_assert(username);
131 
132  if (!(pw = tor_getpwnam(username))) {
133  log_err(LD_CONFIG,"User \"%s\" not found.", username);
134  return NULL;
135  }
136  return tor_strdup(pw->pw_dir);
137 }
138 #endif /* !defined(_WIN32) */
static struct passwd * tor_passwd_dup(const struct passwd *pw)
Definition: userdb.c:32
#define LD_GENERAL
Definition: log.h:60
const struct passwd * tor_getpwnam(const char *username)
Definition: userdb.c:70
static struct passwd * passwd_cached
Definition: userdb.c:24
#define tor_free(p)
Definition: malloc.h:52
Headers for util_malloc.c.
tor_assert(buffer)
static void tor_passwd_free_(struct passwd *pw)
Definition: userdb.c:50
char * get_user_homedir(const char *username)
Definition: userdb.c:127
Headers for log.c.
const struct passwd * tor_getpwuid(uid_t uid)
Definition: userdb.c:106
Header for userdb.c.
Macros to manage assertions, fatal and non-fatal.
#define LD_CONFIG
Definition: log.h:66