Blame SOURCES/fix-post-login.patch

9fa8e4
From c3f39b437f6ef32174f322bd107071cdf1379d12 Mon Sep 17 00:00:00 2001
9fa8e4
From: Ray Strode <rstrode@redhat.com>
9fa8e4
Date: Mon, 18 Apr 2016 16:09:08 -0400
9fa8e4
Subject: [PATCH 1/2] worker: run PostLogin/PreSession scripts later
9fa8e4
9fa8e4
Right now we run them while the login screen is still up, so
9fa8e4
they have no way of showing UI to the user.
9fa8e4
9fa8e4
This commit moves them until after the login screen is torn
9fa8e4
down.
9fa8e4
---
9fa8e4
 daemon/gdm-session-worker.c | 34 ++++++++++++++++++----------------
9fa8e4
 1 file changed, 18 insertions(+), 16 deletions(-)
9fa8e4
9fa8e4
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
9fa8e4
index acc826b..e07d32e 100644
9fa8e4
--- a/daemon/gdm-session-worker.c
9fa8e4
+++ b/daemon/gdm-session-worker.c
9fa8e4
@@ -1793,60 +1793,78 @@ out:
9fa8e4
 }
9fa8e4
 
9fa8e4
 static gboolean
9fa8e4
 gdm_session_worker_start_session (GdmSessionWorker  *worker,
9fa8e4
                                   GError           **error)
9fa8e4
 {
9fa8e4
         struct passwd *passwd_entry;
9fa8e4
         pid_t session_pid;
9fa8e4
         int   error_code;
9fa8e4
 
9fa8e4
         gdm_get_pwent_for_name (worker->priv->username, &passwd_entry);
9fa8e4
         if (worker->priv->is_program_session) {
9fa8e4
                 g_debug ("GdmSessionWorker: opening session for program '%s'",
9fa8e4
                          worker->priv->arguments[0]);
9fa8e4
         } else {
9fa8e4
                 g_debug ("GdmSessionWorker: opening user session with program '%s'",
9fa8e4
                          worker->priv->arguments[0]);
9fa8e4
         }
9fa8e4
 
9fa8e4
         error_code = PAM_SUCCESS;
9fa8e4
 
9fa8e4
 #ifdef ENABLE_WAYLAND_SUPPORT
9fa8e4
         /* If we're in new vt mode, jump to the new vt now. There's no need to jump for
9fa8e4
          * the other two modes: in the logind case, the session will activate itself when
9fa8e4
          * ready, and in the reuse server case, we're already on the correct VT. */
9fa8e4
         if (worker->priv->display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) {
9fa8e4
                 jump_to_vt (worker, worker->priv->session_vt);
9fa8e4
         }
9fa8e4
 #endif
9fa8e4
 
9fa8e4
+        if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PostLogin")) {
9fa8e4
+                g_set_error (error,
9fa8e4
+                             GDM_SESSION_WORKER_ERROR,
9fa8e4
+                             GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
+                             "Failed to execute PostLogin script");
9fa8e4
+                error_code = PAM_ABORT;
9fa8e4
+                goto out;
9fa8e4
+        }
9fa8e4
+
9fa8e4
+        if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PreSession")) {
9fa8e4
+                g_set_error (error,
9fa8e4
+                             GDM_SESSION_WORKER_ERROR,
9fa8e4
+                             GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
+                             "Failed to execute PreSession script");
9fa8e4
+                error_code = PAM_ABORT;
9fa8e4
+                goto out;
9fa8e4
+        }
9fa8e4
+
9fa8e4
         session_pid = fork ();
9fa8e4
 
9fa8e4
         if (session_pid < 0) {
9fa8e4
                 g_set_error (error,
9fa8e4
                              GDM_SESSION_WORKER_ERROR,
9fa8e4
                              GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
                              "%s", g_strerror (errno));
9fa8e4
                 error_code = PAM_ABORT;
9fa8e4
                 goto out;
9fa8e4
         }
9fa8e4
 
