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

#include <stddef.h>
#include <sys/mount.h>

#include "blockdev-util.h"
#include "chown-recursive.h"
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
#include "fs-util.h"
#include "home-util.h"
#include "homework-cifs.h"
#include "homework-directory.h"
#include "homework-fido2.h"
#include "homework-fscrypt.h"
#include "homework-luks.h"
#include "homework-mount.h"
#include "homework-pkcs11.h"
#include "homework.h"
#include "libcrypt-util.h"
#include "main-func.h"
#include "memory-util.h"
#include "missing_magic.h"
#include "mount-util.h"
#include "path-util.h"
#include "recovery-key.h"
#include "rm-rf.h"
#include "stat-util.h"
#include "strv.h"
#include "sync-util.h"
#include "tmpfile-util.h"
#include "user-util.h"
#include "virt.h"

/* Make sure a bad password always results in a 3s delay, no matter what */
#define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)

int user_record_authenticate(
                UserRecord *h,
                UserRecord *secret,
                PasswordCache *cache,
                bool strict_verify) {

        bool need_password = false, need_recovery_key = false, need_token = false, need_pin = false,
                need_protected_authentication_path_permitted = false, need_user_presence_permitted = false,
                need_user_verification_permitted = false, pin_locked = false, pin_incorrect = false,
                pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false, token_action_timeout = false;
        int r;

        assert(h);
        assert(secret);

        /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
         * supplied plaintext passwords matches a hashed password field of the user record. Or if a
         * configured PKCS#11 or FIDO2 token is around and can unlock the record.
         *
         * Note that the 'cache' parameter is both an input and output parameter: it contains lists of
         * configured, decrypted PKCS#11/FIDO2 passwords. We typically have to call this function multiple
         * times over the course of an operation (think: on login we authenticate the host user record, the
         * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
         * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
         * PKCS#11/FIDO2 dance for the relevant token again and again. */

        /* First, let's see if the supplied plain-text passwords work? */
        r = user_record_test_password(h, secret);
        if (r == -ENOKEY)
                need_password = true;
        else if (r == -ENXIO)
                log_debug_errno(r, "User record has no hashed passwords, plaintext passwords not tested.");
        else if (r < 0)
                return log_error_errno(r, "Failed to validate password of record: %m");
        else {
                log_info("Provided password unlocks user record.");
                return 1;
        }

        /* Similar, but test against the recovery keys */
        r = user_record_test_recovery_key(h, secret);
        if (r == -ENOKEY)
                need_recovery_key = true;
        else if (r == -ENXIO)
                log_debug_errno(r, "User record has no recovery keys, plaintext passwords not tested against it.");
        else if (r < 0)
                return log_error_errno(r, "Failed to validate the recovery key of the record: %m");
        else {
                log_info("Provided password is a recovery key that unlocks the user record.");
                return 1;
        }

        if (need_password && need_recovery_key)
                log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords or recovery keys.");
        else if (need_password)
                log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords.");
        else
                log_info("None of the supplied plaintext passwords unlock the user record's hashed recovery keys.");

        /* Second, test cached PKCS#11 passwords */
        for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++)
                STRV_FOREACH(pp, cache->pkcs11_passwords) {
                        r = test_password_one(h->pkcs11_encrypted_key[n].hashed_password, *pp);
                        if (r < 0)
                                return log_error_errno(r, "Failed to check supplied PKCS#11 password: %m");
                        if (r > 0) {
                                log_info("Previously acquired PKCS#11 password unlocks user record.");
                                return 1;
                        }
                }

        /* Third, test cached FIDO2 passwords */
        for (size_t n = 0; n < h->n_fido2_hmac_salt; n++)
                /* See if any of the previously calculated passwords work */
                STRV_FOREACH(pp, cache->fido2_passwords) {
                        r = test_password_one(h->fido2_hmac_salt[n].hashed_password, *pp);
                        if (r < 0)
                                return log_error_errno(r, "Failed to check supplied FIDO2 password: %m");
                        if (r > 0) {
                                log_info("Previously acquired FIDO2 password unlocks user record.");
                                return 1;
                        }
                }

        /* Fourth, let's see if any of the PKCS#11 security tokens are plugged in and help us */
        for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
#if HAVE_P11KIT
                _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
                        .user_record = h,
                        .secret = secret,
                        .encrypted_key = h->pkcs11_encrypted_key + n,
                };

                r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
                switch (r) {
                case -EAGAIN:
                        need_token = true;
                        break;
                case -ENOANO:
                        need_pin = true;
                        break;
                case -ERFKILL:
                        need_protected_authentication_path_permitted = true;
                        break;
                case -EOWNERDEAD:
                        pin_locked = true;
                        break;
                case -ENOLCK:
                        pin_incorrect = true;
                        break;
                case -ETOOMANYREFS:
                        pin_incorrect = pin_incorrect_few_tries_left = true;
                        break;
                case -EUCLEAN:
                        pin_incorrect = pin_incorrect_few_tries_left = pin_incorrect_one_try_left = true;
                        break;
                default:
                        if (r < 0)
                                return r;

                        r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
                        if (r < 0)
                                return log_error_errno(r, "Failed to test PKCS#11 password: %m");
                        if (r == 0)
                                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.", data.encrypted_key->uri);

                        log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data.encrypted_key->uri);

                        r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
                        if (r < 0)
                                return log_oom();

                        return 1;
                }
#else
                need_token = true;
                break;
