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

#if HAVE_LINUX_MEMFD_H
#include <linux/memfd.h>
#endif

#include <sys/mman.h>
#include <sys/quota.h>
#include <sys/vfs.h>

#include "blockdev-util.h"
#include "btrfs-util.h"
#include "bus-common-errors.h"
#include "data-fd-util.h"
#include "env-util.h"
#include "errno-list.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
#include "fs-util.h"
#include "glyph-util.h"
#include "home-util.h"
#include "homed-home-bus.h"
#include "homed-home.h"
#include "missing_magic.h"
#include "missing_syscall.h"
#include "mkdir.h"
#include "path-util.h"
#include "process-util.h"
#include "pwquality-util.h"
#include "quota-util.h"
#include "resize-fs.h"
#include "set.h"
#include "signal-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "strv.h"
#include "uid-alloc-range.h"
#include "user-record-pwquality.h"
#include "user-record-sign.h"
#include "user-record-util.h"
#include "user-record.h"
#include "user-util.h"

/* Retry to deactivate home directories again and again every 15s until it works */
#define RETRY_DEACTIVATE_USEC (15U * USEC_PER_SEC)

#define HOME_USERS_MAX 500
#define PENDING_OPERATIONS_MAX 100

assert_cc(HOME_UID_MIN <= HOME_UID_MAX);
assert_cc(HOME_USERS_MAX <= (HOME_UID_MAX - HOME_UID_MIN + 1));

static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord *secret);

DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(operation_hash_ops, void, trivial_hash_func, trivial_compare_func, Operation, operation_unref);

static int suitable_home_record(UserRecord *hr) {
        int r;

        assert(hr);

        if (!hr->user_name)
                return -EUNATCH;

        /* We are a bit more restrictive with what we accept as homed-managed user than what we accept in
         * home records in general. Let's enforce the stricter rule here. */
        if (!suitable_user_name(hr->user_name))
                return -EINVAL;
        if (!uid_is_valid(hr->uid))
                return -EINVAL;

        /* Insist we are outside of the dynamic and system range */
        if (uid_is_system(hr->uid) || gid_is_system(user_record_gid(hr)) ||
            uid_is_dynamic(hr->uid) || gid_is_dynamic(user_record_gid(hr)))
                return -EADDRNOTAVAIL;

        /* Insist that GID and UID match */
        if (user_record_gid(hr) != (gid_t) hr->uid)
                return -EBADSLT;

        /* Similar for the realm */
        if (hr->realm) {
                r = suitable_realm(hr->realm);
                if (r < 0)
                        return r;
                if (r == 0)
                        return -EINVAL;
        }

        return 0;
}

int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret) {
        _cleanup_(home_freep) Home *home = NULL;
        _cleanup_free_ char *nm = NULL, *ns = NULL;
        int r;

        assert(m);
        assert(hr);

        r = suitable_home_record(hr);
        if (r < 0)
                return r;

        if (hashmap_contains(m->homes_by_name, hr->user_name))
                return -EBUSY;

        if (hashmap_contains(m->homes_by_uid, UID_TO_PTR(hr->uid)))
                return -EBUSY;

        if (sysfs && hashmap_contains(m->homes_by_sysfs, sysfs))
                return -EBUSY;

        if (hashmap_size(m->homes_by_name) >= HOME_USERS_MAX)
                return -EUSERS;

        nm = strdup(hr->user_name);
        if (!nm)
                return -ENOMEM;

        if (sysfs) {
                ns = strdup(sysfs);
                if (!ns)
                        return -ENOMEM;
        }

        home = new(Home, 1);
        if (!home)
                return -ENOMEM;

        *home = (Home) {
                .manager = m,
                .user_name = TAKE_PTR(nm),
                .uid = hr->uid,
                .state = _HOME_STATE_INVALID,
                .worker_stdout_fd = -EBADF,
                .sysfs = TAKE_PTR(ns),
                .signed_locally = -1,
                .pin_fd = -EBADF,
                .luks_lock_fd = -EBADF,
        };

        r = hashmap_put(m->homes_by_name, home->user_name, home);
        if (r < 0)
                return r;

        r = hashmap_put(m->homes_by_uid, UID_TO_PTR(home->uid), home);
        if (r < 0)
                return r;

        if (home->sysfs) {
                r = hashmap_put(m->homes_by_sysfs, home->sysfs, home);
                if (r < 0)
                        return r;
        }

        r = user_record_clone(hr, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &home->record);
        if (r < 0)
                return r;

        (void) bus_manager_emit_auto_login_changed(m);
        (void) bus_home_emit_change(home);
        (void) manager_schedule_rebalance(m, /* immediately= */ false);

        if (ret)
                *ret = TAKE_PTR(home);
        else
                TAKE_PTR(home);

        return 0;
}

Home *home_free(Home *h) {

        if (!h)
                return NULL;

        if (h->manager) {
                (void) bus_home_emit_remove(h);
                (void) bus_manager_emit_auto_login_changed(h->manager);

                if (h->user_name)
                        (void) hashmap_remove_value(h->manager->homes_by_name, h->user_name, h);

                if (uid_is_valid(h->uid))
                        (void) hashmap_remove_value(h->manager->homes_by_uid, UID_TO_PTR(h->uid), h);

                if (h->sysfs)
                        (void) hashmap_remove_value(h->manager->homes_by_sysfs, h->sysfs, h);

                if (h->worker_pid > 0)
                        (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);

                if (h->manager->gc_focus == h)
                        h->manager->gc_focus = NULL;

                (void) manager_schedule_rebalance(h->manager, /* immediately= */ false);
        }

        user_record_unref(h->record);
        user_record_unref(h->secret);

        h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);
        safe_close(h->worker_stdout_fd);
        free(h->user_name);
        free(h->sysfs);

        h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);
        h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);

        h->pending_operations = ordered_set_free(h->pending_operations);
        h->pending_event_source = sd_event_source_disable_unref(h->pending_event_source);
        h->deferred_change_event_source = sd_event_source_disable_unref(h->deferred_change_event_source);

        h->current_operation = operation_unref(h->current_operation);

        safe_close(h->pin_fd);
        safe_close(h->luks_lock_fd);

        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);

        return mfree(h);
}

int home_set_record(Home *h, UserRecord *hr) {
        _cleanup_(user_record_unrefp) UserRecord *new_hr = NULL;
        Home *other;
        int r;

        assert(h);
        assert(h->user_name);
        assert(h->record);
        assert(hr);

        if (user_record_equal(h->record, hr))
                return 0;

        r = suitable_home_record(hr);
        if (r < 0)
                return r;

        if (!user_record_compatible(h->record, hr))
                return -EREMCHG;

        if (!FLAGS_SET(hr->mask, USER_RECORD_REGULAR) ||
            FLAGS_SET(hr->mask, USER_RECORD_SECRET))
                return -EINVAL;

        if (FLAGS_SET(h->record->mask, USER_RECORD_STATUS)) {
                _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;

                /* Hmm, the existing record has status fields? If so, copy them over */

                v = json_variant_ref(hr->json);
                r = json_variant_set_field(&v, "status", json_variant_by_key(h->record->json, "status"));
                if (r < 0)
                        return r;

                new_hr = user_record_new();
                if (!new_hr)
                        return -ENOMEM;

                r = user_record_load(new_hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
                if (r < 0)
                        return r;

                hr = new_hr;
        }

        other = hashmap_get(h->manager->homes_by_uid, UID_TO_PTR(hr->uid));
        if (other && other != h)
                return -EBUSY;

        if (h->uid != hr->uid) {
                r = hashmap_remove_and_replace(h->manager->homes_by_uid, UID_TO_PTR(h->uid), UID_TO_PTR(hr->uid), h);
                if (r < 0)
                        return r;
        }

        user_record_unref(h->record);
        h->record = user_record_ref(hr);
        h->uid = h->record->uid;

        /* The updated record might have a different autologin setting, trigger a PropertiesChanged event for it */
        (void) bus_manager_emit_auto_login_changed(h->manager);
        (void) bus_home_emit_change(h);

        return 0;
}

int home_save_record(Home *h) {
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        _cleanup_free_ char *text = NULL;
        const char *fn;
        int r;

        assert(h);

        v = json_variant_ref(h->record->json);
        r = json_variant_normalize(&v);
        if (r < 0)
                log_warning_errno(r, "User record could not be normalized.");

        r = json_variant_format(v, JSON_FORMAT_PRETTY|JSON_FORMAT_NEWLINE, &text);
        if (r < 0)
                return r;

        (void) mkdir("/var/lib/systemd/", 0755);
        (void) mkdir(home_record_dir(), 0700);

        fn = strjoina(home_record_dir(), "/", h->user_name, ".identity");

        r = write_string_file(fn, text, WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0600|WRITE_STRING_FILE_SYNC);
        if (r < 0)
                return r;

        return 0;
}

int home_unlink_record(Home *h) {
        const char *fn;

        assert(h);

        fn = strjoina(home_record_dir(), "/", h->user_name, ".identity");
        if (unlink(fn) < 0 && errno != ENOENT)
                return -errno;

        fn = strjoina("/run/systemd/home/", h->user_name, ".ref");
        if (unlink(fn) < 0 && errno != ENOENT)
                return -errno;

        return 0;
}

static void home_unpin(Home *h) {
        assert(h);

        if (h->pin_fd < 0)
                return;

        h->pin_fd = safe_close(h->pin_fd);
        log_debug("Successfully closed pin fd on home for %s.", h->user_name);
}

static void home_pin(Home *h) {
        const char *path;

        assert(h);

        if (h->pin_fd >= 0) /* Already pinned? */
                return;

        path = user_record_home_directory(h->record);
        if (!path) {
                log_warning("No home directory path to pin for %s, ignoring.", h->user_name);
                return;
        }

        h->pin_fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
        if (h->pin_fd < 0) {
                log_warning_errno(errno, "Couldn't open home directory '%s' for pinning, ignoring: %m", path);
                return;
        }

        log_debug("Successfully pinned home directory '%s'.", path);
}

static void home_update_pin_fd(Home *h, HomeState state) {
        assert(h);

        if (state < 0)
                state = home_get_state(h);

        return HOME_STATE_SHALL_PIN(state) ? home_pin(h) : home_unpin(h);
}

static void home_maybe_close_luks_lock_fd(Home *h, HomeState state) {
        assert(h);

        if (h->luks_lock_fd < 0)
                return;

        if (state < 0)
                state = home_get_state(h);

        /* Keep the lock as long as the home dir is active or has some operation going */
        if (HOME_STATE_IS_EXECUTING_OPERATION(state) || HOME_STATE_IS_ACTIVE(state) || state == HOME_LOCKED)
                return;

        h->luks_lock_fd = safe_close(h->luks_lock_fd);
        log_debug("Successfully closed LUKS backing file lock for %s.", h->user_name);
}

static void home_maybe_stop_retry_deactivate(Home *h, HomeState state) {
        assert(h);

        /* Free the deactivation retry event source if we won't need it anymore. Specifically, we'll free the
         * event source whenever the home directory is already deactivated (and we thus where successful) or
         * if we start executing an operation that indicates that the home directory is going to be used or
         * operated on again. Also, if the home is referenced again stop the timer */

        if (HOME_STATE_MAY_RETRY_DEACTIVATE(state) &&
            !h->ref_event_source_dont_suspend &&
            !h->ref_event_source_please_suspend)
                return;

        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
}

static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error);
static void home_start_retry_deactivate(Home *h);

