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

#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "clean-ipc.h"
#include "dynamic-user.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "io-util.h"
#include "nscd-flush.h"
#include "parse-util.h"
#include "random-util.h"
#include "serialize.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "uid-alloc-range.h"
#include "user-util.h"

/* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
#define UID_CLAMP_INTO_RANGE(rnd) (((uid_t) (rnd) % (DYNAMIC_UID_MAX - DYNAMIC_UID_MIN + 1)) + DYNAMIC_UID_MIN)

DEFINE_PRIVATE_TRIVIAL_REF_FUNC(DynamicUser, dynamic_user);

static DynamicUser* dynamic_user_free(DynamicUser *d) {
        if (!d)
                return NULL;

        if (d->manager)
                (void) hashmap_remove(d->manager->dynamic_users, d->name);

        safe_close_pair(d->storage_socket);
        return mfree(d);
}

static int dynamic_user_add(Manager *m, const char *name, int storage_socket[static 2], DynamicUser **ret) {
        DynamicUser *d;
        int r;

        assert(m);
        assert(name);
        assert(storage_socket);

        r = hashmap_ensure_allocated(&m->dynamic_users, &string_hash_ops);
        if (r < 0)
                return r;

        d = malloc0(offsetof(DynamicUser, name) + strlen(name) + 1);
        if (!d)
                return -ENOMEM;

        strcpy(d->name, name);

        d->storage_socket[0] = storage_socket[0];
        d->storage_socket[1] = storage_socket[1];

        r = hashmap_put(m->dynamic_users, d->name, d);
        if (r < 0) {
                free(d);
                return r;
        }

        d->manager = m;

        if (ret)
                *ret = d;

        return 0;
}

static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) {
        _cleanup_close_pair_ int storage_socket[2] = PIPE_EBADF;
        DynamicUser *d;
        int r;

        assert(m);
        assert(name);

        /* Return the DynamicUser structure for a specific user name. Note that this won't actually allocate a UID for
         * it, but just prepare the data structure for it. The UID is allocated only on demand, when it's really
         * needed, and in the child process we fork off, since allocation involves NSS checks which are not OK to do
         * from PID 1. To allow the children and PID 1 share information about allocated UIDs we use an anonymous
         * AF_UNIX/SOCK_DGRAM socket (called the "storage socket") that contains at most one datagram with the
         * allocated UID number, plus an fd referencing the lock file for the UID
         * (i.e. /run/systemd/dynamic-uid/$UID). Why involve the socket pair? So that PID 1 and all its children can
         * share the same storage for the UID and lock fd, simply by inheriting the storage socket fds. The socket pair
         * may exist in three different states:
         *
         * a) no datagram stored. This is the initial state. In this case the dynamic user was never realized.
         *
         * b) a datagram containing a UID stored, but no lock fd attached to it. In this case there was already a
         *    statically assigned UID by the same name, which we are reusing.
         *
         * c) a datagram containing a UID stored, and a lock fd is attached to it. In this case we allocated a dynamic
         *    UID and locked it in the file system, using the lock fd.
         *
         * As PID 1 and various children might access the socket pair simultaneously, and pop the datagram or push it
         * back in any time, we also maintain a lock on the socket pair. Note one peculiarity regarding locking here:
         * the UID lock on disk is protected via a BSD file lock (i.e. an fd-bound lock), so that the lock is kept in
         * place as long as there's a reference to the fd open. The lock on the storage socket pair however is a POSIX
         * file lock (i.e. a process-bound lock), as all users share the same fd of this (after all it is anonymous,
         * nobody else could get any access to it except via our own fd) and we want to synchronize access between all
         * processes that have access to it. */

        d = hashmap_get(m->dynamic_users, name);
        if (d) {
                if (ret) {
                        /* We already have a structure for the dynamic user, let's increase the ref count and reuse it */
                        d->n_ref++;
                        *ret = d;
                }
                return 0;
        }

        if (!valid_user_group_name(name, VALID_USER_ALLOW_NUMERIC))
                return -EINVAL;

        if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, storage_socket) < 0)
                return -errno;

        r = dynamic_user_add(m, name, storage_socket, &d);
        if (r < 0)
                return r;

        storage_socket[0] = storage_socket[1] = -EBADF;

        if (ret) {
                d->n_ref++;
                *ret = d;
        }

        return 1;
}

