summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-03-15 16:46:53 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2011-03-15 16:46:53 +0100
commit821d8fc6d0e3bc596dd2f1c72296efe5dce33b45 (patch)
treea5e9c4f25409370fc187843cd5a6ea0e008eb88e
parent4df9a21293f121e8d46d52404b89614d9b2b3cec (diff)
downloadabrt-821d8fc6d0e3bc596dd2f1c72296efe5dce33b45.tar.gz
abrt-821d8fc6d0e3bc596dd2f1c72296efe5dce33b45.tar.xz
abrt-821d8fc6d0e3bc596dd2f1c72296efe5dce33b45.zip
gui-wizard-gtk: sanitize file mode/uid/gid after event run
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r--src/gui-wizard-gtk/wizard.c13
-rw-r--r--src/include/report/dump_dir.h3
-rw-r--r--src/lib/dump_dir.c49
3 files changed, 64 insertions, 1 deletions
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 96a939f7..e22b7630 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -778,6 +778,17 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g
strbuf_clear(evd->event_log);
evd->event_log_state = LOGSTATE_FIRSTLINE;
+ if (geteuid() == 0)
+ {
+ /* Reset mode/uig/gid to correct values for all files created by event run */
+ struct dump_dir *dd = dd_opendir(g_dump_dir_name, 0);
+ if (dd)
+ {
+ dd_sanitize_mode_and_owner(dd);
+ dd_close(dd);
+ }
+ }
+
/* Stop if exit code is not 0, or no more commands */
if (retval != 0
|| spawn_next_command_in_evd(evd) < 0
@@ -902,6 +913,8 @@ static void start_event_run(const char *event_name,
);
gtk_label_set_text(status_label, start_msg);
+//TODO: save_to_event_log(evd, "message that we run event foo")?
+
/* Freeze assistant so it can't move away from the page until event run is done */
gtk_assistant_set_page_complete(g_assistant, page, false);
}
diff --git a/src/include/report/dump_dir.h b/src/include/report/dump_dir.h
index 86bfcf0e..a97a4f5c 100644
--- a/src/include/report/dump_dir.h
+++ b/src/include/report/dump_dir.h
@@ -50,8 +50,11 @@ struct dump_dir *dd_opendir(const char *dir, int flags);
* (IOW: if you aren't running under root):
*/
struct dump_dir *dd_create(const char *dir, uid_t uid);
+
void dd_create_basic_files(struct dump_dir *dd, uid_t uid);
int dd_exist(struct dump_dir *dd, const char *path);
+void dd_sanitize_mode_and_owner(struct dump_dir *dd);
+
DIR *dd_init_next_file(struct dump_dir *dd);
int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name);
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index d0b1d478..fefec608 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -491,6 +491,53 @@ void dd_create_basic_files(struct dump_dir *dd, uid_t uid)
free(release);
}
+void dd_sanitize_mode_and_owner(struct dump_dir *dd)
+{
+ /* 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 */
+
+ DIR *d = opendir(dd->dd_dirname);
+ if (!d)
+ return;
+
+ struct dirent *dent;
+ while ((dent = readdir(d)) != NULL)
+ {
+ 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) != 0640)
+ chmod(full_path, 0640);
+ if (statbuf.st_uid != dd->dd_uid || statbuf.st_gid != dd->dd_gid)
+ {
+ if (chown(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);
+ }
+ closedir(d);
+}
+
static int delete_file_dir(const char *dir, bool skip_lock_file)
{
DIR *d = opendir(dir);
@@ -615,7 +662,7 @@ static char *load_text_file(const char *path, unsigned flags)
static bool save_binary_file(const char *path, const char* data, unsigned size, uid_t uid, gid_t gid)
{
- /* "Why 0640?!" See ::Create() for security analysis */
+ /* "Why 0640?!" See dd_create() for security analysis */
unlink(path);
int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0640);
if (fd < 0)