static int home_on_retry_deactivate(sd_event_source *s, uint64_t usec, void *userdata) {
        Home *h = ASSERT_PTR(userdata);
        HomeState state;

        assert(s);

        /* 15s after the last attempt to deactivate the home directory passed. Let's try it one more time. */

        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);

        state = home_get_state(h);
        if (!HOME_STATE_MAY_RETRY_DEACTIVATE(state))
                return 0;

        if (IN_SET(state, HOME_ACTIVE, HOME_LINGERING)) {
                log_info("Again trying to deactivate home directory.");

                /* If we are not executing any operation, let's start deactivating now. Note that this will
                 * restart our timer again, we are gonna be called again if this doesn't work. */
                (void) home_deactivate_internal(h, /* force= */ false, NULL);
        } else
                /* if we are executing an operation (specifically, area already running a deactivation
                 * operation), then simply reque the timer, so that we retry again. */
                home_start_retry_deactivate(h);

        return 0;
}

static void home_start_retry_deactivate(Home *h) {
        int r;

        assert(h);
        assert(h->manager);

        /* Already allocated? */
        if (h->retry_deactivate_event_source)
                return;

        /* If the home directory is being used now don't start the timer */
        if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
                return;

        r = sd_event_add_time_relative(
                        h->manager->event,
                        &h->retry_deactivate_event_source,
                        CLOCK_MONOTONIC,
                        RETRY_DEACTIVATE_USEC,
                        1*USEC_PER_MINUTE,
                        home_on_retry_deactivate,
                        h);
        if (r < 0)
                return (void) log_warning_errno(r, "Failed to install retry-deactivate event source, ignoring: %m");

        (void) sd_event_source_set_description(h->retry_deactivate_event_source, "retry-deactivate");
}

static void home_set_state(Home *h, HomeState state) {
        HomeState old_state, new_state;

        assert(h);

        old_state = home_get_state(h);
        h->state = state;
        new_state = home_get_state(h); /* Query the new state, since the 'state' variable might be set to -1,
                                        * in which case we synthesize an high-level state on demand */

        log_info("%s: changing state %s %s %s", h->user_name,
                 home_state_to_string(old_state),
                 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
                 home_state_to_string(new_state));

        home_update_pin_fd(h, new_state);
        home_maybe_close_luks_lock_fd(h, new_state);
        home_maybe_stop_retry_deactivate(h, new_state);

        if (HOME_STATE_IS_EXECUTING_OPERATION(old_state) && !HOME_STATE_IS_EXECUTING_OPERATION(new_state)) {
                /* If we just finished executing some operation, process the queue of pending operations. And
                 * enqueue it for GC too. */

                home_schedule_operation(h, NULL, NULL);
                manager_reschedule_rebalance(h->manager);
                manager_enqueue_gc(h->manager, h);
        }
}

static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        _cleanup_close_ int fd = _fd; /* take possession, even on failure */
        _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        unsigned line, column;
        struct stat st;
        int r;

        if (fstat(fd, &st) < 0)
                return log_error_errno(errno, "Failed to stat stdout fd: %m");

        assert(S_ISREG(st.st_mode));

        if (st.st_size == 0) { /* empty record */
                *ret = NULL;
                return 0;
        }

        if (lseek(fd, SEEK_SET, 0) == (off_t) -1)
                return log_error_errno(errno, "Failed to seek to beginning of memfd: %m");

        f = take_fdopen(&fd, "r");
        if (!f)
                return log_error_errno(errno, "Failed to reopen memfd: %m");

        if (DEBUG_LOGGING) {
                _cleanup_free_ char *text = NULL;

                r = read_full_stream(f, &text, NULL);
                if (r < 0)
                        return log_error_errno(r, "Failed to read from client: %m");

                log_debug("Got from worker: %s", text);
                rewind(f);
        }

        r = json_parse_file(f, "stdout", JSON_PARSE_SENSITIVE, &v, &line, &column);
        if (r < 0)
                return log_error_errno(r, "Failed to parse identity at %u:%u: %m", line, column);

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

        r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
        if (r < 0)
                return log_error_errno(r, "Failed to load home record identity: %m");

        *ret = TAKE_PTR(hr);
        return 1;
}

static int home_verify_user_record(Home *h, UserRecord *hr, bool *ret_signed_locally, sd_bus_error *ret_error) {
        int is_signed;

        assert(h);
        assert(hr);
        assert(ret_signed_locally);

        is_signed = manager_verify_user_record(h->manager, hr);
        switch (is_signed) {

        case USER_RECORD_SIGNED_EXCLUSIVE:
                log_info("Home %s is signed exclusively by our key, accepting.", hr->user_name);
                *ret_signed_locally = true;
                return 0;

        case USER_RECORD_SIGNED:
                log_info("Home %s is signed by our key (and others), accepting.", hr->user_name);
                *ret_signed_locally = false;
                return 0;

        case USER_RECORD_FOREIGN:
                log_info("Home %s is signed by foreign key we like, accepting.", hr->user_name);
                *ret_signed_locally = false;
                return 0;

        case USER_RECORD_UNSIGNED:
                sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed at all, refusing.", hr->user_name);
                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Home %s contains user record that is not signed at all, refusing.", hr->user_name);

        case -ENOKEY:
                sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed by any known key, refusing.", hr->user_name);
                return log_error_errno(is_signed, "Home %s contains user record that is not signed by any known key, refusing.", hr->user_name);

        default:
                assert(is_signed < 0);
                return log_error_errno(is_signed, "Failed to verify signature on user record for %s, refusing fixation: %m", hr->user_name);
        }
}

static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
        /* Converts the error numbers the worker process returned into somewhat sensible dbus errors */

        switch (e) {

        case -EMSGSIZE:
                return sd_bus_error_set(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot be shrunk");
        case -ETXTBSY:
                return sd_bus_error_set(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type can only be shrunk offline");
        case -ERANGE:
                return sd_bus_error_set(error, BUS_ERROR_BAD_HOME_SIZE, "File system size too small");
        case -ENOLINK:
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "System does not support selected storage backend");
        case -EPROTONOSUPPORT:
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "System does not support selected file system");
        case -ENOTTY:
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Operation not supported on storage backend");
        case -ESOCKTNOSUPPORT:
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Operation not supported on file system");
        case -ENOKEY:
                return sd_bus_error_setf(error, BUS_ERROR_BAD_PASSWORD, "Password for home %s is incorrect or not sufficient for authentication.", h->user_name);
        case -EBADSLT:
                return sd_bus_error_setf(error, BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN, "Password for home %s is incorrect or not sufficient, and configured security token not found either.", h->user_name);
        case -EREMOTEIO:
                return sd_bus_error_setf(error, BUS_ERROR_BAD_RECOVERY_KEY, "Recovery key for home %s is incorrect or not sufficient for authentication.", h->user_name);
        case -ENOANO:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_PIN_NEEDED, "PIN for security token required.");
        case -ERFKILL:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, "Security token requires protected authentication path.");
        case -EMEDIUMTYPE:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, "Security token requires presence confirmation.");
        case -ENOCSI:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED, "Security token requires user verification.");
        case -ENOSTR:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_ACTION_TIMEOUT, "Token action timeout. (User was supposed to verify presence or similar, by interacting with the token, and didn't do that in time.)");
        case -EOWNERDEAD:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_PIN_LOCKED, "PIN of security token locked.");
        case -ENOLCK:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_BAD_PIN, "Bad PIN of security token.");
        case -ETOOMANYREFS:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT, "Bad PIN of security token, and only a few tries left.");
        case -EUCLEAN:
                return sd_bus_error_set(error, BUS_ERROR_TOKEN_BAD_PIN_ONE_TRY_LEFT, "Bad PIN of security token, and only one try left.");
        case -EBUSY:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
        case -ENOEXEC:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is currently not active", h->user_name);
        case -ENOSPC:
                return sd_bus_error_setf(error, BUS_ERROR_NO_DISK_SPACE, "Not enough disk space for home %s", h->user_name);
        case -EKEYREVOKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_CANT_AUTHENTICATE, "Home %s has no password or other authentication mechanism defined.", h->user_name);
        case -EADDRINUSE:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_IN_USE, "Home %s is currently being used elsewhere.", h->user_name);
        }

        return 0;
}

static void home_count_bad_authentication(Home *h, bool save) {
        int r;

        assert(h);

        r = user_record_bad_authentication(h->record);
        if (r < 0) {
                log_warning_errno(r, "Failed to increase bad authentication counter, ignoring: %m");
                return;
        }

        if (save) {
                r = home_save_record(h);
                if (r < 0)
                        log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
        }
}

static void home_fixate_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(user_record_unrefp) UserRecord *secret = NULL;
        bool signed_locally;
        int r;

        assert(h);
        assert(IN_SET(h->state, HOME_FIXATING, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE));

        secret = TAKE_PTR(h->secret); /* Take possession */

        if (ret < 0) {
                if (ret == -ENOKEY)
                        (void) home_count_bad_authentication(h, false);

                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Fixation failed: %m");
                goto fail;
        }
        if (!hr) {
                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Did not receive user record from worker process, fixation failed.");
                goto fail;
        }

        r = home_verify_user_record(h, hr, &signed_locally, &error);
        if (r < 0)
                goto fail;

        r = home_set_record(h, hr);
        if (r < 0) {
                log_error_errno(r, "Failed to update home record: %m");
                goto fail;
        }

        h->signed_locally = signed_locally;

        /* When we finished fixating (and don't follow-up with activation), let's count this as good authentication */
        if (h->state == HOME_FIXATING) {
                r = user_record_good_authentication(h->record);
                if (r < 0)
                        log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
        }

        r = home_save_record(h);
        if (r < 0)
                log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");

        if (IN_SET(h->state, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE)) {

                r = home_start_work(h, "activate", h->record, secret);
                if (r < 0) {
                        h->current_operation = operation_result_unref(h->current_operation, r, NULL);
                        home_set_state(h, _HOME_STATE_INVALID);
                } else
                        home_set_state(h, h->state == HOME_FIXATING_FOR_ACTIVATION ? HOME_ACTIVATING : HOME_ACTIVATING_FOR_ACQUIRE);

                return;
        }

        log_debug("Fixation of %s completed.", h->user_name);

        h->current_operation = operation_result_unref(h->current_operation, 0, NULL);

        /* Reset the state to "invalid", which makes home_get_state() test if the image exists and returns
         * HOME_ABSENT vs. HOME_INACTIVE as necessary. */
        home_set_state(h, _HOME_STATE_INVALID);
        (void) manager_schedule_rebalance(h->manager, /* immediately= */ false);
        return;

fail:
        /* If fixation fails, we stay in unfixated state! */
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, HOME_UNFIXATED);
}

