- related to trac#927
Signed-off-by: Jakub Filak <[email protected]>
---
src/include/dump_dir.h | 1 +
src/lib/dump_dir.c | 71 ++++++++++++++++++++++++++++++++++----------------
2 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index 21169c8..c95fc1a 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -57,6 +57,7 @@ struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t
mode);
void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char
*chroot_dir);
int dd_exist(const struct dump_dir *dd, const char *path);
+void dd_sanitize_items_mode_and_owner(struct dump_dir *dd, const char *name);
void dd_sanitize_mode_and_owner(struct dump_dir *dd);
DIR *dd_init_next_file(struct dump_dir *dd);
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index 37606dd..c79151e 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -629,6 +629,53 @@ void dd_create_basic_files(struct dump_dir *dd, uid_t uid,
const char *chroot_di
free(release);
}
+static void sanitize_mode_and_owner(struct dump_dir *dd, const char *item)
+{
+ char *full_path = concat_path_file(dd->dd_dirname, item);
+ struct stat statbuf;
+ if (lstat(full_path, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
+ {
+ if ((statbuf.st_mode & 0777) != dd->mode)
+ {
+ if (chmod(full_path, dd->mode) != 0)
+ {
+ perror_msg("Can't change '%s' mode to 0%o", full_path,
+ (unsigned)dd->mode);
+ }
+ }
+ if (statbuf.st_uid != dd->dd_uid || statbuf.st_gid != dd->dd_gid)
+ {
+ if (lchown(full_path, dd->dd_uid, dd->dd_gid) != 0)
+ {
+ perror_msg("Can't change '%s' ownership to %lu:%lu", full_path,
+ (long)dd->dd_uid, (long)dd->dd_gid);
+ }
+ }
+ }
+ free(full_path);
+}
+
+void dd_sanitize_items_mode_and_owner(struct dump_dir *dd, const char *name)
+{
+ /* Don't sanitize if we aren't run under root:
+ * we assume that during file creation (by whatever means,
+ * even by "hostname >file" in abrt_event.conf)
+ * normal umask-based mode setting takes care of correct mode,
+ * and uid:gid is, of course, set to user's uid and gid.
+ *
+ * For root operating on /var/spool/abrt/USERS_PROBLEM, this isn't true:
+ * "hostname >file", for example, would create file OWNED BY ROOT!
+ * This routine resets mode and uid:gid for all such files.
+ */
+ if (dd->dd_uid == (uid_t)-1)
+ return;
+
+ if (!dd->locked)
+ error_msg_and_die("dump_dir is not opened"); /* bug */
+
+ sanitize_mode_and_owner(dd, name);
+}
+
void dd_sanitize_mode_and_owner(struct dump_dir *dd)
{
/* Don't sanitize if we aren't run under root:
@@ -656,28 +703,8 @@ void dd_sanitize_mode_and_owner(struct dump_dir *dd)
{
if (dent->d_name[0] == '.') /* ".lock", ".", ".."? skip */
continue;
- char *full_path = concat_path_file(dd->dd_dirname, dent->d_name);
- struct stat statbuf;
- if (lstat(full_path, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
- {
- if ((statbuf.st_mode & 0777) != dd->mode)
- {
- if (chmod(full_path, dd->mode) != 0)
- {
- perror_msg("Can't change '%s' mode to 0%o", full_path,
- (unsigned)dd->mode);
- }
- }
- if (statbuf.st_uid != dd->dd_uid || statbuf.st_gid != dd->dd_gid)
- {
- if (lchown(full_path, dd->dd_uid, dd->dd_gid) != 0)
- {
- perror_msg("Can't change '%s' ownership to %lu:%lu",
full_path,
- (long)dd->dd_uid, (long)dd->dd_gid);
- }
- }
- }
- free(full_path);
+
+ sanitize_mode_and_owner(dd, dent->d_name);
}
closedir(d);
}
--
1.8.1