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

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