static void home_activate_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(IN_SET(h->state, HOME_ACTIVATING, HOME_ACTIVATING_FOR_ACQUIRE));

        if (ret < 0) {
                if (ret == -ENOKEY)
                        home_count_bad_authentication(h, true);

                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Activation failed: %m");
                goto finish;
        }

        if (hr) {
                bool signed_locally;

                r = home_verify_user_record(h, hr, &signed_locally, &error);
                if (r < 0)
                        goto finish;

                r = home_set_record(h, hr);
                if (r < 0) {
                        log_error_errno(r, "Failed to update home record, ignoring: %m");
                        goto finish;
                }

                h->signed_locally = signed_locally;

                r = user_record_good_authentication(h->record);
                if (r < 0)
                        log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");

                r = home_save_record(h);
                if (r < 0)
                        log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
        }

        log_debug("Activation of %s completed.", h->user_name);
        r = 0;

finish:
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);

        if (r >= 0)
                (void) manager_schedule_rebalance(h->manager, /* immediately= */ true);
}

static void home_deactivate_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(h->state == HOME_DEACTIVATING);
        assert(!hr); /* We don't expect a record on this operation */

        if (ret < 0) {
                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Deactivation of %s failed: %m", h->user_name);
                goto finish;
        }

        log_debug("Deactivation of %s completed.", h->user_name);
        r = 0;

finish:
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);

        if (r >= 0)
                (void) manager_schedule_rebalance(h->manager, /* immediately= */ true);
}

static void home_remove_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        Manager *m;
        int r;

        assert(h);
        assert(h->state == HOME_REMOVING);
        assert(!hr); /* We don't expect a record on this operation */

        m = h->manager;

        if (ret < 0 && ret != -EALREADY) {
                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Removing %s failed: %m", h->user_name);
                goto fail;
        }

        /* For a couple of storage types we can't delete the actual data storage when called (such as LUKS on
         * partitions like USB sticks, or so). Sometimes these storage locations are among those we normally
         * automatically discover in /home or in udev. When such a home is deleted let's hence issue a rescan
         * after completion, so that "unfixated" entries are rediscovered.  */
        if (!IN_SET(user_record_test_image_path(h->record), USER_TEST_UNDEFINED, USER_TEST_ABSENT))
                manager_enqueue_rescan(m);

        /* The image is now removed from disk. Now also remove our stored record */
        r = home_unlink_record(h);
        if (r < 0) {
                log_error_errno(r, "Removing record file failed: %m");
                goto fail;
        }

        log_debug("Removal of %s completed.", h->user_name);
        h->current_operation = operation_result_unref(h->current_operation, 0, NULL);

        /* Unload this record from memory too now. */
        h = home_free(h);

        (void) manager_schedule_rebalance(m, /* immediately= */ true);
        return;

fail:
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);
}

static void home_create_finish(Home *h, int ret, UserRecord *hr) {
        int r;

        assert(h);
        assert(h->state == HOME_CREATING);

        if (ret < 0) {
                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;

                (void) convert_worker_errno(h, ret, &error);
                log_error_errno(ret, "Operation on %s failed: %m", h->user_name);
                h->current_operation = operation_result_unref(h->current_operation, ret, &error);

                if (h->unregister_on_failure) {
                        (void) home_unlink_record(h);
                        h = home_free(h);
                        return;
                }

                home_set_state(h, _HOME_STATE_INVALID);
                return;
        }

        if (hr) {
                r = home_set_record(h, hr);
                if (r < 0)
                        log_warning_errno(r, "Failed to update home record, ignoring: %m");
        }

        r = home_save_record(h);
        if (r < 0)
                log_warning_errno(r, "Failed to save record to disk, ignoring: %m");

        log_debug("Creation of %s completed.", h->user_name);

        h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
        home_set_state(h, _HOME_STATE_INVALID);

        (void) manager_schedule_rebalance(h->manager, /* immediately= */ true);
}

static void home_change_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);

        if (ret < 0) {
                if (ret == -ENOKEY)
                        (void) home_count_bad_authentication(h, true);

                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Change operation failed: %m");
                goto finish;
        }

        if (hr) {
                r = home_set_record(h, hr);
                if (r < 0)
                        log_warning_errno(r, "Failed to update home record, ignoring: %m");
                else {
                        r = user_record_good_authentication(h->record);
                        if (r < 0)
                                log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");

                        r = home_save_record(h);
                        if (r < 0)
                                log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
                }
        }

        log_debug("Change operation of %s completed.", h->user_name);
        (void) manager_schedule_rebalance(h->manager, /* immediately= */ false);
        r = 0;

finish:
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);
}

static void home_locking_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(h->state == HOME_LOCKING);

        if (ret < 0) {
                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Locking operation failed: %m");
                goto finish;
        }

        log_debug("Locking operation of %s completed.", h->user_name);
        h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
        home_set_state(h, HOME_LOCKED);
        return;

finish:
        /* If a specific home doesn't know the concept of locking, then that's totally OK, don't propagate
         * the error if we are executing a LockAllHomes() operation. */

        if (h->current_operation->type == OPERATION_LOCK_ALL && r == -ENOTTY)
                h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
        else
                h->current_operation = operation_result_unref(h->current_operation, r, &error);

        home_set_state(h, _HOME_STATE_INVALID);
}

static void home_unlocking_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(IN_SET(h->state, HOME_UNLOCKING, HOME_UNLOCKING_FOR_ACQUIRE));

        if (ret < 0) {
                if (ret == -ENOKEY)
                        (void) home_count_bad_authentication(h, true);

                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Unlocking operation failed: %m");

                /* Revert to locked state */
                home_set_state(h, HOME_LOCKED);
                h->current_operation = operation_result_unref(h->current_operation, r, &error);
                return;
        }

        r = user_record_good_authentication(h->record);
        if (r < 0)
                log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
        else {
                r = home_save_record(h);
                if (r < 0)
                        log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
        }

        log_debug("Unlocking operation of %s completed.", h->user_name);

        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);
        return;
}

static void home_authenticating_finish(Home *h, int ret, UserRecord *hr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(IN_SET(h->state, HOME_AUTHENTICATING, HOME_AUTHENTICATING_WHILE_ACTIVE, HOME_AUTHENTICATING_FOR_ACQUIRE));

        if (ret < 0) {
                if (ret == -ENOKEY)
                        (void) home_count_bad_authentication(h, true);

                (void) convert_worker_errno(h, ret, &error);
                r = log_error_errno(ret, "Authentication failed: %m");
                goto finish;
        }

        if (hr) {
                r = home_set_record(h, hr);
                if (r < 0)
                        log_warning_errno(r, "Failed to update home record, ignoring: %m");
                else {
                        r = user_record_good_authentication(h->record);
                        if (r < 0)
                                log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");

                        r = home_save_record(h);
                        if (r < 0)
                                log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
                }
        }

        log_debug("Authentication of %s completed.", h->user_name);
        r = 0;

finish:
        h->current_operation = operation_result_unref(h->current_operation, r, &error);
        home_set_state(h, _HOME_STATE_INVALID);
}

static int home_on_worker_process(sd_event_source *s, const siginfo_t *si, void *userdata) {
        _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
        Home *h = ASSERT_PTR(userdata);
        int ret;

        assert(s);
        assert(si);

        assert(h->worker_pid == si->si_pid);
        assert(h->worker_event_source);
        assert(h->worker_stdout_fd >= 0);

        (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);

        h->worker_pid = 0;
        h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);

        if (si->si_code != CLD_EXITED) {
                assert(IN_SET(si->si_code, CLD_KILLED, CLD_DUMPED));
                ret = log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Worker process died abnormally with signal %s.", signal_to_string(si->si_status));
        } else if (si->si_status != EXIT_SUCCESS) {
                /* If we received an error code via sd_notify(), use it */
                if (h->worker_error_code != 0)
                        ret = log_debug_errno(h->worker_error_code, "Worker reported error code %s.", errno_to_name(h->worker_error_code));
                else
                        ret = log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Worker exited with exit code %i.", si->si_status);
        } else
                ret = home_parse_worker_stdout(TAKE_FD(h->worker_stdout_fd), &hr);

        h->worker_stdout_fd = safe_close(h->worker_stdout_fd);

        switch (h->state) {

        case HOME_FIXATING:
        case HOME_FIXATING_FOR_ACTIVATION:
        case HOME_FIXATING_FOR_ACQUIRE:
                home_fixate_finish(h, ret, hr);
                break;

        case HOME_ACTIVATING:
        case HOME_ACTIVATING_FOR_ACQUIRE:
                home_activate_finish(h, ret, hr);
                break;

        case HOME_DEACTIVATING:
                home_deactivate_finish(h, ret, hr);
                break;

        case HOME_LOCKING:
                home_locking_finish(h, ret, hr);
                break;

        case HOME_UNLOCKING:
        case HOME_UNLOCKING_FOR_ACQUIRE:
                home_unlocking_finish(h, ret, hr);
                break;

        case HOME_CREATING:
                home_create_finish(h, ret, hr);
                break;

        case HOME_REMOVING:
                home_remove_finish(h, ret, hr);
                break;

        case HOME_UPDATING:
        case HOME_UPDATING_WHILE_ACTIVE:
        case HOME_RESIZING:
        case HOME_RESIZING_WHILE_ACTIVE:
        case HOME_PASSWD:
        case HOME_PASSWD_WHILE_ACTIVE:
                home_change_finish(h, ret, hr);
                break;

        case HOME_AUTHENTICATING:
        case HOME_AUTHENTICATING_WHILE_ACTIVE:
        case HOME_AUTHENTICATING_FOR_ACQUIRE:
                home_authenticating_finish(h, ret, hr);
                break;

        default:
                assert_not_reached();
        }

        return 0;
}

