1016 lines
39 KiB
Diff
1016 lines
39 KiB
Diff
|
From d3b60b5211d804e23c663d053c5b511dede22a28 Mon Sep 17 00:00:00 2001
|
||
|
From: Iain Lane <iainl@gnome.org>
|
||
|
Date: Thu, 31 Jan 2019 10:52:35 +0000
|
||
|
Subject: [PATCH 2/4] manager,session: Add some debugging around starting
|
||
|
reauthentication
|
||
|
|
||
|
There's a bug right now dealing with timed login and reauthentication,
|
||
|
but it's not clear what's going on by looking at the logs.
|
||
|
|
||
|
This commit sprinkles some more logging throughout the code, to make
|
||
|
the bug easier to track.
|
||
|
---
|
||
|
daemon/gdm-manager.c | 46 ++++++++++++++++++++++++++++++++++++++------
|
||
|
daemon/gdm-session.c | 25 ++++++++++++++++++++----
|
||
|
2 files changed, 61 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
||
|
index b2d0578f5..0cc06a978 100644
|
||
|
--- a/daemon/gdm-manager.c
|
||
|
+++ b/daemon/gdm-manager.c
|
||
|
@@ -340,77 +340,94 @@ session_unlock (GdmManager *manager,
|
||
|
"org.freedesktop.login1.Manager",
|
||
|
"UnlockSession",
|
||
|
g_variant_new ("(s)", ssid),
|
||
|
NULL, /* expected reply */
|
||
|
G_DBUS_CALL_FLAGS_NONE,
|
||
|
-1,
|
||
|
NULL,
|
||
|
&error);
|
||
|
if (reply == NULL) {
|
||
|
g_debug ("GdmManager: logind 'UnlockSession' %s raised:\n %s\n\n",
|
||
|
g_dbus_error_get_remote_error (error), error->message);
|
||
|
g_error_free (error);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
g_variant_unref (reply);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static GdmSession *
|
||
|
find_session_for_user_on_seat (GdmManager *manager,
|
||
|
const char *username,
|
||
|
const char *seat_id,
|
||
|
GdmSession *dont_count_session)
|
||
|
{
|
||
|
GList *node;
|
||
|
|
||
|
for (node = manager->priv->user_sessions; node != NULL; node = node->next) {
|
||
|
GdmSession *candidate_session = node->data;
|
||
|
- const char *candidate_username, *candidate_seat_id;
|
||
|
+ const char *candidate_username, *candidate_seat_id, *candidate_session_id;
|
||
|
|
||
|
- if (candidate_session == dont_count_session)
|
||
|
+ candidate_session_id = gdm_session_get_session_id (candidate_session);
|
||
|
+
|
||
|
+ if (candidate_session == dont_count_session) {
|
||
|
+ g_debug ("GdmSession: Ignoring session %s as requested",
|
||
|
+ candidate_session_id);
|
||
|
continue;
|
||
|
+ }
|
||
|
|
||
|
- if (!gdm_session_is_running (candidate_session))
|
||
|
+ if (!gdm_session_is_running (candidate_session)) {
|
||
|
+ g_debug ("GdmSession: Ignoring session %s as it isn't running",
|
||
|
+ candidate_session_id);
|
||
|
continue;
|
||
|
+ }
|
||
|
|
||
|
candidate_username = gdm_session_get_username (candidate_session);
|
||
|
candidate_seat_id = gdm_session_get_display_seat_id (candidate_session);
|
||
|
|
||
|
+ g_debug ("GdmManager: Considering session %s on seat %s belonging to user %s",
|
||
|
+ candidate_session_id,
|
||
|
+ candidate_seat_id,
|
||
|
+ candidate_username);
|
||
|
+
|
||
|
if (g_strcmp0 (candidate_username, username) == 0 &&
|
||
|
g_strcmp0 (candidate_seat_id, seat_id) == 0) {
|
||
|
+ g_debug ("GdmManager: yes, found session %s", candidate_session_id);
|
||
|
return candidate_session;
|
||
|
}
|
||
|
+
|
||
|
+ g_debug ("GdmManager: no, will not use session %s", candidate_session_id);
|
||
|
}
|
||
|
|
||
|
+ g_debug ("GdmManager: no matching sessions found");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
is_remote_session (GdmManager *self,
|
||
|
const char *session_id,
|
||
|
GError **error)
|
||
|
{
|
||
|
char *seat;
|
||
|
int ret;
|
||
|
gboolean is_remote;
|
||
|
|
||
|
/* FIXME: The next release of logind is going to have explicit api for
|
||
|
* checking remoteness.
|
||
|
*/
|
||
|
seat = NULL;
|
||
|
ret = sd_session_get_seat (session_id, &seat);
|
||
|
|
||
|
if (ret < 0 && ret != -ENOENT) {
|
||
|
g_debug ("GdmManager: Error while retrieving seat for session %s: %s",
|
||
|
session_id, strerror (-ret));
|
||
|
}
|
||
|
|
||
|
if (seat != NULL) {
|
||
|
is_remote = FALSE;
|
||
|
free (seat);
|
||
|
} else {
|
||
|
is_remote = TRUE;
|
||
|
}
|
||
|
|
||
|
@@ -840,62 +857,66 @@ gdm_manager_handle_open_session (GdmDBusManager *manager,
|
||
|
if (display == NULL) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("No session available"));
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
#ifdef HAVE_LIBXDMCP
|
||
|
if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) {
|
||
|
GdmLaunchEnvironment *launch_environment;
|
||
|
|
||
|
g_object_get (display, "launch-environment", &launch_environment, NULL);
|
||
|
|
||
|
if (launch_environment != NULL) {
|
||
|
session = gdm_launch_environment_get_session (launch_environment);
|
||
|
}
|
||
|
|
||
|
if (session == NULL) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("Chooser session unavailable"));
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
if (session == NULL) {
|
||
|
session = get_user_session_for_display (display);
|
||
|
+ g_debug ("GdmSession: Considering session %s for username %s",
|
||
|
+ gdm_session_get_session_id (session),
|
||
|
+ gdm_session_get_username (session));
|
||
|
|
||
|
if (gdm_session_is_running (session)) {
|
||
|
+ g_debug ("GdmSession: the session is running, and therefore can't be used");
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("Can only be called before user is logged in"));
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
allowed_user = gdm_session_get_allowed_user (session);
|
||
|
|
||
|
if (uid != allowed_user) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("Caller not GDM"));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
address = gdm_session_get_server_address (session);
|
||
|
|
||
|
if (address == NULL) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("Unable to open private communication channel"));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
|
||
|
invocation,
|
||
|
@@ -1017,60 +1038,64 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
||
|
char *seat_id,
|
||
|
char *session_id,
|
||
|
GPid pid,
|
||
|
uid_t uid,
|
||
|
gboolean is_remote)
|
||
|
{
|
||
|
GdmSession *session;
|
||
|
char **environment;
|
||
|
const char *display, *auth_file;
|
||
|
const char *address;
|
||
|
|
||
|
/* Note we're just using a minimal environment here rather than the
|
||
|
* session's environment because the caller is unprivileged and the
|
||
|
* associated worker will be privileged */
|
||
|
environment = g_get_environ ();
|
||
|
display = "";
|
||
|
auth_file = "/dev/null";
|
||
|
|
||
|
session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE,
|
||
|
uid,
|
||
|
display,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
seat_id,
|
||
|
auth_file,
|
||
|
is_remote == FALSE,
|
||
|
(const char * const *)
|
||
|
environment);
|
||
|
g_strfreev (environment);
|
||
|
|
||
|
+ g_debug ("GdmSession: Created session for temporary reauthentication channel for user %d (seat %s)",
|
||
|
+ (int) uid,
|
||
|
+ seat_id);
|
||
|
+
|
||
|
g_object_set_data_full (G_OBJECT (session),
|
||
|
"caller-session-id",
|
||
|
g_strdup (session_id),
|
||
|
(GDestroyNotify)
|
||
|
g_free);
|
||
|
g_object_set_data (G_OBJECT (session),
|
||
|
"caller-pid",
|
||
|
GUINT_TO_POINTER (pid));
|
||
|
g_hash_table_insert (self->priv->transient_sessions,
|
||
|
GINT_TO_POINTER (pid),
|
||
|
session);
|
||
|
|
||
|
g_signal_connect (session,
|
||
|
"client-connected",
|
||
|
G_CALLBACK (on_reauthentication_client_connected),
|
||
|
self);
|
||
|
g_signal_connect (session,
|
||
|
"client-disconnected",
|
||
|
G_CALLBACK (on_reauthentication_client_disconnected),
|
||
|
self);
|
||
|
g_signal_connect (session,
|
||
|
"client-rejected",
|
||
|
G_CALLBACK (on_reauthentication_client_rejected),
|
||
|
self);
|
||
|
g_signal_connect (session,
|
||
|
"cancelled",
|
||
|
G_CALLBACK (on_reauthentication_cancelled),
|
||
|
self);
|
||
|
g_signal_connect (session,
|
||
|
"conversation-started",
|
||
|
@@ -1096,65 +1121,67 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
|
||
|
const char *username)
|
||
|
{
|
||
|
GdmManager *self = GDM_MANAGER (manager);
|
||
|
const char *sender;
|
||
|
GdmDisplay *display = NULL;
|
||
|
GdmSession *session;
|
||
|
GDBusConnection *connection;
|
||
|
char *seat_id = NULL;
|
||
|
char *session_id = NULL;
|
||
|
GPid pid = 0;
|
||
|
uid_t uid = (uid_t) -1;
|
||
|
gboolean is_login_screen = FALSE;
|
||
|
gboolean is_remote = FALSE;
|
||
|
|
||
|
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
||
|
|
||
|
sender = g_dbus_method_invocation_get_sender (invocation);
|
||
|
connection = g_dbus_method_invocation_get_connection (invocation);
|
||
|
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote);
|
||
|
|
||
|
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
_("No session available"));
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if (is_login_screen) {
|
||
|
+ g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id);
|
||
|
session = find_session_for_user_on_seat (self,
|
||
|
username,
|
||
|
seat_id,
|
||
|
NULL);
|
||
|
} else {
|
||
|
+ g_debug ("GdmManager: looking for user session on display");
|
||
|
session = get_user_session_for_display (display);
|
||
|
}
|
||
|
|
||
|
if (session != NULL && gdm_session_is_running (session)) {
|
||
|
gdm_session_start_reauthentication (session, pid, uid);
|
||
|
g_hash_table_insert (self->priv->open_reauthentication_requests,
|
||
|
GINT_TO_POINTER (pid),
|
||
|
invocation);
|
||
|
} else if (is_login_screen) {
|
||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||
|
G_DBUS_ERROR,
|
||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||
|
"Login screen only allowed to open reauthentication channels for running sessions");
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
char *address;
|
||
|
address = open_temporary_reauthentication_channel (self,
|
||
|
seat_id,
|
||
|
session_id,
|
||
|
pid,
|
||
|
uid,
|
||
|
is_remote);
|
||
|
gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
|
||
|
invocation,
|
||
|
address);
|
||
|
g_free (address);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
@@ -2087,107 +2114,107 @@ on_session_client_ready_for_session_to_start (GdmSession *session,
|
||
|
if (client_is_ready) {
|
||
|
g_debug ("GdmManager: Will start session when ready");
|
||
|
} else {
|
||
|
g_debug ("GdmManager: Will start session when ready and told");
|
||
|
}
|
||
|
|
||
|
waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session),
|
||
|
"waiting-to-start"));
|
||
|
|
||
|
g_object_set_data (G_OBJECT (session),
|
||
|
"start-when-ready",
|
||
|
GINT_TO_POINTER (client_is_ready));
|
||
|
|
||
|
if (client_is_ready && waiting_to_start_user_session) {
|
||
|
start_user_session_if_ready (manager, session, service_name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_session_client_connected (GdmSession *session,
|
||
|
GCredentials *credentials,
|
||
|
GPid pid_of_client,
|
||
|
GdmManager *manager)
|
||
|
{
|
||
|
GdmDisplay *display;
|
||
|
char *username;
|
||
|
int delay;
|
||
|
gboolean enabled;
|
||
|
gboolean allow_timed_login = FALSE;
|
||
|
|
||
|
- g_debug ("GdmManager: client connected");
|
||
|
+ g_debug ("GdmManager: client with pid %d connected", (int) pid_of_client);
|
||
|
|
||
|
display = get_display_for_user_session (session);
|
||
|
|
||
|
if (display == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!display_is_on_seat0 (display)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#ifdef WITH_PLYMOUTH
|
||
|
if (manager->priv->plymouth_is_running) {
|
||
|
plymouth_quit_with_transition ();
|
||
|
manager->priv->plymouth_is_running = FALSE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL);
|
||
|
|
||
|
if (!allow_timed_login) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
enabled = get_timed_login_details (manager, &username, &delay);
|
||
|
|
||
|
if (! enabled) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
gdm_session_set_timed_login_details (session, username, delay);
|
||
|
|
||
|
g_debug ("GdmManager: Starting automatic login conversation (for timed login)");
|
||
|
gdm_session_start_conversation (session, "gdm-autologin");
|
||
|
|
||
|
g_free (username);
|
||
|
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_session_client_disconnected (GdmSession *session,
|
||
|
GCredentials *credentials,
|
||
|
GPid pid_of_client,
|
||
|
GdmManager *manager)
|
||
|
{
|
||
|
- g_debug ("GdmManager: client disconnected");
|
||
|
+ g_debug ("GdmManager: client with pid %d disconnected", (int) pid_of_client);
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
GdmManager *manager;
|
||
|
GdmSession *session;
|
||
|
guint idle_id;
|
||
|
} ResetSessionOperation;
|
||
|
|
||
|
static void
|
||
|
destroy_reset_session_operation (ResetSessionOperation *operation)
|
||
|
{
|
||
|
g_object_set_data (G_OBJECT (operation->session),
|
||
|
"reset-session-operation",
|
||
|
NULL);
|
||
|
g_object_unref (operation->session);
|
||
|
g_slice_free (ResetSessionOperation, operation);
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
on_reset_session (ResetSessionOperation *operation)
|
||
|
{
|
||
|
gdm_session_reset (operation->session);
|
||
|
|
||
|
destroy_reset_session_operation (operation);
|
||
|
|
||
|
return G_SOURCE_REMOVE;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -2200,63 +2227,64 @@ queue_session_reset (GdmManager *manager,
|
||
|
|
||
|
if (operation != NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
operation = g_slice_new0 (ResetSessionOperation);
|
||
|
operation->manager = manager;
|
||
|
operation->session = g_object_ref (session);
|
||
|
operation->idle_id = g_idle_add ((GSourceFunc) on_reset_session, operation);
|
||
|
|
||
|
g_object_set_data (G_OBJECT (session), "reset-session-operation", operation);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_session_cancelled (GdmSession *session,
|
||
|
GdmManager *manager)
|
||
|
{
|
||
|
g_debug ("GdmManager: Session was cancelled");
|
||
|
queue_session_reset (manager, session);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_session_conversation_started (GdmSession *session,
|
||
|
const char *service_name,
|
||
|
GdmManager *manager)
|
||
|
{
|
||
|
GdmDisplay *display;
|
||
|
gboolean enabled;
|
||
|
char *username;
|
||
|
|
||
|
- g_debug ("GdmManager: session conversation started for service %s", service_name);
|
||
|
+ g_debug ("GdmManager: session conversation started for service %s on session", service_name);
|
||
|
|
||
|
if (g_strcmp0 (service_name, "gdm-autologin") != 0) {
|
||
|
+ g_debug ("GdmManager: ignoring session conversation since its not automatic login conversation");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
display = get_display_for_user_session (session);
|
||
|
|
||
|
if (display == NULL) {
|
||
|
g_debug ("GdmManager: conversation has no associated display");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!display_is_on_seat0 (display)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
enabled = get_automatic_login_details (manager, &username);
|
||
|
|
||
|
if (! enabled) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
g_debug ("GdmManager: begin auto login for user '%s'", username);
|
||
|
|
||
|
/* service_name will be "gdm-autologin"
|
||
|
*/
|
||
|
gdm_session_setup_for_user (session, service_name, username);
|
||
|
|
||
|
g_free (username);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -2312,60 +2340,66 @@ create_user_session_for_display (GdmManager *manager,
|
||
|
char *display_auth_file = NULL;
|
||
|
char *display_seat_id = NULL;
|
||
|
char *display_id = NULL;
|
||
|
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
|
||
|
char *display_session_type = NULL;
|
||
|
gboolean greeter_is_wayland;
|
||
|
#endif
|
||
|
|
||
|
g_object_get (G_OBJECT (display),
|
||
|
"id", &display_id,
|
||
|
"x11-display-name", &display_name,
|
||
|
"is-local", &display_is_local,
|
||
|
"remote-hostname", &remote_hostname,
|
||
|
"x11-authority-file", &display_auth_file,
|
||
|
"seat-id", &display_seat_id,
|
||
|
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
|
||
|
"session-type", &display_session_type,
|
||
|
#endif
|
||
|
NULL);
|
||
|
display_device = get_display_device (manager, display);
|
||
|
|
||
|
session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
|
||
|
allowed_user,
|
||
|
display_name,
|
||
|
remote_hostname,
|
||
|
display_device,
|
||
|
display_seat_id,
|
||
|
display_auth_file,
|
||
|
display_is_local,
|
||
|
NULL);
|
||
|
+
|
||
|
+ g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)",
|
||
|
+ (int) allowed_user,
|
||
|
+ display_id,
|
||
|
+ display_seat_id);
|
||
|
+
|
||
|
g_free (display_name);
|
||
|
g_free (remote_hostname);
|
||
|
g_free (display_auth_file);
|
||
|
g_free (display_seat_id);
|
||
|
|
||
|
g_signal_connect (session,
|
||
|
"reauthentication-started",
|
||
|
G_CALLBACK (on_session_reauthentication_started),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
"reauthenticated",
|
||
|
G_CALLBACK (on_session_reauthenticated),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
"client-ready-for-session-to-start",
|
||
|
G_CALLBACK (on_session_client_ready_for_session_to_start),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
"client-connected",
|
||
|
G_CALLBACK (on_session_client_connected),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
"client-disconnected",
|
||
|
G_CALLBACK (on_session_client_disconnected),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
"cancelled",
|
||
|
G_CALLBACK (on_session_cancelled),
|
||
|
manager);
|
||
|
g_signal_connect (session,
|
||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||
|
index 0f821e390..f23a83c5e 100644
|
||
|
--- a/daemon/gdm-session.c
|
||
|
+++ b/daemon/gdm-session.c
|
||
|
@@ -624,61 +624,64 @@ get_fallback_session_name (GdmSession *self)
|
||
|
|
||
|
static const char *
|
||
|
get_default_session_name (GdmSession *self)
|
||
|
{
|
||
|
if (self->priv->saved_session != NULL) {
|
||
|
return self->priv->saved_session;
|
||
|
}
|
||
|
|
||
|
return get_fallback_session_name (self);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gdm_session_defaults_changed (GdmSession *self)
|
||
|
{
|
||
|
|
||
|
update_session_type (self);
|
||
|
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
||
|
get_default_language_name (self));
|
||
|
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
||
|
get_default_session_name (self));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_select_user (GdmSession *self,
|
||
|
const char *text)
|
||
|
{
|
||
|
|
||
|
- g_debug ("GdmSession: Setting user: '%s'", text);
|
||
|
+ g_debug ("GdmSession: selecting user '%s' for session '%s' (%p)",
|
||
|
+ text,
|
||
|
+ gdm_session_get_session_id (self),
|
||
|
+ self);
|
||
|
|
||
|
g_free (self->priv->selected_user);
|
||
|
self->priv->selected_user = g_strdup (text);
|
||
|
|
||
|
g_free (self->priv->saved_session);
|
||
|
self->priv->saved_session = NULL;
|
||
|
|
||
|
g_free (self->priv->saved_session_type);
|
||
|
self->priv->saved_session_type = NULL;
|
||
|
|
||
|
g_free (self->priv->saved_language);
|
||
|
self->priv->saved_language = NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
cancel_pending_query (GdmSessionConversation *conversation)
|
||
|
{
|
||
|
if (conversation->pending_invocation == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
g_debug ("GdmSession: Cancelling pending query");
|
||
|
|
||
|
g_dbus_method_invocation_return_dbus_error (conversation->pending_invocation,
|
||
|
GDM_SESSION_DBUS_ERROR_CANCEL,
|
||
|
"Operation cancelled");
|
||
|
conversation->pending_invocation = NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -1416,117 +1419,121 @@ gdm_session_handle_client_cancel (GdmDBusUserVerifier *user_verifier_interfac
|
||
|
gdm_dbus_user_verifier_complete_cancel (user_verifier_interface,
|
||
|
invocation);
|
||
|
gdm_session_cancel (self);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interface,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
const char *session,
|
||
|
GdmSession *self)
|
||
|
{
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_complete_select_session (greeter_interface,
|
||
|
invocation);
|
||
|
}
|
||
|
gdm_session_select_session (self, session);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
const char *username,
|
||
|
GdmSession *self)
|
||
|
{
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_complete_select_user (greeter_interface,
|
||
|
invocation);
|
||
|
}
|
||
|
+ g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self);
|
||
|
gdm_session_select_user (self, username);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greeter_interface,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
const char *service_name,
|
||
|
gboolean client_is_ready,
|
||
|
GdmSession *self)
|
||
|
{
|
||
|
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface,
|
||
|
invocation);
|
||
|
}
|
||
|
g_signal_emit (G_OBJECT (self),
|
||
|
signals [CLIENT_READY_FOR_SESSION_TO_START],
|
||
|
0,
|
||
|
service_name,
|
||
|
client_is_ready);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
GdmSession *self)
|
||
|
{
|
||
|
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface,
|
||
|
invocation,
|
||
|
self->priv->timed_login_username != NULL,
|
||
|
self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
|
||
|
self->priv->timed_login_delay);
|
||
|
if (self->priv->timed_login_username != NULL) {
|
||
|
gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
|
||
|
self->priv->timed_login_username,
|
||
|
self->priv->timed_login_delay);
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
const char *username,
|
||
|
GdmSession *self)
|
||
|
{
|
||
|
if (self->priv->greeter_interface != NULL) {
|
||
|
gdm_dbus_greeter_complete_begin_auto_login (greeter_interface,
|
||
|
invocation);
|
||
|
}
|
||
|
|
||
|
- g_debug ("GdmSession: begin auto login for user '%s'", username);
|
||
|
+ g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)",
|
||
|
+ username,
|
||
|
+ gdm_session_get_session_id (self),
|
||
|
+ self);
|
||
|
|
||
|
gdm_session_setup_for_user (self, "gdm-autologin", username);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
export_user_verifier_interface (GdmSession *self,
|
||
|
GDBusConnection *connection)
|
||
|
{
|
||
|
GdmDBusUserVerifier *user_verifier_interface;
|
||
|
user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ());
|
||
|
|
||
|
g_object_set_data (G_OBJECT (connection), "gdm-session", self);
|
||
|
|
||
|
g_signal_connect (user_verifier_interface,
|
||
|
"handle-enable-extensions",
|
||
|
G_CALLBACK (gdm_session_handle_client_enable_extensions),
|
||
|
connection);
|
||
|
g_signal_connect (user_verifier_interface,
|
||
|
"handle-begin-verification",
|
||
|
G_CALLBACK (gdm_session_handle_client_begin_verification),
|
||
|
self);
|
||
|
g_signal_connect (user_verifier_interface,
|
||
|
"handle-begin-verification-for-user",
|
||
|
G_CALLBACK (gdm_session_handle_client_begin_verification_for_user),
|
||
|
self);
|
||
|
g_signal_connect (user_verifier_interface,
|
||
|
"handle-answer-query",
|
||
|
G_CALLBACK (gdm_session_handle_client_answer_query),
|
||
|
@@ -1775,61 +1782,63 @@ allow_user_function (GDBusAuthObserver *observer,
|
||
|
{
|
||
|
uid_t client_uid;
|
||
|
GPid pid_of_client;
|
||
|
|
||
|
client_uid = g_credentials_get_unix_user (credentials, NULL);
|
||
|
if (client_uid == self->priv->allowed_user) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
g_debug ("GdmSession: User not allowed");
|
||
|
|
||
|
pid_of_client = g_credentials_get_unix_pid (credentials, NULL);
|
||
|
g_signal_emit (G_OBJECT (self),
|
||
|
signals [CLIENT_REJECTED],
|
||
|
0,
|
||
|
credentials,
|
||
|
(guint)
|
||
|
pid_of_client);
|
||
|
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
setup_outside_server (GdmSession *self)
|
||
|
{
|
||
|
GDBusAuthObserver *observer;
|
||
|
GDBusServer *server;
|
||
|
GError *error = NULL;
|
||
|
|
||
|
- g_debug ("GdmSession: Creating D-Bus server for greeters and such");
|
||
|
+ g_debug ("GdmSession: Creating D-Bus server for greeters and such for session %s (%p)",
|
||
|
+ gdm_session_get_session_id (self),
|
||
|
+ self);
|
||
|
|
||
|
observer = g_dbus_auth_observer_new ();
|
||
|
g_signal_connect_object (observer,
|
||
|
"authorize-authenticated-peer",
|
||
|
G_CALLBACK (allow_user_function),
|
||
|
self,
|
||
|
0);
|
||
|
|
||
|
server = gdm_dbus_setup_private_server (observer, &error);
|
||
|
g_object_unref (observer);
|
||
|
|
||
|
if (server == NULL) {
|
||
|
g_warning ("Cannot create greeter D-Bus server for the session: %s",
|
||
|
error->message);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
g_signal_connect_object (server,
|
||
|
"new-connection",
|
||
|
G_CALLBACK (handle_connection_from_outside),
|
||
|
self,
|
||
|
0);
|
||
|
self->priv->outside_server = server;
|
||
|
|
||
|
g_dbus_server_start (server);
|
||
|
|
||
|
g_debug ("GdmSession: D-Bus server for greeters listening on %s",
|
||
|
g_dbus_server_get_client_address (self->priv->outside_server));
|
||
|
}
|
||
|
|
||
|
@@ -2160,61 +2169,61 @@ stop_conversation_now (GdmSessionConversation *conversation)
|
||
|
void
|
||
|
gdm_session_set_ignore_wayland (GdmSession *self,
|
||
|
gboolean ignore_wayland)
|
||
|
{
|
||
|
self->priv->ignore_wayland = ignore_wayland;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
gboolean
|
||
|
gdm_session_start_conversation (GdmSession *self,
|
||
|
const char *service_name)
|
||
|
{
|
||
|
GdmSessionConversation *conversation;
|
||
|
|
||
|
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
||
|
|
||
|
conversation = g_hash_table_lookup (self->priv->conversations,
|
||
|
service_name);
|
||
|
|
||
|
if (conversation != NULL) {
|
||
|
if (!conversation->is_stopping) {
|
||
|
g_warning ("GdmSession: conversation %s started more than once", service_name);
|
||
|
return FALSE;
|
||
|
}
|
||
|
g_debug ("GdmSession: stopping old conversation %s", service_name);
|
||
|
gdm_session_worker_job_stop_now (conversation->job);
|
||
|
g_object_unref (conversation->job);
|
||
|
conversation->job = NULL;
|
||
|
}
|
||
|
|
||
|
- g_debug ("GdmSession: starting conversation %s", service_name);
|
||
|
+ g_debug ("GdmSession: starting conversation %s for session (%p)", service_name, self);
|
||
|
|
||
|
conversation = start_conversation (self, service_name);
|
||
|
|
||
|
g_hash_table_insert (self->priv->conversations,
|
||
|
g_strdup (service_name), conversation);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_stop_conversation (GdmSession *self,
|
||
|
const char *service_name)
|
||
|
{
|
||
|
GdmSessionConversation *conversation;
|
||
|
|
||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||
|
|
||
|
g_debug ("GdmSession: stopping conversation %s", service_name);
|
||
|
|
||
|
conversation = find_conversation_by_name (self, service_name);
|
||
|
|
||
|
if (conversation != NULL) {
|
||
|
stop_conversation (conversation);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_initialization_complete_cb (GdmDBusWorker *proxy,
|
||
|
GAsyncResult *res,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
@@ -2319,60 +2328,64 @@ initialize (GdmSession *self,
|
||
|
}
|
||
|
|
||
|
g_free (extensions);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_setup (GdmSession *self,
|
||
|
const char *service_name)
|
||
|
{
|
||
|
|
||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||
|
|
||
|
update_session_type (self);
|
||
|
|
||
|
initialize (self, service_name, NULL, NULL);
|
||
|
gdm_session_defaults_changed (self);
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
gdm_session_setup_for_user (GdmSession *self,
|
||
|
const char *service_name,
|
||
|
const char *username)
|
||
|
{
|
||
|
|
||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||
|
g_return_if_fail (username != NULL);
|
||
|
|
||
|
update_session_type (self);
|
||
|
|
||
|
+ g_debug ("GdmSession: Set up service %s for username %s on session (%p)",
|
||
|
+ service_name,
|
||
|
+ username,
|
||
|
+ self);
|
||
|
gdm_session_select_user (self, username);
|
||
|
|
||
|
self->priv->is_program_session = FALSE;
|
||
|
initialize (self, service_name, self->priv->selected_user, NULL);
|
||
|
gdm_session_defaults_changed (self);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_setup_for_program (GdmSession *self,
|
||
|
const char *service_name,
|
||
|
const char *username,
|
||
|
const char *log_file)
|
||
|
{
|
||
|
|
||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||
|
|
||
|
self->priv->is_program_session = TRUE;
|
||
|
initialize (self, service_name, username, log_file);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_authenticate (GdmSession *self,
|
||
|
const char *service_name)
|
||
|
{
|
||
|
GdmSessionConversation *conversation;
|
||
|
|
||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||
|
|
||
|
conversation = find_conversation_by_name (self, service_name);
|
||
|
if (conversation != NULL) {
|
||
|
@@ -2968,60 +2981,64 @@ gdm_session_set_timed_login_details (GdmSession *self,
|
||
|
|
||
|
gboolean
|
||
|
gdm_session_is_running (GdmSession *self)
|
||
|
{
|
||
|
return self->priv->session_pid > 0;
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gdm_session_client_is_connected (GdmSession *self)
|
||
|
{
|
||
|
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
||
|
|
||
|
return self->priv->outside_connections != NULL;
|
||
|
}
|
||
|
|
||
|
uid_t
|
||
|
gdm_session_get_allowed_user (GdmSession *self)
|
||
|
{
|
||
|
return self->priv->allowed_user;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
gdm_session_start_reauthentication (GdmSession *session,
|
||
|
GPid pid_of_caller,
|
||
|
uid_t uid_of_caller)
|
||
|
{
|
||
|
GdmSessionConversation *conversation = session->priv->session_conversation;
|
||
|
|
||
|
g_return_if_fail (conversation != NULL);
|
||
|
|
||
|
+ g_debug ("GdmSession: starting reauthentication for session %s for client with pid %d",
|
||
|
+ conversation->session_id,
|
||
|
+ (int) uid_of_caller);
|
||
|
+
|
||
|
conversation->reauth_pid_of_caller = pid_of_caller;
|
||
|
|
||
|
gdm_dbus_worker_call_start_reauthentication (conversation->worker_proxy,
|
||
|
(int) pid_of_caller,
|
||
|
(int) uid_of_caller,
|
||
|
conversation->worker_cancellable,
|
||
|
(GAsyncReadyCallback) on_reauthentication_started_cb,
|
||
|
conversation);
|
||
|
}
|
||
|
|
||
|
const char *
|
||
|
gdm_session_get_server_address (GdmSession *self)
|
||
|
{
|
||
|
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
|
||
|
|
||
|
return g_dbus_server_get_client_address (self->priv->outside_server);
|
||
|
}
|
||
|
|
||
|
const char *
|
||
|
gdm_session_get_username (GdmSession *self)
|
||
|
{
|
||
|
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
|
||
|
|
||
|
return self->priv->selected_user;
|
||
|
}
|
||
|
|
||
|
const char *
|
||
|
gdm_session_get_display_device (GdmSession *self)
|
||
|
{
|
||
|
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
|
||
|
--
|
||
|
2.21.0
|
||
|
|