mirror of
https://github.com/systemd/systemd.git
synced 2026-08-09 17:38:42 +00:00
Some bug fixes for logind inhibitors (#40400)
See individual commits Related: - https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4040 - https://gitlab.gnome.org/GNOME/gnome-session/-/merge_requests/170 - https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/3309
This commit is contained in:
8
NEWS
8
NEWS
@@ -64,6 +64,14 @@ CHANGES WITH 260 in spe:
|
||||
directory or not, we make use of it unconditionally and have dropped
|
||||
support for the old way using protofiles.
|
||||
|
||||
* The org.systemd.login1.Manager D-Bus interface has a minor API break.
|
||||
The `CanPowerOff()`, `CanReboot()`, `CanSuspend()`, etc. family of
|
||||
methods have introduced new return values which may break downstream
|
||||
consumers, such as desktop environments. The new return values more
|
||||
precisely communicate the status of inhibitors. This allows desktops
|
||||
to differentiate between system administrator policy and
|
||||
temporary restrictions imposed by inhibitors.
|
||||
|
||||
New system interfaces and components:
|
||||
|
||||
* The os-release(3) gained a new field FANCY_NAME= that is similar
|
||||
|
||||
@@ -276,7 +276,6 @@ node /org/freedesktop/login1 {
|
||||
readonly t RuntimeDirectoryInodesMax = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t InhibitorsMax = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t NCurrentInhibitors = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t SessionsMax = ...;
|
||||
@@ -711,12 +710,19 @@ node /org/freedesktop/login1 {
|
||||
<function>CanRebootParameter()</function>, <function>CanRebootToFirmwareSetup()</function>,
|
||||
<function>CanRebootToBootLoaderMenu()</function>, and <function>CanRebootToBootLoaderEntry()</function>
|
||||
test whether the system supports the respective operation and whether the calling user is allowed to
|
||||
execute it. Returns one of <literal>na</literal>, <literal>yes</literal>, <literal>no</literal>, and
|
||||
<literal>challenge</literal>. If <literal>na</literal> is returned, the operation is not available because
|
||||
hardware, kernel, or drivers do not support it. If <literal>yes</literal> is returned, the operation is
|
||||
supported and the user may execute the operation without further authentication. If <literal>no</literal>
|
||||
is returned, the operation is available but the user is not allowed to execute the operation. If
|
||||
<literal>challenge</literal> is returned, the operation is available but only after authorization.</para>
|
||||
execute it. Returns one of <literal>na</literal>, <literal>yes</literal>, <literal>no</literal>,
|
||||
<literal>challenge</literal>, and <literal>inhibited</literal>. If <literal>na</literal> is returned,
|
||||
the operation is not available because hardware, kernel, or drivers do not support it. If <literal>yes</literal>
|
||||
is returned, the operation is supported and the user may execute the operation without further authentication.
|
||||
If <literal>no</literal> is returned, the operation is available but the user is not allowed to execute
|
||||
the operation. If <literal>challenge</literal> is returned, the operation is available but only after
|
||||
authorization. If <literal>inhibited</literal> is returned, the operation is normally available without
|
||||
authorization but is currently inhibited. The operation is available only if inhibitors are ignored and
|
||||
after authorization. If <literal>inhibitor-blocked</literal> is returned, the operation is normally
|
||||
available without authorization but is currently inhibited. While the inhibitor remains active, the user
|
||||
is not allowed to execute the operation. <literal>challenge-inhibitor-blocked</literal> is similar:
|
||||
the operation is normally available after authorization but a held inhibitor disallows the user from
|
||||
executing the operation.</para>
|
||||
|
||||
<para><function>ScheduleShutdown()</function> schedules a shutdown operation <varname>type</varname> at
|
||||
time <varname>usec</varname> in microseconds since the UNIX epoch. Alternatively, if
|
||||
|
||||
@@ -2927,7 +2927,6 @@ static int method_can_shutdown_or_sleep(
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
bool multiple_sessions, challenge, blocked, check_unit_state = true;
|
||||
const HandleActionData *a;
|
||||
const char *result = NULL;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
@@ -2984,12 +2983,27 @@ static int method_can_shutdown_or_sleep(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!streq(load_state, "loaded")) {
|
||||
result = "no";
|
||||
goto finish;
|
||||
}
|
||||
if (!streq(load_state, "loaded"))
|
||||
return sd_bus_reply_method_return(message, "s", "no");
|
||||
}
|
||||
|
||||
const char *result;
|
||||
r = bus_test_polkit(
|
||||
message,
|
||||
a->polkit_action,
|
||||
/* details= */ NULL,
|
||||
/* good_user= */ UID_INVALID,
|
||||
&challenge,
|
||||
error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
result = "yes";
|
||||
else if (challenge)
|
||||
result = "challenge";
|
||||
else
|
||||
result = "no";
|
||||
|
||||
if (multiple_sessions) {
|
||||
r = bus_test_polkit(
|
||||
message,
|
||||
@@ -3001,12 +3015,13 @@ static int method_can_shutdown_or_sleep(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r > 0)
|
||||
result = "yes";
|
||||
else if (challenge)
|
||||
result = "challenge";
|
||||
else
|
||||
result = "no";
|
||||
if (r == 0) {
|
||||
if (challenge) {
|
||||
if (streq(result, "yes")) /* Avoid upgrading no -> challenge */
|
||||
result = "challenge";
|
||||
} else
|
||||
result = "no";
|
||||
}
|
||||
}
|
||||
|
||||
if (blocked) {
|
||||
@@ -3020,39 +3035,21 @@ static int method_can_shutdown_or_sleep(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r > 0) {
|
||||
if (!result)
|
||||
result = "yes";
|
||||
} else if (challenge) {
|
||||
if (!result || streq(result, "yes"))
|
||||
result = "challenge";
|
||||
} else
|
||||
result = "no";
|
||||
if (r == 0) {
|
||||
if (challenge) {
|
||||
if (streq(result, "yes"))
|
||||
result = "inhibited";
|
||||
/* If result is already "challenge" or "no", the held inhibitor has no effect */
|
||||
} else {
|
||||
if (streq(result, "yes"))
|
||||
result = "inhibitor-blocked";
|
||||
else if (streq(result, "challenge"))
|
||||
result = "challenge-inhibitor-blocked";
|
||||
/* If the result is already "no", the held inhibitor has no effect */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!multiple_sessions && !blocked) {
|
||||
/* If neither inhibit nor multiple sessions
|
||||
* apply then just check the normal policy */
|
||||
|
||||
r = bus_test_polkit(
|
||||
message,
|
||||
a->polkit_action,
|
||||
/* details= */ NULL,
|
||||
/* good_user= */ UID_INVALID,
|
||||
&challenge,
|
||||
error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r > 0)
|
||||
result = "yes";
|
||||
else if (challenge)
|
||||
result = "challenge";
|
||||
else
|
||||
result = "no";
|
||||
}
|
||||
|
||||
finish:
|
||||
return sd_bus_reply_method_return(message, "s", result);
|
||||
}
|
||||
|
||||
@@ -3963,7 +3960,7 @@ static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RuntimeDirectoryInodesMax", "t", NULL, offsetof(Manager, runtime_dir_inodes), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), 0),
|
||||
SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0),
|
||||
SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
|
||||
@@ -148,13 +148,11 @@ static int inhibitor_save(Inhibitor *i) {
|
||||
}
|
||||
|
||||
static int bus_manager_send_inhibited_change(Inhibitor *i) {
|
||||
const char *property;
|
||||
|
||||
assert(i);
|
||||
|
||||
property = IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK) ? "BlockInhibited" : "DelayInhibited";
|
||||
|
||||
return manager_send_changed(i->manager, property);
|
||||
return manager_send_changed(i->manager,
|
||||
i->mode == INHIBIT_DELAY ? "DelayInhibited" : "BlockInhibited",
|
||||
"NCurrentInhibitors");
|
||||
}
|
||||
|
||||
int inhibitor_start(Inhibitor *i) {
|
||||
|
||||
Reference in New Issue
Block a user