From 0ecacfd6123e4026c78d5d61670da0abdcbf7559 Mon Sep 17 00:00:00 2001 From: Ray Strode 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 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