static int make_uid_symlinks(uid_t uid, const char *name, bool b) {

        char path1[STRLEN("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1];
        const char *path2;
        int r = 0, k;

        /* Add direct additional symlinks for direct lookups of dynamic UIDs and their names by userspace code. The
         * only reason we have this is because dbus-daemon cannot use D-Bus for resolving users and groups (since it
         * would be its own client then). We hence keep these world-readable symlinks in place, so that the
         * unprivileged dbus user can read the mappings when it needs them via these symlinks instead of having to go
         * via the bus. Ideally, we'd use the lock files we keep for this anyway, but we can't since we use BSD locks
         * on them and as those may be taken by any user with read access we can't make them world-readable. */

        xsprintf(path1, "/run/systemd/dynamic-uid/direct:" UID_FMT, uid);
        if (unlink(path1) < 0 && errno != ENOENT)
                r = -errno;

        if (b && symlink(name, path1) < 0) {
                k = log_warning_errno(errno, "Failed to symlink \"%s\": %m", path1);
                if (r == 0)
                        r = k;
        }

        path2 = strjoina("/run/systemd/dynamic-uid/direct:", name);
        if (unlink(path2) < 0 && errno != ENOENT) {
                k = -errno;
                if (r == 0)
                        r = k;
        }

        if (b && symlink(path1 + STRLEN("/run/systemd/dynamic-uid/direct:"), path2) < 0) {
                k = log_warning_errno(errno,  "Failed to symlink \"%s\": %m", path2);
                if (r == 0)
                        r = k;
        }

        return r;
}

static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) {

        /* Find a suitable free UID. We use the following strategy to find a suitable UID:
         *
         * 1. Initially, we try to read the UID of a number of specified paths. If any of these UIDs works, we use
         *    them. We use in order to increase the chance of UID reuse, if StateDirectory=, CacheDirectory= or
         *    LogsDirectory= are used, as reusing the UID these directories are owned by saves us from having to
         *    recursively chown() them to new users.
         *
         * 2. If that didn't yield a currently unused UID, we hash the user name, and try to use that. This should be
         *    pretty good, as the use ris by default derived from the unit name, and hence the same service and same
         *    user should usually get the same UID as long as our hashing doesn't clash.
         *
         * 3. Finally, if that didn't work, we randomly pick UIDs, until we find one that is empty.
         *
         * Since the dynamic UID space is relatively small we'll stop trying after 100 iterations, giving up. */

        enum {
                PHASE_SUGGESTED,  /* the first phase, reusing directory ownership UIDs */
                PHASE_HASHED,     /* the second phase, deriving a UID from the username by hashing */
                PHASE_RANDOM,     /* the last phase, randomly picking UIDs */
        } phase = PHASE_SUGGESTED;

        static const uint8_t hash_key[] = {
                0x37, 0x53, 0x7e, 0x31, 0xcf, 0xce, 0x48, 0xf5,
                0x8a, 0xbb, 0x39, 0x57, 0x8d, 0xd9, 0xec, 0x59
        };

        unsigned n_tries = 100, current_suggested = 0;
        int r;

        (void) mkdir("/run/systemd/dynamic-uid", 0755);

        for (;;) {
                char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
                _cleanup_close_ int lock_fd = -EBADF;
                uid_t candidate;
                ssize_t l;

                if (--n_tries <= 0) /* Give up retrying eventually */
                        return -EBUSY;

                switch (phase) {

                case PHASE_SUGGESTED: {
                        struct stat st;

                        if (!suggested_paths || !suggested_paths[current_suggested]) {
                                /* We reached the end of the suggested paths list, let's try by hashing the name */
                                phase = PHASE_HASHED;
                                continue;
                        }

                        if (stat(suggested_paths[current_suggested++], &st) < 0)
                                continue; /* We can't read the UID of this path, but that doesn't matter, just try the next */

                        candidate = st.st_uid;
                        break;
                }

                case PHASE_HASHED:
                        /* A static user by this name does not exist yet. Let's find a free ID then, and use that. We
                         * start with a UID generated as hash from the user name. */
                        candidate = UID_CLAMP_INTO_RANGE(siphash24(name, strlen(name), hash_key));

                        /* If this one fails, we should proceed with random tries */
                        phase = PHASE_RANDOM;
                        break;

                case PHASE_RANDOM:

                        /* Pick another random UID, and see if that works for us. */
                        random_bytes(&candidate, sizeof(candidate));
                        candidate = UID_CLAMP_INTO_RANGE(candidate);
                        break;

                default:
                        assert_not_reached();
                }

                /* Make sure whatever we picked here actually is in the right range */
                if (!uid_is_dynamic(candidate))
                        continue;

                xsprintf(lock_path, "/run/systemd/dynamic-uid/" UID_FMT, candidate);

                for (;;) {
                        struct stat st;

                        lock_fd = open(lock_path, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600);
                        if (lock_fd < 0)
                                return -errno;

                        r = flock(lock_fd, LOCK_EX|LOCK_NB); /* Try to get a BSD file lock on the UID lock file */
                        if (r < 0) {
                                if (IN_SET(errno, EBUSY, EAGAIN))
                                        goto next; /* already in use */

                                return -errno;
                        }

                        if (fstat(lock_fd, &st) < 0)
                                return -errno;
                        if (st.st_nlink > 0)
                                break;

                        /* Oh, bummer, we got the lock, but the file was unlinked between the time we opened it and
                         * got the lock. Close it, and try again. */
                        lock_fd = safe_close(lock_fd);
                }

                /* Some superficial check whether this UID/GID might already be taken by some static user */
                if (getpwuid(candidate) ||
                    getgrgid((gid_t) candidate) ||
                    search_ipc(candidate, (gid_t) candidate) != 0) {
                        (void) unlink(lock_path);
                        continue;
                }

                /* Let's store the user name in the lock file, so that we can use it for looking up the username for a UID */
                l = pwritev(lock_fd,
                            (struct iovec[2]) {
                                    IOVEC_INIT_STRING(name),
                                    IOVEC_INIT((char[1]) { '\n' }, 1),
                            }, 2, 0);
                if (l < 0) {
                        r = -errno;
                        (void) unlink(lock_path);
                        return r;
                }

                (void) ftruncate(lock_fd, l);
                (void) make_uid_symlinks(candidate, name, true); /* also add direct lookup symlinks */

                *ret_uid = candidate;
                return TAKE_FD(lock_fd);

        next:
                ;
        }
}

static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) {
        uid_t uid = UID_INVALID;
        struct iovec iov = IOVEC_INIT(&uid, sizeof(uid));
        int lock_fd;
        ssize_t k;

        assert(d);
        assert(ret_uid);
        assert(ret_lock_fd);

        /* Read the UID and lock fd that is stored in the storage AF_UNIX socket. This should be called with
         * the lock on the socket taken. */

        k = receive_one_fd_iov(d->storage_socket[0], &iov, 1, MSG_DONTWAIT, &lock_fd);
        if (k < 0)
                return (int) k;

        *ret_uid = uid;
        *ret_lock_fd = lock_fd;

        return 0;
}