#endif
        }

        /* Fifth, let's see if any of the FIDO2 security tokens are plugged in and help us */
        for (size_t n = 0; n < h->n_fido2_hmac_salt; n++) {
#if HAVE_LIBFIDO2
                _cleanup_(erase_and_freep) char *decrypted_password = NULL;

                r = fido2_use_token(h, secret, h->fido2_hmac_salt + n, &decrypted_password);
                switch (r) {
                case -EAGAIN:
                        need_token = true;
                        break;
                case -ENOANO:
                        need_pin = true;
                        break;
                case -EOWNERDEAD:
                        pin_locked = true;
                        break;
                case -ENOLCK:
                        pin_incorrect = true;
                        break;
                case -EMEDIUMTYPE:
                        need_user_presence_permitted = true;
                        break;
                case -ENOCSI:
                        need_user_verification_permitted = true;
                        break;
                case -ENOSTR:
                        token_action_timeout = true;
                        break;
                default:
                        if (r < 0)
                                return r;

                        r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
                        if (r < 0)
                                return log_error_errno(r, "Failed to test FIDO2 password: %m");
                        if (r == 0)
                                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured FIDO2 security token does not decrypt encrypted key correctly.");

                        log_info("Decrypted password from FIDO2 security token unlocks user record.");

                        r = strv_extend(&cache->fido2_passwords, decrypted_password);
                        if (r < 0)
                                return log_oom();

                        return 1;
                }
#else
                need_token = true;
                break;
#endif
        }

        /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
        if (pin_incorrect_one_try_left)
                return -EUCLEAN;
        if (pin_incorrect_few_tries_left)
                return -ETOOMANYREFS;
        if (pin_incorrect)
                return -ENOLCK;
        if (pin_locked)
                return -EOWNERDEAD;
        if (token_action_timeout)
                return -ENOSTR;
        if (need_protected_authentication_path_permitted)
                return -ERFKILL;
        if (need_user_presence_permitted)
                return -EMEDIUMTYPE;
        if (need_user_verification_permitted)
                return -ENOCSI;
        if (need_pin)
                return -ENOANO;
        if (need_token)
                return -EBADSLT;
        if (need_password)
                return -ENOKEY;
        if (need_recovery_key)
                return -EREMOTEIO;

        /* Hmm, this means neither PCKS#11/FIDO2 nor classic hashed passwords or recovery keys were supplied,
         * we cannot authenticate this reasonably */
        if (strict_verify)
                return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED),
                                       "No hashed passwords, no recovery keys and no PKCS#11/FIDO2 tokens defined, cannot authenticate user record, refusing.");

        /* If strict verification is off this means we are possibly in the case where we encountered an
         * unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
         * case, allow the authentication to pass for now, so that the second (or third) authentication level
         * (the ones of the user record in the LUKS header or inside the home directory) will then catch
         * invalid passwords. The second/third authentication always runs in strict verification mode. */
        log_debug("No hashed passwords, not recovery keys and no PKCS#11 tokens defined in record, cannot authenticate user record. "
                  "Deferring to embedded user record.");
        return 0;
}

static void drop_caches_now(void) {
        int r;

        /* Drop file system caches now. See https://docs.kernel.org/admin-guide/sysctl/vm.html
         * for details. We write "2" into /proc/sys/vm/drop_caches to ensure dentries/inodes are flushed, but
         * not more. */

        r = write_string_file("/proc/sys/vm/drop_caches", "2\n", WRITE_STRING_FILE_DISABLE_BUFFER);
        if (r < 0)
                log_warning_errno(r, "Failed to drop caches, ignoring: %m");
        else
                log_debug("Dropped caches.");
}

int home_setup_undo_mount(HomeSetup *setup, int level) {
        int r;

        assert(setup);

        if (!setup->undo_mount)
                return 0;

        r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0);
        if (r < 0) {
                if (level >= LOG_DEBUG) /* umount_recursive() does debug level logging anyway, no need to
                                         * repeat that here */
                        return r;

                /* If a higher log level is requested, the generate a non-debug message here too. */
                return log_full_errno(level, r, "Failed to unmount mount tree below %s: %m", HOME_RUNTIME_WORK_DIR);
        }

        setup->undo_mount = false;
        return 1;
}

int home_setup_undo_dm(HomeSetup *setup, int level) {
        int r, ret;

        assert(setup);

        if (setup->undo_dm) {
                assert(setup->crypt_device);
                assert(setup->dm_name);

                r = sym_crypt_deactivate_by_name(setup->crypt_device, setup->dm_name, 0);
                if (r < 0)
                        return log_full_errno(level, r, "Failed to deactivate LUKS device: %m");

                /* In case the device was already remove asynchronously by an early unmount via the deferred
                 * remove logic, let's wait for it */
                (void) wait_for_block_device_gone(setup, USEC_PER_SEC * 30);

                setup->undo_dm = false;
                ret = 1;
        } else
                ret = 0;

        if (setup->crypt_device) {
                sym_crypt_free(setup->crypt_device);
                setup->crypt_device = NULL;
        }

        return ret;
}

int keyring_unlink(key_serial_t k) {

        if (k == -1) /* already invalidated? */
                return -1;

        if (keyctl(KEYCTL_UNLINK, k, KEY_SPEC_SESSION_KEYRING, 0, 0) < 0)
                log_debug_errno(errno, "Failed to unlink key from session kernel keyring, ignoring: %m");

        return -1; /* Always return the key_serial_t value for "invalid" */
}

static int keyring_flush(UserRecord *h) {
        _cleanup_free_ char *name = NULL;
        long serial;

        assert(h);

        name = strjoin("homework-user-", h->user_name);
        if (!name)
                return log_oom();

        serial = keyctl(KEYCTL_SEARCH, (unsigned long) KEY_SPEC_SESSION_KEYRING, (unsigned long) "user", (unsigned long) name, 0);
        if (serial == -1)
                return log_debug_errno(errno, "Failed to find kernel keyring entry for user, ignoring: %m");

        return keyring_unlink(serial);
}

int home_setup_done(HomeSetup *setup) {
        int r = 0, q;

        assert(setup);

        if (setup->root_fd >= 0) {
                if (setup->do_offline_fitrim) {
                        q = run_fitrim(setup->root_fd);
                        if (q < 0)
                                r = q;
                }

                if (syncfs(setup->root_fd) < 0)
                        log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");

                setup->root_fd = safe_close(setup->root_fd);
        }

        q = home_setup_undo_mount(setup, LOG_DEBUG);
        if (q < 0)
                r = q;

        q = home_setup_undo_dm(setup, LOG_DEBUG);
        if (q < 0)
                r = q;

        if (setup->image_fd >= 0) {
                if (setup->do_offline_fallocate) {
                        q = run_fallocate(setup->image_fd, NULL);
                        if (q < 0)
                                r = q;
                }

                if (setup->do_mark_clean) {
                        q = run_mark_dirty(setup->image_fd, false);
                        if (q < 0)
                                r = q;
                }

                setup->image_fd = safe_close(setup->image_fd);
        }

        if (setup->temporary_image_path) {
                if (unlink(setup->temporary_image_path) < 0)
                        log_debug_errno(errno, "Failed to remove temporary image file '%s', ignoring: %m",
                                        setup->temporary_image_path);

                setup->temporary_image_path = mfree(setup->temporary_image_path);
        }

        setup->key_serial = keyring_unlink(setup->key_serial);

        setup->undo_mount = false;
        setup->undo_dm = false;
        setup->do_offline_fitrim = false;
        setup->do_offline_fallocate = false;
        setup->do_mark_clean = false;

        setup->dm_name = mfree(setup->dm_name);
        setup->dm_node = mfree(setup->dm_node);

        setup->loop = loop_device_unref(setup->loop);

        setup->volume_key = erase_and_free(setup->volume_key);
        setup->volume_key_size = 0;

        if (setup->do_drop_caches)
                drop_caches_now();

        setup->mount_suffix = mfree(setup->mount_suffix);

        return r;
}

