From add6e55332d9432297366b4d9fbb39bf2ec88691 Mon Sep 17 00:00:00 2001 From: Joan Torres Lopez Date: Wed, 29 Jul 2026 02:20:22 +0200 Subject: [PATCH] Set GDM_AUTH_SESSION_ID env var for PAM conversations Resolves: RHEL-162581 --- ...ION_ID-env-var-for-PAM-conversations.patch | 372 ++++++++++++++++++ gdm.spec | 4 + 2 files changed, 376 insertions(+) create mode 100644 0001-session-Set-GDM_AUTH_SESSION_ID-env-var-for-PAM-conversations.patch diff --git a/0001-session-Set-GDM_AUTH_SESSION_ID-env-var-for-PAM-conversations.patch b/0001-session-Set-GDM_AUTH_SESSION_ID-env-var-for-PAM-conversations.patch new file mode 100644 index 0000000..aa2d85f --- /dev/null +++ b/0001-session-Set-GDM_AUTH_SESSION_ID-env-var-for-PAM-conversations.patch @@ -0,0 +1,372 @@ +From bbf4a3a065cd9705abb8dd3c0fc2164ab2a92356 Mon Sep 17 00:00:00 2001 +From: Joan Torres Lopez +Date: Thu, 18 Jun 2026 21:09:26 +0200 +Subject: [PATCH 1/2] session: Add "session-id-of-caller" property + +This was used as an external gobject data property but it will be used +internally in GdmSession to inform about the session id of the caller +through PAM environment. + +Part-of: +--- + daemon/gdm-manager.c | 22 +++++++++------------- + daemon/gdm-session.c | 27 +++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 13 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index f16b7c21d..867d02bfc 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -880,7 +880,7 @@ on_reauthentication_client_rejected (GdmSession *session, + pid = (GPid) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (session), "caller-pid")); + + if (pid != pid_of_client) { +- const char *session_id; ++ g_autofree char *session_id = NULL; + g_autofree char *client_session_id = NULL; + + /* rejected client isn't the process that started the +@@ -890,7 +890,7 @@ on_reauthentication_client_rejected (GdmSession *session, + */ + client_session_id = get_session_id_for_pid (pid_of_client, + NULL); +- session_id = g_object_get_data (G_OBJECT (session), "caller-session-id"); ++ g_object_get (session, "session-id-of-caller", &session_id, NULL); + + if (g_strcmp0 (session_id, client_session_id) != 0) { + return; +@@ -934,21 +934,21 @@ on_reauthentication_verification_complete (GdmSession *session, + GdmManager *self) + { + GdmSession *user_session; +- const char *caller_session_id; ++ g_autofree char *session_id_of_caller = NULL; + + user_session = g_object_get_data (G_OBJECT (session), "user-session"); +- caller_session_id = g_object_get_data (G_OBJECT (session), "caller-session-id"); ++ g_object_get (session, "session-id-of-caller", &session_id_of_caller, NULL); + + if (user_session != NULL) { + g_debug ("GdmManager: reauthenticated user in frozen session '%s' with service '%s'", + gdm_session_get_session_id (user_session), service_name); + + switch_to_compatible_user_session (self, user_session, FALSE); +- } else if (caller_session_id != NULL) { ++ } else if (session_id_of_caller != NULL) { + g_debug ("GdmManager: reauthenticated user in unmanaged session '%s' with service '%s'", +- caller_session_id, service_name); ++ session_id_of_caller, service_name); + +- session_unlock (self, caller_session_id); ++ session_unlock (self, session_id_of_caller); + } + + close_transient_session (self, session); +@@ -964,7 +964,7 @@ static char * + open_temporary_reauthentication_channel (GdmManager *self, + GdmSession *user_session, + char *seat_id, +- char *caller_session_id, ++ char *session_id_of_caller, + GPid pid, + uid_t uid, + gboolean is_remote) +@@ -992,11 +992,7 @@ open_temporary_reauthentication_channel (GdmManager *self, + (int) uid, + seat_id); + +- g_object_set_data_full (G_OBJECT (session), +- "caller-session-id", +- g_strdup (caller_session_id), +- (GDestroyNotify) +- g_free); ++ g_object_set (session, "session-id-of-caller", session_id_of_caller, NULL); + g_object_set_data_full (G_OBJECT (session), + "user-session", + user_session? g_object_ref (user_session) : NULL, +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index 395cda2d0..917fb6532 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -134,6 +134,7 @@ struct _GdmSession + GStrv supported_session_types; + + char *remote_id; ++ char *session_id_of_caller; + + guint32 is_program_session : 1; + guint32 display_is_initial : 1; +@@ -155,6 +156,7 @@ enum { + PROP_CONVERSATION_ENVIRONMENT, + PROP_SUPPORTED_SESSION_TYPES, + PROP_REMOTE_ID, ++ PROP_SESSION_ID_OF_CALLER, + }; + + enum { +@@ -3629,6 +3631,14 @@ set_remote_id (GdmSession *self, + self->remote_id = g_strdup (remote_id); + } + ++static void ++set_session_id_of_caller (GdmSession *self, ++ const char *session_id_of_caller) ++{ ++ g_free (self->session_id_of_caller); ++ self->session_id_of_caller = g_strdup (session_id_of_caller); ++} ++ + static void + gdm_session_set_property (GObject *object, + guint prop_id, +@@ -3673,6 +3683,9 @@ gdm_session_set_property (GObject *object, + case PROP_REMOTE_ID: + set_remote_id (self, g_value_get_string (value)); + break; ++ case PROP_SESSION_ID_OF_CALLER: ++ set_session_id_of_caller (self, g_value_get_string (value)); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -3723,6 +3736,9 @@ gdm_session_get_property (GObject *object, + case PROP_REMOTE_ID: + g_value_set_string (value, self->remote_id); + break; ++ case PROP_SESSION_ID_OF_CALLER: ++ g_value_set_string (value, self->session_id_of_caller); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -3762,6 +3778,9 @@ gdm_session_dispose (GObject *object) + g_strfreev (self->conversation_environment); + self->conversation_environment = NULL; + ++ g_free (self->session_id_of_caller); ++ self->session_id_of_caller = NULL; ++ + if (self->worker_server != NULL) { + g_dbus_server_stop (self->worker_server); + g_clear_object (&self->worker_server); +@@ -4146,6 +4165,14 @@ gdm_session_class_init (GdmSessionClass *session_class) + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + ++ g_object_class_install_property (object_class, ++ PROP_SESSION_ID_OF_CALLER, ++ g_param_spec_string ("session-id-of-caller", ++ "session id of caller", ++ "session id of caller", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); ++ + /* Ensure we can resolve errors */ + gdm_dbus_error_ensure (GDM_SESSION_WORKER_ERROR); + } +-- +2.51.0 + + +From 6bee0c43b24a09213b1a69451e1a3ca46e529fe3 Mon Sep 17 00:00:00 2001 +From: Joan Torres Lopez +Date: Thu, 18 Jun 2026 14:01:21 +0200 +Subject: [PATCH 2/2] session: Set GDM_AUTH_SESSION_ID env var for PAM + conversations + +Add a "caller-session-id" property to GdmSession to track the session +ID of the context where authentication is initiated. This is set from +the greeter session ID when a user logs in from the login screen +(on_session_client_connected), and from the caller's session ID during +reauthentication, both at the login screen and lock screen. + +The caller session ID is passed through to the session worker via the +Initialize D-Bus call, and for reauthentication also via +StartReauthentication. The worker sets it as a process environment +variable GDM_AUTH_SESSION_ID via setenv() during PAM initialization, +making it available to any library used by PAM modules (e.g. libgrdpcsc). + +This will be used to redirect smartcard access on PAM conversations for +remote sessions. + +Part-of: +--- + daemon/gdm-manager.c | 13 +++++++------ + daemon/gdm-session-worker.c | 26 ++++++++++++++++++++++++-- + daemon/gdm-session-worker.xml | 1 + + daemon/gdm-session.c | 4 ++++ + 4 files changed, 36 insertions(+), 8 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 2efeeb1..33f334b 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1218,6 +1218,7 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager + return TRUE; + } else if (session != NULL && gdm_session_is_running (session)) { + if (!gdm_session_is_frozen (session)) { ++ g_object_set (session, "session-id-of-caller", session_id, NULL); + gdm_session_start_reauthentication (session, pid, uid); + g_hash_table_insert (self->open_reauthentication_requests, + GINT_TO_POINTER (pid), +@@ -2355,20 +2356,20 @@ on_session_conversation_started (GdmSession *session, + + g_debug ("GdmManager: session conversation started for service %s on session", service_name); + +- if (g_strcmp0 (service_name, "gdm-autologin") != 0) { +- g_debug ("GdmManager: ignoring session conversation since its not automatic login conversation"); ++ display = get_display_for_user_session (session); ++ if (display == NULL) { ++ g_debug ("GdmManager: conversation has no associated display"); + return; + } + +- display = get_display_for_user_session (session); ++ g_object_set (session, "session-id-of-caller", gdm_display_get_session_id (display), NULL); + +- if (display == NULL) { +- g_debug ("GdmManager: conversation has no associated display"); ++ if (g_strcmp0 (service_name, "gdm-autologin") != 0) { ++ g_debug ("GdmManager: ignoring session conversation since its not automatic login conversation"); + return; + } + + enabled = get_automatic_login_details (manager, display, &username); +- + if (! enabled) { + return; + } +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index eed4fa2..e0fa729 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -114,6 +114,8 @@ + #define RELEASE_DISPLAY_SIGNAL (SIGRTMAX) + #define ACQUIRE_DISPLAY_SIGNAL (SIGRTMAX - 1) + ++#define GDM_AUTH_SESSION_ID "GDM_AUTH_SESSION_ID" ++ + typedef struct + { + GdmSessionWorker *worker; +@@ -145,6 +147,7 @@ struct _GdmSessionWorker + char *username; + char *log_file; + char *session_id; ++ char *session_id_of_caller; + uid_t uid; + gid_t gid; + gboolean password_is_required; +@@ -1301,6 +1304,10 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter"); + } + ++ if (worker->session_id_of_caller != NULL) { ++ setenv (GDM_AUTH_SESSION_ID, worker->session_id_of_caller, 1); ++ } ++ + g_debug ("GdmSessionWorker: state SETUP_COMPLETE"); + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); + +@@ -1383,6 +1390,9 @@ gdm_session_worker_authenticate_user (GdmSessionWorker *worker, + goto out; + } + ++ gdm_session_worker_set_environment_variable (worker, GDM_AUTH_SESSION_ID, NULL); ++ unsetenv (GDM_AUTH_SESSION_ID); ++ + g_debug ("GdmSessionWorker: state AUTHENTICATED"); + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_AUTHENTICATED); + +@@ -3086,6 +3096,8 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, + worker->display_is_local = g_variant_get_boolean (value); + } else if (g_strcmp0 (key, "display-is-initial") == 0) { + worker->display_is_initial = g_variant_get_boolean (value); ++ } else if (g_strcmp0 (key, "session-id-of-caller") == 0) { ++ worker->session_id_of_caller = g_variant_dup_string (value, NULL); + } + } + +@@ -3370,6 +3382,7 @@ static ReauthenticationRequest * + reauthentication_request_new (GdmSessionWorker *worker, + GPid pid_of_caller, + uid_t uid_of_caller, ++ const char *session_id_of_caller, + GDBusMethodInvocation *invocation) + { + ReauthenticationRequest *request; +@@ -3393,6 +3406,9 @@ reauthentication_request_new (GdmSessionWorker *worker, + worker->display_is_local, + environment); + ++ if (session_id_of_caller != NULL && session_id_of_caller[0] != '\0') ++ g_object_set (request->session, "session-id-of-caller", session_id_of_caller, NULL); ++ + g_signal_connect (request->session, + "client-connected", + G_CALLBACK (on_reauthentication_client_connected), +@@ -3431,7 +3447,8 @@ static gboolean + gdm_session_worker_handle_start_reauthentication (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + int pid_of_caller, +- int uid_of_caller) ++ int uid_of_caller, ++ const char *session_id_of_caller) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + ReauthenticationRequest *request; +@@ -3447,7 +3464,11 @@ gdm_session_worker_handle_start_reauthentication (GdmDBusWorker *object, + + g_debug ("GdmSessionWorker: start reauthentication"); + +- request = reauthentication_request_new (worker, pid_of_caller, uid_of_caller, invocation); ++ request = reauthentication_request_new (worker, ++ pid_of_caller, ++ uid_of_caller, ++ session_id_of_caller, ++ invocation); + g_hash_table_replace (worker->reauthentication_requests, + GINT_TO_POINTER (pid_of_caller), + request); +@@ -3634,6 +3655,7 @@ gdm_session_worker_finalize (GObject *object) + g_free (worker->display_seat_id); + g_free (worker->hostname); + g_free (worker->username); ++ g_free (worker->session_id_of_caller); + g_free (worker->server_address); + g_strfreev (worker->arguments); + g_strfreev (worker->extensions); +diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml +index 214ca8d..13001d2 100644 +--- a/daemon/gdm-session-worker.xml ++++ b/daemon/gdm-session-worker.xml +@@ -63,6 +63,7 @@ + + + ++ + + + +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index ac70568..cf22259 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -2659,6 +2659,9 @@ initialize (GdmSession *self, + if (self->display_x11_authority_file != NULL) + g_variant_builder_add_parsed (&details, "{'x11-authority-file', <%s>}", self->display_x11_authority_file); + ++ if (self->session_id_of_caller != NULL) ++ g_variant_builder_add_parsed (&details, "{'session-id-of-caller', <%s>}", self->session_id_of_caller); ++ + g_debug ("GdmSession: Beginning initialization"); + + conversation = find_conversation_by_name (self, service_name); +@@ -3459,6 +3462,7 @@ gdm_session_start_reauthentication (GdmSession *self, + gdm_dbus_worker_call_start_reauthentication (conversation->worker_proxy, + (int) pid_of_caller, + (int) uid_of_caller, ++ self->session_id_of_caller ? self->session_id_of_caller : "", + conversation->worker_cancellable, + (GAsyncReadyCallback) on_reauthentication_started_cb, + conversation); diff --git a/gdm.spec b/gdm.spec index 482a95b..67febb0 100644 --- a/gdm.spec +++ b/gdm.spec @@ -76,6 +76,10 @@ Patch: 0001-local-display-factory-look-for-boot_display-sysfs-at.patch # https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/378 Patch: 0001-data-Add-PAM-substack-wrappers-to-prevent-auth-bypas.patch +# RHEL-162581 +# https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/374 +Patch: 0001-session-Set-GDM_AUTH_SESSION_ID-env-var-for-PAM-conversations.patch + BuildRequires: dconf BuildRequires: desktop-file-utils BuildRequires: gettext-devel