mirror of
https://github.com/systemd/systemd
synced 2024-10-15 04:24:19 +00:00
logind/systemctl: introduce SetWallMessage and --message
Enable unprivileged users to set wall message on a shutdown operation. When the message is set via the --message option, it is logged together with the default shutdown message. $ systemctl reboot --message "Applied kernel updates." $ journalctl -b -1 ... systemd-logind[27]: System is rebooting. (Applied kernel updates.) ...
This commit is contained in:
parent
72aa2c2a20
commit
9ef15026c0
|
@ -473,6 +473,18 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--message=</option></term>
|
||||
|
||||
<listitem>
|
||||
<para>When used with <command>halt</command>,
|
||||
<command>poweroff</command>, <command>reboot</command> or
|
||||
<command>kexec</command>, set a short message explaining the reason
|
||||
for the operation. The message will be logged together with the
|
||||
default shutdown message.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--now</option></term>
|
||||
|
||||
|
|
|
@ -1339,7 +1339,8 @@ static int bus_manager_log_shutdown(
|
|||
InhibitWhat w,
|
||||
const char *unit_name) {
|
||||
|
||||
const char *p, *q;
|
||||
const char *p;
|
||||
const char *q;
|
||||
|
||||
assert(m);
|
||||
assert(unit_name);
|
||||
|
@ -1364,6 +1365,9 @@ static int bus_manager_log_shutdown(
|
|||
q = NULL;
|
||||
}
|
||||
|
||||
if (m->wall_message)
|
||||
p = strjoina(p, " (", m->wall_message, ")", NULL);
|
||||
|
||||
return log_struct(LOG_NOTICE,
|
||||
LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
|
||||
p,
|
||||
|
@ -2282,6 +2286,44 @@ static int method_can_reboot_to_firmware_setup(
|
|||
return sd_bus_reply_method_return(message, "s", result);
|
||||
}
|
||||
|
||||
static int method_set_wall_message(
|
||||
sd_bus_message *message,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int r;
|
||||
Manager *m = userdata;
|
||||
char *wall_message;
|
||||
bool enable_wall_messages;
|
||||
|
||||
assert(message);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_verify_polkit_async(message,
|
||||
CAP_SYS_ADMIN,
|
||||
"org.freedesktop.login1.set-wall-message",
|
||||
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();
|
||||
m->enable_wall_messages = enable_wall_messages;
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
const char *who, *why, *what, *mode;
|
||||
|
@ -2463,6 +2505,7 @@ const sd_bus_vtable manager_vtable[] = {
|
|||
SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_SIGNAL("SessionNew", "so", 0),
|
||||
SD_BUS_SIGNAL("SessionRemoved", "so", 0),
|
||||
|
|
|
@ -180,6 +180,10 @@
|
|||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="SetRebootToFirmwareSetup"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="SetWallMessage"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="AttachDevice"/>
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.set-wall-message</annotate>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.login1.power-off-multiple-sessions">
|
||||
|
@ -182,6 +183,7 @@
|
|||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.set-wall-message</annotate>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.login1.reboot-multiple-sessions">
|
||||
|
@ -300,4 +302,14 @@
|
|||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.login1.set-wall-message">
|
||||
<_description>Set a wall message</_description>
|
||||
<_message>Authentication is required to set a wall message</_message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
||||
|
|
|
@ -2794,6 +2794,33 @@ static int reboot_with_logind(sd_bus *bus, enum action a) {
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!strv_isempty(arg_wall)) {
|
||||
_cleanup_free_ char *m;
|
||||
|
||||
m = strv_join(arg_wall, " ");
|
||||
if (!m)
|
||||
return log_oom();
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"SetWallMessage",
|
||||
&error,
|
||||
NULL,
|
||||
"sb",
|
||||
m,
|
||||
!arg_no_wall);
|
||||
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set wall message, ignoring: %s",
|
||||
bus_error_message(&error, r));
|
||||
sd_bus_error_free(&error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.login1",
|
||||
|
@ -6260,6 +6287,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
ARG_PRESET_MODE,
|
||||
ARG_FIRMWARE_SETUP,
|
||||
ARG_NOW,
|
||||
ARG_MESSAGE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
|
@ -6304,6 +6332,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
{ "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
|
||||
{ "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
|
||||
{ "now", no_argument, NULL, ARG_NOW },
|
||||
{ "message", required_argument, NULL, ARG_MESSAGE },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -6588,6 +6617,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
arg_now = true;
|
||||
break;
|
||||
|
||||
case ARG_MESSAGE:
|
||||
if (strv_extend(&arg_wall, optarg) < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -7356,30 +7390,20 @@ static int halt_main(sd_bus *bus) {
|
|||
if (!m)
|
||||
return log_oom();
|
||||
|
||||
r = sd_bus_set_property(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"WallMessage",
|
||||
&error,
|
||||
"s", m);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set WallMessage property in logind: %s",
|
||||
bus_error_message(&error, r));
|
||||
sd_bus_error_free(&error);
|
||||
}
|
||||
r = sd_bus_call_method(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"SetWallMessage",
|
||||
&error,
|
||||
NULL,
|
||||
"sb",
|
||||
m,
|
||||
!arg_no_wall);
|
||||
|
||||
r = sd_bus_set_property(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"EnableWallMessages",
|
||||
&error,
|
||||
"b", !arg_no_wall);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set EnableWallMessages property in logind: %s",
|
||||
log_warning_errno(r, "Failed to set wall message, ignoring: %s",
|
||||
bus_error_message(&error, r));
|
||||
sd_bus_error_free(&error);
|
||||
}
|
||||
|
@ -7537,30 +7561,20 @@ int main(int argc, char*argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
r = sd_bus_set_property(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"WallMessage",
|
||||
&error,
|
||||
"s", arg_wall);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set WallMessage property in logind: %s",
|
||||
bus_error_message(&error, r));
|
||||
sd_bus_error_free(&error);
|
||||
}
|
||||
r = sd_bus_call_method(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"SetWallMessage",
|
||||
&error,
|
||||
NULL,
|
||||
"sb",
|
||||
m,
|
||||
!arg_no_wall);
|
||||
|
||||
r = sd_bus_set_property(
|
||||
b,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"EnableWallMessages",
|
||||
&error,
|
||||
"b", !arg_no_wall);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set EnableWallMessages property in logind: %s",
|
||||
log_warning_errno(r, "Failed to set wall message, ignoring: %s",
|
||||
bus_error_message(&error, r));
|
||||
sd_bus_error_free(&error);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue