26 #ifdef HAVE_SYS_TYPES_H
27 #include <sys/types.h>
29 #ifdef HAVE_SYS_STAT_H
71 const char *effective_user))
80 const struct passwd *pw = NULL;
102 if (errno != ENOENT) {
104 log_warn(
LD_FS,
"Directory %s cannot be read: %s", dirname,
112 if (check & CPD_CREATE) {
113 log_info(
LD_GENERAL,
"Creating directory %s", dirname);
114 if (check & CPD_GROUP_READ) {
115 r = mkdir(dirname, 0750);
117 r = mkdir(dirname, 0700);
122 log_warn(
LD_FS,
"Error creating directory %s: %s", dirname,
132 log_warn(
LD_FS,
"Could not reopen recently created directory %s: %s",
140 }
else if (!(check & CPD_CHECK)) {
141 log_warn(
LD_FS,
"Directory %s does not exist.", dirname);
154 log_debug(
LD_FS,
"stat()ing %s", dirname);
158 log_warn(
LD_FS,
"fstat() on directory %s failed.", dirname);
165 if (!(st.st_mode & S_IFDIR)) {
166 log_warn(
LD_FS,
"%s is not a directory", dirname);
171 if (effective_user) {
176 log_warn(
LD_CONFIG,
"Error setting configured user: %s not found",
181 running_uid = pw->pw_uid;
182 running_gid = pw->pw_gid;
184 running_uid = getuid();
185 running_gid = getgid();
187 if (st.st_uid != running_uid) {
188 char *process_ownername = NULL, *file_ownername = NULL;
191 const struct passwd *pw_running =
tor_getpwuid(running_uid);
192 process_ownername = pw_running ? tor_strdup(pw_running->pw_name) :
193 tor_strdup(
"<unknown>");
198 file_ownername = pw_stat ? tor_strdup(pw_stat->pw_name) :
199 tor_strdup(
"<unknown>");
202 log_warn(
LD_FS,
"%s is not owned by this user (%s, %d) but by "
203 "%s (%d). Perhaps you are running Tor as the wrong user?",
204 dirname, process_ownername, (
int)running_uid,
205 file_ownername, (
int)st.st_uid);
212 if ( (check & (CPD_GROUP_OK|CPD_GROUP_READ))
213 && (st.st_gid != running_gid) && (st.st_gid != 0)) {
215 char *process_groupname = NULL;
216 gr = getgrgid(running_gid);
217 process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup(
"<unknown>");
218 gr = getgrgid(st.st_gid);
220 log_warn(
LD_FS,
"%s is not owned by this group (%s, %d) but by group "
221 "%s (%d). Are you running Tor as the wrong user?",
222 dirname, process_groupname, (
int)running_gid,
223 gr ? gr->gr_name :
"<unknown>", (
int)st.st_gid);
229 unsigned unwanted_bits = 0;
230 if (check & (CPD_GROUP_OK|CPD_GROUP_READ)) {
231 unwanted_bits = 0027;
233 unwanted_bits = 0077;
235 unsigned check_bits_filter = ~0;
236 if (check & CPD_RELAX_DIRMODE_CHECK) {
237 check_bits_filter = 0022;
239 if ((st.st_mode & unwanted_bits & check_bits_filter) != 0) {
241 if (check & CPD_CHECK_MODE_ONLY) {
242 log_warn(
LD_FS,
"Permissions on directory %s are too permissive.",
247 log_warn(
LD_FS,
"Fixing permissions on directory %s", dirname);
248 new_mode = st.st_mode;
250 if (check & CPD_GROUP_READ) {
253 new_mode &= ~unwanted_bits;
254 if (fchmod(fd, new_mode)) {
255 log_warn(
LD_FS,
"Could not chmod directory %s: %s", dirname,
267 (void)effective_user;
269 char *f = tor_strdup(dirname);
271 log_debug(
LD_FS,
"stat()ing %s", f);
275 if (errno != ENOENT) {
276 log_warn(
LD_FS,
"Directory %s cannot be read: %s", dirname,
280 if (check & CPD_CREATE) {
281 log_info(
LD_GENERAL,
"Creating directory %s", dirname);
284 log_warn(
LD_FS,
"Error creating directory %s: %s", dirname,
288 }
else if (!(check & CPD_CHECK)) {
289 log_warn(
LD_FS,
"Directory %s does not exist.", dirname);
294 if (!(st.st_mode & S_IFDIR)) {
295 log_warn(
LD_FS,
"%s is not a directory", dirname);
312 TCHAR tpattern[MAX_PATH] = {0};
313 char name[MAX_PATH*2+1] = {0};
315 WIN32_FIND_DATA findData;
318 mbstowcs(tpattern,pattern,MAX_PATH);
320 strlcpy(tpattern, pattern, MAX_PATH);
322 if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(tpattern, &findData))) {
329 wcstombs(
name,findData.cFileName,MAX_PATH);
332 strlcpy(
name,findData.cFileName,
sizeof(
name));
334 if (strcmp(
name,
".") &&
335 strcmp(
name,
"..")) {
338 if (!FindNextFile(handle, &findData)) {
340 if ((err = GetLastError()) != ERROR_NO_MORE_FILES) {
341 char *errstr = format_win32_error(err);
342 log_warn(
LD_FS,
"Error reading directory '%s': %s", dirname, errstr);
354 if (!(d = opendir(prot_dname)))
358 while ((de = readdir(d))) {
359 if (!strcmp(de->d_name,
".") ||
360 !strcmp(de->d_name,
".."))
Header for compat_string.c.
smartlist_t * tor_listdir(const char *dirname)
int check_private_dir(const char *dirname, cpd_check_t check, const char *effective_user)
Headers for util_malloc.c.
void clean_fname_for_stat(char *name)
int tor_asprintf(char **strp, const char *fmt,...)
Header file for sandbox.c.
#define sandbox_intern_string(s)
smartlist_t * smartlist_new(void)
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
#define MOCK_IMPL(rv, funcname, arglist)
const struct passwd * tor_getpwuid(uid_t uid)
const struct passwd * tor_getpwnam(const char *username)
Macros to manage assertions, fatal and non-fatal.