summaryrefslogtreecommitdiff
path: root/src/login/logind-dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/logind-dbus.c')
-rw-r--r--src/login/logind-dbus.c148
1 files changed, 89 insertions, 59 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 5b2b36b9c0..aeedf68e77 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -942,6 +942,7 @@ static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.lock-sessions",
+ NULL,
false,
UID_INVALID,
&m->polkit_registry,
@@ -1096,6 +1097,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-user-linger",
+ NULL,
interactive,
UID_INVALID,
&m->polkit_registry,
@@ -1268,6 +1270,7 @@ static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.attach-device",
+ NULL,
interactive,
UID_INVALID,
&m->polkit_registry,
@@ -1299,6 +1302,7 @@ static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.flush-devices",
+ NULL,
interactive,
UID_INVALID,
&m->polkit_registry,
@@ -1339,8 +1343,7 @@ static int bus_manager_log_shutdown(
InhibitWhat w,
const char *unit_name) {
- const char *p;
- const char *q;
+ const char *p, *q;
assert(m);
assert(unit_name);
@@ -1349,24 +1352,26 @@ static int bus_manager_log_shutdown(
return 0;
if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
- p = "MESSAGE=System is powering down.";
+ p = "MESSAGE=System is powering down";
q = "SHUTDOWN=power-off";
} else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
- p = "MESSAGE=System is halting.";
+ p = "MESSAGE=System is halting";
q = "SHUTDOWN=halt";
} else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
- p = "MESSAGE=System is rebooting.";
+ p = "MESSAGE=System is rebooting";
q = "SHUTDOWN=reboot";
} else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
- p = "MESSAGE=System is rebooting with kexec.";
+ p = "MESSAGE=System is rebooting with kexec";
q = "SHUTDOWN=kexec";
} else {
- p = "MESSAGE=System is shutting down.";
+ p = "MESSAGE=System is shutting down";
q = NULL;
}
- if (m->wall_message)
- p = strjoina(p, " (", m->wall_message, ")", NULL);
+ if (isempty(m->wall_message))
+ p = strjoina(p, ".");
+ else
+ p = strjoina(p, " (", m->wall_message, ").");
return log_struct(LOG_NOTICE,
LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
@@ -1420,6 +1425,20 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
return r;
}
+static void reset_scheduled_shutdown(Manager *m) {
+ m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
+ m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
+ m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
+ m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
+ m->scheduled_shutdown_timeout = 0;
+ m->shutdown_dry_run = false;
+
+ if (m->unlink_nologin) {
+ (void) unlink("/run/nologin");
+ m->unlink_nologin = false;
+ }
+}
+
static int execute_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
@@ -1427,8 +1446,8 @@ static int execute_shutdown_or_sleep(
sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ char *c = NULL;
const char *p;
- char *c;
int r;
assert(m);
@@ -1438,25 +1457,30 @@ static int execute_shutdown_or_sleep(
bus_manager_log_shutdown(m, w, unit_name);
- r = sd_bus_call_method(
- m->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartUnit",
- error,
- &reply,
- "ss", unit_name, "replace-irreversibly");
- if (r < 0)
- return r;
+ if (m->shutdown_dry_run) {
+ log_info("Running in dry run, suppressing action.");
+ reset_scheduled_shutdown(m);
+ } else {
+ r = sd_bus_call_method(
+ m->bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartUnit",
+ error,
+ &reply,
+ "ss", unit_name, "replace-irreversibly");
+ if (r < 0)
+ return r;
- r = sd_bus_message_read(reply, "o", &p);
- if (r < 0)
- return r;
+ r = sd_bus_message_read(reply, "o", &p);
+ if (r < 0)
+ return r;
- c = strdup(p);
- if (!c)
- return -ENOMEM;
+ c = strdup(p);
+ if (!c)
+ return -ENOMEM;
+ }
m->action_unit = unit_name;
free(m->action_job);
@@ -1650,7 +1674,7 @@ static int verify_shutdown_creds(
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions && action_multiple_sessions) {
- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
+ r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
@@ -1658,7 +1682,7 @@ static int verify_shutdown_creds(
}
if (blocked && action_ignore_inhibit) {
- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
+ 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)
@@ -1666,7 +1690,7 @@ static int verify_shutdown_creds(
}
if (!multiple_sessions && !blocked && action) {
- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
+ r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
if (r < 0)
return r;
if (r == 0)
@@ -1786,10 +1810,9 @@ static int nologin_timeout_handler(
}
static int update_schedule_file(Manager *m) {
-
- int r;
+ _cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *t = NULL, *temp_path = NULL;
+ int r;
assert(m);
@@ -1797,10 +1820,6 @@ static int update_schedule_file(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
- t = cescape(m->wall_message);
- if (!t)
- return log_oom();
-
r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
if (r < 0)
return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
@@ -1815,8 +1834,17 @@ static int update_schedule_file(Manager *m) {
m->enable_wall_messages,
m->scheduled_shutdown_type);
- if (!isempty(m->wall_message))
+ if (!isempty(m->wall_message)) {
+ _cleanup_free_ char *t;
+
+ t = cescape(m->wall_message);
+ if (!t) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
fprintf(f, "WALL_MESSAGE=%s\n", t);
+ }
r = fflush_and_check(f);
if (r < 0)
@@ -1882,6 +1910,11 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
if (r < 0)
return r;
+ if (startswith(type, "dry-")) {
+ type += 4;
+ m->shutdown_dry_run = true;
+ }
+
if (streq(type, "reboot")) {
action = "org.freedesktop.login1.reboot";
action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
@@ -1976,18 +2009,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
assert(message);
cancelled = m->scheduled_shutdown_type != NULL;
-
- m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
- m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
- m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
- free(m->scheduled_shutdown_type);
- m->scheduled_shutdown_type = NULL;
- m->scheduled_shutdown_timeout = 0;
-
- if (m->unlink_nologin) {
- (void) unlink("/run/nologin");
- m->unlink_nologin = false;
- }
+ reset_scheduled_shutdown(m);
if (cancelled) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
@@ -2084,7 +2106,7 @@ static int method_can_shutdown_or_sleep(
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions) {
- r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
+ r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
if (r < 0)
return r;
@@ -2097,7 +2119,7 @@ static int method_can_shutdown_or_sleep(
}
if (blocked) {
- r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
+ r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
if (r < 0)
return r;
@@ -2113,7 +2135,7 @@ static int method_can_shutdown_or_sleep(
/* If neither inhibit nor multiple sessions
* apply then just check the normal policy */
- r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
+ r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
if (r < 0)
return r;
@@ -2232,6 +2254,7 @@ static int method_set_reboot_to_firmware_setup(
r = bus_verify_polkit_async(message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-reboot-to-firmware-setup",
+ NULL,
false,
UID_INVALID,
&m->polkit_registry,
@@ -2270,6 +2293,7 @@ static int method_can_reboot_to_firmware_setup(
r = bus_test_polkit(message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-reboot-to-firmware-setup",
+ NULL,
UID_INVALID,
&challenge,
error);
@@ -2294,7 +2318,7 @@ static int method_set_wall_message(
int r;
Manager *m = userdata;
char *wall_message;
- bool enable_wall_messages;
+ int enable_wall_messages;
assert(message);
assert(m);
@@ -2306,19 +2330,24 @@ static int method_set_wall_message(
r = bus_verify_polkit_async(message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.set-wall-message",
+ NULL,
false,
UID_INVALID,
&m->polkit_registry,
error);
-
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
- r = free_and_strdup(&m->wall_message, wall_message);
- if (r < 0)
- return log_oom();
+ if (isempty(wall_message))
+ m->wall_message = mfree(m->wall_message);
+ else {
+ r = free_and_strdup(&m->wall_message, wall_message);
+ if (r < 0)
+ return log_oom();
+ }
+
m->enable_wall_messages = enable_wall_messages;
return sd_bus_reply_method_return(message, NULL);
@@ -2373,6 +2402,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
"org.freedesktop.login1.inhibit-handle-lid-switch",
+ NULL,
false,
UID_INVALID,
&m->polkit_registry,
@@ -2558,7 +2588,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
}
if (m->action_job && streq(m->action_job, path)) {
- log_info("Operation finished.");
+ log_info("Operation '%s' finished.", inhibit_what_to_string(m->action_what));
/* Tell people that they now may take a lock again */
send_prepare_for(m, m->action_what, false);