Jakub Filak 9fdda6
From f3ef192d2ee78bdb4290ea966bc1467d2b599a7e Mon Sep 17 00:00:00 2001
Jakub Filak 9fdda6
From: Jakub Filak <jfilak@redhat.com>
Jakub Filak 9fdda6
Date: Fri, 22 Mar 2013 10:18:16 +0100
Jakub Filak 9fdda6
Subject: [ABRT PATCH] abrtd: recreate Dump Location directory if it is delete
Jakub Filak 9fdda6
Jakub Filak 9fdda6
- add inotify watch IN_DELETE_SELF and IN_MOVE_SELF and as a rection on
Jakub Filak 9fdda6
these events create the dump location and restore inotify watch.
Jakub Filak 9fdda6
Jakub Filak 9fdda6
- closes #624
Jakub Filak 9fdda6
Jakub Filak 9fdda6
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Jakub Filak 9fdda6
---
Jakub Filak 9fdda6
 src/daemon/abrtd.c | 82 +++++++++++++++++++++++++++++++++---------------------
Jakub Filak 9fdda6
 1 file changed, 50 insertions(+), 32 deletions(-)
Jakub Filak 9fdda6
Jakub Filak 9fdda6
diff --git a/src/daemon/abrtd.c b/src/daemon/abrtd.c
Jakub Filak 9fdda6
index f6d3965..7bc93ef 100644
Jakub Filak 9fdda6
--- a/src/daemon/abrtd.c
Jakub Filak 9fdda6
+++ b/src/daemon/abrtd.c
Jakub Filak 9fdda6
@@ -41,6 +41,7 @@
Jakub Filak 9fdda6
 /* Maximum number of simultaneously opened client connections. */
Jakub Filak 9fdda6
 #define MAX_CLIENT_COUNT  10
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
+#define IN_DUMP_LOCATION_FLAGS (IN_CREATE | IN_MOVED_TO | IN_DELETE_SELF | IN_MOVE_SELF)
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
 /* Daemon initializes, then sits in glib main loop, waiting for events.
Jakub Filak 9fdda6
  * Events can be:
Jakub Filak 9fdda6
@@ -490,6 +491,36 @@ static gboolean handle_event_output_cb(GIOChannel *gio, GIOCondition condition,
Jakub Filak 9fdda6
     /* Removing will also drop the last ref to this gio, closing/freeing it */
Jakub Filak 9fdda6
 }
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
+static void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
Jakub Filak 9fdda6
+{
Jakub Filak 9fdda6
+    struct stat sb;
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
+    if (mkdir(dir, mode) != 0 && errno != EEXIST)
Jakub Filak 9fdda6
+        perror_msg_and_die("Can't create '%s'", dir);
Jakub Filak 9fdda6
+    if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
Jakub Filak 9fdda6
+        error_msg_and_die("'%s' is not a directory", dir);
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
+    struct passwd *pw = getpwnam(user);
Jakub Filak 9fdda6
+    if (!pw)
Jakub Filak 9fdda6
+        perror_msg_and_die("Can't find user '%s'", user);
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
+    if ((sb.st_uid != pw->pw_uid || sb.st_gid != pw->pw_gid) && lchown(dir, pw->pw_uid, pw->pw_gid) != 0)
Jakub Filak 9fdda6
+        perror_msg_and_die("Can't set owner %u:%u on '%s'", (unsigned int)pw->pw_uid, (unsigned int)pw->pw_gid, dir);
Jakub Filak 9fdda6
+    if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
Jakub Filak 9fdda6
+        perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
Jakub Filak 9fdda6
+}
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
+static void sanitize_dump_dir_rights()
Jakub Filak 9fdda6
+{
Jakub Filak 9fdda6
+    /* We can't allow everyone to create dumps: otherwise users can flood
Jakub Filak 9fdda6
+     * us with thousands of bogus or malicious dumps */
Jakub Filak 9fdda6
+    /* 07000 bits are setuid, setgit, and sticky, and they must be unset */
Jakub Filak 9fdda6
+    /* 00777 bits are usual "rwxrwxrwx" access rights */
Jakub Filak 9fdda6
+    ensure_writable_dir(g_settings_dump_location, 0755, "abrt");
Jakub Filak 9fdda6
+    /* temp dir */
Jakub Filak 9fdda6
+    ensure_writable_dir(VAR_RUN"/abrt", 0755, "root");
Jakub Filak 9fdda6
+}
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
 /* Inotify handler */
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
 static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
Jakub Filak 9fdda6
@@ -594,6 +625,22 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
Jakub Filak 9fdda6
             continue;
