1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 06:25:37 +03:00

execute: rework load_credential() not to take an ExecLoadCredential object we must synthesize

Let's just simplify the logic and pass the fields we need as regular
arguments, even if that means the function now has a lot. It's otherwise
really weird that we have to fake a local ExecLoadCredential from the
real one.
This commit is contained in:
Lennart Poettering 2022-04-13 18:43:02 +02:00
parent 9a6994e971
commit 10b44e1dc1

View File

@ -2598,7 +2598,9 @@ static int write_credential(
static int load_credential(
const ExecContext *context,
const ExecParameters *params,
ExecLoadCredential *lc,
const char *id,
const char *path,
bool encrypted,
const char *unit,
int read_dfd,
int write_dfd,
@ -2606,12 +2608,6 @@ static int load_credential(
bool ownership_ok,
uint64_t *left) {
assert(context);
assert(lc);
assert(unit);
assert(write_dfd >= 0);
assert(left);
ReadFullFileFlags flags = READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER;
_cleanup_(erase_and_freep) char *data = NULL;
_cleanup_free_ char *j = NULL, *bindname = NULL;
@ -2620,14 +2616,22 @@ static int load_credential(
size_t size, add;
int r;
if (path_is_absolute(lc->path) || read_dfd >= 0) {
assert(context);
assert(params);
assert(id);
assert(path);
assert(unit);
assert(write_dfd >= 0);
assert(left);
if (path_is_absolute(path) || read_dfd >= 0) {
/* If this is an absolute path, read the data directly from it, and support AF_UNIX sockets */
source = lc->path;
source = path;
flags |= READ_FULL_FILE_CONNECT_SOCKET;
/* Pass some minimal info about the unit and the credential name we are looking to acquire
* via the source socket address in case we read off an AF_UNIX socket. */
if (asprintf(&bindname, "@%" PRIx64"/unit/%s/%s", random_u64(), unit, lc->id) < 0)
if (asprintf(&bindname, "@%" PRIx64"/unit/%s/%s", random_u64(), unit, id) < 0)
return -ENOMEM;
missing_ok = false;
@ -2636,7 +2640,7 @@ static int load_credential(
/* If this is a relative path, take it relative to the credentials we received
* ourselves. We don't support the AF_UNIX stuff in this mode, since we are operating
* on a credential store, i.e. this is guaranteed to be regular files. */
j = path_join(params->received_credentials, lc->path);
j = path_join(params->received_credentials, path);
if (!j)
return -ENOMEM;
@ -2648,14 +2652,14 @@ static int load_credential(
r = read_full_file_full(
read_dfd, source,
UINT64_MAX,
lc->encrypted ? CREDENTIAL_ENCRYPTED_SIZE_MAX : CREDENTIAL_SIZE_MAX,
flags | (lc->encrypted ? READ_FULL_FILE_UNBASE64 : 0),
encrypted ? CREDENTIAL_ENCRYPTED_SIZE_MAX : CREDENTIAL_SIZE_MAX,
flags | (encrypted ? READ_FULL_FILE_UNBASE64 : 0),
bindname,
&data, &size);
else
r = -ENOENT;
if (r == -ENOENT && (missing_ok || hashmap_contains(context->set_credentials, lc->id))) {
if (r == -ENOENT && (missing_ok || hashmap_contains(context->set_credentials, id))) {
/* Make a missing inherited credential non-fatal, let's just continue. After all apps
* will get clear errors if we don't pass such a missing credential on as they
* themselves will get ENOENT when trying to read them, which should not be much
@ -2663,17 +2667,17 @@ static int load_credential(
*
* Also, if the source file doesn't exist, but a fallback is set via SetCredentials=
* we are fine, too. */
log_debug_errno(r, "Couldn't read inherited credential '%s', skipping: %m", lc->path);
log_debug_errno(r, "Couldn't read inherited credential '%s', skipping: %m", path);
return 0;
}
if (r < 0)
return log_debug_errno(r, "Failed to read credential '%s': %m", lc->path);
return log_debug_errno(r, "Failed to read credential '%s': %m", path);
if (lc->encrypted) {
if (encrypted) {
_cleanup_free_ void *plaintext = NULL;
size_t plaintext_size = 0;
r = decrypt_credential_and_warn(lc->id, now(CLOCK_REALTIME), NULL, data, size, &plaintext, &plaintext_size);
r = decrypt_credential_and_warn(id, now(CLOCK_REALTIME), NULL, data, size, &plaintext, &plaintext_size);
if (r < 0)
return r;
@ -2681,11 +2685,11 @@ static int load_credential(
size = plaintext_size;
}
add = strlen(lc->id) + size;
add = strlen(id) + size;
if (add > *left)
return -E2BIG;
r = write_credential(write_dfd, lc->id, data, size, uid, ownership_ok);
r = write_credential(write_dfd, id, data, size, uid, ownership_ok);
if (r < 0)
return r;
@ -2695,10 +2699,9 @@ static int load_credential(
struct load_cred_args {
Set *seen_creds;
const ExecContext *context;
const ExecParameters *params;
ExecLoadCredential *parent_local_credential;
ExecLoadCredential *parent_load_credential;
const char *unit;
int dfd;
uid_t uid;
@ -2729,7 +2732,7 @@ static int load_cred_recurse_dir_cb(
if (!credname)
return -ENOMEM;
sub_id = strjoin(args->parent_local_credential->id, "_", credname);
sub_id = strjoin(args->parent_load_credential->id, "_", credname);
if (!sub_id)
return -ENOMEM;
@ -2745,12 +2748,18 @@ static int load_cred_recurse_dir_cb(
if (r < 0)
return r;
r = load_credential(args->context, args->params,
&(ExecLoadCredential) {
.id = sub_id,
.path = (char *) de->d_name,
.encrypted = args->parent_local_credential->encrypted,
}, args->unit, dir_fd, args->dfd, args->uid, args->ownership_ok, args->left);
r = load_credential(
args->context,
args->params,
sub_id,
de->d_name,
args->parent_load_credential->encrypted,
args->unit,
dir_fd,
args->dfd,
args->uid,
args->ownership_ok,
args->left);
if (r < 0)
return r;
@ -2797,14 +2806,30 @@ static int acquire_credentials(
return -errno;
if (sub_fd < 0) {
/* Regular file */
r = set_put_strdup(&seen_creds, lc->id);
if (r < 0)
return r;
r = load_credential(context, params, lc, unit, -1, dfd, uid, ownership_ok, &left);
r = load_credential(
context,
params,
lc->id,
lc->path,
lc->encrypted,
unit,
-1,
dfd,
uid,
ownership_ok,
&left);
if (r < 0)
return r;
} else {
/* Directory */
r = recurse_dir(
sub_fd,
/* path= */ "",
@ -2816,7 +2841,7 @@ static int acquire_credentials(
.seen_creds = seen_creds,
.context = context,
.params = params,
.parent_local_credential = lc,
.parent_load_credential = lc,
.unit = unit,
.dfd = dfd,
.uid = uid,