static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord *secret) {
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        _cleanup_(erase_and_freep) char *formatted = NULL;
        _cleanup_close_ int stdin_fd = -EBADF, stdout_fd = -EBADF;
        pid_t pid = 0;
        int r;

        assert(h);
        assert(verb);
        assert(hr);

        if (h->worker_pid != 0)
                return -EBUSY;

        assert(h->worker_stdout_fd < 0);
        assert(!h->worker_event_source);

        v = json_variant_ref(hr->json);

        if (secret) {
                JsonVariant *sub = NULL;

                sub = json_variant_by_key(secret->json, "secret");
                if (!sub)
                        return -ENOKEY;

                r = json_variant_set_field(&v, "secret", sub);
                if (r < 0)
                        return r;
        }

        r = json_variant_format(v, 0, &formatted);
        if (r < 0)
                return r;

        stdin_fd = acquire_data_fd(formatted, strlen(formatted), 0);
        if (stdin_fd < 0)
                return stdin_fd;

        log_debug("Sending to worker: %s", formatted);

        stdout_fd = memfd_create("homework-stdout", MFD_CLOEXEC);
        if (stdout_fd < 0)
                return -errno;

        r = safe_fork_full("(sd-homework)",
                           (int[]) { stdin_fd, stdout_fd }, 2,
                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &pid);
        if (r < 0)
                return r;
        if (r == 0) {
                _cleanup_free_ char *joined = NULL;
                const char *homework, *suffix, *unix_path;

                /* Child */

                suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
                if (suffix) {
                        joined = strjoin("/run/systemd/home/notify.", suffix);
                        if (!joined)
                                return log_oom();
                        unix_path = joined;
                } else
                        unix_path = "/run/systemd/home/notify";

                if (setenv("NOTIFY_SOCKET", unix_path, 1) < 0) {
                        log_error_errno(errno, "Failed to set $NOTIFY_SOCKET: %m");
                        _exit(EXIT_FAILURE);
                }

                /* If we haven't locked the device yet, ask for a lock to be taken and be passed back to us via sd_notify(). */
                if (setenv("SYSTEMD_LUKS_LOCK", one_zero(h->luks_lock_fd < 0), 1) < 0) {
                        log_error_errno(errno, "Failed to set $SYSTEMD_LUKS_LOCK: %m");
                        _exit(EXIT_FAILURE);
                }

                if (h->manager->default_storage >= 0)
                        if (setenv("SYSTEMD_HOME_DEFAULT_STORAGE", user_storage_to_string(h->manager->default_storage), 1) < 0) {
                                log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_STORAGE: %m");
                                _exit(EXIT_FAILURE);
                        }

                if (h->manager->default_file_system_type)
                        if (setenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE", h->manager->default_file_system_type, 1) < 0) {
                                log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE: %m");
                                _exit(EXIT_FAILURE);
                        }

                r = setenv_systemd_exec_pid(true);
                if (r < 0)
                        log_warning_errno(r, "Failed to update $SYSTEMD_EXEC_PID, ignoring: %m");

                r = rearrange_stdio(TAKE_FD(stdin_fd), TAKE_FD(stdout_fd), STDERR_FILENO); /* fds are invalidated by rearrange_stdio() even on failure */
                if (r < 0) {
                        log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m");
                        _exit(EXIT_FAILURE);
                }


                /* Allow overriding the homework path via an environment variable, to make debugging
                 * easier. */
                homework = getenv("SYSTEMD_HOMEWORK_PATH") ?: SYSTEMD_HOMEWORK_PATH;

                execl(homework, homework, verb, NULL);
                log_error_errno(errno, "Failed to invoke %s: %m", homework);
                _exit(EXIT_FAILURE);
        }

        r = sd_event_add_child(h->manager->event, &h->worker_event_source, pid, WEXITED, home_on_worker_process, h);
        if (r < 0)
                return r;

        (void) sd_event_source_set_description(h->worker_event_source, "worker");

        r = hashmap_put(h->manager->homes_by_worker_pid, PID_TO_PTR(pid), h);
        if (r < 0) {
                h->worker_event_source = sd_event_source_disable_unref(h->worker_event_source);
                return r;
        }

        h->worker_stdout_fd = TAKE_FD(stdout_fd);
        h->worker_pid = pid;
        h->worker_error_code = 0;

        return 0;
}

static int home_ratelimit(Home *h, sd_bus_error *error) {
        int r, ret;

        assert(h);

        ret = user_record_ratelimit(h->record);
        if (ret < 0)
                return ret;

        if (h->state != HOME_UNFIXATED) {
                r = home_save_record(h);
                if (r < 0)
                        log_warning_errno(r, "Failed to save updated record, ignoring: %m");
        }

        if (ret == 0) {
                usec_t t, n;

                n = now(CLOCK_REALTIME);
                t = user_record_ratelimit_next_try(h->record);

                if (t != USEC_INFINITY && t > n)
                        return sd_bus_error_setf(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT,
                                                 "Too many login attempts, please try again in %s!",
                                                 FORMAT_TIMESPAN(t - n, USEC_PER_SEC));

                return sd_bus_error_set(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT, "Too many login attempts, please try again later.");
        }

        return 0;
}

static int home_fixate_internal(
                Home *h,
                UserRecord *secret,
                HomeState for_state,
                sd_bus_error *error) {

        int r;

        assert(h);
        assert(IN_SET(for_state, HOME_FIXATING, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE));

        r = home_start_work(h, "inspect", h->record, secret);
        if (r < 0)
                return r;

        if (IN_SET(for_state, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE)) {
                /* Remember the secret data, since we need it for the activation again, later on. */
                user_record_unref(h->secret);
                h->secret = user_record_ref(secret);
        }

        home_set_state(h, for_state);
        return 0;
}

int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error) {
        int r;

        assert(h);

        switch (home_get_state(h)) {
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_INACTIVE:
        case HOME_DIRTY:
        case HOME_ACTIVE:
        case HOME_LINGERING:
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_FIXATED, "Home %s is already fixated.", h->user_name);
        case HOME_UNFIXATED:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        return home_fixate_internal(h, secret, HOME_FIXATING, error);
}

static int home_activate_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
        int r;

        assert(h);
        assert(IN_SET(for_state, HOME_ACTIVATING, HOME_ACTIVATING_FOR_ACQUIRE));

        r = home_start_work(h, "activate", h->record, secret);
        if (r < 0)
                return r;

        home_set_state(h, for_state);
        return 0;
}

int home_activate(Home *h, UserRecord *secret, sd_bus_error *error) {
        int r;

        assert(h);

        switch (home_get_state(h)) {
        case HOME_UNFIXATED:
                return home_fixate_internal(h, secret, HOME_FIXATING_FOR_ACTIVATION, error);
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_ACTIVE:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_ACTIVE, "Home %s is already active.", h->user_name);
        case HOME_LINGERING:
                /* If we are lingering, i.e. active but are supposed to be deactivated, then cancel this
                 * timer if the user explicitly asks us to be active */
                h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
                return 0;
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_INACTIVE:
        case HOME_DIRTY:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        return home_activate_internal(h, secret, HOME_ACTIVATING, error);
}

static int home_authenticate_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
        int r;

        assert(h);
        assert(IN_SET(for_state, HOME_AUTHENTICATING, HOME_AUTHENTICATING_WHILE_ACTIVE, HOME_AUTHENTICATING_FOR_ACQUIRE));

        r = home_start_work(h, "inspect", h->record, secret);
        if (r < 0)
                return r;

        home_set_state(h, for_state);
        return 0;
}

int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error) {
        HomeState state;
        int r;

        assert(h);

        state = home_get_state(h);
        switch (state) {
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_UNFIXATED:
        case HOME_INACTIVE:
        case HOME_DIRTY:
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        return home_authenticate_internal(h, secret, HOME_STATE_IS_ACTIVE(state) ? HOME_AUTHENTICATING_WHILE_ACTIVE : HOME_AUTHENTICATING, error);
}

static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error) {
        int r;

        assert(h);

        home_unpin(h); /* unpin so that we can deactivate */

        r = home_start_work(h, force ? "deactivate-force" : "deactivate", h->record, NULL);
        if (r < 0)
                /* Operation failed before it even started, reacquire pin fd, if state still dictates so */
                home_update_pin_fd(h, _HOME_STATE_INVALID);
        else {
                home_set_state(h, HOME_DEACTIVATING);
                r = 0;
        }

        /* Let's start a timer to retry deactivation in 15. We'll stop the timer once we manage to deactivate
         * the home directory again, or we start any other operation. */
        home_start_retry_deactivate(h);

        return r;
}

int home_deactivate(Home *h, bool force, sd_bus_error *error) {
        assert(h);

        switch (home_get_state(h)) {
        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        return home_deactivate_internal(h, force, error);
}

int home_create(Home *h, UserRecord *secret, sd_bus_error *error) {
        int r;

        assert(h);

        switch (home_get_state(h)) {
        case HOME_INACTIVE: {
                int t;

                if (h->record->storage < 0)
                        break; /* if no storage is defined we don't know what precisely to look for, hence
                                * HOME_INACTIVE is OK in that case too. */

                t = user_record_test_image_path(h->record);
                if (IN_SET(t, USER_TEST_MAYBE, USER_TEST_UNDEFINED))
                        break; /* And if the image path test isn't conclusive, let's also go on */

                if (IN_SET(t, -EBADF, -ENOTDIR))
                        return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists or has wrong inode type.", h->user_name);

                return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists.", h->user_name);
        }
        case HOME_UNFIXATED:
        case HOME_DIRTY:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name);
        case HOME_ABSENT:
                break;
        case HOME_ACTIVE:
        case HOME_LINGERING:
        case HOME_LOCKED:
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
        }

        if (h->record->enforce_password_policy == false)
                log_debug("Password quality check turned off for account, skipping.");
        else {
                r = user_record_quality_check_password(h->record, secret, error);
                if (r < 0)
                        return r;
        }

        r = home_start_work(h, "create", h->record, secret);
        if (r < 0)
                return r;

        home_set_state(h, HOME_CREATING);
        return 0;
}

int home_remove(Home *h, sd_bus_error *error) {
        HomeState state;
        int r;

        assert(h);

        state = home_get_state(h);
        switch (state) {
        case HOME_ABSENT: /* If the home directory is absent, then this is just like unregistering */
                return home_unregister(h, error);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_UNFIXATED:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                break;
        case HOME_ACTIVE:
        case HOME_LINGERING:
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
        }

        r = home_start_work(h, "remove", h->record, NULL);
        if (r < 0)
                return r;

        home_set_state(h, HOME_REMOVING);
        return 0;
}

