From 8885fed4e3a52cf1bf105e42043203c485ed9d92 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 25 Jan 2021 09:14:08 -0800 Subject: logind: Introduce RebootWithFlags and others Add new systemd-logind WithFlags version for Reboot and others. These methods add a unit64 parameter, with which can send additional control flags. --- src/login/logind-dbus.c | 97 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 14 deletions(-) (limited to 'src/login') diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index b95af1a9fd..8f27fe7ee9 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1793,14 +1793,14 @@ static int verify_shutdown_creds( Manager *m, sd_bus_message *message, InhibitWhat w, - bool interactive, const char *action, const char *action_multiple_sessions, const char *action_ignore_inhibit, + uint64_t flags, sd_bus_error *error) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; - bool multiple_sessions, blocked; + bool multiple_sessions, blocked, interactive; uid_t uid; int r; @@ -1823,6 +1823,7 @@ static int verify_shutdown_creds( multiple_sessions = r > 0; blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); + interactive = flags & SD_LOGIND_INTERACTIVE; if (multiple_sessions && action_multiple_sessions) { r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error); @@ -1832,12 +1833,19 @@ static int verify_shutdown_creds( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ } - if (blocked && action_ignore_inhibit) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, 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 */ + if (blocked) { + /* We don't check polkit for root here, because you can't be more privileged than root */ + if (uid == 0 && (flags & SD_LOGIND_ROOT_CHECK_INHIBITORS)) + return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, + "Access denied to root due to active block inhibitor"); + + if (action_ignore_inhibit) { + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, 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 */ + } } if (!multiple_sessions && !blocked && action) { @@ -1860,9 +1868,11 @@ static int method_do_shutdown_or_sleep( const char *action_multiple_sessions, const char *action_ignore_inhibit, const char *sleep_verb, + bool with_flags, sd_bus_error *error) { - int interactive, r; + int interactive = false, r; + uint64_t flags = 0; assert(m); assert(message); @@ -1870,10 +1880,20 @@ static int method_do_shutdown_or_sleep( assert(w >= 0); assert(w <= _INHIBIT_WHAT_MAX); - r = sd_bus_message_read(message, "b", &interactive); + if (with_flags) + r = sd_bus_message_read(message, "t", &flags); + else + r = sd_bus_message_read(message, "b", &interactive); + if (r < 0) return r; + if (with_flags && (flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Invalid flags parameter"); + + SET_FLAG(flags, SD_LOGIND_INTERACTIVE, interactive); + /* Don't allow multiple jobs being executed at the same time */ if (m->action_what > 0) return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, @@ -1891,8 +1911,8 @@ static int method_do_shutdown_or_sleep( return r; } - r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions, - action_ignore_inhibit, error); + r = verify_shutdown_creds(m, message, w, action, action_multiple_sessions, + action_ignore_inhibit, flags, error); if (r != 0) return r; @@ -1914,6 +1934,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.power-off-multiple-sessions", "org.freedesktop.login1.power-off-ignore-inhibit", NULL, + sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"), error); } @@ -1928,6 +1949,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * "org.freedesktop.login1.reboot-multiple-sessions", "org.freedesktop.login1.reboot-ignore-inhibit", NULL, + sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"), error); } @@ -1942,6 +1964,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er "org.freedesktop.login1.halt-multiple-sessions", "org.freedesktop.login1.halt-ignore-inhibit", NULL, + sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"), error); } @@ -1956,6 +1979,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error "org.freedesktop.login1.suspend-multiple-sessions", "org.freedesktop.login1.suspend-ignore-inhibit", "suspend", + sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"), error); } @@ -1970,6 +1994,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro "org.freedesktop.login1.hibernate-multiple-sessions", "org.freedesktop.login1.hibernate-ignore-inhibit", "hibernate", + sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"), error); } @@ -1984,6 +2009,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e "org.freedesktop.login1.hibernate-multiple-sessions", "org.freedesktop.login1.hibernate-ignore-inhibit", "hybrid-sleep", + sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"), error); } @@ -1998,6 +2024,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata "org.freedesktop.login1.hibernate-multiple-sessions", "org.freedesktop.login1.hibernate-ignore-inhibit", "hybrid-sleep", + sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"), error); } @@ -2185,8 +2212,8 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_ } else return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type"); - r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false, - action, action_multiple_sessions, action_ignore_inhibit, error); + r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, action, action_multiple_sessions, + action_ignore_inhibit, 0, error); if (r != 0) return r; @@ -3538,42 +3565,84 @@ static const sd_bus_vtable manager_vtable[] = { NULL,, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("PowerOffWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_poweroff, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("Reboot", "b", SD_BUS_PARAM(interactive), NULL,, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("RebootWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_reboot, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("Halt", "b", SD_BUS_PARAM(interactive), NULL,, method_halt, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("HaltWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_halt, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("Suspend", "b", SD_BUS_PARAM(interactive), NULL,, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SuspendWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_suspend, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("Hibernate", "b", SD_BUS_PARAM(interactive), NULL,, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("HibernateWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_hibernate, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("HybridSleep", "b", SD_BUS_PARAM(interactive), NULL,, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("HybridSleepWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_hybrid_sleep, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernate", "b", SD_BUS_PARAM(interactive), NULL,, method_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernateWithFlags", + "t", + SD_BUS_PARAM(flags), + NULL,, + method_suspend_then_hibernate, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("CanPowerOff", NULL,, "s", -- cgit v1.2.1