Blame SOURCES/0007-daemon-run-PostSession-script-from-mnager-not-worker.patch

675525
From ab06d95076705cdaee9945adb2e22ac75be72952 Mon Sep 17 00:00:00 2001
675525
From: Ray Strode <rstrode@redhat.com>
675525
Date: Thu, 29 Aug 2019 09:34:04 -0400
675525
Subject: [PATCH 7/7] daemon: run PostSession script from mnager not worker
675525
675525
After a user logs out, the session worker baby sitting
675525
the session, may optionally run admin provided PostSession
675525
scripts.
675525
675525
Those scripts aren't getting reliably run on reboots, because
675525
systemd kills the worker prematurely.
675525
675525
There's no easy way to prevent this... the worker is part of
675525
the user session and user sessions are terminated immediately
675525
at shutdown time.
675525
675525
This commit moves PostSession handling to the daemon process,
675525
where it can happen unimpeded by session bring down.
675525
675525
This also makes the scripts more reliable in other potential
675525
cases where the worker is killed explicitly.
675525
---
675525
 daemon/gdm-manager.c        | 40 +++++++++++++++++++++++++++++++++++++
675525
 daemon/gdm-session-worker.c |  3 ---
675525
 2 files changed, 40 insertions(+), 3 deletions(-)
675525
675525
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
675525
index 779b716be..d31c9d718 100644
675525
--- a/daemon/gdm-manager.c
675525
+++ b/daemon/gdm-manager.c
675525
@@ -1933,70 +1933,107 @@ on_user_session_opened (GdmSession       *session,
675525
                                                       g_object_ref (session));
675525
         if (g_strcmp0 (service_name, "gdm-autologin") == 0 &&
675525
             !gdm_session_client_is_connected (session)) {
675525
                 /* If we're auto logging in then don't wait for the go-ahead from a greeter,
675525
                  * (since there is no greeter) */
675525
                 g_object_set_data (G_OBJECT (session), "start-when-ready", GINT_TO_POINTER (TRUE));
675525
         }
675525
 
675525
         start_user_session_if_ready (manager, session, service_name);
675525
 }
675525
 
675525
 static void
675525
 on_user_session_started (GdmSession      *session,
675525
                          const char      *service_name,
675525
                          GPid             pid,
675525
                          GdmManager      *manager)
675525
 {
675525
         g_debug ("GdmManager: session started %d", pid);
675525
         add_session_record (manager, session, pid, SESSION_RECORD_LOGIN);
675525
 
675525
 #ifdef WITH_PLYMOUTH
675525
         if (g_strcmp0 (service_name, "gdm-autologin") == 0) {
675525
                 if (manager->priv->plymouth_is_running) {
675525
                         g_timeout_add_seconds (20, (GSourceFunc) plymouth_quit_with_transition, NULL);
675525
                         manager->priv->plymouth_is_running = FALSE;
675525
                 }
675525
         }
675525
 #endif
675525
 }
675525
 
675525
+static void
675525
+run_post_session_script (GdmSession *session)
675525
+{
675525
+        GPid pid;
675525
+        GdmDisplay *display;
675525
+        gboolean display_is_local = FALSE;
675525
+        const char *username;
675525
+        g_autofree char *display_name = NULL, *remote_hostname = NULL, *display_auth_file = NULL;
675525
+
675525
+        display = get_display_for_user_session (session);
675525
+
675525
+        if (display == NULL)
675525
+                return;
675525
+
675525
+        pid = gdm_session_get_pid (session);
675525
+
675525
+        if (pid <= 0)
675525
+                return;
675525
+
675525
+        username = gdm_session_get_username (session);
675525
+
675525
+        g_object_get (G_OBJECT (display),
675525
+                      "x11-display-name", &display_name,
675525
+                      "is-local", &display_is_local,
675525
+                      "remote-hostname", &remote_hostname,
675525
+                      "x11-authority-file", &display_auth_file,
675525
+                      NULL);
675525
+
675525
+        gdm_run_script (GDMCONFDIR "/PostSession",
675525
+                        username,
675525
+                        display_name,
675525
+                        display_is_local? NULL : remote_hostname,
675525
+                        display_auth_file);
675525
+}
675525
+
675525
 static void
675525
 remove_user_session (GdmManager *manager,
675525
                      GdmSession *session)
675525
 {
675525
         GList *node;
675525
         GdmDisplay *display;
675525
 
675525
         display = get_display_for_user_session (session);
675525
 
675525
         if (display != NULL) {
675525
+                run_post_session_script (session);
675525
+
675525
                 gdm_display_unmanage (display);
675525
                 gdm_display_finish (display);
675525
         }
675525
 
675525
         node = g_list_find (manager->priv->user_sessions, session);
675525
 
675525
         if (node != NULL) {
675525
                 manager->priv->user_sessions = g_list_delete_link (manager->priv->user_sessions, node);
675525
                 gdm_session_close (session);
675525
                 g_object_unref (session);
675525
         }
675525
 }
675525
 
675525
 static void
675525
 on_session_start_failed (GdmSession *session,
675525
                          const char *service_name,
675525
                          const char *message,
675525
                          GdmManager *manager)
675525
 {
675525
         g_debug ("GdmManager: session failed to start: %s", message);
675525
         remove_user_session (manager, session);
675525
 }
