Signed-off-by: Jiri Moskovcak <jmoskovc(a)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;
+}
--
1.8.1.4
Show replies by date
Pushed slightly different version. Thanks!
----- Original Message -----
From: "Jiri Moskovcak" <jmoskovc(a)redhat.com>
To: crash-catcher(a)lists.fedorahosted.org
Sent: Friday, May 10, 2013 12:42:54 PM
Subject: [LIBREPORT PATCH] added DD_DONT_WAIT_FOR_LOCK and
int dump_dir_accessible_by_uid() - rhbz#961231
Signed-off-by: Jiri Moskovcak <jmoskovc(a)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;
+}
--
1.8.1.4