int home_setup(
                UserRecord *h,
                HomeSetupFlags flags,
                HomeSetup *setup,
                PasswordCache *cache,
                UserRecord **ret_header_home) {

        int r;

        assert(h);
        assert(setup);
        assert(!setup->loop);
        assert(!setup->crypt_device);
        assert(setup->root_fd < 0);
        assert(!setup->undo_dm);
        assert(!setup->undo_mount);

        /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */

        if (!FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) /* If we set up the directory, we should also drop caches once we are done */
                setup->do_drop_caches = setup->do_drop_caches || user_record_drop_caches(h);

        switch (user_record_storage(h)) {

        case USER_LUKS:
                return home_setup_luks(h, flags, NULL, setup, cache, ret_header_home);

        case USER_SUBVOLUME:
        case USER_DIRECTORY:
                r = home_setup_directory(h, setup);
                break;

        case USER_FSCRYPT:
                r = home_setup_fscrypt(h, setup, cache);
                break;

        case USER_CIFS:
                r = home_setup_cifs(h, flags, setup);
                break;

        default:
                return log_error_errno(SYNTHETIC_ERRNO(ENOLINK), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
        }

        if (r < 0)
                return r;

        if (ret_header_home)
                *ret_header_home = NULL;

        return r;
}

int home_sync_and_statfs(int root_fd, struct statfs *ret) {
        assert(root_fd >= 0);

        /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
         * systems such as btrfs where this is determined lazily). */

        if (syncfs(root_fd) < 0)
                return log_error_errno(errno, "Failed to synchronize file system: %m");

        if (ret)
                if (fstatfs(root_fd, ret) < 0)
                        return log_error_errno(errno, "Failed to statfs() file system: %m");

        log_info("Synchronized disk.");

        return 0;
}

static int read_identity_file(int root_fd, JsonVariant **ret) {
        _cleanup_(fclosep) FILE *identity_file = NULL;
        _cleanup_close_ int identity_fd = -EBADF;
        unsigned line, column;
        int r;

        assert(root_fd >= 0);
        assert(ret);

        identity_fd = openat(root_fd, ".identity", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
        if (identity_fd < 0)
                return log_error_errno(errno, "Failed to open .identity file in home directory: %m");

        r = fd_verify_regular(identity_fd);
        if (r < 0)
                return log_error_errno(r, "Embedded identity file is not a regular file, refusing: %m");

        identity_file = take_fdopen(&identity_fd, "r");
        if (!identity_file)
                return log_oom();

        r = json_parse_file(identity_file, ".identity", JSON_PARSE_SENSITIVE, ret, &line, &column);
        if (r < 0)
                return log_error_errno(r, "[.identity:%u:%u] Failed to parse JSON data: %m", line, column);

        log_info("Read embedded .identity file.");

        return 0;
}

static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) {
        _cleanup_(json_variant_unrefp) JsonVariant *normalized = NULL;
        _cleanup_(fclosep) FILE *identity_file = NULL;
        _cleanup_close_ int identity_fd = -EBADF;
        _cleanup_free_ char *fn = NULL;
        int r;

        assert(root_fd >= 0);
        assert(v);

        normalized = json_variant_ref(v);

        r = json_variant_normalize(&normalized);
        if (r < 0)
                log_warning_errno(r, "Failed to normalize user record, ignoring: %m");

        r = tempfn_random(".identity", NULL, &fn);
        if (r < 0)
                return r;

        identity_fd = openat(root_fd, fn, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
        if (identity_fd < 0)
                return log_error_errno(errno, "Failed to create .identity file in home directory: %m");

        identity_file = take_fdopen(&identity_fd, "w");
        if (!identity_file) {
                r = log_oom();
                goto fail;
        }

        json_variant_dump(normalized, JSON_FORMAT_PRETTY, identity_file, NULL);

        r = fflush_and_check(identity_file);
        if (r < 0) {
                log_error_errno(r, "Failed to write .identity file: %m");
                goto fail;
        }

        if (fchown(fileno(identity_file), uid, uid) < 0) {
                r = log_error_errno(errno, "Failed to change ownership of identity file: %m");
                goto fail;
        }

        if (renameat(root_fd, fn, root_fd, ".identity") < 0) {
                r = log_error_errno(errno, "Failed to move identity file into place: %m");
                goto fail;
        }

        log_info("Wrote embedded .identity file.");

        return 0;

fail:
        (void) unlinkat(root_fd, fn, 0);
        return r;
}

int home_load_embedded_identity(
                UserRecord *h,
                int root_fd,
                UserRecord *header_home,
                UserReconcileMode mode,
                PasswordCache *cache,
                UserRecord **ret_embedded_home,
                UserRecord **ret_new_home) {

        _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *intermediate_home = NULL, *new_home = NULL;
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        int r;

        assert(h);
        assert(root_fd >= 0);

        r = read_identity_file(root_fd, &v);
        if (r < 0)
                return r;

        embedded_home = user_record_new();
        if (!embedded_home)
                return log_oom();

        r = user_record_load(embedded_home, v, USER_RECORD_LOAD_EMBEDDED|USER_RECORD_PERMISSIVE);
        if (r < 0)
                return r;

        if (!user_record_compatible(h, embedded_home))
                return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");

        /* Insist that credentials the user supplies also unlocks any embedded records. */
        r = user_record_authenticate(embedded_home, h, cache, /* strict_verify= */ true);
        if (r < 0)
                return r;
        assert(r > 0); /* Insist that a password was verified */

        /* At this point we have three records to deal with:
         *
         *      · The record we got passed from the host
         *      · The record included in the LUKS header (only if LUKS is used)
         *      · The record in the home directory itself (~.identity)
         *
         *  Now we have to reconcile all three, and let the newest one win. */

        if (header_home) {
                /* Note we relax the requirements here. Instead of insisting that the host record is strictly
                 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
                 * embedded record must be newer, so that we update at least one of the two. */

                r = user_record_reconcile(h, header_home, mode == USER_RECONCILE_REQUIRE_NEWER ? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL : mode, &intermediate_home);
                if (r == -EREMCHG) /* this was supposed to be checked earlier already, but let's check this again */
                        return log_error_errno(r, "Identity stored on host and in header don't match, refusing.");
                if (r == -ESTALE)
                        return log_error_errno(r, "Embedded identity record is newer than supplied record, refusing.");
                if (r < 0)
                        return log_error_errno(r, "Failed to reconcile host and header identities: %m");
                if (r == USER_RECONCILE_EMBEDDED_WON)
                        log_info("Reconciling header user identity completed (header version was newer).");
                else if (r == USER_RECONCILE_HOST_WON) {
                        log_info("Reconciling header user identity completed (host version was newer).");

                        if (mode == USER_RECONCILE_REQUIRE_NEWER) /* Host version is newer than the header
                                                                   * version, hence we'll update
                                                                   * something. This means we can relax the
                                                                   * requirements on the embedded
                                                                   * identity. */
                                mode = USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL;
                } else {
                        assert(r == USER_RECONCILE_IDENTICAL);
                        log_info("Reconciling user identities completed (host and header version were identical).");
                }

                h = intermediate_home;
        }

        r = user_record_reconcile(h, embedded_home, mode, &new_home);
        if (r == -EREMCHG)
                return log_error_errno(r, "Identity stored on host and in home don't match, refusing.");
        if (r == -ESTALE)
                return log_error_errno(r, "Embedded identity record is equally new or newer than supplied record, refusing.");
        if (r < 0)
                return log_error_errno(r, "Failed to reconcile host and embedded identities: %m");
        if (r == USER_RECONCILE_EMBEDDED_WON)
                log_info("Reconciling embedded user identity completed (embedded version was newer).");
        else if (r == USER_RECONCILE_HOST_WON)
                log_info("Reconciling embedded user identity completed (host version was newer).");
        else {
                assert(r == USER_RECONCILE_IDENTICAL);
                log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
        }

        if (ret_embedded_home)
                *ret_embedded_home = TAKE_PTR(embedded_home);

        if (ret_new_home)
                *ret_new_home = TAKE_PTR(new_home);

        return 0;
}

int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserRecord *old_home) {
        _cleanup_(user_record_unrefp) UserRecord *embedded = NULL;
        int r;

        assert(h);
        assert(root_fd >= 0);
        assert(uid_is_valid(uid));

        r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &embedded);
        if (r < 0)
                return log_error_errno(r, "Failed to determine new embedded record: %m");

        if (old_home && user_record_equal(old_home, embedded)) {
                log_debug("Not updating embedded home record.");
                return 0;
        }

        /* The identity has changed, let's update it in the image */
        r = write_identity_file(root_fd, embedded->json, h->uid);
        if (r < 0)
                return r;

        return 1;
}

