/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <sys/mount.h>

#include "copy.h"
#include "creds-util.h"
#include "escape.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "initrd-util.h"
#include "import-creds.h"
#include "io-util.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mountpoint-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "recurse-dir.h"
#include "strv.h"
#include "virt.h"

/* This imports credentials passed in from environments higher up (VM manager, boot loader, …) and rearranges
 * them so that later code can access them using our regular credential protocol
 * (i.e. $CREDENTIALS_DIRECTORY). It's supposed to be minimal glue to unify behaviour how PID 1 (and
 * generators invoked by it) can acquire credentials from outside, to mimic how we support it for containers,
 * but on VM/physical environments.
 *
 * This does four things:
 *
 * 1. It imports credentials picked up by sd-boot (and placed in the /.extra/credentials/ dir in the initrd)
 *    and puts them in /run/credentials/@encrypted/. Note that during the initrd→host transition the initrd root
 *    file system is cleaned out, thus it is essential we pick up these files before they are deleted. Note
 *    that these credentials originate from an untrusted source, i.e. the ESP and are not
 *    pre-authenticated. They still have to be authenticated before use.
 *
 * 2. It imports credentials from /proc/cmdline and puts them in /run/credentials/@system/. These come from a
 *    trusted environment (i.e. the boot loader), and are typically authenticated (if authentication is done
 *    at all). However, they are world-readable, which might be less than ideal. Hence only use this for data
 *    that doesn't require trust.
 *
 * 3. It imports credentials passed in through qemu's fw_cfg logic. Specifically, credential data passed in
 *    /sys/firmware/qemu_fw_cfg/by_name/opt/io.systemd.credentials/ is picked up and also placed in
 *    /run/credentials/@system/.
 *
 * 4. It imports credentials passed in via the DMI/SMBIOS OEM string tables, quite similar to fw_cfg. It
 *    looks for strings starting with "io.systemd.credential:" and "io.systemd.credential.binary:". Both
 *    expect a key=value assignment, but in the latter case the value is Base64 decoded, allowing binary
 *    credentials to be passed in.
 *
 * If it picked up any credentials it will set the $CREDENTIALS_DIRECTORY and
 * $ENCRYPTED_CREDENTIALS_DIRECTORY environment variables to point to these directories, so that processes
 * can find them there later on. If "ramfs" is available $CREDENTIALS_DIRECTORY will be backed by it (but
 * $ENCRYPTED_CREDENTIALS_DIRECTORY is just a regular tmpfs).
 *
 * Net result: the service manager can pick up trusted credentials from $CREDENTIALS_DIRECTORY afterwards,
 * and untrusted ones from $ENCRYPTED_CREDENTIALS_DIRECTORY. */

typedef struct ImportCredentialContext {
        int target_dir_fd;
        size_t size_sum;
        unsigned n_credentials;
} ImportCredentialContext;

static void import_credentials_context_free(ImportCredentialContext *c) {
        assert(c);

        c->target_dir_fd = safe_close(c->target_dir_fd);
}

