- related to trac#927
Signed-off-by: Jakub Filak <[email protected]>
---
src/include/dump_dir.h | 9 +++++++++
src/lib/dump_dir.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index 89c7ff7..0a6a1b0 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -83,6 +83,15 @@ int dd_delete_item(struct dump_dir *dd, const char *name);
/* Returns 0 if directory is deleted or not found */
int dd_delete(struct dump_dir *dd);
int dd_rename(struct dump_dir *dd, const char *new_path);
+/* Changes owner of dump dir
+ * Uses two different strategies selected at build time by
+ * DUMP_DIR_OWNED_BY_USER configuration:
+ * <= 0 : owner = abrt user's uid, group = new_uid's gid
+ * > 0 : owner = new_uid, group = abrt group's gid
+ *
+ * On success, zero is returned. On error, -1 is returned.
+ */
+int dd_chown(struct dump_dir *dd, uid_t new_uid);
/* reported_to handling */
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index dfa19aa..f815848 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -760,6 +760,58 @@ int dd_delete(struct dump_dir *dd)
return r;
}
+int dd_chown(struct dump_dir *dd, uid_t new_uid)
+{
+ if (!dd->locked)
+ error_msg_and_die("dump_dir is not opened"); /* bug */
+
+ errno = 0;
+ struct stat statbuf;
+ if (!(stat(dd->dd_dirname, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)))
+ {
+ perror_msg("stat");
+ errno = 0;
+ return 1;
+ }
+
+ struct passwd *pw = getpwuid(new_uid);
+ if (!pw)
+ {
+ error_msg("UID %ld is not found in user database", (long)new_uid);
+ return 1;
+ }
+
+#if DUMP_DIR_OWNED_BY_USER > 0
+ uid_t owners_uid = pw->pw_uid;
+ gid_t groups_gid = statbuf.st_gid;
+#else
+ uid_t owners_uid = statbuf.st_uid;
+ gid_t groups_gid = pw->pw_gid;
+#endif
+
+ int chown_res = lchown(dd->dd_dirname, owners_uid, groups_gid);
+ int chown_errno = errno;
+ dd_init_next_file(dd);
+ char *full_name;
+ while (chown_res == 0 && dd_get_next_file(dd, /*short_name*/ NULL,
&full_name))
+ {
+ VERB3 log("chowning %s", full_name);
+ chown_res = lchown(full_name, owners_uid, groups_gid);
+ chown_errno = errno;
+ free(full_name);
+ }
+
+ if (chown_res != 0)
+ {
+ errno = chown_errno;
+ perror_msg("chown");
+ errno = 0;
+ return 1;
+ }
+
+ return 0;
+}
+
static char *load_text_file(const char *path, unsigned flags)
{
int fd = open(path, O_RDONLY | ((flags & DD_OPEN_FOLLOW) ? 0 :
O_NOFOLLOW));
--
1.7.11.7