static int user_record_extend_with_binding(UserRecord *hr, UserRecord *with_binding, UserRecordLoadFlags flags, UserRecord **ret) {
        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        _cleanup_(user_record_unrefp) UserRecord *nr = NULL;
        JsonVariant *binding;
        int r;

        assert(hr);
        assert(with_binding);
        assert(ret);

        assert_se(v = json_variant_ref(hr->json));

        binding = json_variant_by_key(with_binding->json, "binding");
        if (binding) {
                r = json_variant_set_field(&v, "binding", binding);
                if (r < 0)
                        return r;
        }

        nr = user_record_new();
        if (!nr)
                return -ENOMEM;

        r = user_record_load(nr, v, flags);
        if (r < 0)
                return r;

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

static int home_update_internal(
                Home *h,
                const char *verb,
                UserRecord *hr,
                UserRecord *secret,
                sd_bus_error *error) {

        _cleanup_(user_record_unrefp) UserRecord *new_hr = NULL, *saved_secret = NULL, *signed_hr = NULL;
        int r, c;

        assert(h);
        assert(verb);
        assert(hr);

        if (!user_record_compatible(hr, h->record))
                return sd_bus_error_set(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Updated user record is not compatible with existing one.");
        c = user_record_compare_last_change(hr, h->record); /* refuse downgrades */
        if (c < 0)
                return sd_bus_error_set(error, BUS_ERROR_HOME_RECORD_DOWNGRADE, "Refusing to update to older home record.");

        if (!secret && FLAGS_SET(hr->mask, USER_RECORD_SECRET)) {
                r = user_record_clone(hr, USER_RECORD_EXTRACT_SECRET|USER_RECORD_PERMISSIVE, &saved_secret);
                if (r < 0)
                        return r;

                secret = saved_secret;
        }

        r = manager_verify_user_record(h->manager, hr);
        switch (r) {

        case USER_RECORD_UNSIGNED:
                if (h->signed_locally <= 0) /* If the existing record is not owned by us, don't accept an
                                             * unsigned new record. i.e. only implicitly sign new records
                                             * that where previously signed by us too. */
                        return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);

                /* The updated record is not signed, then do so now */
                r = manager_sign_user_record(h->manager, hr, &signed_hr, error);
                if (r < 0)
                        return r;

                hr = signed_hr;
                break;

        case USER_RECORD_SIGNED_EXCLUSIVE:
        case USER_RECORD_SIGNED:
        case USER_RECORD_FOREIGN:
                /* Has already been signed. Great! */
                break;

        case -ENOKEY:
        default:
                return r;
        }

        r = user_record_extend_with_binding(hr, h->record, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_hr);
        if (r < 0)
                return r;

        if (c == 0) {
                /* different payload but same lastChangeUSec field? That's not cool! */

                r = user_record_masked_equal(new_hr, h->record, USER_RECORD_REGULAR|USER_RECORD_PRIVILEGED|USER_RECORD_PER_MACHINE);
                if (r < 0)
                        return r;
                if (r == 0)
                        return sd_bus_error_set(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Home record different but timestamp remained the same, refusing.");
        }

        r = home_start_work(h, verb, new_hr, secret);
        if (r < 0)
                return r;

        return 0;
}

int home_update(Home *h, UserRecord *hr, sd_bus_error *error) {
        HomeState state;
        int r;

        assert(h);
        assert(hr);

        state = home_get_state(h);
        switch (state) {
        case HOME_UNFIXATED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_INACTIVE:
        case HOME_DIRTY:
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        r = home_update_internal(h, "update", hr, NULL, error);
        if (r < 0)
                return r;

        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_UPDATING_WHILE_ACTIVE : HOME_UPDATING);
        return 0;
}

int home_resize(Home *h,
                uint64_t disk_size,
                UserRecord *secret,
                bool automatic,
                sd_bus_error *error) {

        _cleanup_(user_record_unrefp) UserRecord *c = NULL;
        HomeState state;
        int r;

        assert(h);

        state = home_get_state(h);
        switch (state) {
        case HOME_UNFIXATED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_INACTIVE:
        case HOME_DIRTY:
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        /* If the user didn't specify any size explicitly and rebalancing is on, then the disk size is
         * determined by automatic rebalancing and hence not user configured but determined by us and thus
         * applied anyway. */
        if (disk_size == UINT64_MAX && h->record->rebalance_weight != REBALANCE_WEIGHT_OFF)
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Disk size is being determined by automatic disk space rebalancing.");

        if (disk_size == UINT64_MAX || disk_size == h->record->disk_size) {
                if (h->record->disk_size == UINT64_MAX)
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "No disk size to resize to specified.");

                c = user_record_ref(h->record); /* Shortcut if size is unspecified or matches the record */
        } else {
                _cleanup_(user_record_unrefp) UserRecord *signed_c = NULL;

                if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
                        return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);

                r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE, &c);
                if (r < 0)
                        return r;

                r = user_record_set_disk_size(c, disk_size);
                if (r == -ERANGE)
                        return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "Requested size for home %s out of acceptable range.", h->user_name);
                if (r < 0)
                        return r;

                /* If user picked an explicit size, then turn off rebalancing, so that we don't undo what user chose */
                r = user_record_set_rebalance_weight(c, REBALANCE_WEIGHT_OFF);
                if (r < 0)
                        return r;

                r = user_record_update_last_changed(c, false);
                if (r == -ECHRNG)
                        return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Record last change time of %s is newer than current time, cannot update.", h->user_name);
                if (r < 0)
                        return r;

                r = manager_sign_user_record(h->manager, c, &signed_c, error);
                if (r < 0)
                        return r;

                user_record_unref(c);
                c = TAKE_PTR(signed_c);
        }

        r = home_update_internal(h, automatic ? "resize-auto" : "resize", c, secret, error);
        if (r < 0)
                return r;

        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_RESIZING_WHILE_ACTIVE : HOME_RESIZING);
        return 0;
}

static int home_may_change_password(
                Home *h,
                sd_bus_error *error) {

        int r;

        assert(h);

        r = user_record_test_password_change_required(h->record);
        if (IN_SET(r, -EKEYREVOKED, -EOWNERDEAD, -EKEYEXPIRED, -ESTALE))
                return 0; /* expired in some form, but changing is allowed */
        if (IN_SET(r, -EKEYREJECTED, -EROFS))
                return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Expiration settings of account %s do not allow changing of password.", h->user_name);
        if (r < 0)
                return log_error_errno(r, "Failed to test password expiry: %m");

        return 0; /* not expired */
}

int home_passwd(Home *h,
                UserRecord *new_secret,
                UserRecord *old_secret,
                sd_bus_error *error) {

        _cleanup_(user_record_unrefp) UserRecord *c = NULL, *merged_secret = NULL, *signed_c = NULL;
        HomeState state;
        int r;

        assert(h);

        if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
                return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);

        state = home_get_state(h);
        switch (state) {
        case HOME_UNFIXATED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
        case HOME_ABSENT:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_INACTIVE:
        case HOME_DIRTY:
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        r = home_may_change_password(h, error);
        if (r < 0)
                return r;

        r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE, &c);
        if (r < 0)
                return r;

        merged_secret = user_record_new();
        if (!merged_secret)
                return -ENOMEM;

        r = user_record_merge_secret(merged_secret, old_secret);
        if (r < 0)
                return r;

        r = user_record_merge_secret(merged_secret, new_secret);
        if (r < 0)
                return r;

        if (!strv_isempty(new_secret->password)) {
                /* Update the password only if one is specified, otherwise let's just reuse the old password
                 * data. This is useful as a way to propagate updated user records into the LUKS backends
                 * properly. */

                r = user_record_make_hashed_password(c, new_secret->password, /* extend = */ false);
                if (r < 0)
                        return r;

                r = user_record_set_password_change_now(c, -1 /* remove */);
                if (r < 0)
                        return r;
        }

        r = user_record_update_last_changed(c, true);
        if (r == -ECHRNG)
                return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Record last change time of %s is newer than current time, cannot update.", h->user_name);
        if (r < 0)
                return r;

        r = manager_sign_user_record(h->manager, c, &signed_c, error);
        if (r < 0)
                return r;

        if (c->enforce_password_policy == false)
                log_debug("Password quality check turned off for account, skipping.");
        else {
                r = user_record_quality_check_password(c, merged_secret, error);
                if (r < 0)
                        return r;
        }

        r = home_update_internal(h, "passwd", signed_c, merged_secret, error);
        if (r < 0)
                return r;

        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_PASSWD_WHILE_ACTIVE : HOME_PASSWD);
        return 0;
}

int home_unregister(Home *h, sd_bus_error *error) {
        int r;

        assert(h);

        switch (home_get_state(h)) {
        case HOME_UNFIXATED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s is not registered.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                break;
        case HOME_ACTIVE:
        case HOME_LINGERING:
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
        }

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

        /* And destroy the whole entry. The caller needs to be prepared for that. */
        h = home_free(h);
        return 1;
}

int home_lock(Home *h, sd_bus_error *error) {
        int r;

        assert(h);

        switch (home_get_state(h)) {
        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is not active.", h->user_name);
        case HOME_LOCKED:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is already locked.", h->user_name);
        case HOME_ACTIVE:
        case HOME_LINGERING:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        r = home_start_work(h, "lock", h->record, NULL);
        if (r < 0)
                return r;

        home_set_state(h, HOME_LOCKING);
        return 0;
}

static int home_unlock_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
        int r;

        assert(h);
        assert(IN_SET(for_state, HOME_UNLOCKING, HOME_UNLOCKING_FOR_ACQUIRE));

        r = home_start_work(h, "unlock", h->record, secret);
        if (r < 0)
                return r;

        home_set_state(h, for_state);
        return 0;
}

int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error) {
        int r;
        assert(h);

        r = home_ratelimit(h, error);
        if (r < 0)
                return r;

        switch (home_get_state(h)) {
        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_ACTIVE:
        case HOME_LINGERING:
        case HOME_DIRTY:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_LOCKED, "Home %s is not locked.", h->user_name);
        case HOME_LOCKED:
                break;
        default:
                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
        }

        return home_unlock_internal(h, secret, HOME_UNLOCKING, error);
}

HomeState home_get_state(Home *h) {
        int r;
        assert(h);

        /* When the state field is initialized, it counts. */
        if (h->state >= 0)
                return h->state;

        /* Otherwise, let's see if the home directory is mounted. If so, we assume for sure the home
         * directory is active */
        if (user_record_test_home_directory(h->record) == USER_TEST_MOUNTED)
                return h->retry_deactivate_event_source ? HOME_LINGERING : HOME_ACTIVE;

        /* And if we see the image being gone, we report this as absent */
        r = user_record_test_image_path(h->record);
        if (r == USER_TEST_ABSENT)
                return HOME_ABSENT;
        if (r == USER_TEST_DIRTY)
                return HOME_DIRTY;

        /* And for all other cases we return "inactive". */
        return HOME_INACTIVE;
}

void home_process_notify(Home *h, char **l, int fd) {
        _cleanup_close_ int taken_fd = TAKE_FD(fd);
        const char *e;
        int error;
        int r;

        assert(h);

        e = strv_env_get(l, "SYSTEMD_LUKS_LOCK_FD");
        if (e) {
                r = parse_boolean(e);
                if (r < 0)
                        return (void) log_debug_errno(r, "Failed to parse SYSTEMD_LUKS_LOCK_FD value: %m");
                if (r > 0) {
                        if (taken_fd < 0)
                                return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=1 but no fd passed, ignoring: %m");

                        close_and_replace(h->luks_lock_fd, taken_fd);

                        log_debug("Successfully acquired LUKS lock fd from worker.");

                        /* Immediately check if we actually want to keep it */
                        home_maybe_close_luks_lock_fd(h, _HOME_STATE_INVALID);
                } else {
                        if (taken_fd >= 0)
                                return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=0 but fd passed, ignoring: %m");

                        h->luks_lock_fd = safe_close(h->luks_lock_fd);
                }

                return;
        }

        e = strv_env_get(l, "ERRNO");
        if (!e)
                return (void) log_debug("Got notify message lacking both ERRNO= and SYSTEMD_LUKS_LOCK_FD= field, ignoring.");

        r = safe_atoi(e, &error);
        if (r < 0)
                return (void) log_debug_errno(r, "Failed to parse received error number, ignoring: %s", e);
        if (error <= 0)
                return (void) log_debug("Error number is out of range: %i", error);

        h->worker_error_code = error;
}