static const char *file_system_type_fd(int fd) {
        struct statfs sfs;

        assert(fd >= 0);

        if (fstatfs(fd, &sfs) < 0) {
                log_debug_errno(errno, "Failed to statfs(): %m");
                return NULL;
        }

        return fs_type_to_string(sfs.f_type);
}

int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup) {
        int r;

        assert(h);
        assert(used);
        assert(setup);

        r = user_record_add_binding(
                        h,
                        user_record_storage(used),
                        user_record_image_path(used),
                        setup->found_partition_uuid,
                        setup->found_luks_uuid,
                        setup->found_fs_uuid,
                        setup->crypt_device ? sym_crypt_get_cipher(setup->crypt_device) : NULL,
                        setup->crypt_device ? sym_crypt_get_cipher_mode(setup->crypt_device) : NULL,
                        setup->crypt_device ? luks_volume_key_size_convert(setup->crypt_device) : UINT64_MAX,
                        file_system_type_fd(setup->root_fd),
                        user_record_home_directory(used),
                        used->uid,
                        (gid_t) used->uid);
        if (r < 0)
                return log_error_errno(r, "Failed to update binding in record: %m");

        return 0;
}

static int chown_recursive_directory(int root_fd, uid_t uid) {
        int r;

        assert(root_fd >= 0);
        assert(uid_is_valid(uid));

        r = fd_chown_recursive(root_fd, uid, (gid_t) uid, 0777);
        if (r < 0)
                return log_error_errno(r, "Failed to change ownership of files and directories: %m");
        if (r == 0)
                log_info("Recursive changing of ownership not necessary, skipped.");
        else
                log_info("Recursive changing of ownership completed.");

        return 0;
}

int home_maybe_shift_uid(
                UserRecord *h,
                HomeSetupFlags flags,
                HomeSetup *setup) {

        _cleanup_close_ int mount_fd = -EBADF;
        struct stat st;

        assert(h);
        assert(setup);
        assert(setup->root_fd >= 0);

        /* If the home dir is already activated, then the UID shift is already applied. */
        if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED))
                return 0;

        if (fstat(setup->root_fd, &st) < 0)
                return log_error_errno(errno, "Failed to stat() home directory: %m");

        /* Let's shift UIDs of this mount. Hopefully this makes the later chowning unnecessary. (Note that we
         * also prefer to do UID mapping even if the UID already matches our goal UID. That's because we want
         * to leave UIDs in the homed managed range unmapped.) */
        (void) home_shift_uid(setup->root_fd, NULL, st.st_uid, h->uid, &mount_fd);

        /* If this worked, then we'll have a reference to the mount now, which we can also use like an O_PATH
         * fd to the new dir. Let's convert it into a proper O_DIRECTORY fd. */
        if (mount_fd >= 0) {
                safe_close(setup->root_fd);

                setup->root_fd = fd_reopen(mount_fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
                if (setup->root_fd < 0)
                        return log_error_errno(setup->root_fd, "Failed to convert mount fd into regular directory fd: %m");
        }

        return 0;
}

int home_refresh(
                UserRecord *h,
                HomeSetupFlags flags,
                HomeSetup *setup,
                UserRecord *header_home,
                PasswordCache *cache,
                struct statfs *ret_statfs,
                UserRecord **ret_new_home) {

        _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *new_home = NULL;
        int r;

        assert(h);
        assert(setup);
        assert(ret_new_home);

        /* When activating a home directory, does the identity work: loads the identity from the $HOME
         * directory, reconciles it with our idea, chown()s everything. */

        r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_ANY, cache, &embedded_home, &new_home);
        if (r < 0)
                return r;

        r = home_maybe_shift_uid(h, flags, setup);
        if (r < 0)
                return r;

        r = home_store_header_identity_luks(new_home, setup, header_home);
        if (r < 0)
                return r;

        r = home_store_embedded_identity(new_home, setup->root_fd, h->uid, embedded_home);
        if (r < 0)
                return r;

        r = chown_recursive_directory(setup->root_fd, h->uid);
        if (r < 0)
                return r;

        r = home_sync_and_statfs(setup->root_fd, ret_statfs);
        if (r < 0)
                return r;

        *ret_new_home = TAKE_PTR(new_home);
        return 0;
}

static int home_activate(UserRecord *h, UserRecord **ret_home) {
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        HomeSetupFlags flags = 0;
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
        if (!uid_is_valid(h->uid))
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
        if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
        if (r < 0)
                return r;

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;
        if (r == USER_TEST_MOUNTED)
                return log_error_errno(SYNTHETIC_ERRNO(EALREADY), "Home directory %s is already mounted, refusing.", user_record_home_directory(h));

        r = user_record_test_image_path_and_warn(h);
        if (r < 0)
                return r;
        if (r == USER_TEST_ABSENT)
                return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s is missing, refusing.", user_record_image_path(h));

        switch (user_record_storage(h)) {

        case USER_LUKS:
                r = home_activate_luks(h, flags, &setup, &cache, &new_home);
                if (r < 0)
                        return r;

                break;

        case USER_SUBVOLUME:
        case USER_DIRECTORY:
        case USER_FSCRYPT:
                r = home_activate_directory(h, flags, &setup, &cache, &new_home);
                if (r < 0)
                        return r;

                break;

        case USER_CIFS:
                r = home_activate_cifs(h, flags, &setup, &cache, &new_home);
                if (r < 0)
                        return r;

                break;

        default:
                assert_not_reached();
        }

        /* Note that the returned object might either be a reference to an updated version of the existing
         * home object, or a reference to a newly allocated home object. The caller has to be able to deal
         * with both, and consider the old object out-of-date. */
        if (user_record_equal(h, new_home)) {
                *ret_home = NULL;
                return 0; /* no identity change */
        }

        *ret_home = TAKE_PTR(new_home);
        return 1; /* identity updated */
}