static int dynamic_user_push(DynamicUser *d, uid_t uid, int lock_fd) {
        struct iovec iov = IOVEC_INIT(&uid, sizeof(uid));

        assert(d);

        /* Store the UID and lock_fd in the storage socket. This should be called with the socket pair lock taken. */
        return send_one_fd_iov(d->storage_socket[1], lock_fd, &iov, 1, MSG_DONTWAIT);
}

static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) {
        char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];

        if (lock_fd < 0)
                return;

        xsprintf(lock_path, "/run/systemd/dynamic-uid/" UID_FMT, uid);
        (void) unlink(lock_path);

        (void) make_uid_symlinks(uid, name, false); /* remove direct lookup symlinks */
}

static int lockfp(int fd, int *fd_lock) {
        if (lockf(fd, F_LOCK, 0) < 0)
                return -errno;
        *fd_lock = fd;
        return 0;
}

static void unlockfp(int *fd_lock) {
        if (*fd_lock < 0)
                return;
        lockf(*fd_lock, F_ULOCK, 0);
        *fd_lock = -EBADF;
}

static int dynamic_user_realize(
                DynamicUser *d,
                char **suggested_dirs,
                uid_t *ret_uid, gid_t *ret_gid,
                bool is_user) {

        _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
        _cleanup_close_ int uid_lock_fd = -EBADF;
        _cleanup_close_ int etc_passwd_lock_fd = -EBADF;
        uid_t num = UID_INVALID; /* a uid if is_user, and a gid otherwise */
        gid_t gid = GID_INVALID; /* a gid if is_user, ignored otherwise */
        bool flush_cache = false;
        int r;

        assert(d);
        assert(is_user == !!ret_uid);
        assert(ret_gid);

        /* Acquire a UID for the user name. This will allocate a UID for the user name if the user doesn't exist
         * yet. If it already exists its existing UID/GID will be reused. */

        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
        if (r < 0)
                return r;

        r = dynamic_user_pop(d, &num, &uid_lock_fd);
        if (r < 0) {
                int new_uid_lock_fd;
                uid_t new_uid;

                if (r != -EAGAIN)
                        return r;

                /* OK, nothing stored yet, let's try to find something useful. While we are working on this release the
                 * lock however, so that nobody else blocks on our NSS lookups. */
                unlockfp(&storage_socket0_lock);

                /* Let's see if a proper, static user or group by this name exists. Try to take the lock on
                 * /etc/passwd, if that fails with EROFS then /etc is read-only. In that case it's fine if we don't
                 * take the lock, given that users can't be added there anyway in this case. */
                etc_passwd_lock_fd = take_etc_passwd_lock(NULL);
                if (etc_passwd_lock_fd < 0 && etc_passwd_lock_fd != -EROFS)
                        return etc_passwd_lock_fd;

                /* First, let's parse this as numeric UID */
                r = parse_uid(d->name, &num);
                if (r < 0) {
                        struct passwd *p;
                        struct group *g;

                        if (is_user) {
                                /* OK, this is not a numeric UID. Let's see if there's a user by this name */
                                p = getpwnam(d->name);
                                if (p) {
                                        num = p->pw_uid;
                                        gid = p->pw_gid;
                                } else {
                                        /* if the user does not exist but the group with the same name exists, refuse operation */
                                        g = getgrnam(d->name);
                                        if (g)
                                                return -EILSEQ;
                                }
                        } else {
                                /* Let's see if there's a group by this name */
                                g = getgrnam(d->name);
                                if (g)
                                        num = (uid_t) g->gr_gid;
                                else {
                                        /* if the group does not exist but the user with the same name exists, refuse operation */
                                        p = getpwnam(d->name);
                                        if (p)
                                                return -EILSEQ;
                                }
                        }
                }

                if (num == UID_INVALID) {
                        /* No static UID assigned yet, excellent. Let's pick a new dynamic one, and lock it. */

                        uid_lock_fd = pick_uid(suggested_dirs, d->name, &num);
                        if (uid_lock_fd < 0)
                                return uid_lock_fd;
                }

                /* So, we found a working UID/lock combination. Let's see if we actually still need it. */
                r = lockfp(d->storage_socket[0], &storage_socket0_lock);
                if (r < 0) {
                        unlink_uid_lock(uid_lock_fd, num, d->name);
                        return r;
                }

                r = dynamic_user_pop(d, &new_uid, &new_uid_lock_fd);
                if (r < 0) {
                        if (r != -EAGAIN) {
                                /* OK, something bad happened, let's get rid of the bits we acquired. */
                                unlink_uid_lock(uid_lock_fd, num, d->name);
                                return r;
                        }

                        /* Great! Nothing is stored here, still. Store our newly acquired data. */
                        flush_cache = true;
                } else {
                        /* Hmm, so as it appears there's now something stored in the storage socket. Throw away what we
                         * acquired, and use what's stored now. */

                        unlink_uid_lock(uid_lock_fd, num, d->name);
                        safe_close(uid_lock_fd);

                        num = new_uid;
                        uid_lock_fd = new_uid_lock_fd;
                }
        } else if (is_user && !uid_is_dynamic(num)) {
                struct passwd *p;

                /* Statically allocated user may have different uid and gid. So, let's obtain the gid. */
                errno = 0;
                p = getpwuid(num);
                if (!p)
                        return errno_or_else(ESRCH);

                gid = p->pw_gid;
        }

        /* If the UID/GID was already allocated dynamically, push the data we popped out back in. If it was already
         * allocated statically, push the UID back too, but do not push the lock fd in. If we allocated the UID
         * dynamically right here, push that in along with the lock fd for it. */
        r = dynamic_user_push(d, num, uid_lock_fd);
        if (r < 0)
                return r;

        if (flush_cache) {
                /* If we allocated a new dynamic UID, refresh nscd, so that it forgets about potentially cached
                 * negative entries. But let's do so after we release the /etc/passwd lock, so that there's no
                 * potential for nscd wanting to lock that for completing the invalidation. */
                etc_passwd_lock_fd = safe_close(etc_passwd_lock_fd);
                (void) nscd_flush_cache(STRV_MAKE("passwd", "group"));
        }

        if (is_user) {
                *ret_uid = num;
                *ret_gid = gid != GID_INVALID ? gid : num;
        } else
                *ret_gid = num;

        return 0;
}

