]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: Add support for RebootParameter 11602/head
authorVesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
Sat, 9 Mar 2019 20:30:58 +0000 (22:30 +0200)
committerVesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
Fri, 22 Mar 2019 18:30:33 +0000 (20:30 +0200)
This adds support for user to set & get reboot parameter for reboot.

As callee would be next issuing Reboot call same policy checks are being used.

If unit file issuing the reboot action defines RebootArgument (or similar) that
setting takes precedence.

src/login/logind-dbus.c
src/login/org.freedesktop.login1.conf
src/login/org.freedesktop.login1.policy
src/shared/reboot-util.c
src/shared/reboot-util.h

index 795fc3b645bbc197028f2a26281a34a252ca211c..5f82b21995627ecd514aca5eb3a59e1118d14648 100644 (file)
@@ -32,6 +32,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "reboot-util.h"
 #include "selinux-util.h"
 #include "sleep-config.h"
 #include "special.h"
@@ -42,6 +43,7 @@
 #include "unit-name.h"
 #include "user-util.h"
 #include "utmp-wtmp.h"
+#include "virt.h"
 
 static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) {
 
@@ -2408,6 +2410,97 @@ static int method_can_suspend_then_hibernate(sd_bus_message *message, void *user
                         error);
 }
 
+static int property_get_reboot_parameter(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+        _cleanup_free_ char *parameter = NULL;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(userdata);
+
+        r = read_reboot_parameter(&parameter);
+        if (r < 0)
+                return r;
+
+        return sd_bus_message_append(reply, "s", parameter);
+}
+
+static int method_set_reboot_parameter(
+                sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Manager *m = userdata;
+        const char *arg;
+        int r;
+
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "s", &arg);
+        if (r < 0)
+                return r;
+
+        r = detect_container();
+        if (r < 0)
+                return r;
+        if (r > 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
+                                         "Reboot parameter not supported in containers, refusing.");
+
+        r = bus_verify_polkit_async(message,
+                                    CAP_SYS_ADMIN,
+                                    "org.freedesktop.login1.set-reboot-parameter",
+                                    NULL,
+                                    false,
+                                    UID_INVALID,
+                                    &m->polkit_registry,
+                                    error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = update_reboot_parameter_and_warn(arg, false);
+        if (r < 0)
+                return r;
+
+        return sd_bus_reply_method_return(message, NULL);
+}
+
+static int method_can_reboot_parameter(
+                sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Manager *m = userdata;
+        int r;
+
+        assert(message);
+        assert(m);
+
+        r = detect_container();
+        if (r < 0)
+                return r;
+        if (r > 0) /* Inside containers, specifying a reboot parameter, doesn't make much sense */
+                return sd_bus_reply_method_return(message, "s", "na");
+
+        return return_test_polkit(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.set-reboot-parameter",
+                        NULL,
+                        UID_INVALID,
+                        error);
+}
+
 static int property_get_reboot_to_firmware_setup(
                 sd_bus *bus,
                 const char *path,
@@ -3137,6 +3230,7 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RebootParameter", "s", property_get_reboot_parameter, 0, 0),
         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, 0),
         SD_BUS_PROPERTY("RebootToBootLoaderMenu", "t", property_get_reboot_to_boot_loader_menu, 0, 0),
         SD_BUS_PROPERTY("RebootToBootLoaderEntry", "s", property_get_reboot_to_boot_loader_entry, 0, 0),
@@ -3213,6 +3307,8 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("CanRebootParameter", NULL, "s", method_can_reboot_parameter, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("SetRebootParameter", "s", NULL, method_set_reboot_parameter, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CanRebootToBootLoaderMenu", NULL, "s", method_can_reboot_to_boot_loader_menu, SD_BUS_VTABLE_UNPRIVILEGED),
index 5677c15b8a963bdb694b227429794a32137f79d1..f3c13ad89a00ac139b4513d5c8d43c40c362907a 100644 (file)
                        send_interface="org.freedesktop.login1.Manager"
                        send_member="CancelScheduledShutdown"/>
 
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanRebootParameter"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="SetRebootParameter"/>
+
                 <allow send_destination="org.freedesktop.login1"
                        send_interface="org.freedesktop.login1.Manager"
                        send_member="CanRebootToFirmwareSetup"/>
index 671384d34e88bd8ecc8ee8d39404772ab15ef9ce..6ad6512f5a336afffc50d9253380746c56921654 100644 (file)
                 </defaults>
         </action>
 
+        <action id="org.freedesktop.login1.set-reboot-parameter">
+                <description gettext-domain="systemd">Configure reboot parameter for kernel's reboot reason driver</description>
+                <message gettext-domain="systemd">Authentication is required to configure reboot parameter for kernel's reboot reason driver.</message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
+        </action>
+
         <action id="org.freedesktop.login1.set-reboot-to-firmware-setup">
                 <description gettext-domain="systemd">Indicate to the firmware to boot to setup interface</description>
                 <message gettext-domain="systemd">Authentication is required to indicate to the firmware to boot to setup interface.</message>
index 6d5eee031734b287ea8103d8801620725c030236..08569e8bf3409a01aa72bb15ea1fe11d2944c9da 100644 (file)
@@ -39,6 +39,18 @@ int update_reboot_parameter_and_warn(const char *parameter, bool keep) {
         return 0;
 }
 
+int read_reboot_parameter(char **parameter) {
+        int r;
+
+        assert(parameter);
+
+        r = read_one_line_file("/run/systemd/reboot-param", parameter);
+        if (r < 0 && r != -ENOENT)
+                return log_debug_errno(r, "Failed to read /run/systemd/reboot-param: %m");
+
+        return 0;
+}
+
 int reboot_with_parameter(RebootFlags flags) {
         int r;
 
index ac59b7d79c68fcb279eaf7e0b5e55d55695f5cf9..7bddc91ea60bbf5e840b3a7a5a8b64f8ad4623db 100644 (file)
@@ -9,4 +9,5 @@ typedef enum RebootFlags {
         REBOOT_FALLBACK = 1 << 2, /* fallback to plain reboot() if argument-based reboot doesn't work, isn't configured or doesn't apply otherwise */
 } RebootFlags;
 
+int read_reboot_parameter(char **parameter);
 int reboot_with_parameter(RebootFlags flags);