diff options
author | Ray Strode <halfline@gmail.com> | 2018-08-02 20:07:18 +0000 |
---|---|---|
committer | Ray Strode <halfline@gmail.com> | 2018-08-02 20:07:18 +0000 |
commit | c22145194b7153253743c94d95c7e1f1a056b7d3 (patch) | |
tree | f57c7b738d025aef9ac83908fd0d927478fbe438 | |
parent | 77c791afa4dc02ef7c6f3278dd20b23d69cee7fe (diff) | |
parent | 5e737a57402fa626af7f037b9485bd172c8a3dff (diff) | |
download | gdm-c22145194b7153253743c94d95c7e1f1a056b7d3.tar.gz |
Merge branch 'wip/try-harder-to-get-a-login-screen' into 'master'
Wip/try harder to get a login screen
See merge request GNOME/gdm!25
-rw-r--r-- | common/gdm-common.c | 57 | ||||
-rw-r--r-- | common/gdm-common.h | 8 | ||||
-rw-r--r-- | daemon/gdm-local-display-factory.c | 36 | ||||
-rw-r--r-- | daemon/gdm-manager.c | 178 |
4 files changed, 80 insertions, 199 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c index a5b59242..d807c019 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -352,10 +352,10 @@ create_transient_display (GDBusConnection *connection, return TRUE; } -static gboolean -activate_session_id (GDBusConnection *connection, - const char *seat_id, - const char *session_id) +gboolean +gdm_activate_session_by_id (GDBusConnection *connection, + const char *seat_id, + const char *session_id) { GError *local_error = NULL; GVariant *reply; @@ -381,13 +381,14 @@ activate_session_id (GDBusConnection *connection, return TRUE; } -static gboolean -get_login_window_session_id (const char *seat_id, - char **session_id) +gboolean +gdm_get_login_window_session_id (const char *seat_id, + char **session_id) { gboolean ret; int res, i; char **sessions; + char *service_id; char *service_class; char *state; @@ -399,13 +400,19 @@ get_login_window_session_id (const char *seat_id, if (sessions == NULL || sessions[0] == NULL) { *session_id = NULL; - ret = TRUE; + ret = FALSE; goto out; } for (i = 0; sessions[i]; i ++) { + res = sd_session_get_class (sessions[i], &service_class); if (res < 0) { + if (res == -ENOENT) { + free (service_class); + continue; + } + g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); ret = FALSE; goto out; @@ -431,21 +438,35 @@ get_login_window_session_id (const char *seat_id, } free (state); - *session_id = g_strdup (sessions[i]); - ret = TRUE; - break; + res = sd_session_get_service (sessions[i], &service_id); + if (res < 0) { + g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + if (strcmp (service_id, "gdm-launch-environment") == 0) { + *session_id = g_strdup (sessions[i]); + ret = TRUE; + + free (service_id); + goto out; + } + + free (service_id); } *session_id = NULL; - ret = TRUE; + ret = FALSE; out: - for (i = 0; sessions[i]; i ++) { - free (sessions[i]); - } + if (sessions) { + for (i = 0; sessions[i]; i ++) { + free (sessions[i]); + } - free (sessions); + free (sessions); + } return ret; } @@ -506,9 +527,9 @@ goto_login_session (GDBusConnection *connection, return FALSE; } - res = get_login_window_session_id (seat_id, &session_id); + res = gdm_get_login_window_session_id (seat_id, &session_id); if (res && session_id != NULL) { - res = activate_session_id (connection, seat_id, session_id); + res = gdm_activate_session_by_id (connection, seat_id, session_id); if (res) { ret = TRUE; diff --git a/common/gdm-common.h b/common/gdm-common.h index e13c3a3d..07812b10 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -22,6 +22,8 @@ #define _GDM_COMMON_H #include <glib-unix.h> +#include <gio/gio.h> + #include <pwd.h> #include <errno.h> @@ -51,6 +53,8 @@ gboolean gdm_clear_close_on_exec_flag (int fd); char *gdm_generate_random_bytes (gsize size, GError **error); +gboolean gdm_get_login_window_session_id (const char *seat_id, + char **session_id); gboolean gdm_goto_login_session (GError **error); GPtrArray *gdm_get_script_environment (const char *username, @@ -69,6 +73,10 @@ char * gdm_shell_expand (const char *str, GdmExpandVarFunc expand_func, gpointer user_data); +gboolean gdm_activate_session_by_id (GDBusConnection *connection, + const char *seat_id, + const char *session_id); + G_END_DECLS #endif /* _GDM_COMMON_H */ diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c index f68eda8d..f214185f 100644 --- a/daemon/gdm-local-display-factory.c +++ b/daemon/gdm-local-display-factory.c @@ -28,6 +28,8 @@ #include <glib-object.h> #include <gio/gio.h> +#include <systemd/sd-login.h> + #include "gdm-common.h" #include "gdm-manager.h" #include "gdm-display-factory.h" @@ -267,6 +269,7 @@ on_display_status_changed (GdmDisplay *display, int num; char *seat_id = NULL; char *session_type = NULL; + char *session_class = NULL; gboolean is_initial = TRUE; gboolean is_local = TRUE; @@ -278,6 +281,7 @@ on_display_status_changed (GdmDisplay *display, "is-initial", &is_initial, "is-local", &is_local, "session-type", &session_type, + "session-class", &session_class, NULL); status = gdm_display_get_status (display); @@ -297,7 +301,7 @@ on_display_status_changed (GdmDisplay *display, * ensures we get a new login screen when the user logs out, * if there isn't one. */ - if (is_local) { + if (is_local && g_strcmp0 (session_class, "greeter") != 0) { /* reset num failures */ factory->priv->num_failures = 0; @@ -342,6 +346,7 @@ on_display_status_changed (GdmDisplay *display, g_free (seat_id); g_free (session_type); + g_free (session_class); } static gboolean @@ -370,12 +375,33 @@ create_display (GdmLocalDisplayFactory *factory, { GdmDisplayStore *store; GdmDisplay *display = NULL; + char *active_session_id = NULL; + int ret; - /* Ensure we don't create the same display more than once */ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); - if (display != NULL) { - return NULL; + + ret = sd_seat_get_active (seat_id, &active_session_id, NULL); + + if (ret == 0) { + char *login_session_id = NULL; + + /* If we already have a login window, switch to it */ + if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { + if (g_strcmp0 (active_session_id, login_session_id) != 0) { + gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id); + } + g_clear_pointer (&login_session_id, g_free); + g_clear_pointer (&active_session_id, g_free); + return NULL; + } + g_clear_pointer (&active_session_id, g_free); + } else { + /* Ensure we don't create the same display more than once */ + display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); + + if (display != NULL) { + return NULL; + } } g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index 1370bab4..f17bd1a5 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -295,37 +295,6 @@ is_login_session (GdmManager *self, } static gboolean -activate_session_id (GdmManager *manager, - const char *seat_id, - const char *session_id) -{ - GError *error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (manager->priv->connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ActivateSessionOnSeat", - g_variant_new ("(ss)", session_id, seat_id), - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmManager: logind 'ActivateSessionOnSeat' %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 gboolean session_unlock (GdmManager *manager, const char *ssid) { @@ -621,7 +590,7 @@ switch_to_compatible_user_session (GdmManager *manager, if (existing_session != NULL) { ssid_to_activate = gdm_session_get_session_id (existing_session); if (seat_id != NULL) { - res = activate_session_id (manager, seat_id, ssid_to_activate); + res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); if (! res) { g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); goto out; @@ -1318,148 +1287,6 @@ maybe_start_pending_initial_login (GdmManager *manager, g_free (user_session_seat_id); } -static gboolean -get_login_window_session_id (const char *seat_id, - char **session_id) -{ - gboolean ret; - int res, i; - char **sessions; - char *service_id; - char *service_class; - char *state; - - res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); - if (res < 0) { - g_debug ("Failed to determine sessions: %s", strerror (-res)); - return FALSE; - } - - if (sessions == NULL || sessions[0] == NULL) { - *session_id = NULL; - ret = TRUE; - goto out; - } - - for (i = 0; sessions[i]; i ++) { - - res = sd_session_get_class (sessions[i], &service_class); - if (res < 0) { - if (res == -ENOENT) { - free (service_class); - continue; - } - - g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); - ret = FALSE; - goto out; - } - - if (strcmp (service_class, "greeter") != 0) { - free (service_class); - continue; - } - - free (service_class); - - ret = sd_session_get_state (sessions[i], &state); - if (ret < 0) { - if (res == -ENOENT) - continue; - - g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); - ret = FALSE; - goto out; - } - - if (g_strcmp0 (state, "closing") == 0) { - free (state); - continue; - } - free (state); - - res = sd_session_get_service (sessions[i], &service_id); - if (res < 0) { - if (res == -ENOENT) - continue; - g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); - ret = FALSE; - goto out; - } - - if (strcmp (service_id, "gdm-launch-environment") == 0) { - *session_id = g_strdup (sessions[i]); - ret = TRUE; - - free (service_id); - goto out; - } - - free (service_id); - } - - *session_id = NULL; - ret = TRUE; - -out: - if (sessions) { - for (i = 0; sessions[i]; i ++) { - free (sessions[i]); - } - - free (sessions); - } - - return ret; -} - -static void -activate_login_window_session_on_seat (GdmManager *self, - const char *seat_id) -{ - char *session_id; - - if (!get_login_window_session_id (seat_id, &session_id)) { - return; - } - - if (session_id) { - activate_session_id (self, seat_id, session_id); - g_free (session_id); - } -} - -static void -maybe_activate_other_session (GdmManager *self, - GdmDisplay *old_display) -{ - char *seat_id = NULL; - char *session_id = NULL; - int ret; - - g_object_get (G_OBJECT (old_display), - "seat-id", &seat_id, - NULL); - - ret = sd_seat_get_active (seat_id, &session_id, NULL); - - if (ret == 0) { - GdmDisplay *display; - - display = gdm_display_store_find (self->priv->display_store, - lookup_by_session_id, - (gpointer) session_id); - - if (display == NULL || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) { - activate_login_window_session_on_seat (self, seat_id); - } - - g_free (session_id); - } - - g_free (seat_id); -} - static const char * get_username_for_greeter_display (GdmManager *manager, GdmDisplay *display) @@ -1705,7 +1532,6 @@ on_display_status_changed (GdmDisplay *display, manager->priv->ran_once = TRUE; } maybe_start_pending_initial_login (manager, display); - maybe_activate_other_session (manager, display); break; default: break; @@ -2059,7 +1885,7 @@ on_session_reauthenticated (GdmSession *session, char *session_id; seat_id = gdm_session_get_display_seat_id (session); - if (get_login_window_session_id (seat_id, &session_id)) { + if (gdm_get_login_window_session_id (seat_id, &session_id)) { GdmDisplay *display = gdm_display_store_find (manager->priv->display_store, lookup_by_session_id, (gpointer) session_id); |