int dynamic_user_current(DynamicUser *d, uid_t *ret) {
        _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
        _cleanup_close_ int lock_fd = -EBADF;
        uid_t uid;
        int r;

        assert(d);

        /* Get the currently assigned UID for the user, if there's any. This simply pops the data from the
         * storage socket, and pushes it back in right-away. */

        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
        if (r < 0)
                return r;

        r = dynamic_user_pop(d, &uid, &lock_fd);
        if (r < 0)
                return r;

        r = dynamic_user_push(d, uid, lock_fd);
        if (r < 0)
                return r;

        if (ret)
                *ret = uid;

        return 0;
}

static DynamicUser* dynamic_user_unref(DynamicUser *d) {
        if (!d)
                return NULL;

        /* Note that this doesn't actually release any resources itself. If a dynamic user should be fully
         * destroyed and its UID released, use dynamic_user_destroy() instead. NB: the dynamic user table may
         * contain entries with no references, which is commonly the case right before a daemon reload. */

        assert(d->n_ref > 0);
        d->n_ref--;

        return NULL;
}

static int dynamic_user_close(DynamicUser *d) {
        _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
        _cleanup_close_ int lock_fd = -EBADF;
        uid_t uid;
        int r;

        /* Release the user ID, by releasing the lock on it, and emptying the storage socket. After this the
         * user is unrealized again, much like it was after it the DynamicUser object was first allocated. */

        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
        if (r < 0)
                return r;

        r = dynamic_user_pop(d, &uid, &lock_fd);
        if (r == -EAGAIN)
                /* User wasn't realized yet, nothing to do. */
                return 0;
        if (r < 0)
                return r;

        /* This dynamic user was realized and dynamically allocated. In this case, let's remove the lock file. */
        unlink_uid_lock(lock_fd, uid, d->name);

        (void) nscd_flush_cache(STRV_MAKE("passwd", "group"));
        return 1;
}

