logind: Add support for RebootParameter
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.
This commit is contained in:
parent
ce7f10707d
commit
428b296a59
|
@ -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),
|
||||
|
|
|
@ -190,6 +190,14 @@
|
|||
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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue