mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
Merge pull request #30307 from bluca/enforce_inhibitors
logind: always check for inhibitor locks
This commit is contained in:
commit
e520b1258c
11
NEWS
11
NEWS
@ -31,6 +31,17 @@ CHANGES WITH 257 in spe:
|
||||
by default when combined with --scope, will be changed in a future
|
||||
release to be enabled by default.
|
||||
|
||||
* systemd-logind now always obeys inhibitor locks, where previously it
|
||||
ignored locks taken by the caller or when the caller was root. A
|
||||
privileged caller can always close the other sessions, remove the
|
||||
inhibitor locks, or use --force or --check-inhibitors=no to ignore the
|
||||
inhibitors. This change thus doesn't affect security, since everything
|
||||
that was possible before at a given privilege level is still possible,
|
||||
but it should make the inhibitor logic easier to use and understand,
|
||||
and also help avoiding accidental reboots and shutdowns. New 'delay-weak'
|
||||
and 'block-weak' inhibitor modes were added, if taken they will make
|
||||
the inhibitor lock work as in the previous versions.
|
||||
|
||||
— <place>, <date>
|
||||
|
||||
CHANGES WITH 256:
|
||||
|
@ -42,6 +42,9 @@ If such a lock is taken the operation will fail (but still may be overridden if
|
||||
The InhibitDelayMaxSec= setting in [logind.conf(5)](http://www.freedesktop.org/software/systemd/man/logind.conf.html) controls the timeout for this. This is intended to be used by applications which need a synchronous way to execute actions before system suspend but shall not be allowed to block suspend indefinitely.
|
||||
This mode is only available for _sleep_ and _shutdown_ locks.
|
||||
|
||||
3. _block-weak_ and _delay-weak_ that work as the non-weak counterparts, but that in addition may be ignored
|
||||
automatically and silently under certain circumstances, unlike the formers which are always respected.
|
||||
|
||||
Inhibitor locks are taken via the Inhibit() D-Bus call on the logind Manager object:
|
||||
|
||||
```
|
||||
|
@ -665,15 +665,18 @@ node /org/freedesktop/login1 {
|
||||
#define SD_LOGIND_KEXEC_REBOOT (UINT64_C(1) << 1)
|
||||
#define SD_LOGIND_SOFT_REBOOT (UINT64_C(1) << 2)
|
||||
#define SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP (UINT64_C(1) << 3)
|
||||
#define SD_LOGIND_SKIP_INHIBITORS (UINT64_C(1) << 4)
|
||||
</programlisting>
|
||||
<para>When the <varname>flags</varname> is 0 then these methods behave just like the versions without
|
||||
flags. When <constant>SD_LOGIND_ROOT_CHECK_INHIBITORS</constant> (0x01) is set, active inhibitors are
|
||||
honoured for privileged users too. When <constant>SD_LOGIND_KEXEC_REBOOT</constant> (0x02) is set,
|
||||
then <function>RebootWithFlags()</function> performs a kexec reboot if kexec kernel is loaded. When
|
||||
<constant>SD_LOGIND_SOFT_REBOOT</constant> (0x04) is set, or
|
||||
<constant>SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP</constant> (0x08) is set and a new root file system
|
||||
has been set up on <literal>/run/nextroot/</literal>, then <function>RebootWithFlags()</function>
|
||||
performs a userspace reboot only. <constant>SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP</constant> and
|
||||
flags. Since systemd version 256 <constant>SD_LOGIND_ROOT_CHECK_INHIBITORS</constant> (0x01) is deprecated,
|
||||
and active inhibitors are always honoured by default for privileged users too, and a new flag
|
||||
<constant>SD_LOGIND_SKIP_INHIBITORS</constant> (0x04) can be specified to bypass inhibitors. When
|
||||
<constant>SD_LOGIND_KEXEC_REBOOT</constant> (0x02) is set, then <function>RebootWithFlags()</function>
|
||||
performs a kexec reboot if kexec kernel is loaded. When <constant>SD_LOGIND_SOFT_REBOOT</constant>
|
||||
(0x04) is set, or <constant>SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP</constant> (0x08) is set and a
|
||||
new root file system has been set up on <literal>/run/nextroot/</literal>, then
|
||||
<function>RebootWithFlags()</function> performs a userspace reboot only.
|
||||
<constant>SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP</constant> and
|
||||
<constant>SD_LOGIND_KEXEC_REBOOT</constant> can be combined, with soft-reboot having precedence.</para>
|
||||
|
||||
<para><function>SetRebootParameter()</function> sets a parameter for a subsequent reboot operation.
|
||||
@ -731,8 +734,10 @@ node /org/freedesktop/login1 {
|
||||
should be a short human readable string identifying the reason why the lock is taken. Finally,
|
||||
<varname>mode</varname> is either <literal>block</literal> or <literal>delay</literal> which encodes
|
||||
whether the inhibit shall be consider mandatory or whether it should just delay the operation to a
|
||||
certain maximum time. The method returns a file descriptor. The lock is released the moment this file
|
||||
descriptor and all its duplicates are closed. For more information on the inhibition logic see
|
||||
certain maximum time, while the <literal>block-weak</literal> and <literal>delay-weak</literal>
|
||||
variants will create an inhibitor that is automatically ignored in some circumstances. The method
|
||||
returns a file descriptor. The lock is released the moment this file descriptor and all its duplicates
|
||||
are closed. For more information on the inhibition logic see
|
||||
<ulink url="https://systemd.io/INHIBITOR_LOCKS">Inhibitor Locks</ulink>.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
@ -2288,17 +2288,15 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||
<listitem>
|
||||
<para>When system shutdown or sleep state is requested, this option controls checking of inhibitor
|
||||
locks. It takes one of <literal>auto</literal>, <literal>yes</literal> or
|
||||
<literal>no</literal>. Defaults to <literal>auto</literal>, which will behave like
|
||||
<literal>yes</literal> for interactive invocations (i.e. from a TTY) and <literal>no</literal> for
|
||||
non-interactive invocations. <literal>yes</literal> lets the request respect inhibitor locks.
|
||||
<literal>no</literal> lets the request ignore inhibitor locks.</para>
|
||||
<literal>no</literal>. Defaults to <literal>auto</literal>, which means logind will perform the
|
||||
check and respect active inhibitor locks, but systemctl will only do a client-side check for
|
||||
interactive invocations (i.e. from a TTY), so that a more friendly and informative error can be
|
||||
returned to users. <literal>no</literal> disables both the systemctl and logind checks.</para>
|
||||
|
||||
<para>Applications can establish inhibitor locks to prevent certain important operations (such as
|
||||
CD burning) from being interrupted by system shutdown or sleep. Any user may take these locks and
|
||||
privileged users may override these locks. If any locks are taken, shutdown and sleep state
|
||||
requests will normally fail (unless privileged). However, if <literal>no</literal> is specified or
|
||||
<literal>auto</literal> is specified on a non-interactive requests, the operation will be
|
||||
attempted. If locks are present, the operation may require additional privileges.</para>
|
||||
requests will normally fail (unless explicitly overridden with <literal>no</literal>).</para>
|
||||
|
||||
<para>Option <option>--force</option> provides another way to override inhibitors.</para>
|
||||
|
||||
|
@ -92,19 +92,17 @@
|
||||
<varlistentry>
|
||||
<term><option>--mode=</option></term>
|
||||
|
||||
<listitem><para>Takes either <literal>block</literal> or
|
||||
<literal>delay</literal> and describes how the lock is
|
||||
applied. If <literal>block</literal> is used (the default),
|
||||
the lock prohibits any of the requested operations without
|
||||
time limit, and only privileged users may override it. If
|
||||
<literal>delay</literal> is used, the lock can only delay the
|
||||
requested operations for a limited time. If the time elapses,
|
||||
the lock is ignored and the operation executed. The time limit
|
||||
may be specified in
|
||||
<listitem><para>Takes <literal>block</literal>, <literal>delay</literal>,
|
||||
<literal>block-weak</literal> or <literal>delay-weak</literal> and describes how the lock is
|
||||
applied. If <literal>block</literal> is used (the default), the lock prohibits any of the requested
|
||||
operations without time limit, and only privileged users may override it. If
|
||||
<literal>delay</literal> is used, the lock can only delay the requested operations for a limited
|
||||
time. If the time elapses, the lock is ignored and the operation executed. The time limit may be
|
||||
specified in
|
||||
<citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
Note that <literal>delay</literal> is only available for
|
||||
<literal>sleep</literal> and
|
||||
<literal>shutdown</literal>.</para></listitem>
|
||||
Note that <literal>delay</literal> is only available for <literal>sleep</literal> and
|
||||
<literal>shutdown</literal>. In addition, the weak variants will automatically and silently be
|
||||
bypassed under some circumstances.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -33,6 +33,6 @@ _arguments \
|
||||
'--what=[Operations to inhibit]:options:_systemd-inhibit_what' \
|
||||
'--who=[A descriptive string who is inhibiting]:who is inhibiting:' \
|
||||
'--why=[A descriptive string why is being inhibited]:reason for the lock:' \
|
||||
'--mode=[One of block or delay]:lock mode:( block delay )' \
|
||||
'--mode=[One of block, block-weak, delay, or delay-weak]:lock mode:( block block-weak delay delay-weak )' \
|
||||
'--list[List active inhibitors]' \
|
||||
'*:commands:_systemd-inhibit_commands'
|
||||
|
@ -8,11 +8,12 @@
|
||||
#define SD_LOGIND_REBOOT_VIA_KEXEC (UINT64_C(1) << 1)
|
||||
#define SD_LOGIND_SOFT_REBOOT (UINT64_C(1) << 2)
|
||||
#define SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP (UINT64_C(1) << 3)
|
||||
#define SD_LOGIND_SKIP_INHIBITORS (UINT64_C(1) << 4)
|
||||
|
||||
/* For internal use only */
|
||||
#define SD_LOGIND_INTERACTIVE (UINT64_C(1) << 63)
|
||||
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_REBOOT_VIA_KEXEC|SD_LOGIND_SOFT_REBOOT|SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP)
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_REBOOT_VIA_KEXEC|SD_LOGIND_SOFT_REBOOT|SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP|SD_LOGIND_SKIP_INHIBITORS)
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC|SD_LOGIND_INTERACTIVE)
|
||||
|
||||
bool session_id_valid(const char *id);
|
||||
|
@ -157,7 +157,7 @@ static int help(void) {
|
||||
" handle-lid-switch\n"
|
||||
" --who=STRING A descriptive string who is inhibiting\n"
|
||||
" --why=STRING A descriptive string why is being inhibited\n"
|
||||
" --mode=MODE One of block or delay\n"
|
||||
" --mode=MODE One of block, block-weak, delay, or delay-weak\n"
|
||||
" --list List active inhibitors\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
|
@ -234,7 +234,7 @@ static int handle_action_execute(
|
||||
/* If the actual operation is inhibited, warn and fail */
|
||||
if (inhibit_what_is_valid(inhibit_operation) &&
|
||||
!ignore_inhibited &&
|
||||
manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
|
||||
manager_is_inhibited(m, inhibit_operation, /* block= */ true, NULL, false, false, 0, &offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
(void) pidref_get_comm(&offending->pid, &comm);
|
||||
@ -372,7 +372,7 @@ int manager_handle_action(
|
||||
|
||||
/* If the key handling is inhibited, don't do anything */
|
||||
if (inhibit_key > 0) {
|
||||
if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) {
|
||||
if (manager_is_inhibited(m, inhibit_key, /* block= */ true, NULL, true, false, 0, NULL)) {
|
||||
log_debug("Refusing %s operation, %s is inhibited.",
|
||||
handle_action_to_string(handle),
|
||||
inhibit_what_to_string(inhibit_key));
|
||||
|
@ -411,7 +411,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
||||
|
||||
assert(m);
|
||||
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, /* block= */ true, t, false, false, 0, NULL);
|
||||
|
||||
HASHMAP_FOREACH(s, m->sessions) {
|
||||
dual_timestamp k;
|
||||
|
@ -311,7 +311,7 @@ static int property_get_inhibited(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
|
||||
w = manager_inhibit_what(m, /* block= */ streq(property, "BlockInhibited"));
|
||||
|
||||
return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
|
||||
}
|
||||
@ -1881,7 +1881,7 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
|
||||
if (!manager->delayed_action || manager->action_job)
|
||||
return 0;
|
||||
|
||||
if (manager_is_inhibited(manager, manager->delayed_action->inhibit_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
|
||||
if (manager_is_inhibited(manager, manager->delayed_action->inhibit_what, /* block= */ false, NULL, false, false, 0, &offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
if (!timeout)
|
||||
@ -1978,7 +1978,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
|
||||
|
||||
delayed =
|
||||
m->inhibit_delay_max > 0 &&
|
||||
manager_is_inhibited(m, a->inhibit_what, INHIBIT_DELAY, NULL, false, false, 0, NULL);
|
||||
manager_is_inhibited(m, a->inhibit_what, /* block= */ false, NULL, false, false, 0, NULL);
|
||||
|
||||
if (delayed)
|
||||
/* Shutdown is delayed, keep in mind what we
|
||||
@ -2021,7 +2021,7 @@ static int verify_shutdown_creds(
|
||||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, NULL);
|
||||
interactive = flags & SD_LOGIND_INTERACTIVE;
|
||||
|
||||
if (multiple_sessions) {
|
||||
@ -2040,17 +2040,23 @@ static int verify_shutdown_creds(
|
||||
}
|
||||
|
||||
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))
|
||||
if (!FLAGS_SET(flags, SD_LOGIND_SKIP_INHIBITORS))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED,
|
||||
"Access denied to root due to active block inhibitor");
|
||||
"Access denied due to active block inhibitor");
|
||||
|
||||
/* We want to always ask here, even for root, to only allow bypassing if explicitly allowed
|
||||
* by polkit */
|
||||
PolkitFlags polkit_flags = POLKIT_ALWAYS_QUERY;
|
||||
|
||||
if (interactive)
|
||||
polkit_flags |= POLKIT_ALLOW_INTERACTIVE;
|
||||
|
||||
r = bus_verify_polkit_async_full(
|
||||
message,
|
||||
a->polkit_action_ignore_inhibit,
|
||||
/* details= */ NULL,
|
||||
/* good_user= */ UID_INVALID,
|
||||
interactive ? POLKIT_ALLOW_INTERACTIVE : 0,
|
||||
polkit_flags,
|
||||
&m->polkit_registry,
|
||||
error);
|
||||
if (r < 0)
|
||||
@ -2749,7 +2755,7 @@ static int method_can_shutdown_or_sleep(
|
||||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, NULL);
|
||||
|
||||
if (check_unit_state && a->target) {
|
||||
_cleanup_free_ char *load_state = NULL;
|
||||
@ -3587,7 +3593,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
|
||||
"Invalid mode specification %s", mode);
|
||||
|
||||
/* Delay is only supported for shutdown/sleep */
|
||||
if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
|
||||
if (IN_SET(mm, INHIBIT_DELAY, INHIBIT_DELAY_WEAK) && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Delay inhibitors only supported for shutdown and sleep");
|
||||
|
||||
@ -3604,8 +3610,8 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
|
||||
|
||||
r = bus_verify_polkit_async(
|
||||
message,
|
||||
v == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
|
||||
v == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
|
||||
v == INHIBIT_SHUTDOWN ? (IN_SET(mm, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK) ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
|
||||
v == INHIBIT_SLEEP ? (IN_SET(mm, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK) ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
|
||||
v == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
|
||||
v == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
|
||||
v == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
|
||||
|
@ -165,7 +165,7 @@ static int bus_manager_send_inhibited_change(Inhibitor *i) {
|
||||
|
||||
assert(i);
|
||||
|
||||
property = i->mode == INHIBIT_BLOCK ? "BlockInhibited" : "DelayInhibited";
|
||||
property = IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK) ? "BlockInhibited" : "DelayInhibited";
|
||||
|
||||
return manager_send_changed(i->manager, property, NULL);
|
||||
}
|
||||
@ -363,14 +363,16 @@ bool inhibitor_is_orphan(Inhibitor *i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
|
||||
InhibitWhat manager_inhibit_what(Manager *m, bool block) {
|
||||
Inhibitor *i;
|
||||
InhibitWhat what = 0;
|
||||
|
||||
assert(m);
|
||||
|
||||
HASHMAP_FOREACH(i, m->inhibitors)
|
||||
if (i->mode == mm && i->started)
|
||||
if (i->started &&
|
||||
((!block && IN_SET(i->mode, INHIBIT_DELAY, INHIBIT_DELAY_WEAK)) ||
|
||||
(block && IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK))))
|
||||
what |= i->what;
|
||||
|
||||
return what;
|
||||
@ -399,7 +401,7 @@ static int pidref_is_active_session(Manager *m, const PidRef *pid) {
|
||||
bool manager_is_inhibited(
|
||||
Manager *m,
|
||||
InhibitWhat w,
|
||||
InhibitMode mm,
|
||||
bool block,
|
||||
dual_timestamp *since,
|
||||
bool ignore_inactive,
|
||||
bool ignore_uid,
|
||||
@ -421,13 +423,14 @@ bool manager_is_inhibited(
|
||||
if (!(i->what & w))
|
||||
continue;
|
||||
|
||||
if (i->mode != mm)
|
||||
if ((block && !IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK)) ||
|
||||
(!block && !IN_SET(i->mode, INHIBIT_DELAY, INHIBIT_DELAY_WEAK)))
|
||||
continue;
|
||||
|
||||
if (ignore_inactive && pidref_is_active_session(m, &i->pid) <= 0)
|
||||
continue;
|
||||
|
||||
if (ignore_uid && i->uid == uid)
|
||||
if (IN_SET(i->mode, INHIBIT_BLOCK_WEAK, INHIBIT_DELAY_WEAK) && ignore_uid && i->uid == uid)
|
||||
continue;
|
||||
|
||||
if (!inhibited ||
|
||||
@ -525,8 +528,10 @@ int inhibit_what_from_string(const char *s) {
|
||||
}
|
||||
|
||||
static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
|
||||
[INHIBIT_BLOCK] = "block",
|
||||
[INHIBIT_DELAY] = "delay"
|
||||
[INHIBIT_BLOCK] = "block",
|
||||
[INHIBIT_BLOCK_WEAK] = "block-weak",
|
||||
[INHIBIT_DELAY] = "delay",
|
||||
[INHIBIT_DELAY_WEAK] = "delay-weak"
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(inhibit_mode, InhibitMode);
|
||||
|
@ -20,7 +20,9 @@ typedef enum InhibitWhat {
|
||||
|
||||
typedef enum InhibitMode {
|
||||
INHIBIT_BLOCK,
|
||||
INHIBIT_BLOCK_WEAK,
|
||||
INHIBIT_DELAY,
|
||||
INHIBIT_DELAY_WEAK,
|
||||
_INHIBIT_MODE_MAX,
|
||||
_INHIBIT_MODE_INVALID = -EINVAL,
|
||||
} InhibitMode;
|
||||
@ -65,8 +67,8 @@ int inhibitor_create_fifo(Inhibitor *i);
|
||||
|
||||
bool inhibitor_is_orphan(Inhibitor *i);
|
||||
|
||||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
|
||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
|
||||
InhibitWhat manager_inhibit_what(Manager *m, bool block);
|
||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, bool block, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
|
||||
|
||||
static inline bool inhibit_what_is_valid(InhibitWhat w) {
|
||||
return w > 0 && w < _INHIBIT_WHAT_MAX;
|
||||
|
@ -82,6 +82,7 @@ int logind_reboot(enum action a) {
|
||||
return 0;
|
||||
|
||||
SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0);
|
||||
SET_FLAG(flags, SD_LOGIND_SKIP_INHIBITORS, arg_check_inhibitors == 0);
|
||||
SET_FLAG(flags,
|
||||
SD_LOGIND_REBOOT_VIA_KEXEC,
|
||||
a == ACTION_KEXEC || (a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_KEXEC") <= 0));
|
||||
@ -94,17 +95,17 @@ int logind_reboot(enum action a) {
|
||||
SET_FLAG(flags, SD_LOGIND_SOFT_REBOOT, a == ACTION_SOFT_REBOOT);
|
||||
|
||||
r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
|
||||
if (r < 0 && FLAGS_SET(flags, SD_LOGIND_SKIP_INHIBITORS) &&
|
||||
sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS)) {
|
||||
sd_bus_error_free(&error);
|
||||
flags &= ~SD_LOGIND_SKIP_INHIBITORS;
|
||||
r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
|
||||
}
|
||||
if (r < 0 && FLAGS_SET(flags, SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP) &&
|
||||
sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS)) {
|
||||
sd_bus_error_free(&error);
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
bus_login_mgr,
|
||||
method_with_flags,
|
||||
&error,
|
||||
NULL,
|
||||
"t",
|
||||
flags & ~SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP);
|
||||
flags &= ~SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP;
|
||||
r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
|
||||
}
|
||||
if (r >= 0)
|
||||
return 0;
|
||||
@ -144,13 +145,8 @@ int logind_check_inhibitors(enum action a) {
|
||||
if (arg_when > 0)
|
||||
return 0;
|
||||
|
||||
if (arg_check_inhibitors < 0) {
|
||||
if (geteuid() == 0)
|
||||
return 0;
|
||||
|
||||
if (!on_tty())
|
||||
return 0;
|
||||
}
|
||||
if (arg_check_inhibitors < 0 && !on_tty())
|
||||
return 0;
|
||||
|
||||
if (arg_transport != BUS_TRANSPORT_LOCAL)
|
||||
return 0;
|
||||
@ -172,7 +168,10 @@ int logind_check_inhibitors(enum action a) {
|
||||
_cleanup_free_ char *comm = NULL, *user = NULL;
|
||||
_cleanup_strv_free_ char **sv = NULL;
|
||||
|
||||
if (!streq(mode, "block"))
|
||||
if (!STR_IN_SET(mode, "block", "block-weak"))
|
||||
continue;
|
||||
|
||||
if (streq(mode, "block-weak") && (geteuid() == 0 || geteuid() == uid || !on_tty()))
|
||||
continue;
|
||||
|
||||
sv = strv_split(what, ":");
|
||||
@ -233,6 +232,7 @@ int logind_check_inhibitors(enum action a) {
|
||||
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Please retry operation after closing inhibitors and logging out other users.\n"
|
||||
"'systemd-inhibit' can be used to list active inhibitors.\n"
|
||||
"Alternatively, ignore inhibitors and users with 'systemctl %s -i'.",
|
||||
action_table[a].verb);
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user