diff --git a/SOURCES/polkit-0.115-pkperm-watch-real-ssn-changes.patch b/SOURCES/polkit-0.115-pkperm-watch-real-ssn-changes.patch
new file mode 100644
index 0000000..0e58643
--- /dev/null
+++ b/SOURCES/polkit-0.115-pkperm-watch-real-ssn-changes.patch
@@ -0,0 +1,353 @@
+diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
+index 88da3c0..eea05ae 100644
+--- a/data/org.freedesktop.PolicyKit1.Authority.xml
++++ b/data/org.freedesktop.PolicyKit1.Authority.xml
+@@ -431,7 +431,7 @@ Must match the effective UID of the caller of org.freedesktop.PolicyKit1.Authori
+
+
+
+-
++
+
+
+
+diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
+index 71d527c..93691b6 100644
+--- a/src/polkit/polkitauthority.c
++++ b/src/polkit/polkitauthority.c
+@@ -84,6 +84,7 @@ static PolkitAuthority *the_authority = NULL;
+ enum
+ {
+ CHANGED_SIGNAL,
++ SESSIONS_CHANGED_SIGNAL,
+ LAST_SIGNAL,
+ };
+
+@@ -113,9 +114,19 @@ on_proxy_signal (GDBusProxy *proxy,
+ gpointer user_data)
+ {
+ PolkitAuthority *authority = POLKIT_AUTHORITY (user_data);
++ guint16 msg_mask;
++
+ if (g_strcmp0 (signal_name, "Changed") == 0)
+ {
+- g_signal_emit_by_name (authority, "changed");
++ if ((parameters != NULL) && g_variant_check_format_string(parameters, "(q)", FALSE ) )
++ {
++ g_variant_get(parameters, "(q)", &msg_mask);
++ g_signal_emit (authority, signals[msg_mask], 0);
++ }
++ else
++ {
++ g_signal_emit_by_name (authority, "changed");
++ }
+ }
+ }
+
+@@ -287,6 +298,21 @@ polkit_authority_class_init (PolkitAuthorityClass *klass)
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
++ /**
++ * PolkitAuthority::sessions-changed:
++ * @authority: A #PolkitAuthority.
++ *
++ * Emitted when sessions change
++ */
++ signals[SESSIONS_CHANGED_SIGNAL] = g_signal_new ("sessions-changed",
++ POLKIT_TYPE_AUTHORITY,
++ G_SIGNAL_RUN_LAST,
++ 0, /* class offset */
++ NULL, /* accumulator */
++ NULL, /* accumulator data */
++ g_cclosure_marshal_VOID__VOID,
++ G_TYPE_NONE,
++ 0);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c
+index f264094..3231bf2 100644
+--- a/src/polkit/polkitpermission.c
++++ b/src/polkit/polkitpermission.c
+@@ -24,6 +24,10 @@
+ # include "config.h"
+ #endif
+
++#ifdef HAVE_LIBSYSTEMD
++# include
++#endif
++
+ #include
+ #include
+
+@@ -60,6 +64,8 @@ struct _PolkitPermission
+
+ gchar *action_id;
+
++ gchar *session_state;
++
+ /* non-NULL exactly when authorized with a temporary authorization */
+ gchar *tmp_authz_id;
+ };
+@@ -74,9 +80,14 @@ enum
+ static void process_result (PolkitPermission *permission,
+ PolkitAuthorizationResult *result);
+
++static char *get_session_state();
++
+ static void on_authority_changed (PolkitAuthority *authority,
+ gpointer user_data);
+
++static void on_sessions_changed (PolkitAuthority *authority,
++ gpointer user_data);
++
+ static gboolean acquire (GPermission *permission,
+ GCancellable *cancellable,
+ GError **error);
+@@ -126,6 +137,8 @@ polkit_permission_constructed (GObject *object)
+
+ if (G_OBJECT_CLASS (polkit_permission_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (polkit_permission_parent_class)->constructed (object);
++
++ permission->session_state = get_session_state();
+ }
+
+ static void
+@@ -135,11 +148,15 @@ polkit_permission_finalize (GObject *object)
+
+ g_free (permission->action_id);
+ g_free (permission->tmp_authz_id);
++ g_free (permission->session_state);
+ g_object_unref (permission->subject);
+
+ g_signal_handlers_disconnect_by_func (permission->authority,
+ on_authority_changed,
+ permission);
++ g_signal_handlers_disconnect_by_func (permission->authority,
++ on_sessions_changed,
++ permission);
+ g_object_unref (permission->authority);
+
+ if (G_OBJECT_CLASS (polkit_permission_parent_class)->finalize != NULL)
+@@ -417,6 +434,11 @@ polkit_permission_initable_init (GInitable *initable,
+ G_CALLBACK (on_authority_changed),
+ permission);
+
++ g_signal_connect (permission->authority,
++ "sessions-changed",
++ G_CALLBACK (on_sessions_changed),
++ permission);
++
+ result = polkit_authority_check_authorization_sync (permission->authority,
+ permission->subject,
+ permission->action_id,
+@@ -469,6 +491,37 @@ changed_check_cb (GObject *source_object,
+ g_object_unref (permission);
+ }
+
++static char *get_session_state()
++{
++#ifdef HAVE_LIBSYSTEMD
++ char *session = NULL;
++ char *state = NULL;
++ uid_t uid;
++
++ if ( sd_pid_get_session(getpid(), &session) < 0 )
++ {
++ if ( sd_pid_get_owner_uid(getpid(), &uid) < 0)
++ {
++ goto out;
++ }
++ if (sd_uid_get_display(uid, &session) < 0)
++ {
++ goto out;
++ }
++ }
++
++ if (session != NULL)
++ {
++ sd_session_get_state(session, &state);
++ }
++out:
++ g_free(session);
++ return state;
++#else
++ return NULL;
++#endif
++}
++
+ static void
+ on_authority_changed (PolkitAuthority *authority,
+ gpointer user_data)
+@@ -485,6 +538,40 @@ on_authority_changed (PolkitAuthority *authority,
+ g_object_ref (permission));
+ }
+
++
++static void on_sessions_changed (PolkitAuthority *authority,
++ gpointer user_data)
++{
++#ifdef HAVE_LIBSYSTEMD
++ char *new_session_state = NULL;
++ char *last_state = NULL;
++
++ PolkitPermission *permission = POLKIT_PERMISSION (user_data);
++
++ new_session_state = get_session_state();
++
++ /* if we cannot tell the session state, we should do CheckAuthorization anyway */
++ if ((new_session_state == NULL) || ( g_strcmp0(new_session_state, permission->session_state) != 0 ))
++ {
++ last_state = permission->session_state;
++ permission->session_state = new_session_state;
++ g_free(last_state);
++
++ polkit_authority_check_authorization (permission->authority,
++ permission->subject,
++ permission->action_id,
++ NULL, /* PolkitDetails */
++ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
++ NULL /* cancellable */,
++ changed_check_cb,
++ g_object_ref (permission));
++ }
++#else
++ on_authority_changed(authority, user_data); /* TODO: resolve the "too many session signals" issue for non-systemd systems later */
++#endif
++}
++
++
+ static void
+ process_result (PolkitPermission *permission,
+ PolkitAuthorizationResult *result)
+diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
+index 0d1fac4..6d21af9 100644
+--- a/src/polkitbackend/polkitbackendauthority.c
++++ b/src/polkitbackend/polkitbackendauthority.c
+@@ -48,6 +48,7 @@
+ enum
+ {
+ CHANGED_SIGNAL,
++ SESSIONS_CHANGED_SIGNAL,
+ LAST_SIGNAL,
+ };
+
+@@ -78,6 +79,15 @@ polkit_backend_authority_class_init (PolkitBackendAuthorityClass *klass)
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
++ signals[SESSIONS_CHANGED_SIGNAL] = g_signal_new ("sessions-changed",
++ POLKIT_BACKEND_TYPE_AUTHORITY,
++ G_SIGNAL_RUN_LAST,
++ G_STRUCT_OFFSET (PolkitBackendAuthorityClass, changed),
++ NULL, /* accumulator */
++ NULL, /* accumulator data */
++ g_cclosure_marshal_VOID__VOID,
++ G_TYPE_NONE,
++ 0);
+ }
+
+ /**
+@@ -501,6 +511,8 @@ typedef struct
+
+ gulong authority_changed_id;
+
++ gulong authority_session_monitor_signaller;
++
+ gchar *object_path;
+
+ GHashTable *cancellation_id_to_check_auth_data;
+@@ -523,6 +535,9 @@ server_free (Server *server)
+ if (server->authority != NULL && server->authority_changed_id > 0)
+ g_signal_handler_disconnect (server->authority, server->authority_changed_id);
+
++ if (server->authority != NULL && server->authority_session_monitor_signaller > 0)
++ g_signal_handler_disconnect (server->authority, server->authority_session_monitor_signaller);
++
+ if (server->cancellation_id_to_check_auth_data != NULL)
+ g_hash_table_unref (server->cancellation_id_to_check_auth_data);
+
+@@ -531,20 +546,23 @@ server_free (Server *server)
+ g_free (server);
+ }
+
+-static void
+-on_authority_changed (PolkitBackendAuthority *authority,
+- gpointer user_data)
++static void changed_dbus_call_handler(PolkitBackendAuthority *authority,
++ gpointer user_data,
++ guint16 msg_mask)
+ {
+ Server *server = user_data;
+ GError *error;
++ GVariant *parameters;
+
+ error = NULL;
++
++ parameters = g_variant_new("(q)", msg_mask);
+ if (!g_dbus_connection_emit_signal (server->connection,
+ NULL, /* destination bus name */
+ server->object_path,
+ "org.freedesktop.PolicyKit1.Authority",
+ "Changed",
+- NULL,
++ parameters,
+ &error))
+ {
+ g_warning ("Error emitting Changed() signal: %s", error->message);
+@@ -552,6 +570,29 @@ on_authority_changed (PolkitBackendAuthority *authority,
+ }
+ }
+
++
++static void
++on_authority_changed (PolkitBackendAuthority *authority,
++ gpointer user_data)
++{
++ guint16 msg_mask = 0;
++
++ msg_mask = (guint16) CHANGED_SIGNAL;
++ changed_dbus_call_handler(authority, user_data, msg_mask);
++}
++
++
++static void
++on_sessions_changed (PolkitBackendAuthority *authority,
++ gpointer user_data)
++{
++ guint16 msg_mask = 0;
++
++ msg_mask = (guint16) SESSIONS_CHANGED_SIGNAL;
++ changed_dbus_call_handler(authority, user_data, msg_mask);
++}
++
++
+ static const gchar *server_introspection_data =
+ ""
+ " "
+@@ -1397,6 +1438,11 @@ polkit_backend_authority_register (PolkitBackendAuthority *authority,
+ G_CALLBACK (on_authority_changed),
+ server);
+
++ server->authority_session_monitor_signaller = g_signal_connect (server->authority,
++ "sessions-changed",
++ G_CALLBACK (on_sessions_changed),
++ server);
++
+ return server;
+
+ error:
+diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
+index 08d439e..40376dd 100644
+--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
+@@ -284,7 +284,7 @@ on_session_monitor_changed (PolkitBackendSessionMonitor *monitor,
+ gpointer user_data)
+ {
+ PolkitBackendInteractiveAuthority *authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (user_data);
+- g_signal_emit_by_name (authority, "changed");
++ g_signal_emit_by_name (authority, "sessions-changed");
+ }
+
+ static void
diff --git a/SOURCES/polkit-0.115-session-monitor-watch-sessions-only.patch b/SOURCES/polkit-0.115-session-monitor-watch-sessions-only.patch
new file mode 100644
index 0000000..1000322
--- /dev/null
+++ b/SOURCES/polkit-0.115-session-monitor-watch-sessions-only.patch
@@ -0,0 +1,13 @@
+diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
+index 1a6107a..3abd7c5 100644
+--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
+@@ -106,7 +106,7 @@ sd_source_new (void)
+ source = g_source_new (&sd_source_funcs, sizeof (SdSource));
+ sd_source = (SdSource *)source;
+
+- if ((ret = sd_login_monitor_new (NULL, &sd_source->monitor)) < 0)
++ if ((ret = sd_login_monitor_new ("session", &sd_source->monitor)) < 0)
+ {
+ g_printerr ("Error getting login monitor: %d", ret);
+ }
diff --git a/SPECS/polkit.spec b/SPECS/polkit.spec
index 5b9c530..498e70f 100644
--- a/SPECS/polkit.spec
+++ b/SPECS/polkit.spec
@@ -6,7 +6,7 @@
Summary: An authorization framework
Name: polkit
Version: 0.115
-Release: 15%{?dist}
+Release: 15%{?dist}.2
License: LGPLv2+
URL: http://www.freedesktop.org/wiki/Software/polkit
Source0: http://www.freedesktop.org/software/polkit/releases/%{name}-%{version}.tar.gz
@@ -29,6 +29,8 @@ Patch12: polkit-0.115-CVE-2021-3560.patch
Patch13: polkit-0.115-CVE-2021-4034.patch
Patch14: polkit-0.115-CVE-2021-4115.patch
Patch15: polkit-0.115-tty-flags-restore-if-changed.patch
+Patch16: polkit-0.115-session-monitor-watch-sessions-only.patch
+Patch17: polkit-0.115-pkperm-watch-real-ssn-changes.patch
BuildRequires: gcc-c++
@@ -48,7 +50,8 @@ BuildRequires: automake
BuildRequires: libtool
%endif
-Requires: dbus, polkit-pkla-compat
+Requires: dbus
+Recommends: polkit-pkla-compat
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Requires(pre): shadow-utils
@@ -194,6 +197,15 @@ exit 0
%{_libdir}/girepository-1.0/*.typelib
%changelog
+* Mon May 20 2024 Jan Rybar - 0.115-15.2
+- PolkitPermission re-check on real session changes
+- Resolves: RHEL-34029
+
+* Mon Apr 22 2024 Jan Rybar - 0.115-15.1
+- reduce waking session monitor on uninteresting session changes
+- make polkit-pkla-compat uninstallable (for cases when no .pkla on system)
+- Resolves: RHEL-34029
+
* Tue Nov 08 2022 Jan Rybar - 0.115-15
- pkttyagent gets stopped if killed in the background
- Resolves: rhbz#2128989