mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +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
@ -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) {
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
const char *comm = NULL;
|
||||
Unit *caller;
|
||||
pid_t pid;
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
|
||||
assert(message);
|
||||
assert(manager);
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
/* We need at least the PID, otherwise there's nothing to log, the rest is optional. */
|
||||
if (bus_creds_get_pidref(creds, &pidref) < 0)
|
||||
return;
|
||||
|
||||
const char *comm = NULL;
|
||||
Unit *caller;
|
||||
|
||||
(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...",
|
||||
method, pid,
|
||||
method, pidref.pid,
|
||||
comm ? " ('" : "", strempty(comm), comm ? "')" : "",
|
||||
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);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
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;
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
_cleanup_free_ char *rt = NULL;
|
||||
const char *root;
|
||||
int r;
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
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,
|
||||
"New root directory path '%s' is not absolute.", root);
|
||||
|
||||
rt = strdup(root);
|
||||
if (!rt)
|
||||
return -ENOMEM;
|
||||
r = path_simplify_alloc(root, &rt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
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;
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
_cleanup_free_ char *ri = NULL, *rt = NULL;
|
||||
const char *root, *init;
|
||||
int r;
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1812,10 +1821,6 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
||||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1826,8 +1831,8 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
||||
root = "/sysroot";
|
||||
else {
|
||||
if (!path_is_valid(root))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory must be a valid path.");
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory must be a valid path.");
|
||||
|
||||
if (!path_is_absolute(root))
|
||||
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",
|
||||
root);
|
||||
if (r > 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory cannot be the old root directory.");
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory cannot be the old root directory.");
|
||||
}
|
||||
|
||||
/* Safety check */
|
||||
if (!in_initrd())
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Not in initrd, refusing switch-root operation.");
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Not in initrd, refusing switch-root operation.");
|
||||
|
||||
r = path_is_os_tree(root);
|
||||
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);
|
||||
}
|
||||
|
||||
rt = strdup(root);
|
||||
if (!rt)
|
||||
return -ENOMEM;
|
||||
r = path_simplify_alloc(root, &rt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(init)) {
|
||||
ri = strdup(init);
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
r = path_simplify_alloc(init, &ri);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
free_and_replace(m->switch_root, rt);
|
||||
|
@ -3285,14 +3285,15 @@ int main(int argc, char *argv[]) {
|
||||
&switch_root_dir,
|
||||
&switch_root_init,
|
||||
&error_message);
|
||||
assert(r < 0 || IN_SET(r, MANAGER_EXIT, /* MANAGER_OK and MANAGER_RELOAD are not expected here. */
|
||||
MANAGER_REEXECUTE,
|
||||
MANAGER_REBOOT,
|
||||
MANAGER_SOFT_REBOOT,
|
||||
MANAGER_POWEROFF,
|
||||
MANAGER_HALT,
|
||||
MANAGER_KEXEC,
|
||||
MANAGER_SWITCH_ROOT));
|
||||
/* MANAGER_OK and MANAGER_RELOAD are not expected here. */
|
||||
assert(r < 0 || IN_SET(r, MANAGER_REEXECUTE, MANAGER_EXIT) ||
|
||||
(arg_runtime_scope == RUNTIME_SCOPE_SYSTEM &&
|
||||
IN_SET(r, MANAGER_REBOOT,
|
||||
MANAGER_SOFT_REBOOT,
|
||||
MANAGER_POWEROFF,
|
||||
MANAGER_HALT,
|
||||
MANAGER_KEXEC,
|
||||
MANAGER_SWITCH_ROOT)));
|
||||
|
||||
finish:
|
||||
pager_close();
|
||||
|
@ -3087,41 +3087,43 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||
|
||||
default: {
|
||||
|
||||
/* Starting SIGRTMIN+0 */
|
||||
static const struct {
|
||||
const char *target;
|
||||
JobMode mode;
|
||||
} target_table[] = {
|
||||
[0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
|
||||
[1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
|
||||
[2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
|
||||
[3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
};
|
||||
if (MANAGER_IS_SYSTEM(m)) {
|
||||
/* Starting SIGRTMIN+0 */
|
||||
static const struct {
|
||||
const char *target;
|
||||
JobMode mode;
|
||||
} target_table[] = {
|
||||
[0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
|
||||
[1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
|
||||
[2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
|
||||
[3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||
[5] = { SPECIAL_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 */
|
||||
static const ManagerObjective objective_table[] = {
|
||||
[0] = MANAGER_HALT,
|
||||
[1] = MANAGER_POWEROFF,
|
||||
[2] = MANAGER_REBOOT,
|
||||
[3] = MANAGER_KEXEC,
|
||||
[4] = MANAGER_SOFT_REBOOT,
|
||||
};
|
||||
/* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
|
||||
static const ManagerObjective objective_table[] = {
|
||||
[0] = MANAGER_HALT,
|
||||
[1] = MANAGER_POWEROFF,
|
||||
[2] = MANAGER_REBOOT,
|
||||
[3] = MANAGER_KEXEC,
|
||||
[4] = MANAGER_SOFT_REBOOT,
|
||||
};
|
||||
|
||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
||||
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
||||
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
||||
manager_start_special(m, target_table[idx].target, target_table[idx].mode);
|
||||
break;
|
||||
}
|
||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
||||
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
||||
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
||||
manager_start_special(m, target_table[idx].target, target_table[idx].mode);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
|
||||
(int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
|
||||
m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
|
||||
break;
|
||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
|
||||
(int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
|
||||
m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sfsi.ssi_signo - SIGRTMIN) {
|
||||
|
Loading…
Reference in New Issue
Block a user