675525
 
675525
 static void
675525
 on_user_session_exited (GdmSession *session,
675525
                         int         code,
675525
                         GdmManager *manager)
675525
 {
675525
         GPid pid;
675525
 
675525
@@ -2753,60 +2790,63 @@ finish_display (const char *id,
675525
         if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
675525
                 gdm_display_unmanage (display);
675525
         gdm_display_finish (display);
675525
 }
675525
 
675525
 static void
675525
 gdm_manager_dispose (GObject *object)
675525
 {
675525
         GdmManager *manager;
675525
 
675525
         g_return_if_fail (object != NULL);
675525
         g_return_if_fail (GDM_IS_MANAGER (object));
675525
 
675525
         manager = GDM_MANAGER (object);
675525
 
675525
         g_return_if_fail (manager->priv != NULL);
675525
 
675525
         gdm_manager_stop (manager);
675525
 
675525
 #ifdef HAVE_LIBXDMCP
675525
         g_clear_object (&manager->priv->xdmcp_factory);
675525
 #endif
675525
         g_clear_object (&manager->priv->local_factory);
675525
         g_clear_pointer (&manager->priv->open_reauthentication_requests,
675525
                          (GDestroyNotify)
675525
                          g_hash_table_unref);
675525
         g_clear_pointer (&manager->priv->transient_sessions,
675525
                          (GDestroyNotify)
675525
                          g_hash_table_unref);
675525
 
675525
+        g_list_foreach (manager->priv->user_sessions,
675525
+                        (GFunc) run_post_session_script,
675525
+                        NULL);
675525
         g_list_foreach (manager->priv->user_sessions,
675525
                         (GFunc) gdm_session_close,
675525
                         NULL);
675525
         g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
675525
         manager->priv->user_sessions = NULL;
675525
 
675525
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
675525
                                               G_CALLBACK (on_display_added),
675525
                                               manager);
675525
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
675525
                                               G_CALLBACK (on_display_removed),
675525
                                               manager);
675525
 
675525
         if (!g_dbus_connection_is_closed (manager->priv->connection)) {
675525
                 gdm_display_store_foreach (manager->priv->display_store,
675525
                                            (GdmDisplayStoreFunc)unexport_display,
675525
                                            manager);
675525
                 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
675525
         }
675525
 
675525
         gdm_display_store_foreach (manager->priv->display_store,
675525
                                    (GdmDisplayStoreFunc) finish_display,
675525
                                    manager);
675525
 
675525
         gdm_display_store_clear (manager->priv->display_store);
675525
 
675525
         g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
675525
 
675525
         g_clear_object (&manager->priv->connection);
675525
         g_clear_object (&manager->priv->object_manager);
675525
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
675525
index 07117d857..b0861b971 100644
675525
--- a/daemon/gdm-session-worker.c
675525
+++ b/daemon/gdm-session-worker.c
675525
@@ -1743,72 +1743,69 @@ gdm_session_worker_get_environment (GdmSessionWorker *worker)
675525
 static gboolean
675525
 run_script (GdmSessionWorker *worker,
675525
             const char       *dir)
675525
 {
675525
         /* scripts are for non-program sessions only */
675525
         if (worker->priv->is_program_session) {
675525
                 return TRUE;
675525
         }
675525
 
675525
         return gdm_run_script (dir,
675525
                                worker->priv->username,
675525
                                worker->priv->x11_display_name,
675525
                                worker->priv->display_is_local? NULL : worker->priv->hostname,
675525
                                worker->priv->x11_authority_file);
675525
 }
675525
 
675525
 static void
675525
 session_worker_child_watch (GPid              pid,
675525
                             int               status,
675525
                             GdmSessionWorker *worker)
675525
 {
675525
         g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)",
675525
                  (int) pid,
675525
                  WIFEXITED (status) ? "status"
675525
                  : WIFSIGNALED (status) ? "signal"
675525
                  : "unknown",
675525
                  WIFEXITED (status) ? WEXITSTATUS (status)
675525
                  : WIFSIGNALED (status) ? WTERMSIG (status)
675525
                  : -1);
675525
 
675525
-
675525
         gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
675525
 
675525
         gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker),
675525
                                              worker->priv->service,
675525
                                              status);
675525
-
675525
         killpg (pid, SIGHUP);
675525
 
675525
         worker->priv->child_pid = -1;
675525
         worker->priv->child_watch_id = 0;
675525
-        run_script (worker, GDMCONFDIR "/PostSession");
675525
 }
675525
 
675525
 static void
675525
 gdm_session_worker_watch_child (GdmSessionWorker *worker)
675525
 {
675525
         g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid);
675525
         worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid,
675525
                                                           (GChildWatchFunc)session_worker_child_watch,
675525
                                                           worker);
675525
 
675525
 }
675525
 
675525
 static gboolean
675525
 _is_loggable_file (const char* filename)
675525
 {
675525
         struct stat file_info;
675525
 
675525
         if (g_lstat (filename, &file_info) < 0) {
675525
                 return FALSE;
675525
         }
675525
 
675525
         return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0;
675525
 }
675525
 
675525
 static void
675525
 rotate_logs (const char *path,
675525
              guint       n_copies)
675525
 {
675525
         int i;
675525
 
675525
-- 
675525
2.21.0
675525