static DynamicUser* dynamic_user_destroy(DynamicUser *d) {
        if (!d)
                return NULL;

        /* Drop a reference to a DynamicUser object, and destroy the user completely if this was the last
         * reference. This is called whenever a service is shut down and wants its dynamic UID gone. Note that
         * dynamic_user_unref() is what is called whenever a service is simply freed, for example during a reload
         * cycle, where the dynamic users should not be destroyed, but our datastructures should. */

        dynamic_user_unref(d);

        if (d->n_ref > 0)
                return NULL;

        (void) dynamic_user_close(d);
        return dynamic_user_free(d);
}

int dynamic_user_serialize(Manager *m, FILE *f, FDSet *fds) {
        DynamicUser *d;

        assert(m);
        assert(f);
        assert(fds);

        /* Dump the dynamic user database into the manager serialization, to deal with daemon reloads. */

        HASHMAP_FOREACH(d, m->dynamic_users) {
                int copy0, copy1;

                copy0 = fdset_put_dup(fds, d->storage_socket[0]);
                if (copy0 < 0)
                        return log_error_errno(copy0, "Failed to add dynamic user storage fd to serialization: %m");

                copy1 = fdset_put_dup(fds, d->storage_socket[1]);
                if (copy1 < 0)
                        return log_error_errno(copy1, "Failed to add dynamic user storage fd to serialization: %m");

                (void) serialize_item_format(f, "dynamic-user", "%s %i %i", d->name, copy0, copy1);
        }

        return 0;
}

void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds) {
        _cleanup_free_ char *name = NULL, *s0 = NULL, *s1 = NULL;
        int r, fd0, fd1;

        assert(m);
        assert(value);
        assert(fds);

        /* Parse the serialization again, after a daemon reload */

        r = extract_many_words(&value, NULL, 0, &name, &s0, &s1, NULL);
        if (r != 3 || !isempty(value)) {
                log_debug("Unable to parse dynamic user line.");
                return;
        }

        if (safe_atoi(s0, &fd0) < 0 || !fdset_contains(fds, fd0)) {
                log_debug("Unable to process dynamic user fd specification.");
                return;
        }

        if (safe_atoi(s1, &fd1) < 0 || !fdset_contains(fds, fd1)) {
                log_debug("Unable to process dynamic user fd specification.");
                return;
        }

        r = dynamic_user_add(m, name, (int[]) { fd0, fd1 }, NULL);
        if (r < 0) {
                log_debug_errno(r, "Failed to add dynamic user: %m");
                return;
        }

        (void) fdset_remove(fds, fd0);
        (void) fdset_remove(fds, fd1);
}

