From 9f4d779d17e407aed688c4bee48e6d3474da16f5 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Mon, 14 May 2018 15:26:14 +0100 Subject: [PATCH] act-user-manager: Find the user's graphical session instead of assuming we are in it If we were started by systemd --user, we won't be in a login session. Find the user's graphical session by asking logind for it. https://bugs.freedesktop.org/show_bug.cgi?id=107062 --- src/libaccountsservice/act-user-manager.c | 96 ++++++++++++++++++++--- 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index 325421b..862e530 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -487,8 +487,8 @@ _can_activate_systemd_sessions (ActUserManager *manager) res = sd_seat_can_multi_session (manager->priv->seat.id); if (res < 0) { - g_warning ("unable to determine if seat can activate sessions: %s", - strerror (-res)); + g_warning ("unable to determine if seat %s can activate sessions: %s", + manager->priv->seat.id, strerror (-res)); return FALSE; } @@ -698,13 +698,92 @@ on_get_seat_id_finished (GObject *object, } #ifdef WITH_SYSTEMD +static gboolean +act_systemd_find_session (char **session_id) +{ + const gchar * const graphical_session_types[] = { "wayland", "x11", "mir", NULL }; + g_autofree gchar *class = NULL; + g_autofree gchar *local_session_id = NULL; + g_autofree gchar *type = NULL; + g_auto(GStrv) sessions = NULL; + int n_sessions; + int saved_errno; + + g_return_val_if_fail (session_id != NULL, FALSE); + + if ((saved_errno = sd_uid_get_display (getuid (), &local_session_id)) < 0) { + /* no session, maybe there's a greeter session */ + if (saved_errno == -ENODATA) { + if ((n_sessions = sd_uid_get_sessions (getuid (), 1, &sessions)) < 0) { + g_critical ("Failed to get all sessions for user %d", getuid ()); + return FALSE; + } + + if (n_sessions == 0) { + g_critical ("User %d has no sessions", getuid ()); + return FALSE; + } + + for (int i = 0; i < n_sessions; ++i) { + if ((saved_errno = sd_session_get_class (sessions[i], &class)) < 0) { + g_warning ("Couldn't get class for session '%d': %s", + i, + g_strerror (-saved_errno)); + continue; + } + + if (g_strcmp0 (class, "greeter") == 0) { + local_session_id = g_strdup (sessions[i]); + break; + } + } + + if (!local_session_id) { + g_critical ("Couldn't find a session or a greeter session for user %d", getuid ()); + return FALSE; + } + } else { + g_critical ("Couldn't get display: %s (%s)", g_strerror (-saved_errno), local_session_id); + return FALSE; + } + } + + /* sd_uid_get_display will return any session if there is no graphical + * one, so let's check it really is graphical. */ + if ((saved_errno = sd_session_get_type (local_session_id, &type)) < 0) { + g_critical ("Couldn't get type for session '%s': %s", + local_session_id, + g_strerror (-saved_errno)); + return FALSE; + } + + if (!g_strv_contains (graphical_session_types, type)) { + g_critical ("Session '%s' is not a graphical session (type: '%s')", + local_session_id, + type); + return FALSE; + } + + *session_id = g_steal_pointer (&local_session_id); + + return TRUE; +} + static void _get_systemd_seat_id (ActUserManager *manager) { - int res; + int res; g_autofree gchar *seat_id = NULL; - res = sd_session_get_seat (NULL, &seat_id); + if (manager->priv->seat.session_id == NULL) { + if (!act_systemd_find_session (&manager->priv->seat.session_id)) { + g_warning ("Could not get session"); + return; + } + } + + res = sd_session_get_seat (manager->priv->seat.session_id, &seat_id); + if (res == -ENOENT) { seat_id = NULL; } else if (res < 0) { @@ -1134,15 +1213,8 @@ static void _get_current_systemd_session_id (ActUserManager *manager) { g_autofree gchar *session_id = NULL; - int res; - res = sd_pid_get_session (0, &session_id); - - if (res == -ENOENT) { - session_id = NULL; - } else if (res < 0) { - g_debug ("Failed to identify the current session: %s", - strerror (-res)); + if (!act_systemd_find_session (&session_id)) { unload_seat (manager); return; } -- 2.17.1