diff options
author | Michael Catanzaro <mcatanzaro@igalia.com> | 2016-01-12 21:42:15 -0600 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2017-03-10 13:55:57 -0500 |
commit | cdc7c32724a64ba17359dcaa2800dcbb25db4b1c (patch) | |
tree | 51c90b9e3f01fc623d44712eae2fbdee6056a0fb | |
parent | 61f959a58b0caf2ff1160834cb4b2851f558e088 (diff) | |
download | gdm-cdc7c32724a64ba17359dcaa2800dcbb25db4b1c.tar.gz |
manager: be more robust against autologin having an invalid user
If the configured autologin user does not exist, fall back to a
greeter session.
https://bugzilla.gnome.org/show_bug.cgi?id=695250
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | daemon/gdm-manager.c | 115 |
2 files changed, 86 insertions, 31 deletions
diff --git a/configure.ac b/configure.ac index 312588f5..6002e452 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,7 @@ dnl --------------------------------------------------------------------------- GLIB_REQUIRED_VERSION=2.36.0 GTK_REQUIRED_VERSION=2.91.1 LIBCANBERRA_GTK_REQUIRED_VERSION=0.4 -ACCOUNTS_SERVICE_REQUIRED_VERSION=0.6.12 +ACCOUNTS_SERVICE_REQUIRED_VERSION=0.6.35 EXTRA_COMPILE_WARNINGS(yes) diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index 35a7a0fe..e78228b4 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -34,6 +34,8 @@ #include <glib/gstdio.h> #include <glib-object.h> +#include <act/act-user-manager.h> + #include <systemd/sd-login.h> #include "gdm-common.h" @@ -1254,25 +1256,6 @@ get_automatic_login_details (GdmManager *manager, return enabled; } -static gboolean -display_should_autologin (GdmManager *manager, - GdmDisplay *display) -{ - gboolean enabled = FALSE; - - if (manager->priv->ran_once) { - return FALSE; - } - - if (!display_is_on_seat0 (display)) { - return FALSE; - } - - enabled = get_automatic_login_details (manager, NULL); - - return enabled; -} - static void maybe_start_pending_initial_login (GdmManager *manager, GdmDisplay *greeter_display) @@ -1374,6 +1357,87 @@ set_up_greeter_session (GdmManager *manager, } static void +set_up_automatic_login_session_if_user_exists (GdmManager *manager, + GdmDisplay *display, + ActUser *user) +{ + if (act_user_is_nonexistent (user)) + set_up_greeter_session (manager, display); + else + set_up_automatic_login_session (manager, display); +} + +typedef struct { + GdmManager *manager; + GdmDisplay *display; + char *username; +} UsernameLookupOperation; + +static void +destroy_username_lookup_operation (UsernameLookupOperation *operation) +{ + g_object_unref (operation->manager); + g_object_unref (operation->display); + g_free (operation->username); + g_free (operation); +} + +static void +on_user_is_loaded_changed (ActUser *user, + GParamSpec *pspec, + UsernameLookupOperation *operation) +{ + if (act_user_is_loaded (user)) { + set_up_automatic_login_session_if_user_exists (operation->manager, operation->display, user); + g_signal_handlers_disconnect_by_func (G_OBJECT (user), + G_CALLBACK (on_user_is_loaded_changed), + operation); + destroy_username_lookup_operation (operation); + } +} + +static void +set_up_session (GdmManager *manager, + GdmDisplay *display) +{ + ActUserManager *user_manager; + ActUser *user; + gboolean loaded; + gboolean autologin_enabled = FALSE; + char *username = NULL; + + if (!manager->priv->ran_once && display_is_on_seat0 (display)) + autologin_enabled = get_automatic_login_details (manager, &username); + + if (!autologin_enabled) { + set_up_greeter_session (manager, display); + g_free (username); + return; + } + + /* Check whether the user really exists before committing to autologin. */ + user_manager = act_user_manager_get_default (); + user = act_user_manager_get_user (user_manager, username); + g_object_get (user_manager, "is-loaded", &loaded, NULL); + + if (loaded) { + set_up_automatic_login_session_if_user_exists (manager, display, user); + } else { + UsernameLookupOperation *operation; + + operation = g_new (UsernameLookupOperation, 1); + operation->manager = g_object_ref (manager); + operation->display = g_object_ref (display); + operation->username = username; + + g_signal_connect (user, + "notify::is-loaded", + G_CALLBACK (on_user_is_loaded_changed), + operation); + } +} + +static void greeter_display_started (GdmManager *manager, GdmDisplay *display) { @@ -1417,17 +1481,8 @@ on_display_status_changed (GdmDisplay *display, g_object_get (display, "session-class", &session_class, NULL); - if (g_strcmp0 (session_class, "greeter") == 0) { - gboolean will_autologin; - - will_autologin = display_should_autologin (manager, display); - - if (will_autologin) { - set_up_automatic_login_session (manager, display); - } else { - set_up_greeter_session (manager, display); - } - } + if (g_strcmp0 (session_class, "greeter") == 0) + set_up_session (manager, display); g_free (session_class); } |