Jakub Filak 9fdda6
         }
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
+        if (event->mask & IN_DELETE_SELF || event->mask & IN_MOVE_SELF)
Jakub Filak 9fdda6
+        {
Jakub Filak 9fdda6
+            /* HACK: we expect that we watch deletion only of 'g_settings_dump_location'
Jakub Filak 9fdda6
+             * but this handler is used for 'g_settings_sWatchCrashdumpArchiveDir' too
Jakub Filak 9fdda6
+             */
Jakub Filak 9fdda6
+            log("Recreating deleted dump location '%s'", g_settings_dump_location);
Jakub Filak 9fdda6
+            inotify_rm_watch(g_io_channel_unix_get_fd(gio), event->wd);
Jakub Filak 9fdda6
+            sanitize_dump_dir_rights();
Jakub Filak 9fdda6
+            if (inotify_add_watch(g_io_channel_unix_get_fd(gio), g_settings_dump_location, IN_DUMP_LOCATION_FLAGS) < 0)
Jakub Filak 9fdda6
+            {
Jakub Filak 9fdda6
+                perror_msg_and_die("inotify_add_watch failed on recreated '%s'", g_settings_dump_location);
Jakub Filak 9fdda6
+            }
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
+            continue;
Jakub Filak 9fdda6
+        }
Jakub Filak 9fdda6
+
Jakub Filak 9fdda6
         if (!(event->mask & IN_ISDIR) || !name)
Jakub Filak 9fdda6
         {
Jakub Filak 9fdda6
             /* ignore lock files and such */
Jakub Filak 9fdda6
@@ -810,36 +857,6 @@ static void start_syslog_logging()
Jakub Filak 9fdda6
     putenv((char*)"ABRT_SYSLOG=1");
Jakub Filak 9fdda6
 }
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
-static void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
Jakub Filak 9fdda6
-{
Jakub Filak 9fdda6
-    struct stat sb;
Jakub Filak 9fdda6
-
Jakub Filak 9fdda6
-    if (mkdir(dir, mode) != 0 && errno != EEXIST)
Jakub Filak 9fdda6
-        perror_msg_and_die("Can't create '%s'", dir);
Jakub Filak 9fdda6
-    if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
Jakub Filak 9fdda6
-        error_msg_and_die("'%s' is not a directory", dir);
Jakub Filak 9fdda6
-
Jakub Filak 9fdda6
-    struct passwd *pw = getpwnam(user);
Jakub Filak 9fdda6
-    if (!pw)
Jakub Filak 9fdda6
-        perror_msg_and_die("Can't find user '%s'", user);
Jakub Filak 9fdda6
-
Jakub Filak 9fdda6
-    if ((sb.st_uid != pw->pw_uid || sb.st_gid != pw->pw_gid) && lchown(dir, pw->pw_uid, pw->pw_gid) != 0)
Jakub Filak 9fdda6
-        perror_msg_and_die("Can't set owner %u:%u on '%s'", (unsigned int)pw->pw_uid, (unsigned int)pw->pw_gid, dir);
Jakub Filak 9fdda6
-    if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
Jakub Filak 9fdda6
-        perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
Jakub Filak 9fdda6
-}
Jakub Filak 9fdda6
-
Jakub Filak 9fdda6
-static void sanitize_dump_dir_rights()
Jakub Filak 9fdda6
-{
Jakub Filak 9fdda6
-    /* We can't allow everyone to create dumps: otherwise users can flood
Jakub Filak 9fdda6
-     * us with thousands of bogus or malicious dumps */
Jakub Filak 9fdda6
-    /* 07000 bits are setuid, setgit, and sticky, and they must be unset */
Jakub Filak 9fdda6
-    /* 00777 bits are usual "rwxrwxrwx" access rights */
Jakub Filak 9fdda6
-    ensure_writable_dir(g_settings_dump_location, 0755, "abrt");
Jakub Filak 9fdda6
-    /* temp dir */
Jakub Filak 9fdda6
-    ensure_writable_dir(VAR_RUN"/abrt", 0755, "root");
Jakub Filak 9fdda6
-}
Jakub Filak 9fdda6
-
Jakub Filak 9fdda6
 int main(int argc, char** argv)
Jakub Filak 9fdda6
 {
Jakub Filak 9fdda6
     /* I18n */
Jakub Filak 9fdda6
@@ -966,8 +983,9 @@ int main(int argc, char** argv)
Jakub Filak 9fdda6
         perror_msg_and_die("inotify_init failed");
Jakub Filak 9fdda6
     close_on_exec_on(inotify_fd);
Jakub Filak 9fdda6
 
Jakub Filak 9fdda6
-    /* Watching 'g_settings_dump_location' for new files... */
Jakub Filak 9fdda6
-    if (inotify_add_watch(inotify_fd, g_settings_dump_location, IN_CREATE | IN_MOVED_TO) < 0)
Jakub Filak 9fdda6
+    /* Watching 'g_settings_dump_location' for new files and delete self
Jakub Filak 9fdda6
+     * because hooks expects that the dump location exists if abrtd is runnig*/
Jakub Filak 9fdda6
+    if (inotify_add_watch(inotify_fd, g_settings_dump_location, IN_DUMP_LOCATION_FLAGS) < 0)
Jakub Filak 9fdda6
     {
Jakub Filak 9fdda6
         perror_msg("inotify_add_watch failed on '%s'", g_settings_dump_location);
Jakub Filak 9fdda6
         goto init_error;
Jakub Filak 9fdda6
-- 
Jakub Filak 9fdda6
1.8.1.4
Jakub Filak 9fdda6