static int home_deactivate(UserRecord *h, bool force) {
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        bool done = false;
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
        if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;
        if (r == USER_TEST_MOUNTED) {
                /* Before we do anything, let's move the home mount away. */
                r = home_unshare_and_mkdir();
                if (r < 0)
                        return r;

                r = mount_nofollow_verbose(LOG_ERR, user_record_home_directory(h), HOME_RUNTIME_WORK_DIR, NULL, MS_BIND, NULL);
                if (r < 0)
                        return r;

                setup.undo_mount = true; /* remember to unmount the new bind mount from HOME_RUNTIME_WORK_DIR */

                /* Let's explicitly open the new root fs, using the moved path */
                setup.root_fd = open(HOME_RUNTIME_WORK_DIR, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
                if (setup.root_fd < 0)
                        return log_error_errno(errno, "Failed to open moved home directory: %m");

                /* Now get rid of the home at its original place (we only keep the bind mount we created above) */
                r = umount_verbose(LOG_ERR, user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
                if (r < 0)
                        return r;

                if (user_record_storage(h) == USER_LUKS) {
                        /* Automatically shrink on logout if that's enabled. To be able to shrink we need the
                         * keys to the device. */
                        password_cache_load_keyring(h, &cache);
                        (void) home_trim_luks(h, &setup);
                }

                /* Sync explicitly, so that the drop caches logic below can work as documented */
                if (syncfs(setup.root_fd) < 0)
                        log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");
                else
                        log_info("Syncing completed.");

                if (user_record_storage(h) == USER_LUKS)
                        (void) home_auto_shrink_luks(h, &setup, &cache);

                setup.root_fd = safe_close(setup.root_fd);

                /* Now get rid of the bind mount, too */
                r = umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
                if (r < 0)
                        return r;

                setup.undo_mount = false; /* Remember that the bind mount doesn't need to be unmounted anymore */

                if (user_record_drop_caches(h))
                        setup.do_drop_caches = true;

                log_info("Unmounting completed.");
                done = true;
        } else
                log_info("Directory %s is already unmounted.", user_record_home_directory(h));

        if (user_record_storage(h) == USER_LUKS) {
                r = home_deactivate_luks(h, &setup);
                if (r < 0)
                        return r;
                if (r > 0)
                        done = true;
        }

        /* Explicitly flush any per-user key from the keyring */
        (void) keyring_flush(h);

        if (!done)
                return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home is not active.");

        if (setup.do_drop_caches) {
                setup.do_drop_caches = false;
                drop_caches_now();
        }

        log_info("Everything completed.");
        return 0;
}

static int copy_skel(int root_fd, const char *skel) {
        int r;

        assert(root_fd >= 0);

        r = copy_tree_at(AT_FDCWD, skel, root_fd, ".", UID_INVALID, GID_INVALID, COPY_MERGE|COPY_REPLACE, NULL);
        if (r == -ENOENT) {
                log_info("Skeleton directory %s missing, ignoring.", skel);
                return 0;
        }
        if (r < 0)
                return log_error_errno(r, "Failed to copy in %s: %m", skel);

        log_info("Copying in %s completed.", skel);
        return 0;
}

static int change_access_mode(int root_fd, mode_t m) {
        assert(root_fd >= 0);

        if (fchmod(root_fd, m) < 0)
                return log_error_errno(errno, "Failed to change access mode of top-level directory: %m");

        log_info("Changed top-level directory access mode to 0%o.", m);
        return 0;
}

int home_populate(UserRecord *h, int dir_fd) {
        int r;

        assert(h);
        assert(dir_fd >= 0);

        r = copy_skel(dir_fd, user_record_skeleton_directory(h));
        if (r < 0)
                return r;

        r = home_store_embedded_identity(h, dir_fd, h->uid, NULL);
        if (r < 0)
                return r;

        r = chown_recursive_directory(dir_fd, h->uid);
        if (r < 0)
                return r;

        r = change_access_mode(dir_fd, user_record_access_mode(h));
        if (r < 0)
                return r;

        return 0;
}

static int user_record_compile_effective_passwords(
                UserRecord *h,
                PasswordCache *cache,
                char ***ret_effective_passwords) {

        _cleanup_(strv_free_erasep) char **effective = NULL;
        size_t n;
        int r;

        assert(h);
        assert(cache);

        /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
         * a safe fallback, but also to simplify the password changing algorithm: there we require providing
         * the old literal password only (and do not care for the old PKCS#11 token) */

        if (strv_isempty(h->hashed_password))
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                       "User record has no hashed passwords, refusing.");

        /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
         * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
         * couldn't sync fscrypt/LUKS to the login account properly. */

        STRV_FOREACH(i, h->hashed_password) {
                bool found = false;

                log_debug("Looking for plaintext password for: %s", *i);

                /* Let's scan all provided plaintext passwords */
                STRV_FOREACH(j, h->password) {
                        r = test_password_one(*i, *j);
                        if (r < 0)
                                return log_error_errno(r, "Failed to test plaintext password: %m");
                        if (r > 0) {
                                if (ret_effective_passwords) {
                                        r = strv_extend(&effective, *j);
                                        if (r < 0)
                                                return log_oom();
                                }

                                log_debug("Found literal plaintext password.");
                                found = true;
                                break;
                        }
                }

                if (!found)
                        return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Missing plaintext password for defined hashed password");
        }

        for (n = 0; n < h->n_recovery_key; n++) {
                bool found = false;

                log_debug("Looking for plaintext recovery key for: %s", h->recovery_key[n].hashed_password);

                STRV_FOREACH(j, h->password) {
                        _cleanup_(erase_and_freep) char *mangled = NULL;
                        const char *p;

                        if (streq(h->recovery_key[n].type, "modhex64")) {

                                r = normalize_recovery_key(*j, &mangled);
                                if (r == -EINVAL) /* Not properly formatted, probably a regular password. */
                                        continue;
                                if (r < 0)
                                        return log_error_errno(r, "Failed to normalize recovery key: %m");

                                p = mangled;
                        } else
                                p = *j;

                        r = test_password_one(h->recovery_key[n].hashed_password, p);
                        if (r < 0)
                                return log_error_errno(r, "Failed to test plaintext recovery key: %m");
                        if (r > 0) {
                                if (ret_effective_passwords) {
                                        r = strv_extend(&effective, p);
                                        if (r < 0)
                                                return log_oom();
                                }

                                log_debug("Found plaintext recovery key.");
                                found = true;
                                break;
                        }
                }

                if (!found)
                        return log_error_errno(SYNTHETIC_ERRNO(EREMOTEIO), "Missing plaintext recovery key for defined recovery key");
        }

        for (n = 0; n < h->n_pkcs11_encrypted_key; n++) {
#if HAVE_P11KIT
                _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
                        .user_record = h,
                        .secret = h,
                        .encrypted_key = h->pkcs11_encrypted_key + n,
                };

                r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
                if (r == -EAGAIN)
                        return -EBADSLT;
                if (r < 0)
                        return r;

                r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
                if (r < 0)
                        return log_error_errno(r, "Failed to test PKCS#11 password: %m");
                if (r == 0)
                        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");

                if (ret_effective_passwords) {
                        r = strv_extend(&effective, data.decrypted_password);
                        if (r < 0)
                                return log_oom();
                }

                r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
                if (r < 0)
                        return log_oom();
#else
                return -EBADSLT;
#endif
        }

        for (n = 0; n < h->n_fido2_hmac_salt; n++) {
#if HAVE_LIBFIDO2
                _cleanup_(erase_and_freep) char *decrypted_password = NULL;

                r = fido2_use_token(h, h, h->fido2_hmac_salt + n, &decrypted_password);
                if (r < 0)
                        return r;

                r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
                if (r < 0)
                        return log_error_errno(r, "Failed to test FIDO2 password: %m");
                if (r == 0)
                        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");

                if (ret_effective_passwords) {
                        r = strv_extend(&effective, decrypted_password);
                        if (r < 0)
                                return log_oom();
                }

                r = strv_extend(&cache->fido2_passwords, decrypted_password);
                if (r < 0)
                        return log_oom();
#else
                return -EBADSLT;
#endif
        }

        if (ret_effective_passwords)
                *ret_effective_passwords = TAKE_PTR(effective);

        return 0;
}

static int determine_default_storage(UserStorage *ret) {
        UserStorage storage = _USER_STORAGE_INVALID;
        const char *e;
        int r;

        assert(ret);

        /* homed tells us via an environment variable which default storage to use */
        e = getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
        if (e) {
                storage = user_storage_from_string(e);
                if (storage < 0)
                        log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e);
                else {
                        log_info("Using configured default storage '%s'.", user_storage_to_string(storage));
                        *ret = storage;
                        return 0;
                }
        }

        /* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
         * in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
         * anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
         * "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
         * nothing is specified. */

        r = detect_container();
        if (r < 0)
                return log_error_errno(r, "Failed to determine whether we are in a container: %m");
        if (r == 0) {
                r = path_is_encrypted(get_home_root());
                if (r > 0)
                        log_info("%s is encrypted, not using '%s' storage, in order to avoid double encryption.", get_home_root(), user_storage_to_string(USER_LUKS));
                else {
                        if (r < 0)
                                log_warning_errno(r, "Failed to determine if %s is encrypted, ignoring: %m", get_home_root());

                        r = dlopen_cryptsetup();
                        if (r < 0)
                                log_info("Not using '%s' storage, since libcryptsetup could not be loaded.", user_storage_to_string(USER_LUKS));
                        else {
                                log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
                                *ret = USER_LUKS;
                                return 0;
                        }
                }
        } else
                log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));

        r = path_is_fs_type(get_home_root(), BTRFS_SUPER_MAGIC);
        if (r < 0)
                log_warning_errno(r, "Failed to determine file system of %s, ignoring: %m", get_home_root());
        if (r > 0) {
                log_info("%s is on btrfs, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_SUBVOLUME));
                *ret = USER_SUBVOLUME;
        } else {
                log_info("%s is on simple file system, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_DIRECTORY));
                *ret = USER_DIRECTORY;
        }

        return 0;
}

static int home_create(UserRecord *h, UserRecord **ret_home) {
        _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        UserStorage new_storage = _USER_STORAGE_INVALID;
        const char *new_fs = NULL;
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks name, refusing.");
        if (!uid_is_valid(h->uid))
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");

        r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
        if (r < 0)
                return r;

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;
        if (r != USER_TEST_ABSENT)
                return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Home directory %s already exists, refusing.", user_record_home_directory(h));

        if (h->storage < 0) {
                r = determine_default_storage(&new_storage);
                if (r < 0)
                        return r;
        }

        if ((h->storage == USER_LUKS ||
             (h->storage < 0 && new_storage == USER_LUKS)) &&
            !h->file_system_type)
                new_fs = getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");

        if (new_storage >= 0 || new_fs) {
                r = user_record_add_binding(
                                h,
                                new_storage,
                                NULL,
                                SD_ID128_NULL,
                                SD_ID128_NULL,
                                SD_ID128_NULL,
                                NULL,
                                NULL,
                                UINT64_MAX,
                                new_fs,
                                NULL,
                                UID_INVALID,
                                GID_INVALID);
                if (r < 0)
                        return log_error_errno(r, "Failed to change storage type to LUKS: %m");
        }

        r = user_record_test_image_path_and_warn(h);
        if (r < 0)
                return r;
        if (!IN_SET(r, USER_TEST_ABSENT, USER_TEST_UNDEFINED, USER_TEST_MAYBE))
                return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Image path %s already exists, refusing.", user_record_image_path(h));

        switch (user_record_storage(h)) {

        case USER_LUKS:
                r = home_create_luks(h, &setup, &cache, effective_passwords, &new_home);
                break;

        case USER_DIRECTORY:
        case USER_SUBVOLUME:
                r = home_create_directory_or_subvolume(h, &setup, &new_home);
                break;

        case USER_FSCRYPT:
                r = home_create_fscrypt(h, &setup, effective_passwords, &new_home);
                break;

        case USER_CIFS:
                r = home_create_cifs(h, &setup, &new_home);
                break;

        default:
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY),
                                       "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
        }
        if (r < 0)
                return r;

        if (user_record_equal(h, new_home)) {
                *ret_home = NULL;
                return 0;
        }

        *ret_home = TAKE_PTR(new_home);
        return 1;
}

