|
|
7e7c9f |
From fb419649754767124f30dba36f8fdbd114b0e9d7 Mon Sep 17 00:00:00 2001
|
|
|
7e7c9f |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
7e7c9f |
Date: Wed, 22 Jan 2020 12:04:38 +0100
|
|
|
7e7c9f |
Subject: [PATCH] logind: check PolicyKit before allowing VT switch
|
|
|
7e7c9f |
|
|
|
7e7c9f |
Let's lock this down a bit. Effectively nothing much changes, since the
|
|
|
7e7c9f |
default PK policy will allow users on the VT to change VT. Only users
|
|
|
7e7c9f |
with no local VT session won't be able to switch VTs.
|
|
|
7e7c9f |
|
|
|
7e7c9f |
(cherry picked from commit 4acf0cfd2f92edb94ad48d04f1ce6c9ab4e19d55)
|
|
|
7e7c9f |
|
|
|
7e7c9f |
Resolves: #1797672
|
|
|
7e7c9f |
---
|
|
|
7e7c9f |
src/login/logind-dbus.c | 18 ++++++--
|
|
|
7e7c9f |
src/login/logind-seat-dbus.c | 50 +++++++++++++++++++++-
|
|
|
7e7c9f |
src/login/logind-session-dbus.c | 16 ++++++-
|
|
|
7e7c9f |
src/login/logind-session.h | 2 +
|
|
|
7e7c9f |
src/login/org.freedesktop.login1.policy.in | 10 +++++
|
|
|
7e7c9f |
5 files changed, 89 insertions(+), 7 deletions(-)
|
|
|
7e7c9f |
|
|
|
7e7c9f |
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
|
|
|
7e7c9f |
index 63b9a0df36..019aa193f5 100644
|
|
|
7e7c9f |
--- a/src/login/logind-dbus.c
|
|
|
7e7c9f |
+++ b/src/login/logind-dbus.c
|
|
|
7e7c9f |
@@ -854,11 +854,9 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
|
|
|
7e7c9f |
- r = session_activate(session);
|
|
|
7e7c9f |
- if (r < 0)
|
|
|
7e7c9f |
- return r;
|
|
|
7e7c9f |
+ /* PolicyKit is done by bus_session_method_activate() */
|
|
|
7e7c9f |
|
|
|
7e7c9f |
- return sd_bus_reply_method_return(message, NULL);
|
|
|
7e7c9f |
+ return bus_session_method_activate(bus, message, session, error);
|
|
|
7e7c9f |
}
|
|
|
7e7c9f |
|
|
|
7e7c9f |
static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
|
7e7c9f |
@@ -890,6 +888,18 @@ static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message,
|
|
|
7e7c9f |
if (session->seat != seat)
|
|
|
7e7c9f |
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &m->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
r = session_activate(session);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
|
|
|
7e7c9f |
index 50b0b8842f..f49e416fce 100644
|
|
|
7e7c9f |
--- a/src/login/logind-seat-dbus.c
|
|
|
7e7c9f |
+++ b/src/login/logind-seat-dbus.c
|
|
|
7e7c9f |
@@ -229,6 +229,18 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u
|
|
|
7e7c9f |
if (session->seat != s)
|
|
|
7e7c9f |
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id);
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &s->manager->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
r = session_activate(session);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
@@ -250,7 +262,19 @@ static int method_switch_to(sd_bus *bus, sd_bus_message *message, void *userdata
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
|
|
|
7e7c9f |
if (to <= 0)
|
|
|
7e7c9f |
- return -EINVAL;
|
|
|
7e7c9f |
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid virtual terminal");
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &s->manager->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
|
|
|
7e7c9f |
r = seat_switch_to(s, to);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
@@ -267,6 +291,18 @@ static int method_switch_to_next(sd_bus *bus, sd_bus_message *message, void *use
|
|
|
7e7c9f |
assert(message);
|
|
|
7e7c9f |
assert(s);
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &s->manager->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
r = seat_switch_to_next(s);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
@@ -282,6 +318,18 @@ static int method_switch_to_previous(sd_bus *bus, sd_bus_message *message, void
|
|
|
7e7c9f |
assert(message);
|
|
|
7e7c9f |
assert(s);
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &s->manager->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
r = seat_switch_to_previous(s);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
|
|
|
7e7c9f |
index 75b7186e8f..0ec4196257 100644
|
|
|
7e7c9f |
--- a/src/login/logind-session-dbus.c
|
|
|
7e7c9f |
+++ b/src/login/logind-session-dbus.c
|
|
|
7e7c9f |
@@ -213,7 +213,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
|
|
|
7e7c9f |
return sd_bus_reply_method_return(message, NULL);
|
|
|
7e7c9f |
}
|
|
|
7e7c9f |
|
|
|
7e7c9f |
-static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
|
7e7c9f |
+int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
|
7e7c9f |
Session *s = userdata;
|
|
|
7e7c9f |
int r;
|
|
|
7e7c9f |
|
|
|
7e7c9f |
@@ -221,6 +221,18 @@ static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata,
|
|
|
7e7c9f |
assert(message);
|
|
|
7e7c9f |
assert(s);
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ r = bus_verify_polkit_async(
|
|
|
7e7c9f |
+ message,
|
|
|
7e7c9f |
+ CAP_SYS_ADMIN,
|
|
|
7e7c9f |
+ "org.freedesktop.login1.chvt",
|
|
|
7e7c9f |
+ false,
|
|
|
7e7c9f |
+ &s->manager->polkit_registry,
|
|
|
7e7c9f |
+ error);
|
|
|
7e7c9f |
+ if (r < 0)
|
|
|
7e7c9f |
+ return r;
|
|
|
7e7c9f |
+ if (r == 0)
|
|
|
7e7c9f |
+ return 1; /* Will call us back */
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
r = session_activate(s);
|
|
|
7e7c9f |
if (r < 0)
|
|
|
7e7c9f |
return r;
|
|
|
7e7c9f |
@@ -506,7 +518,7 @@ const sd_bus_vtable session_vtable[] = {
|
|
|
7e7c9f |
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
|
|
7e7c9f |
|
|
|
7e7c9f |
SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
|
|
|
7e7c9f |
- SD_BUS_METHOD("Activate", NULL, NULL, method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
|
|
|
7e7c9f |
+ SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
|
|
|
7e7c9f |
SD_BUS_METHOD("Lock", NULL, NULL, method_lock, 0),
|
|
|
7e7c9f |
SD_BUS_METHOD("Unlock", NULL, NULL, method_lock, 0),
|
|
|
7e7c9f |
SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
|
|
|
7e7c9f |
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
|
|
|
7e7c9f |
index d662082d85..b498f49592 100644
|
|
|
7e7c9f |
--- a/src/login/logind-session.h
|
|
|
7e7c9f |
+++ b/src/login/logind-session.h
|
|
|
7e7c9f |
@@ -184,3 +184,5 @@ void session_leave_vt(Session *s);
|
|
|
7e7c9f |
bool session_is_controller(Session *s, const char *sender);
|
|
|
7e7c9f |
int session_set_controller(Session *s, const char *sender, bool force);
|
|
|
7e7c9f |
void session_drop_controller(Session *s);
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
+int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
|
|
|
7e7c9f |
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in
|
|
|
7e7c9f |
index 49094eeddb..fa51ed8d74 100644
|
|
|
7e7c9f |
--- a/src/login/org.freedesktop.login1.policy.in
|
|
|
7e7c9f |
+++ b/src/login/org.freedesktop.login1.policy.in
|
|
|
7e7c9f |
@@ -270,4 +270,14 @@
|
|
|
7e7c9f |
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate>
|
|
|
7e7c9f |
</action>
|
|
|
7e7c9f |
|
|
|
7e7c9f |
+ <action id="org.freedesktop.login1.chvt">
|
|
|
7e7c9f |
+ <description gettext-domain="systemd">Change Session</description>
|
|
|
7e7c9f |
+ <message gettext-domain="systemd">Authentication is required for changing the virtual terminal.</message>
|
|
|
7e7c9f |
+ <defaults>
|
|
|
7e7c9f |
+ <allow_any>auth_admin_keep</allow_any>
|
|
|
7e7c9f |
+ <allow_inactive>auth_admin_keep</allow_inactive>
|
|
|
7e7c9f |
+ <allow_active>yes</allow_active>
|
|
|
7e7c9f |
+ </defaults>
|
|
|
7e7c9f |
+ </action>
|
|
|
7e7c9f |
+
|
|
|
7e7c9f |
</policyconfig>
|