summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martin.pitt@canonical.com>2016-11-14 12:00:45 +0100
committerMartin Pitt <martin.pitt@canonical.com>2016-11-14 12:00:45 +0100
commit470340e184b7dc12641769a03037100e8bd4d597 (patch)
treef4230873f5273504f361c080c3361cc713e69827
parent3ad3dc920230da46c2fc7b5aba3ae25fe01c83f8 (diff)
downloadlightdm-git-470340e184b7dc12641769a03037100e8bd4d597.tar.gz
Terminate leftover processes in greeter session
It can happen that the greeter session does not properly clean up itself on logout. This causes leaked processes like settings-daemon which act on the user session as they share the same $DISPLAY. Ask logind to terminate remaining processes in the greeter session on closing, which is more robust than trying to fix every greeter.
-rw-r--r--src/login1.c33
-rw-r--r--src/login1.h2
-rw-r--r--src/session.c5
3 files changed, 40 insertions, 0 deletions
diff --git a/src/login1.c b/src/login1.c
index dc60a492..73d2d8b9 100644
--- a/src/login1.c
+++ b/src/login1.c
@@ -437,6 +437,39 @@ login1_service_activate_session (Login1Service *service, const gchar *session_id
}
}
+void
+login1_service_terminate_session (Login1Service *service, const gchar *session_id)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (service != NULL);
+ g_return_if_fail (session_id != NULL);
+
+ g_debug ("Terminating login1 session %s", session_id);
+
+ if (session_id)
+ {
+ GVariant *result;
+
+ result = g_dbus_connection_call_sync (service->priv->connection,
+ LOGIN1_SERVICE_NAME,
+ LOGIN1_OBJECT_NAME,
+ LOGIN1_MANAGER_INTERFACE_NAME,
+ "TerminateSession",
+ g_variant_new ("(s)", session_id),
+ G_VARIANT_TYPE ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (error)
+ g_warning ("Error terminating login1 session: %s", error->message);
+ g_clear_error (&error);
+ if (result)
+ g_variant_unref (result);
+ }
+}
+
static void
login1_service_init (Login1Service *service)
{
diff --git a/src/login1.h b/src/login1.h
index e34e806b..9377dba8 100644
--- a/src/login1.h
+++ b/src/login1.h
@@ -78,6 +78,8 @@ void login1_service_unlock_session (Login1Service *service, const gchar *session
void login1_service_activate_session (Login1Service *service, const gchar *session_id);
+void login1_service_terminate_session (Login1Service *service, const gchar *session_id);
+
const gchar *login1_seat_get_id (Login1Seat *seat);
gboolean login1_seat_get_can_graphical (Login1Seat *seat);
diff --git a/src/session.c b/src/session.c
index 5e7d4767..15598425 100644
--- a/src/session.c
+++ b/src/session.c
@@ -913,6 +913,11 @@ session_stop (Session *session)
{
g_return_if_fail (session != NULL);
+ /* Kill remaining processes in our logind session to avoid them leaking
+ * to the user session (they share the same $DISPLAY) */
+ if (getuid () == 0 && session->priv->login1_session_id)
+ login1_service_terminate_session (login1_service_get_instance (), session->priv->login1_session_id);
+
/* If can cleanly stop then do that */
if (session_get_is_authenticated (session) && !session->priv->command_run)
{