int home_killall(Home *h) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_free_ char *unit = NULL;
        int r;

        assert(h);

        if (!uid_is_valid(h->uid))
                return 0;

        assert(h->uid > 0); /* We never should be UID 0 */

        /* Let's kill everything matching the specified UID */
        r = safe_fork("(sd-killer)",
                      FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG,
                      NULL);
        if (r < 0)
                return r;
        if (r == 0) {
                gid_t gid;

                /* Child */

                gid = user_record_gid(h->record);
                if (setresgid(gid, gid, gid) < 0) {
                        log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
                        _exit(EXIT_FAILURE);
                }

                if (setgroups(0, NULL) < 0) {
                        log_error_errno(errno, "Failed to reset auxiliary groups list: %m");
                        _exit(EXIT_FAILURE);
                }

                if (setresuid(h->uid, h->uid, h->uid) < 0) {
                        log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", h->uid);
                        _exit(EXIT_FAILURE);
                }

                if (kill(-1, SIGKILL) < 0) {
                        log_error_errno(errno, "Failed to kill all processes of UID " UID_FMT ": %m", h->uid);
                        _exit(EXIT_FAILURE);
                }

                _exit(EXIT_SUCCESS);
        }

        /* Let's also kill everything in the user's slice */
        if (asprintf(&unit, "user-" UID_FMT ".slice", h->uid) < 0)
                return log_oom();

        r = sd_bus_call_method(
                        h->manager->bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "KillUnit",
                        &error,
                        NULL,
                        "ssi", unit, "all", SIGKILL);
        if (r < 0)
                log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ? LOG_DEBUG : LOG_WARNING,
                               r, "Failed to kill login processes of user, ignoring: %s", bus_error_message(&error, r));

        return 1;
}

static int home_get_disk_status_luks(
                Home *h,
                HomeState state,
                uint64_t *ret_disk_size,
                uint64_t *ret_disk_usage,
                uint64_t *ret_disk_free,
                uint64_t *ret_disk_ceiling,
                uint64_t *ret_disk_floor,
                statfs_f_type_t *ret_fstype,
                mode_t *ret_access_mode) {

        uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
                disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX,
                stat_used = UINT64_MAX, fs_size = UINT64_MAX, header_size = 0;
        mode_t access_mode = MODE_INVALID;
        statfs_f_type_t fstype = 0;
        struct statfs sfs;
        struct stat st;
        const char *hd;
        int r;

        assert(h);

        if (state != HOME_ABSENT) {
                const char *ip;

                ip = user_record_image_path(h->record);
                if (ip) {
                        if (stat(ip, &st) < 0)
                                log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", ip);
                        else if (S_ISREG(st.st_mode)) {
                                _cleanup_free_ char *parent = NULL;

                                disk_size = st.st_size;
                                stat_used = st.st_blocks * 512;

                                r = path_extract_directory(ip, &parent);
                                if (r < 0)
                                        return log_error_errno(r, "Failed to extract parent directory from image path '%s': %m", ip);

                                if (statfs(parent, &sfs) < 0)
                                        log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", parent);
                                else
                                        disk_ceiling = stat_used + sfs.f_bsize * sfs.f_bavail;

                        } else if (S_ISBLK(st.st_mode)) {
                                _cleanup_free_ char *szbuf = NULL;
                                char p[SYS_BLOCK_PATH_MAX("/size")];

                                /* Let's read the size off sysfs, so that we don't have to open the device */
                                xsprintf_sys_block_path(p, "/size", st.st_rdev);
                                r = read_one_line_file(p, &szbuf);
                                if (r < 0)
                                        log_debug_errno(r, "Failed to read %s, ignoring: %m", p);
                                else {
                                        uint64_t sz;

                                        r = safe_atou64(szbuf, &sz);
                                        if (r < 0)
                                                log_debug_errno(r, "Failed to parse %s, ignoring: %s", p, szbuf);
                                        else
                                                disk_size = sz * 512;
                                }
                        } else
                                log_debug("Image path is not a block device or regular file, not able to acquire size.");
                }
        }

        if (!HOME_STATE_IS_ACTIVE(state))
                goto finish;

        hd = user_record_home_directory(h->record);
        if (!hd)
                goto finish;

        if (stat(hd, &st) < 0) {
                log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", hd);
                goto finish;
        }

        r = stat_verify_directory(&st);
        if (r < 0) {
                log_debug_errno(r, "Home directory %s is not a directory, ignoring: %m", hd);
                goto finish;
        }

        access_mode = st.st_mode & 07777;

        if (statfs(hd, &sfs) < 0) {
                log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd);
                goto finish;
        }

        fstype = sfs.f_type;

        disk_free = sfs.f_bsize * sfs.f_bavail;
        fs_size = sfs.f_bsize * sfs.f_blocks;
        if (disk_size != UINT64_MAX && disk_size > fs_size)
                header_size = disk_size - fs_size;

        /* We take a perspective from the user here (as opposed to from the host): the used disk space is the
         * difference from the limit and what's free. This makes a difference if sparse mode is not used: in
         * that case the image is pre-allocated and thus appears all used from the host PoV but is not used
         * up at all yet from the user's PoV.
         *
         * That said, we use the stat() reported loopback file size as upper boundary: our footprint can
         * never be larger than what we take up on the lowest layers. */

        if (disk_size != UINT64_MAX && disk_size > disk_free) {
                disk_usage = disk_size - disk_free;

                if (stat_used != UINT64_MAX && disk_usage > stat_used)
                        disk_usage = stat_used;
        } else
                disk_usage = stat_used;

        /* If we have the magic, determine floor preferably by magic */
        disk_floor = minimal_size_by_fs_magic(sfs.f_type) + header_size;

finish:
        /* If we don't know the magic, go by file system name */
        if (disk_floor == UINT64_MAX)
                disk_floor = minimal_size_by_fs_name(user_record_file_system_type(h->record));

        if (ret_disk_size)
                *ret_disk_size = disk_size;
        if (ret_disk_usage)
                *ret_disk_usage = disk_usage;
        if (ret_disk_free)
                *ret_disk_free = disk_free;
        if (ret_disk_ceiling)
                *ret_disk_ceiling = disk_ceiling;
        if (ret_disk_floor)
                *ret_disk_floor = disk_floor;
        if (ret_fstype)
                *ret_fstype = fstype;
        if (ret_access_mode)
                *ret_access_mode = access_mode;

        return 0;
}

static int home_get_disk_status_directory(
                Home *h,
                HomeState state,
                uint64_t *ret_disk_size,
                uint64_t *ret_disk_usage,
                uint64_t *ret_disk_free,
                uint64_t *ret_disk_ceiling,
                uint64_t *ret_disk_floor,
                statfs_f_type_t *ret_fstype,
                mode_t *ret_access_mode) {

        uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
                disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
        mode_t access_mode = MODE_INVALID;
        statfs_f_type_t fstype = 0;
        struct statfs sfs;
        struct dqblk req;
        const char *path = NULL;
        int r;

        assert(h);

        if (HOME_STATE_IS_ACTIVE(state))
                path = user_record_home_directory(h->record);

        if (!path) {
                if (state == HOME_ABSENT)
                        goto finish;

                path = user_record_image_path(h->record);
        }

        if (!path)
                goto finish;

        if (statfs(path, &sfs) < 0)
                log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", path);
        else {
                disk_free = sfs.f_bsize * sfs.f_bavail;
                disk_size = sfs.f_bsize * sfs.f_blocks;

                /* We don't initialize disk_usage from statfs() data here, since the device is likely not used
                 * by us alone, and disk_usage should only reflect our own use. */

                fstype = sfs.f_type;
        }

        if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_SUBVOLUME)) {

                r = btrfs_is_subvol(path);
                if (r < 0)
                        log_debug_errno(r, "Failed to determine whether %s is a btrfs subvolume: %m", path);
                else if (r > 0) {
                        BtrfsQuotaInfo qi;

                        r = btrfs_subvol_get_subtree_quota(path, 0, &qi);
                        if (r < 0)
                                log_debug_errno(r, "Failed to query btrfs subtree quota, ignoring: %m");
                        else {
                                disk_usage = qi.referenced;

                                if (disk_free != UINT64_MAX) {
                                        disk_ceiling = qi.referenced + disk_free;

                                        if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
                                                disk_ceiling = disk_size;
                                }

                                if (qi.referenced_max != UINT64_MAX) {
                                        if (disk_size != UINT64_MAX)
                                                disk_size = MIN(qi.referenced_max, disk_size);
                                        else
                                                disk_size = qi.referenced_max;
                                }

                                if (disk_size != UINT64_MAX) {
                                        if (disk_size > disk_usage)
                                                disk_free = disk_size - disk_usage;
                                        else
                                                disk_free = 0;
                                }
                        }

                        goto finish;
                }
        }

        if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_FSCRYPT)) {
                r = quotactl_path(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), path, h->uid, &req);
                if (r < 0) {
                        if (ERRNO_IS_NOT_SUPPORTED(r)) {
                                log_debug_errno(r, "No UID quota support on %s.", path);
                                goto finish;
                        }

                        if (r != -ESRCH) {
                                log_debug_errno(r, "Failed to query disk quota for UID " UID_FMT ": %m", h->uid);
                                goto finish;
                        }

                        disk_usage = 0; /* No record of this user? then nothing was used */
                } else {
                        if (FLAGS_SET(req.dqb_valid, QIF_SPACE) && disk_free != UINT64_MAX) {
                                disk_ceiling = req.dqb_curspace + disk_free;

                                if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
                                        disk_ceiling = disk_size;
                        }

                        if (FLAGS_SET(req.dqb_valid, QIF_BLIMITS)) {
                                uint64_t q;

                                /* Take the minimum of the quota and the available disk space here */
                                q = req.dqb_bhardlimit * QIF_DQBLKSIZE;
                                if (disk_size != UINT64_MAX)
                                        disk_size = MIN(disk_size, q);
                                else
                                        disk_size = q;
                        }
                        if (FLAGS_SET(req.dqb_valid, QIF_SPACE)) {
                                disk_usage = req.dqb_curspace;

                                if (disk_size != UINT64_MAX) {
                                        if (disk_size > disk_usage)
                                                disk_free = disk_size - disk_usage;
                                        else
                                                disk_free = 0;
                                }
                        }
                }
        }

finish:
        if (ret_disk_size)
                *ret_disk_size = disk_size;
        if (ret_disk_usage)
                *ret_disk_usage = disk_usage;
        if (ret_disk_free)
                *ret_disk_free = disk_free;
        if (ret_disk_ceiling)
                *ret_disk_ceiling = disk_ceiling;
        if (ret_disk_floor)
                *ret_disk_floor = disk_floor;
        if (ret_fstype)
                *ret_fstype = fstype;
        if (ret_access_mode)
                *ret_access_mode = access_mode;

        return 0;
}

static int home_get_disk_status_internal(
                Home *h,
                HomeState state,
                uint64_t *ret_disk_size,
                uint64_t *ret_disk_usage,
                uint64_t *ret_disk_free,
                uint64_t *ret_disk_ceiling,
                uint64_t *ret_disk_floor,
                statfs_f_type_t *ret_fstype,
                mode_t *ret_access_mode) {

        assert(h);
        assert(h->record);

        switch (h->record->storage) {

        case USER_LUKS:
                return home_get_disk_status_luks(h, state, ret_disk_size, ret_disk_usage, ret_disk_free, ret_disk_ceiling, ret_disk_floor, ret_fstype, ret_access_mode);

        case USER_CLASSIC:
        case USER_DIRECTORY:
        case USER_SUBVOLUME:
        case USER_FSCRYPT:
        case USER_CIFS:
                return home_get_disk_status_directory(h, state, ret_disk_size, ret_disk_usage, ret_disk_free, ret_disk_ceiling, ret_disk_floor, ret_fstype, ret_access_mode);

        default:
                /* don't know */

                if (ret_disk_size)
                        *ret_disk_size = UINT64_MAX;
                if (ret_disk_usage)
                        *ret_disk_usage = UINT64_MAX;
                if (ret_disk_free)
                        *ret_disk_free = UINT64_MAX;
                if (ret_disk_ceiling)
                        *ret_disk_ceiling = UINT64_MAX;
                if (ret_disk_floor)
                        *ret_disk_floor = UINT64_MAX;
                if (ret_fstype)
                        *ret_fstype = 0;
                if (ret_access_mode)
                        *ret_access_mode = MODE_INVALID;

                return 0;
        }
}

