Signed-off-by: Jiri Moskovcak jmoskovc@redhat.com --- src/include/dump_dir.h | 9 +++++++++ src/lib/dump_dir.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+)
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h index 8f34f2f..37b2a03 100644 --- a/src/include/dump_dir.h +++ b/src/include/dump_dir.h @@ -35,6 +35,7 @@ enum { /* Open symlinks. dd_* funcs don't open symlinks by default */ DD_OPEN_FOLLOW = (1 << 2), DD_OPEN_READONLY = (1 << 3), + DD_DONT_WAIT_FOR_LOCK = (1 << 4), };
struct dump_dir { @@ -93,6 +94,14 @@ report_result_t *find_in_reported_to(struct dump_dir *dd, const char *prefix);
void delete_dump_dir(const char *dirname); +/* Checks dump dir accessibility for particular uid. + * + * If the directory doesn't exist the directory is not accessible and errno is + * set to ENOTDIR. + * + * Returns non zero if dump dir is accessible otherwise return 0 value. + */ +int dump_dir_accessible_by_uid(const char *dirname, uid_t uid);
#ifdef __cplusplus } diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c index d271145..7362bfb 100644 --- a/src/lib/dump_dir.c +++ b/src/lib/dump_dir.c @@ -931,3 +931,56 @@ void delete_dump_dir(const char *dirname) dd_delete(dd); } } + +#if DUMP_DIR_OWNED_BY_USER == 0 +static bool uid_in_group(uid_t uid, gid_t gid) +{ + char **tmp; + struct passwd *pwd = getpwuid(uid); + + if (!pwd) + return FALSE; + + if (pwd->pw_gid == gid) + return TRUE; + + struct group *grp = getgrgid(gid); + if (!(grp && grp->gr_mem)) + return FALSE; + + for (tmp = grp->gr_mem; *tmp != NULL; tmp++) + { + if (g_strcmp0(*tmp, pwd->pw_name) == 0) + { + VERB3 log("user %s belongs to group: %s", pwd->pw_name, grp->gr_name); + return TRUE; + } + } + + VERB2 log("user %s DOESN'T belong to group: %s", pwd->pw_name, grp->gr_name); + return FALSE; +} +#endif + +int dump_dir_accessible_by_uid(const char *dirname, uid_t uid) +{ + struct stat statbuf; + if (stat(dirname, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + errno = ENOTDIR; + else + { + errno = 0; + +#if DUMP_DIR_OWNED_BY_USER > 0 + if (uid == 0 || (statbuf.st_mode & S_IROTH) || uid == statbuf.st_uid) +#else + if (uid == 0 || (statbuf.st_mode & S_IROTH) || uid_in_group(uid, statbuf.st_gid)) +#endif + { + VERB1 log("directory '%s' is accessible by %ld uid", dirname, (long)uid); + return 1; + } + } + + return 0; +}