mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
Merge pull request #33575 from YHNdnzj/soft-reboot-system-manager-only
core/dbus-manager: several cleanups, refuse SoftReboot() for user manager
This commit is contained in:
commit
0f20f7d6fe
src/core
@ -1553,26 +1553,27 @@ static int verify_run_space_permissive(const char *message, sd_bus_error *error)
|
|||||||
|
|
||||||
static void log_caller(sd_bus_message *message, Manager *manager, const char *method) {
|
static void log_caller(sd_bus_message *message, Manager *manager, const char *method) {
|
||||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||||
const char *comm = NULL;
|
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||||
Unit *caller;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
assert(manager);
|
assert(manager);
|
||||||
assert(method);
|
assert(method);
|
||||||
|
|
||||||
if (sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_COMM, &creds) < 0)
|
if (sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_COMM, &creds) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We need at least the PID, otherwise there's nothing to log, the rest is optional */
|
/* We need at least the PID, otherwise there's nothing to log, the rest is optional. */
|
||||||
if (sd_bus_creds_get_pid(creds, &pid) < 0)
|
if (bus_creds_get_pidref(creds, &pidref) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const char *comm = NULL;
|
||||||
|
Unit *caller;
|
||||||
|
|
||||||
(void) sd_bus_creds_get_comm(creds, &comm);
|
(void) sd_bus_creds_get_comm(creds, &comm);
|
||||||
caller = manager_get_unit_by_pid(manager, pid);
|
caller = manager_get_unit_by_pidref(manager, &pidref);
|
||||||
|
|
||||||
log_info("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...",
|
log_info("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...",
|
||||||
method, pid,
|
method, pidref.pid,
|
||||||
comm ? " ('" : "", strempty(comm), comm ? "')" : "",
|
comm ? " ('" : "", strempty(comm), comm ? "')" : "",
|
||||||
caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : "");
|
caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : "");
|
||||||
}
|
}
|
||||||
@ -1687,27 +1688,31 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *
|
|||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"Reboot is only supported by system manager.");
|
||||||
|
|
||||||
r = mac_selinux_access_check(message, "reboot", error);
|
r = mac_selinux_access_check(message, "reboot", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!MANAGER_IS_SYSTEM(m))
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
|
||||||
"Reboot is only supported for system managers.");
|
|
||||||
|
|
||||||
m->objective = MANAGER_REBOOT;
|
m->objective = MANAGER_REBOOT;
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
_cleanup_free_ char *rt = NULL;
|
|
||||||
Manager *m = ASSERT_PTR(userdata);
|
Manager *m = ASSERT_PTR(userdata);
|
||||||
|
_cleanup_free_ char *rt = NULL;
|
||||||
const char *root;
|
const char *root;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"Soft reboot is only supported by system manager.");
|
||||||
|
|
||||||
r = verify_run_space_permissive("soft reboot may fail", error);
|
r = verify_run_space_permissive("soft reboot may fail", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1728,9 +1733,9 @@ static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
"New root directory path '%s' is not absolute.", root);
|
"New root directory path '%s' is not absolute.", root);
|
||||||
|
|
||||||
rt = strdup(root);
|
r = path_simplify_alloc(root, &rt);
|
||||||
if (!rt)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_and_replace(m->switch_root, rt);
|
free_and_replace(m->switch_root, rt);
|
||||||
@ -1745,14 +1750,14 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error
|
|||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"Powering off is only supported by system manager.");
|
||||||
|
|
||||||
r = mac_selinux_access_check(message, "halt", error);
|
r = mac_selinux_access_check(message, "halt", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!MANAGER_IS_SYSTEM(m))
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
|
||||||
"Powering off is only supported for system managers.");
|
|
||||||
|
|
||||||
m->objective = MANAGER_POWEROFF;
|
m->objective = MANAGER_POWEROFF;
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
@ -1764,14 +1769,14 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er
|
|||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"Halt is only supported by system manager.");
|
||||||
|
|
||||||
r = mac_selinux_access_check(message, "halt", error);
|
r = mac_selinux_access_check(message, "halt", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!MANAGER_IS_SYSTEM(m))
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
|
||||||
"Halt is only supported for system managers.");
|
|
||||||
|
|
||||||
m->objective = MANAGER_HALT;
|
m->objective = MANAGER_HALT;
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
@ -1783,27 +1788,31 @@ static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *e
|
|||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"KExec is only supported by system manager.");
|
||||||
|
|
||||||
r = mac_selinux_access_check(message, "reboot", error);
|
r = mac_selinux_access_check(message, "reboot", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!MANAGER_IS_SYSTEM(m))
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
|
||||||
"KExec is only supported for system managers.");
|
|
||||||
|
|
||||||
m->objective = MANAGER_KEXEC;
|
m->objective = MANAGER_KEXEC;
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
_cleanup_free_ char *ri = NULL, *rt = NULL;
|
|
||||||
Manager *m = ASSERT_PTR(userdata);
|
Manager *m = ASSERT_PTR(userdata);
|
||||||
|
_cleanup_free_ char *ri = NULL, *rt = NULL;
|
||||||
const char *root, *init;
|
const char *root, *init;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
|
||||||
|
if (!MANAGER_IS_SYSTEM(m))
|
||||||
|
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
||||||
|
"Root switching is only supported by system manager.");
|
||||||
|
|
||||||
r = verify_run_space_permissive("root switching may fail", error);
|
r = verify_run_space_permissive("root switching may fail", error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1812,10 +1821,6 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!MANAGER_IS_SYSTEM(m))
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
|
|
||||||
"Root switching is only supported by system manager.");
|
|
||||||
|
|
||||||
r = sd_bus_message_read(message, "ss", &root, &init);
|
r = sd_bus_message_read(message, "ss", &root, &init);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1826,8 +1831,8 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
root = "/sysroot";
|
root = "/sysroot";
|
||||||
else {
|
else {
|
||||||
if (!path_is_valid(root))
|
if (!path_is_valid(root))
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
"New root directory must be a valid path.");
|
"New root directory must be a valid path.");
|
||||||
|
|
||||||
if (!path_is_absolute(root))
|
if (!path_is_absolute(root))
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
@ -1839,14 +1844,14 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
"Failed to check if new root directory '%s' is the same as old root: %m",
|
"Failed to check if new root directory '%s' is the same as old root: %m",
|
||||||
root);
|
root);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
"New root directory cannot be the old root directory.");
|
"New root directory cannot be the old root directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Safety check */
|
/* Safety check */
|
||||||
if (!in_initrd())
|
if (!in_initrd())
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
"Not in initrd, refusing switch-root operation.");
|
"Not in initrd, refusing switch-root operation.");
|
||||||
|
|
||||||
r = path_is_os_tree(root);
|
r = path_is_os_tree(root);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1876,14 +1881,14 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
"Could not resolve init executable %s: %m", init);
|
"Could not resolve init executable %s: %m", init);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt = strdup(root);
|
r = path_simplify_alloc(root, &rt);
|
||||||
if (!rt)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
|
|
||||||
if (!isempty(init)) {
|
if (!isempty(init)) {
|
||||||
ri = strdup(init);
|
r = path_simplify_alloc(init, &ri);
|
||||||
if (!ri)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_and_replace(m->switch_root, rt);
|
free_and_replace(m->switch_root, rt);
|
||||||
|
@ -3285,14 +3285,15 @@ int main(int argc, char *argv[]) {
|
|||||||
&switch_root_dir,
|
&switch_root_dir,
|
||||||
&switch_root_init,
|
&switch_root_init,
|
||||||
&error_message);
|
&error_message);
|
||||||
assert(r < 0 || IN_SET(r, MANAGER_EXIT, /* MANAGER_OK and MANAGER_RELOAD are not expected here. */
|
/* MANAGER_OK and MANAGER_RELOAD are not expected here. */
|
||||||
MANAGER_REEXECUTE,
|
assert(r < 0 || IN_SET(r, MANAGER_REEXECUTE, MANAGER_EXIT) ||
|
||||||
MANAGER_REBOOT,
|
(arg_runtime_scope == RUNTIME_SCOPE_SYSTEM &&
|
||||||
MANAGER_SOFT_REBOOT,
|
IN_SET(r, MANAGER_REBOOT,
|
||||||
MANAGER_POWEROFF,
|
MANAGER_SOFT_REBOOT,
|
||||||
MANAGER_HALT,
|
MANAGER_POWEROFF,
|
||||||
MANAGER_KEXEC,
|
MANAGER_HALT,
|
||||||
MANAGER_SWITCH_ROOT));
|
MANAGER_KEXEC,
|
||||||
|
MANAGER_SWITCH_ROOT)));
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
pager_close();
|
pager_close();
|
||||||
|
@ -3087,41 +3087,43 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
|||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
|
||||||
/* Starting SIGRTMIN+0 */
|
if (MANAGER_IS_SYSTEM(m)) {
|
||||||
static const struct {
|
/* Starting SIGRTMIN+0 */
|
||||||
const char *target;
|
static const struct {
|
||||||
JobMode mode;
|
const char *target;
|
||||||
} target_table[] = {
|
JobMode mode;
|
||||||
[0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
|
} target_table[] = {
|
||||||
[1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
|
[0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
|
||||||
[2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
|
[1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
|
||||||
[3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
[2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
|
||||||
[4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
[3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
[5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
[4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
[6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
[5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
[7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
[6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
};
|
[7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
|
};
|
||||||
|
|
||||||
/* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
|
/* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
|
||||||
static const ManagerObjective objective_table[] = {
|
static const ManagerObjective objective_table[] = {
|
||||||
[0] = MANAGER_HALT,
|
[0] = MANAGER_HALT,
|
||||||
[1] = MANAGER_POWEROFF,
|
[1] = MANAGER_POWEROFF,
|
||||||
[2] = MANAGER_REBOOT,
|
[2] = MANAGER_REBOOT,
|
||||||
[3] = MANAGER_KEXEC,
|
[3] = MANAGER_KEXEC,
|
||||||
[4] = MANAGER_SOFT_REBOOT,
|
[4] = MANAGER_SOFT_REBOOT,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
||||||
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
||||||
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
||||||
manager_start_special(m, target_table[idx].target, target_table[idx].mode);
|
manager_start_special(m, target_table[idx].target, target_table[idx].mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
|
if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
|
||||||
(int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
|
(int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
|
||||||
m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
|
m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sfsi.ssi_signo - SIGRTMIN) {
|
switch (sfsi.ssi_signo - SIGRTMIN) {
|
||||||
|
Loading…
Reference in New Issue
Block a user