static int home_remove(UserRecord *h) {
        bool deleted = false;
        const char *ip, *hd;
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
        if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        hd = user_record_home_directory(h);

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;
        if (r == USER_TEST_MOUNTED)
                return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Directory %s is still mounted, refusing.", hd);

        assert(hd);

        r = user_record_test_image_path_and_warn(h);
        if (r < 0)
                return r;

        ip = user_record_image_path(h);

        switch (user_record_storage(h)) {

        case USER_LUKS: {
                struct stat st;

                assert(ip);

                if (stat(ip, &st) < 0) {
                        if (errno != ENOENT)
                                return log_error_errno(errno, "Failed to stat() %s: %m", ip);

                } else {
                        if (S_ISREG(st.st_mode)) {
                                if (unlink(ip) < 0) {
                                        if (errno != ENOENT)
                                                return log_error_errno(errno, "Failed to remove %s: %m", ip);
                                } else {
                                        _cleanup_free_ char *parent = NULL;

                                        deleted = true;

                                        r = path_extract_directory(ip, &parent);
                                        if (r < 0)
                                                log_debug_errno(r, "Failed to determine parent directory of '%s': %m", ip);
                                        else {
                                                r = fsync_path_at(AT_FDCWD, parent);
                                                if (r < 0)
                                                        log_debug_errno(r, "Failed to synchronize disk after deleting '%s', ignoring: %m", ip);
                                        }
                                }

                        } else if (S_ISBLK(st.st_mode))
                                log_info("Not removing file system on block device %s.", ip);
                        else
                                return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Image file %s is neither block device, nor regular, refusing removal.", ip);
                }

                break;
        }

        case USER_SUBVOLUME:
        case USER_DIRECTORY:
        case USER_FSCRYPT:
                assert(ip);

                r = rm_rf(ip, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME|REMOVE_SYNCFS);
                if (r < 0) {
                        if (r != -ENOENT)
                                return log_warning_errno(r, "Failed to remove %s: %m", ip);
                } else
                        deleted = true;

                /* If the image path and the home directory are the same invalidate the home directory, so
                 * that we don't remove it anymore */
                if (path_equal(ip, hd))
                        hd = NULL;

                break;

        case USER_CIFS:
                /* Nothing else to do here: we won't remove remote stuff. */
                log_info("Not removing home directory on remote server.");
                break;

        default:
                assert_not_reached();
        }

        if (hd) {
                if (rmdir(hd) < 0) {
                        if (errno != ENOENT)
                                return log_error_errno(errno, "Failed to remove %s, ignoring: %m", hd);
                } else
                        deleted = true;
        }

        if (deleted) {
                if (user_record_drop_caches(h))
                        drop_caches_now();

                log_info("Everything completed.");
        } else
                return log_notice_errno(SYNTHETIC_ERRNO(EALREADY),
                                        "Nothing to remove.");

        return 0;
}

