]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: Restore chvt as non-root user without polkit
authorJoshua Watt <JPEWhacker@gmail.com>
Fri, 30 Oct 2020 13:15:43 +0000 (08:15 -0500)
committerLennart Poettering <lennart@poettering.net>
Tue, 16 Feb 2021 19:24:53 +0000 (20:24 +0100)
4acf0cfd2f ("logind: check PolicyKit before allowing VT switch") broke
the ability to write user sessions that run graphical sessions (e.g.
weston/X11). This was partially amended in 19bb87fbfa ("login: allow
non-console sessions to change vt") by changing the default PolicyKit
policy so that non-root users with a session are again allowed to switch
the VT. This makes the policy when PolKit is not enabled (as on many
embedded systems) closer the default PolKit policy and allows launching
graphical sessions as a non-root user.

Closes #17473

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
src/login/logind-dbus.c
src/login/logind-polkit.c [new file with mode: 0644]
src/login/logind-polkit.h [new file with mode: 0644]
src/login/logind-seat-dbus.c
src/login/logind-session-dbus.c
src/login/meson.build

index 7e55173e27e6f01204222b360c35c2075755a090..b9b2524822acabad36375fa25858b3edc9b46bd0 100644 (file)
@@ -30,6 +30,7 @@
 #include "format-util.h"
 #include "fs-util.h"
 #include "logind-dbus.h"
+#include "logind-polkit.h"
 #include "logind-seat-dbus.h"
 #include "logind-session-dbus.h"
 #include "logind-user-dbus.h"
@@ -1047,15 +1048,7 @@ static int method_activate_session_on_seat(sd_bus_message *message, void *userda
                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT,
                                          "Session %s not on seat %s", session_name, seat_name);
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &m->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, m, error);
         if (r < 0)
                 return r;
         if (r == 0)
diff --git a/src/login/logind-polkit.c b/src/login/logind-polkit.c
new file mode 100644 (file)
index 0000000..d221bee
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "bus-polkit.h"
+#include "logind-polkit.h"
+#include "missing_capability.h"
+#include "user-util.h"
+
+int check_polkit_chvt(sd_bus_message *message, Manager *manager, sd_bus_error *error) {
+#if ENABLE_POLKIT
+        return bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.chvt",
+                        NULL,
+                        false,
+                        UID_INVALID,
+                        &manager->polkit_registry,
+                        error);
+#else
+        /* Allow chvt when polkit is not present. This allows a service to start a graphical session as a
+         * non-root user when polkit is not compiled in, more closely matching the default polkit policy */
+        return 1;
+#endif
+}
diff --git a/src/login/logind-polkit.h b/src/login/logind-polkit.h
new file mode 100644 (file)
index 0000000..8c124f8
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "sd-bus.h"
+
+#include "bus-object.h"
+#include "logind.h"
+
+int check_polkit_chvt(sd_bus_message *message, Manager *manager, sd_bus_error *error);
index a60ed2d3c2d3e586f8ac3bc3b7164d9757820110..9c2625cdcc3245cbddcec808fc63c14c846d98af 100644 (file)
@@ -9,6 +9,7 @@
 #include "bus-polkit.h"
 #include "bus-util.h"
 #include "logind-dbus.h"
+#include "logind-polkit.h"
 #include "logind-seat-dbus.h"
 #include "logind-seat.h"
 #include "logind-session-dbus.h"
@@ -179,15 +180,7 @@ static int method_activate_session(sd_bus_message *message, void *userdata, sd_b
         if (session->seat != s)
                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id);
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &s->manager->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, s->manager, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -215,15 +208,7 @@ static int method_switch_to(sd_bus_message *message, void *userdata, sd_bus_erro
         if (to <= 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid virtual terminal");
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &s->manager->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, s->manager, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -243,15 +228,7 @@ static int method_switch_to_next(sd_bus_message *message, void *userdata, sd_bus
         assert(message);
         assert(s);
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &s->manager->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, s->manager, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -271,15 +248,7 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd
         assert(message);
         assert(s);
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &s->manager->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, s->manager, error);
         if (r < 0)
                 return r;
         if (r == 0)
index b5d240be6a5585e27bd023b794554f498c2f954e..d342dc4193aa42d53a969568d519ed640ac919b4 100644 (file)
@@ -11,6 +11,7 @@
 #include "fd-util.h"
 #include "logind-brightness.h"
 #include "logind-dbus.h"
+#include "logind-polkit.h"
 #include "logind-seat-dbus.h"
 #include "logind-session-dbus.h"
 #include "logind-session-device.h"
@@ -192,15 +193,7 @@ int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_
         assert(message);
         assert(s);
 
-        r = bus_verify_polkit_async(
-                        message,
-                        CAP_SYS_ADMIN,
-                        "org.freedesktop.login1.chvt",
-                        NULL,
-                        false,
-                        UID_INVALID,
-                        &s->manager->polkit_registry,
-                        error);
+        r = check_polkit_chvt(message, s->manager, error);
         if (r < 0)
                 return r;
         if (r == 0)
index ca644923830fd25a4d0b87dc8b11dc81887a6529..156c391d8ac0529286dfc3e8a95081d1560145e8 100644 (file)
@@ -25,6 +25,8 @@ liblogind_core_sources = files('''
         logind-device.h
         logind-inhibit.c
         logind-inhibit.h
+        logind-polkit.c
+        logind-polkit.h
         logind-seat-dbus.c
         logind-seat-dbus.h
         logind-seat.c