core/service: pass credentials to ExecReload*= if refreshed
Closes #35227
This commit is contained in:
+50
-16
@@ -1689,11 +1689,16 @@ static Service *service_get_triggering_service(Service *s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ExecFlags service_exec_flags(ServiceExecCommand command_id, ExecFlags cred_flag) {
|
||||
static ExecFlags service_exec_flags(
|
||||
const Service *s,
|
||||
ServiceExecCommand command_id,
|
||||
ExecFlags cred_flag) {
|
||||
|
||||
/* All service main/control processes honor sandboxing and namespacing options (except those
|
||||
explicitly excluded in service_spawn()) */
|
||||
ExecFlags flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT;
|
||||
|
||||
assert(s);
|
||||
assert(command_id >= 0);
|
||||
assert(command_id < _SERVICE_EXEC_COMMAND_MAX);
|
||||
assert((cred_flag & ~(EXEC_SETUP_CREDENTIALS_FRESH|EXEC_SETUP_CREDENTIALS)) == 0);
|
||||
@@ -1725,6 +1730,12 @@ static ExecFlags service_exec_flags(ServiceExecCommand command_id, ExecFlags cre
|
||||
if (!IN_SET(command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE))
|
||||
flags |= EXEC_CONTROL_CGROUP;
|
||||
|
||||
/* Pass credentials to ExecReload*= too, but only if the credentials are actually refreshed,
|
||||
* to make sure they have the same understanding of the world as the main process. */
|
||||
if (IN_SET(command_id, SERVICE_EXEC_RELOAD, SERVICE_EXEC_RELOAD_POST) &&
|
||||
FLAGS_SET(s->refreshed_mask, SERVICE_RELOAD_CREDENTIALS))
|
||||
flags |= EXEC_SETUP_CREDENTIALS;
|
||||
|
||||
if (IN_SET(command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST))
|
||||
flags |= EXEC_SETENV_RESULT;
|
||||
|
||||
@@ -2250,7 +2261,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_stop_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2362,7 +2373,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_stop_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2447,7 +2458,7 @@ static void service_enter_start_post(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_start_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2557,7 +2568,7 @@ static void service_enter_start(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
c,
|
||||
service_exec_flags(SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS_FRESH),
|
||||
service_exec_flags(s, SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS_FRESH),
|
||||
timeout,
|
||||
&pidref);
|
||||
if (r < 0) {
|
||||
@@ -2617,7 +2628,7 @@ static void service_enter_start_pre(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_start_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2653,7 +2664,7 @@ static void service_enter_condition(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_start_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2757,7 +2768,7 @@ static void service_enter_reload_post(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_start_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -2832,7 +2843,7 @@ static void service_enter_reload(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
s->timeout_start_usec,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -3063,7 +3074,7 @@ static void service_run_next_control(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
|
||||
service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
|
||||
timeout,
|
||||
&s->control_pid);
|
||||
if (r < 0) {
|
||||
@@ -3094,7 +3105,7 @@ static void service_run_next_main(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->main_command,
|
||||
service_exec_flags(SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS),
|
||||
service_exec_flags(s, SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS),
|
||||
s->timeout_start_usec,
|
||||
&pidref);
|
||||
if (r < 0) {
|
||||
@@ -3275,6 +3286,7 @@ static int service_reload(Unit *u) {
|
||||
assert(IN_SET(s->state, SERVICE_RUNNING, SERVICE_EXITED));
|
||||
|
||||
s->reload_result = SERVICE_SUCCESS;
|
||||
s->refreshed_mask = 0;
|
||||
|
||||
service_enter_refresh_extensions(s);
|
||||
|
||||
@@ -3495,6 +3507,21 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
|
||||
(void) serialize_usec(f, "reload-begin-usec", s->reload_begin_usec);
|
||||
|
||||
if (s->refreshed_mask > 0) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
r = service_refresh_on_reload_to_strv(s->refreshed_mask, &l);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
t = strv_join(l, " ");
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
(void) serialize_item(f, "refreshed-mask", t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3884,7 +3911,11 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
|
||||
} else if (streq(key, "reload-begin-usec"))
|
||||
(void) deserialize_usec(value, &s->reload_begin_usec);
|
||||
else
|
||||
else if (streq(key, "refreshed-mask")) {
|
||||
r = service_refresh_on_reload_from_string_many(value, &s->refreshed_mask);
|
||||
if (r < 0)
|
||||
log_unit_debug_errno(u, r, "Failed to parse refresh-mask value: %s", value);
|
||||
} else
|
||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||
|
||||
return 0;
|
||||
@@ -4506,18 +4537,21 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
break;
|
||||
|
||||
case SERVICE_REFRESH_EXTENSIONS:
|
||||
if (f == SERVICE_SUCCESS)
|
||||
if (f == SERVICE_SUCCESS) {
|
||||
s->refreshed_mask |= SERVICE_RELOAD_EXTENSIONS;
|
||||
service_enter_refresh_credentials(s);
|
||||
else
|
||||
} else
|
||||
service_reload_finish(s, f);
|
||||
break;
|
||||
|
||||
case SERVICE_REFRESH_CREDENTIALS:
|
||||
if (f == SERVICE_SUCCESS ||
|
||||
(f == SERVICE_FAILURE_EXIT_CODE && IN_SET(status, EXIT_NOTINSTALLED, EXIT_NOPERMISSION)))
|
||||
(f == SERVICE_FAILURE_EXIT_CODE && IN_SET(status, EXIT_NOTINSTALLED, EXIT_NOPERMISSION))) {
|
||||
|
||||
/* Refreshing asynchronously done, proceed to reload */
|
||||
s->refreshed_mask |= f == SERVICE_SUCCESS ? SERVICE_RELOAD_CREDENTIALS : 0;
|
||||
service_enter_reload(s);
|
||||
else
|
||||
} else
|
||||
service_reload_finish(s, f);
|
||||
break;
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ typedef struct Service {
|
||||
|
||||
bool refresh_on_reload_set;
|
||||
ServiceRefreshOnReload refresh_on_reload_flags;
|
||||
ServiceRefreshOnReload refreshed_mask;
|
||||
|
||||
OOMPolicy oom_policy;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user