static int home_validate_update(UserRecord *h, HomeSetup *setup, HomeSetupFlags *flags) {
        bool has_mount = false;
        int r;

        assert(h);
        assert(setup);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
        if (!uid_is_valid(h->uid))
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
        if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;

        has_mount = r == USER_TEST_MOUNTED;

        r = user_record_test_image_path_and_warn(h);
        if (r < 0)
                return r;
        if (r == USER_TEST_ABSENT)
                return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s does not exist", user_record_image_path(h));

        switch (user_record_storage(h)) {

        case USER_DIRECTORY:
        case USER_SUBVOLUME:
        case USER_FSCRYPT:
        case USER_CIFS:
                break;

        case USER_LUKS: {
                r = home_get_state_luks(h, setup);
                if (r < 0)
                        return r;
                if ((r > 0) != has_mount)
                        return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Home mount incompletely set up.");

                break;
        }

        default:
                assert_not_reached();
        }

        if (flags)
                SET_FLAG(*flags, HOME_SETUP_ALREADY_ACTIVATED, has_mount);

        return has_mount; /* return true if the home record is already active */
}

static int home_update(UserRecord *h, UserRecord **ret) {
        _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL, *embedded_home = NULL;
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        HomeSetupFlags flags = 0;
        int r;

        assert(h);
        assert(ret);

        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
        if (r < 0)
                return r;
        assert(r > 0); /* Insist that a password was verified */

        r = home_validate_update(h, &setup, &flags);
        if (r < 0)
                return r;

        r = home_setup(h, flags, &setup, &cache, &header_home);
        if (r < 0)
                return r;

        r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER, &cache, &embedded_home, &new_home);
        if (r < 0)
                return r;

        r = home_maybe_shift_uid(h, flags, &setup);
        if (r < 0)
                return r;

        r = home_store_header_identity_luks(new_home, &setup, header_home);
        if (r < 0)
                return r;

        r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
        if (r < 0)
                return r;

        r = home_extend_embedded_identity(new_home, h, &setup);
        if (r < 0)
                return r;

        r = home_sync_and_statfs(setup.root_fd, NULL);
        if (r < 0)
                return r;

        r = home_setup_done(&setup);
        if (r < 0)
                return r;

        log_info("Everything completed.");

        *ret = TAKE_PTR(new_home);
        return 0;
}

static int home_resize(UserRecord *h, bool automatic, UserRecord **ret) {
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        HomeSetupFlags flags = 0;
        int r;

        assert(h);
        assert(ret);

        if (h->disk_size == UINT64_MAX)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");

        if (automatic)
                /* In automatic mode don't want to ask the user for the password, hence load it from the kernel keyring */
                password_cache_load_keyring(h, &cache);
        else {
                /* In manual mode let's ensure the user is fully authenticated */
                r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
                if (r < 0)
                        return r;
                assert(r > 0); /* Insist that a password was verified */
        }

        r = home_validate_update(h, &setup, &flags);
        if (r < 0)
                return r;

        /* In automatic mode let's skip syncing identities, because we can't validate them, since we can't
         * ask the user for reauthentication */
        if (automatic)
                flags |= HOME_SETUP_RESIZE_DONT_SYNC_IDENTITIES;

        switch (user_record_storage(h)) {

        case USER_LUKS:
                return home_resize_luks(h, flags, &setup, &cache, ret);

        case USER_DIRECTORY:
        case USER_SUBVOLUME:
        case USER_FSCRYPT:
                return home_resize_directory(h, flags, &setup, &cache, ret);

        default:
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
        }
}

static int home_passwd(UserRecord *h, UserRecord **ret_home) {
        _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
        _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        HomeSetupFlags flags = 0;
        int r;

        assert(h);
        assert(ret_home);

        if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Changing password of home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
        if (r < 0)
                return r;

        r = home_validate_update(h, &setup, &flags);
        if (r < 0)
                return r;

        r = home_setup(h, flags, &setup, &cache, &header_home);
        if (r < 0)
                return r;

        r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, &cache, &embedded_home, &new_home);
        if (r < 0)
                return r;

        r = home_maybe_shift_uid(h, flags, &setup);
        if (r < 0)
                return r;

        switch (user_record_storage(h)) {

        case USER_LUKS:
                r = home_passwd_luks(h, flags, &setup, &cache, effective_passwords);
                if (r < 0)
                        return r;
                break;

        case USER_FSCRYPT:
                r = home_passwd_fscrypt(h, &setup, &cache, effective_passwords);
                if (r < 0)
                        return r;
                break;

        default:
                break;
        }

        r = home_store_header_identity_luks(new_home, &setup, header_home);
        if (r < 0)
                return r;

        r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
        if (r < 0)
                return r;

        r = home_extend_embedded_identity(new_home, h, &setup);
        if (r < 0)
                return r;

        r = home_sync_and_statfs(setup.root_fd, NULL);
        if (r < 0)
                return r;

        r = home_setup_done(&setup);
        if (r < 0)
                return r;

        log_info("Everything completed.");

        *ret_home = TAKE_PTR(new_home);
        return 1;
}

