|
|
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 |
|