int home_get_disk_status(
                Home *h,
                uint64_t *ret_disk_size,
                uint64_t *ret_disk_usage,
                uint64_t *ret_disk_free,
                uint64_t *ret_disk_ceiling,
                uint64_t *ret_disk_floor,
                statfs_f_type_t *ret_fstype,
                mode_t *ret_access_mode) {

        assert(h);

        return home_get_disk_status_internal(
                        h,
                        home_get_state(h),
                        ret_disk_size,
                        ret_disk_usage,
                        ret_disk_free,
                        ret_disk_ceiling,
                        ret_disk_floor,
                        ret_fstype,
                        ret_access_mode);
}

int home_augment_status(
                Home *h,
                UserRecordLoadFlags flags,
                UserRecord **ret) {

        uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX, disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
        _cleanup_(json_variant_unrefp) JsonVariant *j = NULL, *v = NULL, *m = NULL, *status = NULL;
        _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
        statfs_f_type_t magic;
        const char *fstype;
        mode_t access_mode;
        HomeState state;
        sd_id128_t id;
        int r;

        assert(h);
        assert(ret);

        /* We are supposed to add this, this can't be on hence. */
        assert(!FLAGS_SET(flags, USER_RECORD_STRIP_STATUS));

        r = sd_id128_get_machine(&id);
        if (r < 0)
                return r;

        state = home_get_state(h);

        r = home_get_disk_status_internal(
                        h, state,
                        &disk_size,
                        &disk_usage,
                        &disk_free,
                        &disk_ceiling,
                        &disk_floor,
                        &magic,
                        &access_mode);
        if (r < 0)
                return r;

        fstype = fs_type_to_string(magic);

        if (disk_floor == UINT64_MAX || (disk_usage != UINT64_MAX && disk_floor < disk_usage))
                disk_floor = disk_usage;
        if (disk_floor == UINT64_MAX || disk_floor < USER_DISK_SIZE_MIN)
                disk_floor = USER_DISK_SIZE_MIN;
        if (disk_ceiling == UINT64_MAX || disk_ceiling > USER_DISK_SIZE_MAX)
                disk_ceiling = USER_DISK_SIZE_MAX;

        r = json_build(&status,
                       JSON_BUILD_OBJECT(
                                       JSON_BUILD_PAIR("state", JSON_BUILD_STRING(home_state_to_string(state))),
                                       JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.Home")),
                                       JSON_BUILD_PAIR_CONDITION(disk_size != UINT64_MAX, "diskSize", JSON_BUILD_UNSIGNED(disk_size)),
                                       JSON_BUILD_PAIR_CONDITION(disk_usage != UINT64_MAX, "diskUsage", JSON_BUILD_UNSIGNED(disk_usage)),
                                       JSON_BUILD_PAIR_CONDITION(disk_free != UINT64_MAX, "diskFree", JSON_BUILD_UNSIGNED(disk_free)),
                                       JSON_BUILD_PAIR_CONDITION(disk_ceiling != UINT64_MAX, "diskCeiling", JSON_BUILD_UNSIGNED(disk_ceiling)),
                                       JSON_BUILD_PAIR_CONDITION(disk_floor != UINT64_MAX, "diskFloor", JSON_BUILD_UNSIGNED(disk_floor)),
                                       JSON_BUILD_PAIR_CONDITION(h->signed_locally >= 0, "signedLocally", JSON_BUILD_BOOLEAN(h->signed_locally)),
                                       JSON_BUILD_PAIR_CONDITION(fstype, "fileSystemType", JSON_BUILD_STRING(fstype)),
                                       JSON_BUILD_PAIR_CONDITION(access_mode != MODE_INVALID, "accessMode", JSON_BUILD_UNSIGNED(access_mode))
                       ));
        if (r < 0)
                return r;

        j = json_variant_ref(h->record->json);
        v = json_variant_ref(json_variant_by_key(j, "status"));
        m = json_variant_ref(json_variant_by_key(v, SD_ID128_TO_STRING(id)));

        r = json_variant_filter(&m, STRV_MAKE("diskSize", "diskUsage", "diskFree", "diskCeiling", "diskFloor", "signedLocally"));
        if (r < 0)
                return r;

        r = json_variant_merge(&m, status);
        if (r < 0)
                return r;

        r = json_variant_set_field(&v, SD_ID128_TO_STRING(id), m);
        if (r < 0)
                return r;

        r = json_variant_set_field(&j, "status", v);
        if (r < 0)
                return r;

        ur = user_record_new();
        if (!ur)
                return -ENOMEM;

        r = user_record_load(ur, j, flags);
        if (r < 0)
                return r;

        ur->incomplete =
                FLAGS_SET(h->record->mask, USER_RECORD_PRIVILEGED) &&
                !FLAGS_SET(ur->mask, USER_RECORD_PRIVILEGED);

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

static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        _cleanup_(operation_unrefp) Operation *o = NULL;
        Home *h = ASSERT_PTR(userdata);

        assert(s);

        if (h->ref_event_source_please_suspend == s)
                h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);

        if (h->ref_event_source_dont_suspend == s)
                h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);

        if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
                return 0;

        log_info("Got notification that all sessions of user %s ended, deactivating automatically.", h->user_name);

        o = operation_new(OPERATION_PIPE_EOF, NULL);
        if (!o) {
                log_oom();
                return 0;
        }

        home_schedule_operation(h, o, NULL);
        return 0;
}

int home_create_fifo(Home *h, bool please_suspend) {
        _cleanup_close_ int ret_fd = -EBADF;
        sd_event_source **ss;
        const char *fn, *suffix;
        int r;

        assert(h);

        if (please_suspend) {
                suffix = ".please-suspend";
                ss = &h->ref_event_source_please_suspend;
        } else {
                suffix = ".dont-suspend";
                ss = &h->ref_event_source_dont_suspend;
        }

        fn = strjoina("/run/systemd/home/", h->user_name, suffix);

        if (!*ss) {
                _cleanup_close_ int ref_fd = -EBADF;

                (void) mkdir("/run/systemd/home/", 0755);
                if (mkfifo(fn, 0600) < 0 && errno != EEXIST)
                        return log_error_errno(errno, "Failed to create FIFO %s: %m", fn);

                ref_fd = open(fn, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
                if (ref_fd < 0)
                        return log_error_errno(errno, "Failed to open FIFO %s for reading: %m", fn);

                r = sd_event_add_io(h->manager->event, ss, ref_fd, 0, on_home_ref_eof, h);
                if (r < 0)
                        return log_error_errno(r, "Failed to allocate reference FIFO event source: %m");

                (void) sd_event_source_set_description(*ss, "acquire-ref");

                r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_IDLE-1);
                if (r < 0)
                        return r;

                r = sd_event_source_set_io_fd_own(*ss, true);
                if (r < 0)
                        return log_error_errno(r, "Failed to pass ownership of FIFO event fd to event source: %m");

                TAKE_FD(ref_fd);
        }

        ret_fd = open(fn, O_WRONLY|O_CLOEXEC|O_NONBLOCK);
        if (ret_fd < 0)
                return log_error_errno(errno, "Failed to open FIFO %s for writing: %m", fn);

        return TAKE_FD(ret_fd);
}

static int home_dispatch_acquire(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int (*call)(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) = NULL;
        HomeState for_state;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_ACQUIRE);

        assert(!h->current_operation);

        switch (home_get_state(h)) {

        case HOME_UNFIXATED:
                for_state = HOME_FIXATING_FOR_ACQUIRE;
                call = home_fixate_internal;
                break;

        case HOME_ABSENT:
                r = sd_bus_error_setf(&error, BUS_ERROR_HOME_ABSENT,
                                      "Home %s is currently missing or not plugged in.", h->user_name);
                goto check;

        case HOME_INACTIVE:
        case HOME_DIRTY:
                for_state = HOME_ACTIVATING_FOR_ACQUIRE;
                call = home_activate_internal;
                break;

        case HOME_ACTIVE:
        case HOME_LINGERING:
                for_state = HOME_AUTHENTICATING_FOR_ACQUIRE;
                call = home_authenticate_internal;
                break;

        case HOME_LOCKED:
                for_state = HOME_UNLOCKING_FOR_ACQUIRE;
                call = home_unlock_internal;
                break;

        default:
                /* All other cases means we are currently executing an operation, which means the job remains
                 * pending. */
                return 0;
        }

        r = home_ratelimit(h, &error);
        if (r >= 0)
                r = call(h, o->secret, for_state, &error);

 check:
        if (r != 0) /* failure or completed */
                operation_result(o, r, &error);
        else /* ongoing */
                h->current_operation = operation_ref(o);

        return 1;
}

static int home_dispatch_release(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_RELEASE);

        if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
                /* If there's now a reference again, then let's abort the release attempt */
                r = sd_bus_error_setf(&error, BUS_ERROR_HOME_BUSY, "Home %s is currently referenced.", h->user_name);
        else {
                switch (home_get_state(h)) {

                case HOME_UNFIXATED:
                case HOME_ABSENT:
                case HOME_INACTIVE:
                case HOME_DIRTY:
                        r = 1; /* done */
                        break;

                case HOME_LOCKED:
                        r = sd_bus_error_setf(&error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
                        break;

                case HOME_ACTIVE:
                case HOME_LINGERING:
                        r = home_deactivate_internal(h, false, &error);
                        break;

                default:
                        /* All other cases means we are currently executing an operation, which means the job remains
                         * pending. */
                        return 0;
                }
        }

        assert(!h->current_operation);

        if (r != 0) /* failure or completed */
                operation_result(o, r, &error);
        else /* ongoing */
                h->current_operation = operation_ref(o);

        return 1;
}

static int home_dispatch_lock_all(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_LOCK_ALL);

        switch (home_get_state(h)) {

        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                log_info("Home %s is not active, no locking necessary.", h->user_name);
                r = 1; /* done */
                break;

        case HOME_LOCKED:
                log_info("Home %s is already locked.", h->user_name);
                r = 1; /* done */
                break;

        case HOME_ACTIVE:
        case HOME_LINGERING:
                log_info("Locking home %s.", h->user_name);
                r = home_lock(h, &error);
                break;

        default:
                /* All other cases means we are currently executing an operation, which means the job remains
                 * pending. */
                return 0;
        }

        assert(!h->current_operation);

        if (r != 0) /* failure or completed */
                operation_result(o, r, &error);
        else /* ongoing */
                h->current_operation = operation_ref(o);

        return 1;
}