static int home_inspect(UserRecord *h, UserRecord **ret_home) {
        _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *new_home = NULL;
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        HomeSetupFlags flags = 0;
        int r;

        assert(h);
        assert(ret_home);

        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
        if (r < 0)
                return r;

        r = home_validate_update(h, &setup, &flags);
        if (r < 0)
                return r;

        r = home_setup(h, flags, &setup, &cache, &header_home);
        if (r < 0)
                return r;

        r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_ANY, &cache, NULL, &new_home);
        if (r < 0)
                return r;

        r = home_extend_embedded_identity(new_home, h, &setup);
        if (r < 0)
                return r;

        r = home_setup_done(&setup);
        if (r < 0)
                return r;

        log_info("Everything completed.");

        *ret_home = TAKE_PTR(new_home);
        return 1;
}

static int home_lock(UserRecord *h) {
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
        if (user_record_storage(h) != USER_LUKS)
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        r = user_record_test_home_directory_and_warn(h);
        if (r < 0)
                return r;
        if (r != USER_TEST_MOUNTED)
                return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home directory of %s is not mounted, can't lock.", h->user_name);

        r = home_lock_luks(h, &setup);
        if (r < 0)
                return r;

        log_info("Everything completed.");
        return 1;
}

static int home_unlock(UserRecord *h) {
        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
        _cleanup_(password_cache_free) PasswordCache cache = {};
        int r;

        assert(h);

        if (!h->user_name)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
        if (user_record_storage(h) != USER_LUKS)
                return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));

        /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
         * that mount until we have resumed the device. */

        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
        if (r < 0)
                return r;

        r = home_unlock_luks(h, &setup, &cache);
        if (r < 0)
                return r;

        log_info("Everything completed.");
        return 1;
}

static int run(int argc, char *argv[]) {
        _cleanup_(user_record_unrefp) UserRecord *home = NULL, *new_home = NULL;
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        _cleanup_(fclosep) FILE *opened_file = NULL;
        unsigned line = 0, column = 0;
        const char *json_path = NULL;
        FILE *json_file;
        usec_t start;
        int r;

        start = now(CLOCK_MONOTONIC);

        log_setup();

        cryptsetup_enable_logging(NULL);

        umask(0022);

        if (argc < 2 || argc > 3)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes one or two arguments.");

        if (argc > 2) {
                json_path = argv[2];

                opened_file = fopen(json_path, "re");
                if (!opened_file)
                        return log_error_errno(errno, "Failed to open %s: %m", json_path);

                json_file = opened_file;
        } else {
                json_path = "<stdin>";
                json_file = stdin;
        }

        r = json_parse_file(json_file, json_path, JSON_PARSE_SENSITIVE, &v, &line, &column);
        if (r < 0)
                return log_error_errno(r, "[%s:%u:%u] Failed to parse JSON data: %m", json_path, line, column);

        home = user_record_new();
        if (!home)
                return log_oom();

        r = user_record_load(home, v, USER_RECORD_LOAD_FULL|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
        if (r < 0)
                return r;

        /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
         *
         * EMSGSIZE        → file systems of this type cannot be shrunk
         * ETXTBSY         → file systems of this type can only be shrunk offline
         * ERANGE          → file system size too small
         * ENOLINK         → system does not support selected storage backend
         * EPROTONOSUPPORT → system does not support selected file system
         * ENOTTY          → operation not support on this storage
         * ESOCKTNOSUPPORT → operation not support on this file system
         * ENOKEY          → password incorrect (or not sufficient, or not supplied)
         * EREMOTEIO       → recovery key incorrect (or not sufficeint, or not supplied — only if no passwords defined)
         * EBADSLT         → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
         * ENOANO          → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
         * ERFKILL         → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
         * EMEDIUMTYPE     → suitable FIDO2 device found, but OK to ask for user presence not given
         * ENOCSI          → suitable FIDO2 device found, but OK to ask for user verification not given
         * ENOSTR          → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
         * EOWNERDEAD      → suitable PKCS#11/FIDO2 device found, but its PIN is locked
         * ENOLCK          → suitable PKCS#11/FIDO2 device found, but PIN incorrect
         * ETOOMANYREFS    → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
         * EUCLEAN         → suitable PKCS#11 device found, but PIN incorrect, and only one try left
         * EBUSY           → file system is currently active
         * ENOEXEC         → file system is currently not active
         * ENOSPC          → not enough disk space for operation
         * EKEYREVOKED     → user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
         * EADDRINUSE      → home image is already used elsewhere (lock taken)
         */

        if (streq(argv[1], "activate"))
                r = home_activate(home, &new_home);
        else if (streq(argv[1], "deactivate"))
                r = home_deactivate(home, false);
        else if (streq(argv[1], "deactivate-force"))
                r = home_deactivate(home, true);
        else if (streq(argv[1], "create"))
                r = home_create(home, &new_home);
        else if (streq(argv[1], "remove"))
                r = home_remove(home);
        else if (streq(argv[1], "update"))
                r = home_update(home, &new_home);
        else if (streq(argv[1], "resize")) /* Resize on user request */
                r = home_resize(home, false, &new_home);
        else if (streq(argv[1], "resize-auto")) /* Automatic resize */
                r = home_resize(home, true, &new_home);
        else if (streq(argv[1], "passwd"))
                r = home_passwd(home, &new_home);
        else if (streq(argv[1], "inspect"))
                r = home_inspect(home, &new_home);
        else if (streq(argv[1], "lock"))
                r = home_lock(home);
        else if (streq(argv[1], "unlock"))
                r = home_unlock(home);
        else
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb '%s'.", argv[1]);
        if (IN_SET(r, -ENOKEY, -EREMOTEIO) && !strv_isempty(home->password) ) { /* There were passwords specified but they were incorrect */
                usec_t end, n, d;

                /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
                 * that it's not clear how long we actually needed for our calculations. */
                n = now(CLOCK_MONOTONIC);
                assert(n >= start);

                d = usec_sub_unsigned(n, start);
                if (d > BAD_PASSWORD_DELAY_USEC)
                        end = start + DIV_ROUND_UP(d, BAD_PASSWORD_DELAY_USEC) * BAD_PASSWORD_DELAY_USEC;
                else
                        end = start + BAD_PASSWORD_DELAY_USEC;

                if (n < end)
                        (void) usleep(usec_sub_unsigned(end, n));
        }
        if (r < 0)
                return r;

        /* We always pass the new record back, regardless if it changed or not. This allows our caller to
         * prepare a fresh record, send to us, and only if it works use it without having to keep a local
         * copy. */
        if (new_home)
                json_variant_dump(new_home->json, JSON_FORMAT_NEWLINE, stdout, NULL);

        return 0;
}

DEFINE_MAIN_FUNCTION(run);
