c1c3fec98b
Related: #1184933
275 lines
11 KiB
Diff
275 lines
11 KiB
Diff
From 0ecacfd6123e4026c78d5d61670da0abdcbf7559 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 22 Jan 2015 11:51:18 -0500
|
|
Subject: [PATCH] manager: allow the login screen to do reauthentication
|
|
|
|
At the moment, we only allow the user session to do reauthentication
|
|
from its lock screen. If a user does user switching we instead open
|
|
a new session for checking the user's password.
|
|
|
|
This commit enables reauthentication from the login screen as well.
|
|
---
|
|
daemon/gdm-manager.c | 23 ++++++++++++++---------
|
|
1 file changed, 14 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
index 8c41045..0278512 100644
|
|
--- a/daemon/gdm-manager.c
|
|
+++ b/daemon/gdm-manager.c
|
|
@@ -1161,84 +1161,89 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
|
self);
|
|
|
|
address = gdm_session_get_server_address (session);
|
|
|
|
return g_strdup (address);
|
|
}
|
|
|
|
static gboolean
|
|
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
GDBusMethodInvocation *invocation,
|
|
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, &pid, &uid, &is_login_screen, &is_remote);
|
|
|
|
- if (is_login_screen) {
|
|
- g_dbus_method_invocation_return_error_literal (invocation,
|
|
- G_DBUS_ERROR,
|
|
- G_DBUS_ERROR_ACCESS_DENIED,
|
|
- "Login screen not allow to open reauthentication channel");
|
|
- return TRUE;
|
|
- }
|
|
-
|
|
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;
|
|
}
|
|
|
|
- session = get_seed_session_for_display (display);
|
|
+ if (is_login_screen) {
|
|
+ session = find_session_for_user_on_seat (self,
|
|
+ username,
|
|
+ seat_id,
|
|
+ NULL);
|
|
+ } else {
|
|
+ session = get_seed_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;
|
|
}
|
|
|
|
static void
|
|
manager_interface_init (GdmDBusManagerIface *interface)
|
|
{
|
|
interface->handle_open_session = gdm_manager_handle_open_session;
|
|
interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
|
|
}
|
|
|
|
static void
|
|
set_up_greeter_session (GdmManager *manager,
|
|
GdmDisplay *display)
|
|
{
|
|
char *allowed_user;
|
|
struct passwd *passwd_entry;
|
|
--
|
|
2.2.1
|
|
|
|
From 259ef2d7d7acc4e7bb0602eea835b9585997413b Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 23 Jan 2015 14:25:05 -0500
|
|
Subject: [PATCH] manager: clean seed session when its display goes away
|
|
|
|
If the display goes away right before the session exits, then we
|
|
can crash because we'll try to finish the already finished display.
|
|
|
|
This commit corrects the problem by making sure to dissociate the
|
|
display from the seed session when the display is finished.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=719418
|
|
---
|
|
daemon/gdm-manager.c | 9 ++++++++-
|
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
index 0278512..684e462 100644
|
|
--- a/daemon/gdm-manager.c
|
|
+++ b/daemon/gdm-manager.c
|
|
@@ -1820,60 +1820,67 @@ start_autologin_conversation_if_necessary (GdmManager *manager,
|
|
if (delay == 0 && g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) {
|
|
return;
|
|
}
|
|
|
|
if (!enabled) {
|
|
return;
|
|
}
|
|
|
|
g_debug ("GdmManager: Starting automatic login conversation");
|
|
gdm_session_start_conversation (session, "gdm-autologin");
|
|
}
|
|
|
|
static void
|
|
touch_ran_once_marker_file (GdmManager *manager)
|
|
{
|
|
int fd;
|
|
|
|
fd = g_creat (GDM_RAN_ONCE_MARKER_FILE, 0644);
|
|
|
|
if (fd < 0 && errno != EEXIST) {
|
|
g_warning ("could not create %s to mark run, this may cause auto login "
|
|
"to repeat: %m", GDM_RAN_ONCE_MARKER_FILE);
|
|
return;
|
|
}
|
|
|
|
fsync (fd);
|
|
close (fd);
|
|
}
|
|
|
|
static void
|
|
+clean_seed_session (GdmSession *session)
|
|
+{
|
|
+ g_object_set_data (G_OBJECT (session), "gdm-display", NULL);
|
|
+ g_object_unref (session);
|
|
+}
|
|
+
|
|
+static void
|
|
create_seed_session_for_display (GdmManager *manager,
|
|
GdmDisplay *display,
|
|
uid_t allowed_user)
|
|
{
|
|
GdmSession *session;
|
|
gboolean display_is_local = FALSE;
|
|
char *display_name = NULL;
|
|
char *display_device = NULL;
|
|
char *remote_hostname = NULL;
|
|
char *display_auth_file = NULL;
|
|
char *display_seat_id = NULL;
|
|
char *display_id = NULL;
|
|
|
|
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,
|
|
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,
|
|
@@ -1906,61 +1913,61 @@ create_seed_session_for_display (GdmManager *manager,
|
|
manager);
|
|
g_signal_connect (session,
|
|
"cancelled",
|
|
G_CALLBACK (on_session_cancelled),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"conversation-started",
|
|
G_CALLBACK (on_session_conversation_started),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"conversation-stopped",
|
|
G_CALLBACK (on_session_conversation_stopped),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"session-opened",
|
|
G_CALLBACK (on_session_opened),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"session-started",
|
|
G_CALLBACK (on_session_started),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"session-exited",
|
|
G_CALLBACK (on_user_session_exited),
|
|
manager);
|
|
g_signal_connect (session,
|
|
"session-died",
|
|
G_CALLBACK (on_user_session_died),
|
|
manager);
|
|
g_object_set_data (G_OBJECT (session), "gdm-display", display);
|
|
- g_object_set_data_full (G_OBJECT (display), "gdm-seed-session", g_object_ref (session), (GDestroyNotify) g_object_unref);
|
|
+ g_object_set_data_full (G_OBJECT (display), "gdm-seed-session", g_object_ref (session), (GDestroyNotify) clean_seed_session);
|
|
|
|
start_autologin_conversation_if_necessary (manager, display, session);
|
|
}
|
|
|
|
static void
|
|
on_display_added (GdmDisplayStore *display_store,
|
|
const char *id,
|
|
GdmManager *manager)
|
|
{
|
|
GdmDisplay *display;
|
|
|
|
display = gdm_display_store_lookup (display_store, id);
|
|
|
|
if (display != NULL) {
|
|
g_dbus_object_manager_server_export (manager->priv->object_manager,
|
|
gdm_display_get_object_skeleton (display));
|
|
|
|
g_signal_connect (display, "notify::status",
|
|
G_CALLBACK (on_display_status_changed),
|
|
manager);
|
|
g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id);
|
|
}
|
|
}
|
|
|
|
GQuark
|
|
gdm_manager_error_quark (void)
|
|
{
|
|
static GQuark ret = 0;
|
|
if (ret == 0) {
|
|
ret = g_quark_from_static_string ("gdm_manager_error");
|
|
--
|
|
2.2.1
|
|
|