static int acquire_encrypted_credential_directory(ImportCredentialContext *c) {
        int r;

        assert(c);

        if (c->target_dir_fd >= 0)
                return c->target_dir_fd;

        r = mkdir_safe_label(ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, 0700, 0, 0, MKDIR_WARN_MODE);
        if (r < 0)
                return log_error_errno(r, "Failed to create " ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY ": %m");

        c->target_dir_fd = open(ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
        if (c->target_dir_fd < 0)
                return log_error_errno(errno, "Failed to open " ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY ": %m");

        return c->target_dir_fd;
}

static int open_credential_file_for_write(int target_dir_fd, const char *dir_name, const char *n) {
        int fd;

        assert(target_dir_fd >= 0);
        assert(dir_name);
        assert(n);

        fd = openat(target_dir_fd, n, O_WRONLY|O_CLOEXEC|O_CREAT|O_EXCL|O_NOFOLLOW, 0400);
        if (fd < 0) {
                if (errno == EEXIST) /* In case of EEXIST we'll only debug log! */
                        return log_debug_errno(errno, "Credential '%s' set twice, ignoring.", n);

                return log_error_errno(errno, "Failed to create %s/%s: %m", dir_name, n);
        }

        return fd;
}

static bool credential_size_ok(ImportCredentialContext *c, const char *name, uint64_t size) {
        assert(c);
        assert(name);

        if (size > CREDENTIAL_SIZE_MAX) {
                log_warning("Credential '%s' is larger than allowed limit (%s > %s), skipping.", name, FORMAT_BYTES(size), FORMAT_BYTES(CREDENTIAL_SIZE_MAX));
                return false;
        }

        if (size > CREDENTIALS_TOTAL_SIZE_MAX - c->size_sum) {
                log_warning("Accumulated credential size would be above allowed limit (%s+%s > %s), skipping '%s'.",
                            FORMAT_BYTES(c->size_sum), FORMAT_BYTES(size), FORMAT_BYTES(CREDENTIALS_TOTAL_SIZE_MAX), name);
                return false;
        }

        return true;
}

static int finalize_credentials_dir(const char *dir, const char *envvar) {
        int r;

        assert(dir);
        assert(envvar);

        /* Try to make the credentials directory read-only now */

        r = make_mount_point(dir);
        if (r < 0)
                log_warning_errno(r, "Failed to make '%s' a mount point, ignoring: %m", dir);
        else
                (void) mount_nofollow_verbose(LOG_WARNING, NULL, dir, NULL, MS_BIND|MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_RDONLY|MS_REMOUNT, NULL);

        if (setenv(envvar, dir, /* overwrite= */ true) < 0)
                return log_error_errno(errno, "Failed to set $%s environment variable: %m", envvar);

        return 0;
}

static int import_credentials_boot(void) {
        _cleanup_(import_credentials_context_free) ImportCredentialContext context = {
                .target_dir_fd = -EBADF,
        };
        int r;

        /* systemd-stub will wrap sidecar *.cred files from the UEFI kernel image directory into initrd
         * cpios, so that they unpack into /.extra/. We'll pick them up from there and copy them into /run/
         * so that we can access them during the entire runtime (note that the initrd file system is erased
         * during the initrd → host transition). Note that these credentials originate from an untrusted
         * source (i.e. the ESP typically) and thus need to be authenticated later. We thus put them in a
         * directory separate from the usual credentials which are from a trusted source. */

        if (!in_initrd())
                return 0;

        FOREACH_STRING(p,
                       "/.extra/credentials/", /* specific to this boot menu */
                       "/.extra/global_credentials/") { /* boot partition wide */

                _cleanup_free_ DirectoryEntries *de = NULL;
                _cleanup_close_ int source_dir_fd = -EBADF;

                source_dir_fd = open(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
                if (source_dir_fd < 0) {
                        if (errno == ENOENT) {
                                log_debug("No credentials passed via %s.", p);
                                continue;
                        }

                        log_warning_errno(errno, "Failed to open '%s', ignoring: %m", p);
                        continue;
                }

                r = readdir_all(source_dir_fd, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT, &de);
                if (r < 0) {
                        log_warning_errno(r, "Failed to read '%s' contents, ignoring: %m", p);
                        continue;
                }

                for (size_t i = 0; i < de->n_entries; i++) {
                        const struct dirent *d = de->entries[i];
                        _cleanup_close_ int cfd = -EBADF, nfd = -EBADF;
                        _cleanup_free_ char *n = NULL;
                        const char *e;
                        struct stat st;

                        e = endswith(d->d_name, ".cred");
                        if (!e)
                                continue;

                        /* drop .cred suffix (which we want in the ESP sidecar dir, but not for our internal
                         * processing) */
                        n = strndup(d->d_name, e - d->d_name);
                        if (!n)
                                return log_oom();

                        if (!credential_name_valid(n)) {
                                log_warning("Credential '%s' has invalid name, ignoring.", d->d_name);
                                continue;
                        }

                        cfd = openat(source_dir_fd, d->d_name, O_RDONLY|O_CLOEXEC);
                        if (cfd < 0) {
                                log_warning_errno(errno, "Failed to open %s, ignoring: %m", d->d_name);
                                continue;
                        }

                        if (fstat(cfd, &st) < 0) {
                                log_warning_errno(errno, "Failed to stat %s, ignoring: %m", d->d_name);
                                continue;
                        }

                        r = stat_verify_regular(&st);
                        if (r < 0) {
                                log_warning_errno(r, "Credential file %s is not a regular file, ignoring: %m", d->d_name);
                                continue;
                        }

                        if (!credential_size_ok(&context, n, st.st_size))
                                continue;

                        r = acquire_encrypted_credential_directory(&context);
                        if (r < 0)
                                return r;

                        nfd = open_credential_file_for_write(context.target_dir_fd, ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, n);
                        if (nfd == -EEXIST)
                                continue;
                        if (nfd < 0)
                                return nfd;

                        r = copy_bytes(cfd, nfd, st.st_size, 0);
                        if (r < 0) {
                                (void) unlinkat(context.target_dir_fd, n, 0);
                                return log_error_errno(r, "Failed to create credential '%s': %m", n);
                        }

                        context.size_sum += st.st_size;
                        context.n_credentials++;

                        log_debug("Successfully copied boot credential '%s'.", n);
                }
        }

        if (context.n_credentials > 0) {
                log_debug("Imported %u credentials from boot loader.", context.n_credentials);

                r = finalize_credentials_dir(ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, "ENCRYPTED_CREDENTIALS_DIRECTORY");
                if (r < 0)
                        return r;
        }

        return 0;
}

static int acquire_credential_directory(ImportCredentialContext *c) {
        int r;

        assert(c);

        if (c->target_dir_fd >= 0)
                return c->target_dir_fd;

        r = path_is_mount_point(SYSTEM_CREDENTIALS_DIRECTORY, NULL, 0);
        if (r < 0) {
                if (r != -ENOENT)
                        return log_error_errno(r, "Failed to determine if " SYSTEM_CREDENTIALS_DIRECTORY " is a mount point: %m");

                r = mkdir_safe_label(SYSTEM_CREDENTIALS_DIRECTORY, 0700, 0, 0, MKDIR_WARN_MODE);
                if (r < 0)
                        return log_error_errno(r, "Failed to create " SYSTEM_CREDENTIALS_DIRECTORY " mount point: %m");

                r = 0; /* Now it exists and is not a mount point */
        }
        if (r == 0)
                /* If not a mountpoint yet, try to mount a ramfs there (so that this stuff isn't swapped
                 * out), but if that doesn't work, let's just use the regular tmpfs it already is. */
                (void) mount_nofollow_verbose(LOG_WARNING, "ramfs", SYSTEM_CREDENTIALS_DIRECTORY, "ramfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, "mode=0700");

        c->target_dir_fd = open(SYSTEM_CREDENTIALS_DIRECTORY, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
        if (c->target_dir_fd < 0)
                return log_error_errno(errno, "Failed to open " SYSTEM_CREDENTIALS_DIRECTORY ": %m");

        return c->target_dir_fd;
}

static int proc_cmdline_callback(const char *key, const char *value, void *data) {
        ImportCredentialContext *c = ASSERT_PTR(data);
        _cleanup_free_ char *n = NULL;
        _cleanup_close_ int nfd = -EBADF;
        const char *colon;
        size_t l;
        int r;

        assert(key);

        if (!proc_cmdline_key_streq(key, "systemd.set_credential"))
                return 0;

        colon = value ? strchr(value, ':') : NULL;
        if (!colon) {
                log_warning("Credential assignment through kernel command line lacks ':' character, ignoring: %s", value);
                return 0;
        }

        n = strndup(value, colon - value);
        if (!n)
                return log_oom();

        if (!credential_name_valid(n)) {
                log_warning("Credential name '%s' is invalid, ignoring.", n);
                return 0;
        }

        colon++;
        l = strlen(colon);

        if (!credential_size_ok(c, n, l))
                return 0;

        r = acquire_credential_directory(c);
        if (r < 0)
                return r;

        nfd = open_credential_file_for_write(c->target_dir_fd, SYSTEM_CREDENTIALS_DIRECTORY, n);
        if (nfd == -EEXIST)
                return 0;
        if (nfd < 0)
                return nfd;

        r = loop_write(nfd, colon, l, /* do_poll= */ false);
        if (r < 0) {
                (void) unlinkat(c->target_dir_fd, n, 0);
                return log_error_errno(r, "Failed to write credential: %m");
        }

        c->size_sum += l;
        c->n_credentials++;

        log_debug("Successfully processed kernel command line credential '%s'.", n);

        return 0;
}

static int import_credentials_proc_cmdline(ImportCredentialContext *c) {
        int r;

        assert(c);

        r = proc_cmdline_parse(proc_cmdline_callback, c, 0);
        if (r < 0)
                return log_error_errno(r, "Failed to parse /proc/cmdline: %m");

        return 0;
}

#define QEMU_FWCFG_PATH "/sys/firmware/qemu_fw_cfg/by_name/opt/io.systemd.credentials"

static int import_credentials_qemu(ImportCredentialContext *c) {
        _cleanup_free_ DirectoryEntries *de = NULL;
        _cleanup_close_ int source_dir_fd = -EBADF;
        int r;

        assert(c);

        if (detect_container() > 0) /* don't access /sys/ in a container */
                return 0;

        source_dir_fd = open(QEMU_FWCFG_PATH, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
        if (source_dir_fd < 0) {
                if (errno == ENOENT) {
                        log_debug("No credentials passed via fw_cfg.");
                        return 0;
                }

                log_warning_errno(errno, "Failed to open '" QEMU_FWCFG_PATH "', ignoring: %m");
                return 0;
        }

        r = readdir_all(source_dir_fd, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT, &de);
        if (r < 0) {
                log_warning_errno(r, "Failed to read '" QEMU_FWCFG_PATH "' contents, ignoring: %m");
                return 0;
        }

        for (size_t i = 0; i < de->n_entries; i++) {
                const struct dirent *d = de->entries[i];
                _cleanup_close_ int vfd = -EBADF, rfd = -EBADF, nfd = -EBADF;
                _cleanup_free_ char *szs = NULL;
                uint64_t sz;

                if (!credential_name_valid(d->d_name)) {
                        log_warning("Credential '%s' has invalid name, ignoring.", d->d_name);
                        continue;
                }

                vfd = openat(source_dir_fd, d->d_name, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
                if (vfd < 0) {
                        log_warning_errno(errno, "Failed to open '" QEMU_FWCFG_PATH "'/%s/, ignoring: %m", d->d_name);
                        continue;
                }

                r = read_virtual_file_at(vfd, "size", LINE_MAX, &szs, NULL);
                if (r < 0) {
                        log_warning_errno(r, "Failed to read '" QEMU_FWCFG_PATH "'/%s/size, ignoring: %m", d->d_name);
                        continue;
                }

                r = safe_atou64(strstrip(szs), &sz);
                if (r < 0) {
                        log_warning_errno(r, "Failed to parse size of credential '%s', ignoring: %s", d->d_name, szs);
                        continue;
                }

                if (!credential_size_ok(c, d->d_name, sz))
                        continue;

                /* Ideally we'd just symlink the data here. Alas the kernel driver exports the raw file as
                 * having size zero, and we'd rather not have applications support such credential
                 * files. Let's hence copy the files to make them regular. */

                rfd = openat(vfd, "raw", O_RDONLY|O_CLOEXEC);
                if (rfd < 0) {
                        log_warning_errno(errno, "Failed to open '" QEMU_FWCFG_PATH "'/%s/raw, ignoring: %m", d->d_name);
                        continue;
                }

                r = acquire_credential_directory(c);
                if (r < 0)
                        return r;

                nfd = open_credential_file_for_write(c->target_dir_fd, SYSTEM_CREDENTIALS_DIRECTORY, d->d_name);
                if (nfd == -EEXIST)
                        continue;
                if (nfd < 0)
                        return nfd;

                r = copy_bytes(rfd, nfd, sz, 0);
                if (r < 0) {
                        (void) unlinkat(c->target_dir_fd, d->d_name, 0);
                        return log_error_errno(r, "Failed to create credential '%s': %m", d->d_name);
                }

                c->size_sum += sz;
                c->n_credentials++;

                log_debug("Successfully copied qemu fw_cfg credential '%s'.", d->d_name);
        }

        return 0;
}

static int parse_smbios_strings(ImportCredentialContext *c, const char *data, size_t size) {
        size_t left, skip;
        const char *p;
        int r;

        assert(c);
        assert(data || size == 0);

        /* Unpacks a packed series of SMBIOS OEM vendor strings. These are a series of NUL terminated
         * strings, one after the other. */

        for (p = data, left = size; left > 0; p += skip, left -= skip) {
                _cleanup_free_ void *buf = NULL;
                _cleanup_free_ char *cn = NULL;
                _cleanup_close_ int nfd = -EBADF;
                const char *nul, *n, *eq;
                const void *cdata;
                size_t buflen, cdata_len;
                bool unbase64;

                nul = memchr(p, 0, left);
                if (nul)
                        skip = (nul - p) + 1;
                else {
                        nul = p + left;
                        skip = left;
                }

                if (nul - p == 0) /* Skip empty strings */
                        continue;

                /* Only care about strings starting with either of these two prefixes */
                if ((n = memory_startswith(p, nul - p, "io.systemd.credential:")))
                        unbase64 = false;
                else if ((n = memory_startswith(p, nul - p, "io.systemd.credential.binary:")))
                        unbase64 = true;
                else {
                        _cleanup_free_ char *escaped = NULL;

                        escaped = cescape_length(p, nul - p);
                        log_debug("Ignoring OEM string: %s", strnull(escaped));
                        continue;
                }

                eq = memchr(n, '=', nul - n);
                if (!eq) {
                        log_warning("SMBIOS OEM string lacks '=' character, ignoring.");
                        continue;
                }

                cn = memdup_suffix0(n, eq - n);
                if (!cn)
                        return log_oom();

                if (!credential_name_valid(cn)) {
                        log_warning("SMBIOS credential name '%s' is not valid, ignoring: %m", cn);
                        continue;
                }

                /* Optionally base64 decode the data, if requested, to allow binary credentials */
                if (unbase64) {
                        r = unbase64mem(eq + 1, nul - (eq + 1), &buf, &buflen);
                        if (r < 0) {
                                log_warning_errno(r, "Failed to base64 decode credential '%s', ignoring: %m", cn);
                                continue;
                        }

                        cdata = buf;
                        cdata_len = buflen;
                } else {
                        cdata = eq + 1;
                        cdata_len = nul - (eq + 1);
                }

                if (!credential_size_ok(c, cn, cdata_len))
                        continue;

                r = acquire_credential_directory(c);
                if (r < 0)
                        return r;

                nfd = open_credential_file_for_write(c->target_dir_fd, SYSTEM_CREDENTIALS_DIRECTORY, cn);
                if (nfd == -EEXIST)
                        continue;
                if (nfd < 0)
                        return nfd;

                r = loop_write(nfd, cdata, cdata_len, /* do_poll= */ false);
                if (r < 0) {
                        (void) unlinkat(c->target_dir_fd, cn, 0);
                        return log_error_errno(r, "Failed to write credential: %m");
                }

                c->size_sum += cdata_len;
                c->n_credentials++;

                log_debug("Successfully processed SMBIOS credential '%s'.", cn);
        }

        return 0;
}

static int import_credentials_smbios(ImportCredentialContext *c) {
        int r;

        /* Parses DMI OEM strings fields (SMBIOS type 11), as settable with qemu's -smbios type=11,value=… switch. */

        if (detect_container() > 0) /* don't access /sys/ in a container */
                return 0;

        for (unsigned i = 0;; i++) {
                struct dmi_field_header {
                        uint8_t type;
                        uint8_t length;
                        uint16_t handle;
                        uint8_t count;
                        char contents[];
                } _packed_ *dmi_field_header;
                _cleanup_free_ char *p = NULL;
                _cleanup_free_ void *data = NULL;
                size_t size;

                assert_cc(offsetof(struct dmi_field_header, contents) == 5);

                if (asprintf(&p, "/sys/firmware/dmi/entries/11-%u/raw", i) < 0)
                        return log_oom();

                r = read_virtual_file(p, sizeof(dmi_field_header) + CREDENTIALS_TOTAL_SIZE_MAX, (char**) &data, &size);
                if (r < 0) {
                        /* Once we reach ENOENT there are no more DMI Type 11 fields around. */
                        log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r, "Failed to open '%s', ignoring: %m", p);
                        break;
                }

                if (size < offsetof(struct dmi_field_header, contents))
                        return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "DMI field header of '%s' too short.", p);

                dmi_field_header = data;
                if (dmi_field_header->type != 11 ||
                    dmi_field_header->length != offsetof(struct dmi_field_header, contents))
                        return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Invalid DMI field header.");

                r = parse_smbios_strings(c, dmi_field_header->contents, size - offsetof(struct dmi_field_header, contents));
                if (r < 0)
                        return r;

                if (i == UINT_MAX) /* Prevent overflow */
                        break;
        }

        return 0;
}

static int import_credentials_trusted(void) {
        _cleanup_(import_credentials_context_free) ImportCredentialContext c = {
                .target_dir_fd = -EBADF,
        };
        int q, w, r;

        r = import_credentials_qemu(&c);
        w = import_credentials_smbios(&c);
        q = import_credentials_proc_cmdline(&c);

        if (c.n_credentials > 0) {
                int z;

                log_debug("Imported %u credentials from kernel command line/smbios/fw_cfg.", c.n_credentials);

                z = finalize_credentials_dir(SYSTEM_CREDENTIALS_DIRECTORY, "CREDENTIALS_DIRECTORY");
                if (z < 0)
                        return z;
        }

        return r < 0 ? r : w < 0 ? w : q;
}

static int symlink_credential_dir(const char *envvar, const char *path, const char *where) {
        int r;

        assert(envvar);
        assert(path);
        assert(where);

        if (!path_is_valid(path) || !path_is_absolute(path))
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "String specified via $%s is not a valid absolute path, refusing: %s", envvar, path);

        /* If the env var already points to where we intend to create the symlink, then most likely we
         * already imported some creds earlier, and thus set the env var, and hence don't need to do
         * anything. */
        if (path_equal(path, where))
                return 0;

        r = symlink_idempotent(path, where, /* make_relative= */ true);
        if (r < 0)
                return log_error_errno(r, "Failed to link $%s to %s: %m", envvar, where);

        return 0;
}

int import_credentials(void) {
        const char *received_creds_dir = NULL, *received_encrypted_creds_dir = NULL;
        bool envvar_set = false;
        int r, q;

        r = get_credentials_dir(&received_creds_dir);
        if (r < 0 && r != -ENXIO) /* ENXIO → env var not set yet */
                log_warning_errno(r, "Failed to determine credentials directory, ignoring: %m");

        envvar_set = r >= 0;

        r = get_encrypted_credentials_dir(&received_encrypted_creds_dir);
        if (r < 0 && r != -ENXIO) /* ENXIO → env var not set yet */
                log_warning_errno(r, "Failed to determine encrypted credentials directory, ignoring: %m");

        envvar_set = envvar_set || r >= 0;

        if (envvar_set) {
                /* Maybe an earlier stage initrd already set this up? If so, don't try to import anything again. */
                log_debug("Not importing credentials, $CREDENTIALS_DIRECTORY or $ENCRYPTED_CREDENTIALS_DIRECTORY already set.");

                /* But, let's make sure the creds are available from our regular paths. */
                if (received_creds_dir)
                        r = symlink_credential_dir("CREDENTIALS_DIRECTORY", received_creds_dir, SYSTEM_CREDENTIALS_DIRECTORY);
                else
                        r = 0;

                if (received_encrypted_creds_dir) {
                        q = symlink_credential_dir("ENCRYPTED_CREDENTIALS_DIRECTORY", received_encrypted_creds_dir, ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY);
                        if (r >= 0)
                                r = q;
                }

        } else {
                _cleanup_free_ char *v = NULL;

                r = proc_cmdline_get_key("systemd.import_credentials", PROC_CMDLINE_STRIP_RD_PREFIX, &v);
                if (r < 0)
                        log_debug_errno(r, "Failed to check if 'systemd.import_credentials=' kernel command line option is set, ignoring: %m");
                else if (r > 0) {
                        r = parse_boolean(v);
                        if (r < 0)
                                log_debug_errno(r, "Failed to parse 'systemd.import_credentials=' parameter, ignoring: %m");
                        else if (r == 0) {
                                log_notice("systemd.import_credentials=no is set, skipping importing of credentials.");
                                return 0;
                        }
                }

                r = import_credentials_boot();

                q = import_credentials_trusted();
                if (r >= 0)
                        r = q;
        }

        if (r >= 0) {
                _cleanup_free_ char *address = NULL;

                r = read_credential("vmm.notify_socket", (void **)&address, /* ret_size= */ NULL);
                if (r < 0 && !IN_SET(r, -ENOENT, -ENXIO))
                        log_warning_errno(r, "Failed to read 'vmm.notify_socket' credential, ignoring: %m");
                else if (r >= 0 && !isempty(address)) {
                        r = setenv("NOTIFY_SOCKET", address, /* replace= */ 1);
                        if (r < 0)
                                log_warning_errno(errno, "Failed to set $NOTIFY_SOCKET environment variable, ignoring: %m");
                }
        }

        return r;
}
