Blame SOURCES/0006-manager-fix-up-support-for-chooser.patch

2fc437
From 60a03333bec4f7904a2cfddb291d22ce493e1ced Mon Sep 17 00:00:00 2001
2fc437
From: Ray Strode <rstrode@redhat.com>
2fc437
Date: Fri, 31 Mar 2017 14:54:44 -0400
2fc437
Subject: [PATCH 06/13] manager: fix up support for chooser
2fc437
2fc437
We were missing some chunks of code to handle dealing with
2fc437
the chooser.
2fc437
2fc437
This commit adds in the necessary bits to start the chooser,
2fc437
and deal with the choice.
2fc437
---
2fc437
 daemon/gdm-manager.c | 62 ++++++++++++++++++++++++++++++++++++++++++++--------
2fc437
 1 file changed, 53 insertions(+), 9 deletions(-)
2fc437
2fc437
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
2fc437
index 3014dad3..373778d9 100644
2fc437
--- a/daemon/gdm-manager.c
2fc437
+++ b/daemon/gdm-manager.c
2fc437
@@ -18,67 +18,69 @@
2fc437
  *
2fc437
  */
2fc437
 
2fc437
 #include "config.h"
2fc437
 
2fc437
 #include <stdlib.h>
2fc437
 #include <stdio.h>
2fc437
 #include <fcntl.h>
2fc437
 #include <unistd.h>
2fc437
 #include <string.h>
2fc437
 #include <signal.h>
2fc437
 #include <sys/stat.h>
2fc437
 #include <sys/types.h>
2fc437
 
2fc437
 #include <glib.h>
2fc437
 #include <glib/gi18n.h>
2fc437
 #include <glib/gstdio.h>
2fc437
 #include <glib-object.h>
2fc437
 
2fc437
 #include <act/act-user-manager.h>
2fc437
 
2fc437
 #include <systemd/sd-login.h>
2fc437
 
2fc437
 #include "gdm-common.h"
2fc437
 
2fc437
 #include "gdm-dbus-util.h"
2fc437
 #include "gdm-manager.h"
2fc437
 #include "gdm-manager-glue.h"
2fc437
 #include "gdm-display-store.h"
2fc437
 #include "gdm-display-factory.h"
2fc437
+#include "gdm-launch-environment.h"
2fc437
 #include "gdm-local-display.h"
2fc437
 #include "gdm-local-display-factory.h"
2fc437
 #include "gdm-session.h"
2fc437
 #include "gdm-session-record.h"
2fc437
 #include "gdm-settings-direct.h"
2fc437
 #include "gdm-settings-keys.h"
2fc437
 #include "gdm-xdmcp-display-factory.h"
2fc437
+#include "gdm-xdmcp-chooser-display.h"
2fc437
 
2fc437
 #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
2fc437
 
2fc437
 #define GDM_DBUS_PATH             "/org/gnome/DisplayManager"
2fc437
 #define GDM_MANAGER_PATH          GDM_DBUS_PATH "/Manager"
2fc437
 #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
2fc437
 
2fc437
 #define INITIAL_SETUP_USERNAME "gnome-initial-setup"
2fc437
 
2fc437
 typedef struct
2fc437
 {
2fc437
         GdmManager *manager;
2fc437
         GdmSession *session;
2fc437
         char *service_name;
2fc437
         guint idle_id;
2fc437
 } StartUserSessionOperation;
2fc437
 
2fc437
 struct GdmManagerPrivate
2fc437
 {
2fc437
         GdmDisplayStore        *display_store;
2fc437
         GdmLocalDisplayFactory *local_factory;
2fc437
 #ifdef HAVE_LIBXDMCP
2fc437
         GdmXdmcpDisplayFactory *xdmcp_factory;
2fc437
 #endif
2fc437
         GList                  *user_sessions;
2fc437
         GHashTable             *transient_sessions;
2fc437
         GHashTable             *open_reauthentication_requests;
2fc437
         gboolean                xdmcp_enabled;
2fc437
         GCancellable           *cancellable;
2fc437
 
2fc437
@@ -793,89 +795,107 @@ gdm_manager_handle_register_display (GdmDBusManager        *manager,
2fc437
                 /* FIXME: this should happen in gdm-session.c when the session is opened
2fc437
                  */
2fc437
                 if (tty != NULL)
2fc437
                         g_object_set (G_OBJECT (session), "display-device", tty, NULL);
2fc437
 
2fc437
                 pid = gdm_session_get_pid (session);
2fc437
 
2fc437
                 if (pid > 0) {
2fc437
                         add_session_record (self, session, pid, SESSION_RECORD_LOGIN);
2fc437
                 }
2fc437
         }
2fc437
 
2fc437
         g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL);
2fc437
 
2fc437
         gdm_dbus_manager_complete_register_display (GDM_DBUS_MANAGER (manager),
2fc437
                                                     invocation);
2fc437
 
2fc437
         g_clear_pointer (&x11_display_name, g_free);
2fc437
         g_clear_pointer (&tty, g_free);
2fc437
         return TRUE;
2fc437
 }
2fc437
 
2fc437
 static gboolean
