summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
Diffstat (limited to 'src/login')
-rw-r--r--src/login/logind-dbus.c97
1 files changed, 82 insertions, 15 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index b9ea370ec0..262b0290a8 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -18,6 +18,7 @@
#include "device-util.h"
#include "dirent-util.h"
#include "efivars.h"
+#include "env-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio-label.h"
@@ -2392,9 +2393,24 @@ static int property_get_reboot_to_firmware_setup(
assert(reply);
assert(userdata);
- r = efi_get_reboot_to_firmware();
- if (r < 0 && r != -EOPNOTSUPP)
- log_warning_errno(r, "Failed to determine reboot-to-firmware state: %m");
+ r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
+ if (r == -ENXIO) {
+ /* EFI case: let's see what is currently configured in the EFI variables */
+ r = efi_get_reboot_to_firmware();
+ if (r < 0 && r != -EOPNOTSUPP)
+ log_warning_errno(r, "Failed to determine reboot-to-firmware-setup state: %m");
+ } else if (r < 0)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
+ else if (r > 0) {
+ /* Non-EFI case: let's see whether /run/systemd/reboot-to-firmware-setup exists. */
+ if (access("/run/systemd/reboot-to-firmware-setup", F_OK) < 0) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to check whether /run/systemd/reboot-to-firmware-setup exists: %m");
+
+ r = false;
+ } else
+ r = true;
+ }
return sd_bus_message_append(reply, "b", r > 0);
}
@@ -2404,8 +2420,9 @@ static int method_set_reboot_to_firmware_setup(
void *userdata,
sd_bus_error *error) {
- int b, r;
Manager *m = userdata;
+ bool use_efi;
+ int b, r;
assert(message);
assert(m);
@@ -2414,6 +2431,29 @@ static int method_set_reboot_to_firmware_setup(
if (r < 0)
return r;
+ r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
+ if (r == -ENXIO) {
+ /* EFI case: let's see what the firmware supports */
+
+ r = efi_reboot_to_firmware_supported();
+ if (r == -EOPNOTSUPP)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Firmware does not support boot into firmware.");
+ if (r < 0)
+ return r;
+
+ use_efi = true;
+
+ } else if (r <= 0) {
+ /* non-EFI case: $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP is set to off */
+
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
+
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Firmware does not support boot into firmware.");
+ } else
+ /* non-EFI case: $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP is set to on */
+ use_efi = false;
+
r = bus_verify_polkit_async(message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-reboot-to-firmware-setup",
@@ -2427,9 +2467,20 @@ static int method_set_reboot_to_firmware_setup(
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = efi_set_reboot_to_firmware(b);
- if (r < 0)
- return r;
+ if (use_efi) {
+ r = efi_set_reboot_to_firmware(b);
+ if (r < 0)
+ return r;
+ } else {
+ if (b) {
+ r = touch("/run/systemd/reboot-to-firmware-setup");
+ if (r < 0)
+ return r;
+ } else {
+ if (unlink("/run/systemd/reboot-to-firmware-setup") < 0 && errno != ENOENT)
+ return -errno;
+ }
+ }
return sd_bus_reply_method_return(message, NULL);
}
@@ -2439,22 +2490,38 @@ static int method_can_reboot_to_firmware_setup(
void *userdata,
sd_bus_error *error) {
- int r;
- bool challenge;
- const char *result;
+ const char *result = NULL;
Manager *m = userdata;
+ bool challenge;
+ int r;
assert(message);
assert(m);
- r = efi_reboot_to_firmware_supported();
- if (r < 0) {
- if (r != -EOPNOTSUPP)
- log_warning_errno(r, "Failed to determine whether reboot to firmware is supported: %m");
+ r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
+ if (r == -ENXIO) {
+ /* EFI case: let's see what the firmware supports */
+
+ r = efi_reboot_to_firmware_supported();
+ if (r < 0) {
+ if (r != -EOPNOTSUPP)
+ log_warning_errno(r, "Failed to determine whether reboot to firmware is supported: %m");
+
+ result = "na";
+ }
- return sd_bus_reply_method_return(message, "s", "na");
+ } else if (r <= 0) {
+ /* Non-EFI case: let's trust $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP */
+
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
+
+ result = "na";
}
+ if (result)
+ return sd_bus_reply_method_return(message, "s", result);
+
r = bus_test_polkit(message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-reboot-to-firmware-setup",