Set GDM_AUTH_SESSION_ID env var for PAM conversations

Resolves: RHEL-162581
This commit is contained in:
Joan Torres Lopez 2026-07-29 02:20:22 +02:00
parent e95c354195
commit add6e55332
No known key found for this signature in database
2 changed files with 376 additions and 0 deletions

View File

@ -0,0 +1,372 @@
From bbf4a3a065cd9705abb8dd3c0fc2164ab2a92356 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
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: <https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/374>
---
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 <joantolo@redhat.com>
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: <https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/374>
---
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 @@
<method name="StartReauthentication">
<arg name="pid_of_caller" direction="in" type="i"/>
<arg name="uid_of_caller" direction="in" type="i"/>
+ <arg name="session_id_of_caller" direction="in" type="s"/>
<arg name="address" direction="out" type="s"/>
</method>
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);

View File

@ -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