From f4e7c422bec2167c9648cb063f0cb204789d5f05 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 1 Aug 2018 16:34:30 -0400 Subject: [PATCH 07/48] common: dedupe gdm_get_login_window_session_id Right now there are two slightly different cut-and-pastes of the function to get the session id of the login session in the code. This commit deduplicates them. --- common/gdm-common.c | 47 ++++++++++++++++++++++++++++++++------------ common/gdm-common.h | 2 ++ daemon/gdm-manager.c | 4 ++-- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/common/gdm-common.c b/common/gdm-common.c index c44fa998d..00daf0df8 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -364,186 +364,207 @@ create_transient_display (GDBusConnection *connection, static gboolean activate_session_id (GDBusConnection *connection, const char *seat_id, const char *session_id) { GError *local_error = NULL; GVariant *reply; reply = g_dbus_connection_call_sync (connection, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "ActivateSessionOnSeat", g_variant_new ("(ss)", session_id, seat_id), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &local_error); if (reply == NULL) { g_warning ("Unable to activate session: %s", local_error->message); g_error_free (local_error); return FALSE; } g_variant_unref (reply); 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; 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; + 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; } if (strcmp (service_class, "greeter") != 0) { free (service_class); continue; } free (service_class); ret = sd_session_get_state (sessions[i], &state); if (ret < 0) { 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); - *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; } static gboolean goto_login_session (GDBusConnection *connection, GError **error) { gboolean ret; int res; char *our_session; char *session_id; char *seat_id; ret = FALSE; session_id = NULL; seat_id = NULL; /* First look for any existing LoginWindow sessions on the seat. If none are found, create a new one. */ /* Note that we mostly use free () here, instead of g_free () * since the data allocated is from libsystemd-logind, which * does not use GLib's g_malloc (). */ res = sd_pid_get_session (0, &our_session); if (res < 0) { g_debug ("failed to determine own session: %s", strerror (-res)); g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current session.")); return FALSE; } res = sd_session_get_seat (our_session, &seat_id); free (our_session); if (res < 0) { g_debug ("failed to determine own seat: %s", strerror (-res)); g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current seat.")); return FALSE; } res = sd_seat_can_multi_session (seat_id); if (res < 0) { free (seat_id); g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res)); g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to determine whether to switch to an existing login screen or start up a new login screen.")); return FALSE; } if (res == 0) { free (seat_id); g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to start up a new login screen.")); 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); if (res) { ret = TRUE; } } if (! ret && g_strcmp0 (seat_id, "seat0") == 0) { res = create_transient_display (connection, error); if (res) { ret = TRUE; } } free (seat_id); g_free (session_id); return ret; } gboolean gdm_goto_login_session (GError **error) { GError *local_error; GDBusConnection *connection; local_error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error); if (connection == NULL) { diff --git a/common/gdm-common.h b/common/gdm-common.h index 8d83a1246..c9cbd9c48 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -26,51 +26,53 @@ #include #define VE_IGNORE_EINTR(expr) \ do { \ errno = 0; \ expr; \ } while G_UNLIKELY (errno == EINTR); GQuark gdm_common_error_quark (void); #define GDM_COMMON_ERROR gdm_common_error_quark() typedef char * (*GdmExpandVarFunc) (const char *var, gpointer user_data); G_BEGIN_DECLS int gdm_wait_on_pid (int pid); int gdm_wait_on_and_disown_pid (int pid, int timeout); int gdm_signal_pid (int pid, int signal); gboolean gdm_get_pwent_for_name (const char *name, struct passwd **pwentp); gboolean gdm_clear_close_on_exec_flag (int fd); const char * gdm_make_temp_dir (char *template); 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, const char *display_name, const char *display_hostname, const char *display_x11_authority_file); gboolean gdm_run_script (const char *dir, const char *username, const char *display_name, const char *display_hostname, const char *display_x11_authority_file); gboolean gdm_shell_var_is_valid_char (char c, gboolean first); char * gdm_shell_expand (const char *str, GdmExpandVarFunc expand_func, gpointer user_data); G_END_DECLS #endif /* _GDM_COMMON_H */ diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index 7a5554e9d..375ef6f80 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -1444,61 +1444,61 @@ get_login_window_session_id (const char *seat_id, ret = TRUE; free (service_id); goto out; } free (service_id); } *session_id = NULL; ret = FALSE; 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)) { + if (!gdm_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; 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); @@ -2082,61 +2082,61 @@ on_user_session_exited (GdmSession *session, static void on_user_session_died (GdmSession *session, int signal_number, GdmManager *manager) { g_debug ("GdmManager: session died with signal %s", strsignal (signal_number)); remove_user_session (manager, session); } static char * get_display_device (GdmManager *manager, GdmDisplay *display) { /* systemd finds the display device out on its own based on the display */ return NULL; } static void on_session_reauthenticated (GdmSession *session, const char *service_name, GdmManager *manager) { gboolean fail_if_already_switched = FALSE; if (gdm_session_get_display_mode (session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { const char *seat_id; 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); if (display != NULL) { gdm_display_stop_greeter_session (display); gdm_display_unmanage (display); gdm_display_finish (display); } g_free (session_id); } } /* There should already be a session running, so jump to its * VT. In the event we're already on the right VT, (i.e. user * used an unlock screen instead of a user switched login screen), * then silently succeed and unlock the session. */ switch_to_compatible_user_session (manager, session, fail_if_already_switched); } static void on_session_client_ready_for_session_to_start (GdmSession *session, const char *service_name, gboolean client_is_ready, GdmManager *manager) { gboolean waiting_to_start_user_session; if (client_is_ready) { -- 2.26.0