diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/login/logind-dbus.c | 96 | ||||
-rw-r--r-- | src/login/org.freedesktop.login1.conf | 8 | ||||
-rw-r--r-- | src/login/org.freedesktop.login1.policy | 11 | ||||
-rw-r--r-- | src/shared/reboot-util.c | 12 | ||||
-rw-r--r-- | src/shared/reboot-util.h | 1 |
5 files changed, 128 insertions, 0 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 795fc3b645b..5f82b219956 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -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(¶meter); + 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), diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf index 5677c15b8a9..f3c13ad89a0 100644 --- a/src/login/org.freedesktop.login1.conf +++ b/src/login/org.freedesktop.login1.conf @@ -192,6 +192,14 @@ <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"/> <allow send_destination="org.freedesktop.login1" diff --git a/src/login/org.freedesktop.login1.policy b/src/login/org.freedesktop.login1.policy index 671384d34e8..6ad6512f5a3 100644 --- a/src/login/org.freedesktop.login1.policy +++ b/src/login/org.freedesktop.login1.policy @@ -337,6 +337,17 @@ </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> diff --git a/src/shared/reboot-util.c b/src/shared/reboot-util.c index 6d5eee03173..08569e8bf34 100644 --- a/src/shared/reboot-util.c +++ b/src/shared/reboot-util.c @@ -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; diff --git a/src/shared/reboot-util.h b/src/shared/reboot-util.h index ac59b7d79c6..7bddc91ea60 100644 --- a/src/shared/reboot-util.h +++ b/src/shared/reboot-util.h @@ -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); |