2fc437
 gdm_manager_handle_open_session (GdmDBusManager        *manager,
2fc437
                                  GDBusMethodInvocation *invocation)
2fc437
 {
2fc437
         GdmManager       *self = GDM_MANAGER (manager);
2fc437
         const char       *sender;
2fc437
         GDBusConnection  *connection;
2fc437
         GdmDisplay       *display = NULL;
2fc437
-        GdmSession       *session;
2fc437
+        GdmSession       *session = NULL;
2fc437
         const char       *address;
2fc437
         GPid              pid = 0;
2fc437
         uid_t             uid = (uid_t) -1;
2fc437
         uid_t             allowed_user;
2fc437
 
2fc437
         g_debug ("GdmManager: trying to open new session");
2fc437
 
2fc437
         sender = g_dbus_method_invocation_get_sender (invocation);
2fc437
         connection = g_dbus_method_invocation_get_connection (invocation);
2fc437
         get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, NULL, &pid, &uid, NULL, NULL);
2fc437
 
2fc437
         if (display == NULL) {
2fc437
                 g_dbus_method_invocation_return_error_literal (invocation,
2fc437
                                                                G_DBUS_ERROR,
2fc437
                                                                G_DBUS_ERROR_ACCESS_DENIED,
2fc437
                                                                _("No session available"));
2fc437
 
2fc437
                 return TRUE;
2fc437
         }
2fc437
 
2fc437
-        session = get_embryonic_user_session_for_display (display);
2fc437
+        if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) {
2fc437
+                GdmLaunchEnvironment *launch_environment;
2fc437
 
2fc437
-        if (gdm_session_is_running (session)) {
2fc437
-                g_dbus_method_invocation_return_error_literal (invocation,
2fc437
-                                                               G_DBUS_ERROR,
2fc437
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
2fc437
-                                                               _("Can only be called before user is logged in"));
2fc437
-                return TRUE;
2fc437
+                g_object_get (display, "launch-environment", &launch_environment, NULL);
2fc437
+
2fc437
+                if (launch_environment != NULL) {
2fc437
+                        session = gdm_launch_environment_get_session (launch_environment);
2fc437
+                }
2fc437
+
2fc437
+                if (session == NULL) {
2fc437
+                        g_dbus_method_invocation_return_error_literal (invocation,
2fc437
+                                                                       G_DBUS_ERROR,
2fc437
+                                                                       G_DBUS_ERROR_ACCESS_DENIED,
2fc437
+                                                                       _("Chooser session unavailable"));
2fc437
+                        return TRUE;
2fc437
+                }
2fc437
+        } else {
2fc437
+                session = get_embryonic_user_session_for_display (display);
2fc437
+
2fc437
+                if (gdm_session_is_running (session)) {
2fc437
+                        g_dbus_method_invocation_return_error_literal (invocation,
2fc437
+                                                                       G_DBUS_ERROR,
2fc437
+                                                                       G_DBUS_ERROR_ACCESS_DENIED,
2fc437
+                                                                       _("Can only be called before user is logged in"));
2fc437
+                        return TRUE;
2fc437
+                }
2fc437
         }
2fc437
 
2fc437
         allowed_user = gdm_session_get_allowed_user (session);
2fc437
 
2fc437
         if (uid != allowed_user) {
2fc437
                 g_dbus_method_invocation_return_error_literal (invocation,
2fc437
                                                                G_DBUS_ERROR,
2fc437
                                                                G_DBUS_ERROR_ACCESS_DENIED,
2fc437
                                                                _("Caller not GDM"));
2fc437
                 return TRUE;
2fc437
         }
2fc437
 
2fc437
         address = gdm_session_get_server_address (session);
2fc437
 
2fc437
         if (address == NULL) {
2fc437
                 g_dbus_method_invocation_return_error_literal (invocation,
2fc437
                                                                G_DBUS_ERROR,
2fc437
                                                                G_DBUS_ERROR_ACCESS_DENIED,
2fc437
                                                                _("Unable to open private communication channel"));
2fc437
                 return TRUE;
2fc437
         }
2fc437
 
2fc437
         gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
2fc437
                                                 invocation,
2fc437
                                                 address);