9fa8e4
         if (session_pid == 0) {
9fa8e4
                 const char * const * environment;
9fa8e4
                 char  *home_dir;
9fa8e4
                 int    stdin_fd = -1, stdout_fd = -1, stderr_fd = -1;
9fa8e4
                 gboolean has_journald = FALSE;
9fa8e4
                 sigset_t mask;
9fa8e4
 
9fa8e4
                 /* Leak the TTY into the session as stdin so that it stays open
9fa8e4
                  * without any races. */
9fa8e4
                 if (worker->priv->session_tty_fd > 0) {
9fa8e4
                         dup2 (worker->priv->session_tty_fd, STDIN_FILENO);
9fa8e4
                         close (worker->priv->session_tty_fd);
9fa8e4
                         worker->priv->session_tty_fd = -1;
9fa8e4
                 } else {
9fa8e4
                         stdin_fd = open ("/dev/null", O_RDWR);
9fa8e4
                         dup2 (stdin_fd, STDIN_FILENO);
9fa8e4
                         close (stdin_fd);
9fa8e4
                 }
9fa8e4
 
9fa8e4
@@ -2186,93 +2204,77 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
9fa8e4
 
9fa8e4
         g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
9fa8e4
         g_assert (geteuid () == 0);
9fa8e4
 
9fa8e4
         switch (worker->priv->display_mode) {
9fa8e4
         case GDM_SESSION_DISPLAY_MODE_REUSE_VT:
9fa8e4
                 if (!set_up_for_current_vt (worker, error)) {
9fa8e4
                         return FALSE;
9fa8e4
                 }
9fa8e4
                 break;
9fa8e4
 #ifdef ENABLE_WAYLAND_SUPPORT
9fa8e4
         case GDM_SESSION_DISPLAY_MODE_NEW_VT:
9fa8e4
         case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED:
9fa8e4
                 if (!set_up_for_new_vt (worker)) {
9fa8e4
                         g_set_error (error,
9fa8e4
                                      GDM_SESSION_WORKER_ERROR,
9fa8e4
                                      GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
                                      "Unable to open VT");
9fa8e4
                         return FALSE;
9fa8e4
                 }
9fa8e4
                 break;
9fa8e4
 #endif
9fa8e4
         }
9fa8e4
 
9fa8e4
         flags = 0;
9fa8e4
 
9fa8e4
         if (worker->priv->is_program_session) {
9fa8e4
                 flags |= PAM_SILENT;
9fa8e4
         }
9fa8e4
 
9fa8e4
-        if (!run_script (worker, GDMCONFDIR "/PostLogin")) {
9fa8e4
-                g_set_error (error,
9fa8e4
-                             GDM_SESSION_WORKER_ERROR,
9fa8e4
-                             GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
-                             "Failed to execute PostLogin script");
9fa8e4
-                return FALSE;
9fa8e4
-        }
9fa8e4
-
9fa8e4
         error_code = pam_open_session (worker->priv->pam_handle, flags);
9fa8e4
 
9fa8e4
         if (error_code != PAM_SUCCESS) {
9fa8e4
                 g_set_error (error,
9fa8e4
                              GDM_SESSION_WORKER_ERROR,
9fa8e4
                              GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
9fa8e4
                              "%s", pam_strerror (worker->priv->pam_handle, error_code));
9fa8e4
                 goto out;
9fa8e4
         }
9fa8e4
 
9fa8e4
         g_debug ("GdmSessionWorker: state SESSION_OPENED");
9fa8e4
         worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED;
9fa8e4
 
9fa8e4
 #ifdef WITH_SYSTEMD
9fa8e4
         session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID");
9fa8e4
 #endif
9fa8e4
 
9fa8e4
-        /* FIXME: should we do something here?
9fa8e4
-         * Note that error return status from PreSession script should
9fa8e4
-         * be ignored in the case of a X-GDM-BypassXsession session, which can
9fa8e4
-         * be checked by calling:
9fa8e4
-         * gdm_session_bypasses_xsession (session)
9fa8e4
-         */
9fa8e4
-        run_script (worker, GDMCONFDIR "/PreSession");
9fa8e4
-
9fa8e4
 #ifdef WITH_CONSOLE_KIT
9fa8e4
         register_ck_session (worker);
9fa8e4
 
9fa8e4
         if (session_id == NULL) {
9fa8e4
                 session_id = get_ck_session_id (worker);
9fa8e4
         }
9fa8e4
 #endif
9fa8e4
 
9fa8e4
         if (session_id != NULL) {
9fa8e4
                 g_free (worker->priv->session_id);
9fa8e4
                 worker->priv->session_id = session_id;
9fa8e4
         }
9fa8e4
 
9fa8e4
  out:
9fa8e4
         if (error_code != PAM_SUCCESS) {
9fa8e4
                 gdm_session_worker_uninitialize_pam (worker, error_code);
9fa8e4
                 return FALSE;
9fa8e4
         }
9fa8e4
 
9fa8e4
         gdm_session_worker_get_username (worker, NULL);
9fa8e4
         gdm_session_auditor_report_login (worker->priv->auditor);
9fa8e4
 
9fa8e4
         return TRUE;
9fa8e4
 }