void dynamic_user_vacuum(Manager *m, bool close_user) {
        DynamicUser *d;

        assert(m);

        /* Empty the dynamic user database, optionally cleaning up orphaned dynamic users, i.e. destroy and free users
         * to which no reference exist. This is called after a daemon reload finished, in order to destroy users which
         * might not be referenced anymore. */

        HASHMAP_FOREACH(d, m->dynamic_users) {
                if (d->n_ref > 0)
                        continue;

                if (close_user) {
                        log_debug("Removing orphaned dynamic user %s", d->name);
                        (void) dynamic_user_close(d);
                }

                dynamic_user_free(d);
        }
}

int dynamic_user_lookup_uid(Manager *m, uid_t uid, char **ret) {
        char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
        _cleanup_free_ char *user = NULL;
        uid_t check_uid;
        int r;

        assert(m);
        assert(ret);

        /* A friendly way to translate a dynamic user's UID into a name. */
        if (!uid_is_dynamic(uid))
                return -ESRCH;

        xsprintf(lock_path, "/run/systemd/dynamic-uid/" UID_FMT, uid);
        r = read_one_line_file(lock_path, &user);
        if (IN_SET(r, -ENOENT, 0))
                return -ESRCH;
        if (r < 0)
                return r;

        /* The lock file might be stale, hence let's verify the data before we return it */
        r = dynamic_user_lookup_name(m, user, &check_uid);
        if (r < 0)
                return r;
        if (check_uid != uid) /* lock file doesn't match our own idea */
                return -ESRCH;

        *ret = TAKE_PTR(user);

        return 0;
}

int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret) {
        DynamicUser *d;
        int r;

        assert(m);
        assert(name);

        /* A friendly call for translating a dynamic user's name into its UID */

        d = hashmap_get(m->dynamic_users, name);
        if (!d)
                return -ESRCH;

        r = dynamic_user_current(d, ret);
        if (r == -EAGAIN) /* not realized yet? */
                return -ESRCH;

        return r;
}

int dynamic_creds_acquire(DynamicCreds *creds, Manager *m, const char *user, const char *group) {
        bool acquired = false;
        int r;

        assert(creds);
        assert(m);

        /* A DynamicUser object encapsulates an allocation of both a UID and a GID for a specific name. However, some
         * services use different user and groups. For cases like that there's DynamicCreds containing a pair of user
         * and group. This call allocates a pair. */

        if (!creds->user && user) {
                r = dynamic_user_acquire(m, user, &creds->user);
                if (r < 0)
                        return r;

                acquired = true;
        }

        if (!creds->group) {

                if (creds->user && (!group || streq_ptr(user, group)))
                        creds->group = dynamic_user_ref(creds->user);
                else if (group) {
                        r = dynamic_user_acquire(m, group, &creds->group);
                        if (r < 0) {
                                if (acquired)
                                        creds->user = dynamic_user_unref(creds->user);
                                return r;
                        }
                }
        }

        return 0;
}

int dynamic_creds_realize(DynamicCreds *creds, char **suggested_paths, uid_t *uid, gid_t *gid) {
        uid_t u = UID_INVALID;
        gid_t g = GID_INVALID;
        int r;

        assert(creds);
        assert(uid);
        assert(gid);

        /* Realize both the referenced user and group */

        if (creds->user) {
                r = dynamic_user_realize(creds->user, suggested_paths, &u, &g, true);
                if (r < 0)
                        return r;
        }

        if (creds->group && creds->group != creds->user) {
                r = dynamic_user_realize(creds->group, suggested_paths, NULL, &g, false);
                if (r < 0)
                        return r;
        }

        *uid = u;
        *gid = g;
        return 0;
}

void dynamic_creds_unref(DynamicCreds *creds) {
        assert(creds);

        creds->user = dynamic_user_unref(creds->user);
        creds->group = dynamic_user_unref(creds->group);
}

void dynamic_creds_destroy(DynamicCreds *creds) {
        assert(creds);

        creds->user = dynamic_user_destroy(creds->user);
        creds->group = dynamic_user_destroy(creds->group);
}