2fc437
         return TRUE;
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 close_transient_session (GdmManager *self,
2fc437
@@ -1309,60 +1329,80 @@ get_username_for_greeter_display (GdmManager *manager,
2fc437
         }
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 set_up_automatic_login_session (GdmManager *manager,
2fc437
                                 GdmDisplay *display)
2fc437
 {
2fc437
         GdmSession *session;
2fc437
         char       *display_session_type = NULL;
2fc437
         gboolean is_initial;
2fc437
 
2fc437
         /* 0 is root user; since the daemon talks to the session object
2fc437
          * directly, itself, for automatic login
2fc437
          */
2fc437
         session = create_embryonic_user_session_for_display (manager, display, 0);
2fc437
 
2fc437
         g_object_get (G_OBJECT (display),
2fc437
                       "is-initial", &is_initial,
2fc437
                       "session-type", &display_session_type,
2fc437
                       NULL);
2fc437
 
2fc437
         g_object_set (G_OBJECT (session),
2fc437
                       "display-is-initial", is_initial,
2fc437
                       NULL);
2fc437
 
2fc437
         g_debug ("GdmManager: Starting automatic login conversation");
2fc437
         gdm_session_start_conversation (session, "gdm-autologin");
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
+set_up_chooser_session (GdmManager *manager,
2fc437
+                        GdmDisplay *display)
2fc437
+{
2fc437
+        const char *allowed_user;
2fc437
+        struct passwd *passwd_entry;
2fc437
+
2fc437
+        allowed_user = get_username_for_greeter_display (manager, display);
2fc437
+
2fc437
+        if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
2fc437
+                g_warning ("GdmManager: couldn't look up username %s",
2fc437
+                           allowed_user);
2fc437
+                gdm_display_unmanage (display);
2fc437
+                gdm_display_finish (display);
2fc437
+                return;
2fc437
+        }
2fc437
+
2fc437
+        gdm_display_start_greeter_session (display);
2fc437
+}
2fc437
+
2fc437
+static void
2fc437
 set_up_greeter_session (GdmManager *manager,
2fc437
                         GdmDisplay *display)
2fc437
 {
2fc437
         const char *allowed_user;
2fc437
         struct passwd *passwd_entry;
2fc437
 
2fc437
         allowed_user = get_username_for_greeter_display (manager, display);
2fc437
 
2fc437
         if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
2fc437
                 g_warning ("GdmManager: couldn't look up username %s",
2fc437
                            allowed_user);
2fc437
                 gdm_display_unmanage (display);
2fc437
                 gdm_display_finish (display);
2fc437
                 return;
2fc437
         }
2fc437
 
2fc437
         create_embryonic_user_session_for_display (manager, display, passwd_entry->pw_uid);
2fc437
         gdm_display_start_greeter_session (display);
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 set_up_automatic_login_session_if_user_exists (GdmManager *manager,
2fc437
                                                GdmDisplay *display,
2fc437
                                                ActUser    *user)
2fc437
 {
2fc437
         if (act_user_is_nonexistent (user))
2fc437
                 set_up_greeter_session (manager, display);
2fc437
         else
2fc437
                 set_up_automatic_login_session (manager, display);
2fc437
 }
2fc437
@@ -1383,61 +1423,65 @@ destroy_username_lookup_operation (UsernameLookupOperation *operation)
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 on_user_is_loaded_changed (ActUser                 *user,
2fc437
                            GParamSpec              *pspec,
2fc437
                            UsernameLookupOperation *operation)
2fc437
 {
2fc437
         if (act_user_is_loaded (user)) {
2fc437
                 set_up_automatic_login_session_if_user_exists (operation->manager, operation->display, user);
2fc437
                 g_signal_handlers_disconnect_by_func (G_OBJECT (user),
2fc437
                                                       G_CALLBACK (on_user_is_loaded_changed),
2fc437
                                                       operation);
2fc437
                 destroy_username_lookup_operation (operation);
2fc437
         }
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 set_up_session (GdmManager *manager,
2fc437
                 GdmDisplay *display)
2fc437
 {
2fc437
         ActUserManager *user_manager;
2fc437
         ActUser *user;
2fc437
         gboolean loaded;
2fc437
         gboolean autologin_enabled = FALSE;
2fc437
         char *username = NULL;
2fc437
 
2fc437
         if (!manager->priv->ran_once && display_is_on_seat0 (display))
2fc437
                 autologin_enabled = get_automatic_login_details (manager, &username);
2fc437
 
2fc437
         if (!autologin_enabled) {
2fc437
-                set_up_greeter_session (manager, display);
2fc437
+                if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) {
2fc437
+                        set_up_chooser_session (manager, display);
2fc437
+                } else {
2fc437
+                        set_up_greeter_session (manager, display);
2fc437
+                }
2fc437
                 g_free (username);
2fc437
                 return;
2fc437
         }
2fc437
 
2fc437
         /* Check whether the user really exists before committing to autologin. */
2fc437
         user_manager = act_user_manager_get_default ();
2fc437
         user = act_user_manager_get_user (user_manager, username);
2fc437
         g_object_get (user_manager, "is-loaded", &loaded, NULL);
2fc437
 
2fc437
         if (loaded) {
2fc437
                 set_up_automatic_login_session_if_user_exists (manager, display, user);
2fc437
         } else {
2fc437
                 UsernameLookupOperation *operation;
2fc437
 
2fc437
                 operation = g_new (UsernameLookupOperation, 1);
2fc437
                 operation->manager = g_object_ref (manager);
2fc437
                 operation->display = g_object_ref (display);
2fc437
                 operation->username = username;
2fc437
 
2fc437
                 g_signal_connect (user,
2fc437
                                   "notify::is-loaded",
2fc437
                                   G_CALLBACK (on_user_is_loaded_changed),
2fc437
                                   operation);
2fc437
         }
2fc437
 }
2fc437
 
2fc437
 static void
2fc437
 greeter_display_started (GdmManager *manager,
2fc437
                          GdmDisplay *display)
2fc437
 {
2fc437
-- 
2fc437
2.12.0
2fc437