9fa8e4
 
9fa8e4
 static void
9fa8e4
 gdm_session_worker_set_server_address (GdmSessionWorker *worker,
9fa8e4
                                        const char       *address)
9fa8e4
 {
9fa8e4
         g_free (worker->priv->server_address);
9fa8e4
-- 
9fa8e4
2.8.1
9fa8e4
9fa8e4
9fa8e4
From ebc5a37f8f4a287df4255cbcdf5d51f7a8fe9b44 Mon Sep 17 00:00:00 2001
9fa8e4
From: Ray Strode <rstrode@redhat.com>
9fa8e4
Date: Tue, 19 Apr 2016 11:02:08 -0400
9fa8e4
Subject: [PATCH 2/2] manager: handle session failing to start
9fa8e4
9fa8e4
Right now if a session fails really early in the start up
9fa8e4
process, we fail to handle it.
9fa8e4
9fa8e4
This commit fixes that.
9fa8e4
---
9fa8e4
 daemon/gdm-manager.c | 13 +++++++++++++
9fa8e4
 1 file changed, 13 insertions(+)
9fa8e4
9fa8e4
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
9fa8e4
index 33064ea..72ea968 100644
9fa8e4
--- a/daemon/gdm-manager.c
9fa8e4
+++ b/daemon/gdm-manager.c
9fa8e4
@@ -1475,60 +1475,69 @@ on_session_started (GdmSession      *session,
9fa8e4
 
9fa8e4
                 session_id = gdm_session_get_session_id (session);
9fa8e4
                 g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
9fa8e4
         }
9fa8e4
 }
9fa8e4
 
9fa8e4
 static void
9fa8e4
 remove_user_session (GdmManager *manager,
9fa8e4
                      GdmSession *session)
9fa8e4
 {
9fa8e4
         GList *node;
9fa8e4
         GdmDisplay *display;
9fa8e4
 
9fa8e4
         display = get_display_for_user_session (session);
9fa8e4
 
9fa8e4
         if (display != NULL) {
9fa8e4
                 gdm_display_unmanage (display);
9fa8e4
                 gdm_display_finish (display);
9fa8e4
         }
9fa8e4
 
9fa8e4
         node = g_list_find (manager->priv->user_sessions, session);
9fa8e4
 
9fa8e4
         if (node != NULL) {
9fa8e4
                 manager->priv->user_sessions = g_list_delete_link (manager->priv->user_sessions, node);
9fa8e4
                 gdm_session_close (session);
9fa8e4
                 g_object_unref (session);
9fa8e4
         }
9fa8e4
 }
9fa8e4
 
9fa8e4
 static void