static int home_dispatch_deactivate_all(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_DEACTIVATE_ALL);

        switch (home_get_state(h)) {

        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                log_info("Home %s is already deactivated.", h->user_name);
                r = 1; /* done */
                break;

        case HOME_LOCKED:
                log_info("Home %s is currently locked, not deactivating.", h->user_name);
                r = 1; /* done */
                break;

        case HOME_ACTIVE:
        case HOME_LINGERING:
                log_info("Deactivating home %s.", h->user_name);
                r = home_deactivate_internal(h, false, &error);
                break;

        default:
                /* All other cases means we are currently executing an operation, which means the job remains
                 * pending. */
                return 0;
        }

        assert(!h->current_operation);

        if (r != 0) /* failure or completed */
                operation_result(o, r, &error);
        else /* ongoing */
                h->current_operation = operation_ref(o);

        return 1;
}

static int home_dispatch_pipe_eof(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_PIPE_EOF);

        if (h->ref_event_source_please_suspend || h->ref_event_source_dont_suspend)
                return 1; /* Hmm, there's a reference again, let's cancel this */

        switch (home_get_state(h)) {

        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                log_info("Home %s already deactivated, no automatic deactivation needed.", h->user_name);
                break;

        case HOME_DEACTIVATING:
                log_info("Home %s is already being deactivated, automatic deactivated unnecessary.", h->user_name);
                break;

        case HOME_ACTIVE:
        case HOME_LINGERING:
                r = home_deactivate_internal(h, false, &error);
                if (r < 0)
                        log_warning_errno(r, "Failed to deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
                break;

        case HOME_LOCKED:
        default:
                /* If the device is locked or any operation is being executed, let's leave this pending */
                return 0;
        }

        /* Note that we don't call operation_fail() or operation_success() here, because this kind of
         * operation has no message associated with it, and thus there's no need to propagate success. */

        assert(!o->message);
        return 1;
}

static int home_dispatch_deactivate_force(Home *h, Operation *o) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(h);
        assert(o);
        assert(o->type == OPERATION_DEACTIVATE_FORCE);

        switch (home_get_state(h)) {

        case HOME_UNFIXATED:
        case HOME_ABSENT:
        case HOME_INACTIVE:
        case HOME_DIRTY:
                log_debug("Home %s already deactivated, no forced deactivation due to unplug needed.", h->user_name);
                break;

        case HOME_DEACTIVATING:
                log_debug("Home %s is already being deactivated, forced deactivation due to unplug unnecessary.", h->user_name);
                break;

        case HOME_ACTIVE:
        case HOME_LOCKED:
        case HOME_LINGERING:
                r = home_deactivate_internal(h, true, &error);
                if (r < 0)
                        log_warning_errno(r, "Failed to forcibly deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
                break;

        default:
                /* If any operation is being executed, let's leave this pending */
                return 0;
        }

        /* Note that we don't call operation_fail() or operation_success() here, because this kind of
         * operation has no message associated with it, and thus there's no need to propagate success. */

        assert(!o->message);
        return 1;
}

static int on_pending(sd_event_source *s, void *userdata) {
        Home *h = ASSERT_PTR(userdata);
        Operation *o;
        int r;

        assert(s);

        o = ordered_set_first(h->pending_operations);
        if (o) {
                static int (* const operation_table[_OPERATION_MAX])(Home *h, Operation *o) = {
                        [OPERATION_ACQUIRE]          = home_dispatch_acquire,
                        [OPERATION_RELEASE]          = home_dispatch_release,
                        [OPERATION_LOCK_ALL]         = home_dispatch_lock_all,
                        [OPERATION_DEACTIVATE_ALL]   = home_dispatch_deactivate_all,
                        [OPERATION_PIPE_EOF]         = home_dispatch_pipe_eof,
                        [OPERATION_DEACTIVATE_FORCE] = home_dispatch_deactivate_force,
                };

                assert(operation_table[o->type]);
                r = operation_table[o->type](h, o);
                if (r != 0) {
                        /* The operation completed, let's remove it from the pending list, and exit while
                         * leaving the event source enabled as it is. */
                        assert_se(ordered_set_remove(h->pending_operations, o) == o);
                        operation_unref(o);
                        return 0;
                }
        }

        /* Nothing to do anymore, let's turn off this event source */
        r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
        if (r < 0)
                return log_error_errno(r, "Failed to disable event source: %m");

        /* No operations pending anymore, maybe this is a good time to trigger a rebalancing */
        manager_reschedule_rebalance(h->manager);
        return 0;
}

int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error) {
        int r;

        assert(h);

        if (o) {
                if (ordered_set_size(h->pending_operations) >= PENDING_OPERATIONS_MAX)
                        return sd_bus_error_set(error, BUS_ERROR_TOO_MANY_OPERATIONS, "Too many client operations requested");

                r = ordered_set_ensure_put(&h->pending_operations, &operation_hash_ops, o);
                if (r < 0)
                        return r;

                operation_ref(o);
        }

        if (!h->pending_event_source) {
                r = sd_event_add_defer(h->manager->event, &h->pending_event_source, on_pending, h);
                if (r < 0)
                        return log_error_errno(r, "Failed to allocate pending defer event source: %m");

                (void) sd_event_source_set_description(h->pending_event_source, "pending");

                r = sd_event_source_set_priority(h->pending_event_source, SD_EVENT_PRIORITY_IDLE);
                if (r < 0)
                        return r;
        }

        r = sd_event_source_set_enabled(h->pending_event_source, SD_EVENT_ON);
        if (r < 0)
                return log_error_errno(r, "Failed to trigger pending event source: %m");

        return 0;
}

static int home_get_image_path_seat(Home *h, char **ret) {
        _cleanup_(sd_device_unrefp) sd_device *d = NULL;
        _cleanup_free_ char *c = NULL;
        const char *ip, *seat;
        struct stat st;
        int r;

        assert(h);

        if (user_record_storage(h->record) != USER_LUKS)
                return -ENXIO;

        ip = user_record_image_path(h->record);
        if (!ip)
                return -ENXIO;

        if (!path_startswith(ip, "/dev/"))
                return -ENXIO;

        if (stat(ip, &st) < 0)
                return -errno;

        if (!S_ISBLK(st.st_mode))
                return -ENOTBLK;

        r = sd_device_new_from_stat_rdev(&d, &st);
        if (r < 0)
                return r;

        r = sd_device_get_property_value(d, "ID_SEAT", &seat);
        if (r == -ENOENT) /* no property means seat0 */
                seat = "seat0";
        else if (r < 0)
                return r;

        c = strdup(seat);
        if (!c)
                return -ENOMEM;

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

int home_auto_login(Home *h, char ***ret_seats) {
        _cleanup_free_ char *seat = NULL, *seat2 = NULL;

        assert(h);
        assert(ret_seats);

        (void) home_get_image_path_seat(h, &seat);

        if (h->record->auto_login > 0 && !streq_ptr(seat, "seat0")) {
                /* For now, when the auto-login boolean is set for a user, let's make it mean
                 * "seat0". Eventually we can extend the concept and allow configuration of any kind of seat,
                 * but let's keep simple initially, most likely the feature is interesting on single-user
                 * systems anyway, only.
                 *
                 * We filter out users marked for auto-login in we know for sure their home directory is
                 * absent. */

                if (user_record_test_image_path(h->record) != USER_TEST_ABSENT) {
                        seat2 = strdup("seat0");
                        if (!seat2)
                                return -ENOMEM;
                }
        }

        if (seat || seat2) {
                _cleanup_strv_free_ char **list = NULL;
                size_t i = 0;

                list = new(char*, 3);
                if (!list)
                        return -ENOMEM;

                if (seat)
                        list[i++] = TAKE_PTR(seat);
                if (seat2)
                        list[i++] = TAKE_PTR(seat2);

                list[i] = NULL;
                *ret_seats = TAKE_PTR(list);
                return 1;
        }

        *ret_seats = NULL;
        return 0;
}

int home_set_current_message(Home *h, sd_bus_message *m) {
        assert(h);

        if (!m)
                return 0;

        if (h->current_operation)
                return -EBUSY;

        h->current_operation = operation_new(OPERATION_IMMEDIATE, m);
        if (!h->current_operation)
                return -ENOMEM;

        return 1;
}

int home_wait_for_worker(Home *h) {
        int r;

        assert(h);

        if (h->worker_pid <= 0)
                return 0;

        log_info("Worker process for home %s is still running while exiting. Waiting for it to finish.", h->user_name);

        r = wait_for_terminate_with_timeout(h->worker_pid, 30 * USEC_PER_SEC);
        if (r == -ETIMEDOUT)
                log_warning_errno(r, "Waiting for worker process for home %s timed out. Ignoring.", h->user_name);
        else
                log_warning_errno(r, "Failed to wait for worker process for home %s. Ignoring.", h->user_name);

        (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
        h->worker_pid = 0;
        return 1;
}

bool home_shall_rebalance(Home *h) {
        HomeState state;

        assert(h);

        /* Determines if the home directory is a candidate for rebalancing */

        if (!user_record_shall_rebalance(h->record))
                return false;

        state = home_get_state(h);
        if (!HOME_STATE_SHALL_REBALANCE(state))
                return false;

        return true;
}

bool home_is_busy(Home *h) {
        assert(h);

        if (h->current_operation)
                return true;

        if (!ordered_set_isempty(h->pending_operations))
                return true;

        return HOME_STATE_IS_EXECUTING_OPERATION(home_get_state(h));
}

static const char* const home_state_table[_HOME_STATE_MAX] = {
        [HOME_UNFIXATED]                   = "unfixated",
        [HOME_ABSENT]                      = "absent",
        [HOME_INACTIVE]                    = "inactive",
        [HOME_DIRTY]                       = "dirty",
        [HOME_FIXATING]                    = "fixating",
        [HOME_FIXATING_FOR_ACTIVATION]     = "fixating-for-activation",
        [HOME_FIXATING_FOR_ACQUIRE]        = "fixating-for-acquire",
        [HOME_ACTIVATING]                  = "activating",
        [HOME_ACTIVATING_FOR_ACQUIRE]      = "activating-for-acquire",
        [HOME_DEACTIVATING]                = "deactivating",
        [HOME_ACTIVE]                      = "active",
        [HOME_LINGERING]                   = "lingering",
        [HOME_LOCKING]                     = "locking",
        [HOME_LOCKED]                      = "locked",
        [HOME_UNLOCKING]                   = "unlocking",
        [HOME_UNLOCKING_FOR_ACQUIRE]       = "unlocking-for-acquire",
        [HOME_CREATING]                    = "creating",
        [HOME_REMOVING]                    = "removing",
        [HOME_UPDATING]                    = "updating",
        [HOME_UPDATING_WHILE_ACTIVE]       = "updating-while-active",
        [HOME_RESIZING]                    = "resizing",
        [HOME_RESIZING_WHILE_ACTIVE]       = "resizing-while-active",
        [HOME_PASSWD]                      = "passwd",
        [HOME_PASSWD_WHILE_ACTIVE]         = "passwd-while-active",
        [HOME_AUTHENTICATING]              = "authenticating",
        [HOME_AUTHENTICATING_WHILE_ACTIVE] = "authenticating-while-active",
        [HOME_AUTHENTICATING_FOR_ACQUIRE]  = "authenticating-for-acquire",
};

DEFINE_STRING_TABLE_LOOKUP(home_state, HomeState);