9fa8e4
+on_session_start_failed (GdmSession *session,
9fa8e4
+                         const char *service_name,
9fa8e4
+                         GdmManager *manager)
9fa8e4
+{
9fa8e4
+        g_debug ("GdmManager: session failed to start");
9fa8e4
+        remove_user_session (manager, session);
9fa8e4
+}
9fa8e4
+
9fa8e4
+static void
9fa8e4
 on_user_session_exited (GdmSession *session,
9fa8e4
                         int         code,
9fa8e4
                         GdmManager *manager)
9fa8e4
 {
9fa8e4
         g_debug ("GdmManager: session exited with status %d", code);
9fa8e4
         remove_user_session (manager, session);
9fa8e4
 }
9fa8e4
 
9fa8e4
 static void
9fa8e4
 on_user_session_died (GdmSession *session,
9fa8e4
                       int         signal_number,
9fa8e4
                       GdmManager *manager)
9fa8e4
 {
9fa8e4
         g_debug ("GdmManager: session died with signal %s", strsignal (signal_number));
9fa8e4
         remove_user_session (manager, session);
9fa8e4
 }
9fa8e4
 
9fa8e4
 static char *
9fa8e4
 query_ck_for_display_device (GdmManager *manager,
9fa8e4
                              GdmDisplay *display)
9fa8e4
 {
9fa8e4
         char    *out;
9fa8e4
         char    *command;
9fa8e4
         char    *display_name = NULL;
9fa8e4
         int      status;
9fa8e4
         gboolean res;
9fa8e4
         GError  *error;
9fa8e4
 
9fa8e4
         g_object_get (G_OBJECT (display),
9fa8e4
                       "x11-display-name", &display_name,
9fa8e4
@@ -1894,60 +1903,64 @@ create_seed_session_for_display (GdmManager *manager,
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "client-connected",
9fa8e4
                           G_CALLBACK (on_session_client_connected),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "client-disconnected",
9fa8e4
                           G_CALLBACK (on_session_client_disconnected),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "cancelled",
9fa8e4
                           G_CALLBACK (on_session_cancelled),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "conversation-started",
9fa8e4
                           G_CALLBACK (on_session_conversation_started),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "conversation-stopped",
9fa8e4
                           G_CALLBACK (on_session_conversation_stopped),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "session-opened",
9fa8e4
                           G_CALLBACK (on_session_opened),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "session-started",
9fa8e4
                           G_CALLBACK (on_session_started),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
+                          "session-start-failed",
9fa8e4
+                          G_CALLBACK (on_session_start_failed),
9fa8e4
+                          manager);
9fa8e4
+        g_signal_connect (session,
9fa8e4
                           "session-exited",
9fa8e4
                           G_CALLBACK (on_user_session_exited),
9fa8e4
                           manager);
9fa8e4
         g_signal_connect (session,
9fa8e4
                           "session-died",
9fa8e4
                           G_CALLBACK (on_user_session_died),
9fa8e4
                           manager);
9fa8e4
         g_object_set_data (G_OBJECT (session), "gdm-display", display);
9fa8e4
         g_object_set_data_full (G_OBJECT (display), "gdm-seed-session", g_object_ref (session), (GDestroyNotify) g_object_unref);
9fa8e4
 
9fa8e4
         start_autologin_conversation_if_necessary (manager, display, session);
9fa8e4
 }
9fa8e4
 
9fa8e4
 static void
9fa8e4
 on_display_added (GdmDisplayStore *display_store,
9fa8e4
                   const char      *id,
9fa8e4
                   GdmManager      *manager)
9fa8e4
 {
9fa8e4
         GdmDisplay *display;
9fa8e4
 
9fa8e4
         display = gdm_display_store_lookup (display_store, id);
9fa8e4
 
9fa8e4
         if (display != NULL) {
9fa8e4
                 g_dbus_object_manager_server_export (manager->priv->object_manager,
9fa8e4
                                                      gdm_display_get_object_skeleton (display));
9fa8e4
 
9fa8e4
                 g_signal_connect (display, "notify::status",
9fa8e4
                                   G_CALLBACK (on_display_status_changed),
9fa8e4
                                   manager);
9fa8e4
                 g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id);
9fa8e4
-- 
9fa8e4
2.8.1
9fa8e4