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

#include "chase-symlinks.h"
#include "fd-util.h"
#include "offline-passwd.h"
#include "path-util.h"
#include "user-util.h"

DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(uid_gid_hash_ops, char, string_hash_func, string_compare_func, free);

static int open_passwd_file(const char *root, const char *fname, FILE **ret_file) {
        _cleanup_free_ char *p = NULL;
        _cleanup_close_ int fd = -EBADF;
        _cleanup_fclose_ FILE *f = NULL;

        fd = chase_symlinks_and_open(fname, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC, &p);
        if (fd < 0)
                return fd;

        f = fdopen(fd, "r");
        if (!f)
                return -errno;

        TAKE_FD(fd);

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

                (void) path_extract_filename(fname, &bn);
                log_debug("Reading %s entries from %s...", strna(bn), p);
        }

        *ret_file = TAKE_PTR(f);
        return 0;
}

static int populate_uid_cache(const char *root, Hashmap **ret) {
        _cleanup_(hashmap_freep) Hashmap *cache = NULL;
        int r;

        cache = hashmap_new(&uid_gid_hash_ops);
        if (!cache)
                return -ENOMEM;

        /* The directory list is hardcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
         * could be made configurable, but I don't see the point right now. */

        FOREACH_STRING(fname, "/etc/passwd", "/usr/lib/passwd") {
                _cleanup_fclose_ FILE *f = NULL;

                r = open_passwd_file(root, fname, &f);
                if (r == -ENOENT)
                        continue;
                if (r < 0)
                        return r;

                struct passwd *pw;
                while ((r = fgetpwent_sane(f, &pw)) > 0) {
                        _cleanup_free_ char *n = NULL;

                        n = strdup(pw->pw_name);
                        if (!n)
                                return -ENOMEM;

                        r = hashmap_put(cache, n, UID_TO_PTR(pw->pw_uid));
                        if (IN_SET(r, 0, -EEXIST))
                                continue;
                        if (r < 0)
                                return r;
                        TAKE_PTR(n);
                }
        }

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

static int populate_gid_cache(const char *root, Hashmap **ret) {
        _cleanup_(hashmap_freep) Hashmap *cache = NULL;
        int r;

        cache = hashmap_new(&uid_gid_hash_ops);
        if (!cache)
                return -ENOMEM;

        FOREACH_STRING(fname, "/etc/group", "/usr/lib/group") {
                _cleanup_fclose_ FILE *f = NULL;

                r = open_passwd_file(root, fname, &f);
                if (r == -ENOENT)
                        continue;
                if (r < 0)
                        return r;

                struct group *gr;
                while ((r = fgetgrent_sane(f, &gr)) > 0) {
                        _cleanup_free_ char *n = NULL;

                        n = strdup(gr->gr_name);
                        if (!n)
                                return -ENOMEM;

                        r = hashmap_put(cache, n, GID_TO_PTR(gr->gr_gid));
                        if (IN_SET(r, 0, -EEXIST))
                                continue;
                        if (r < 0)
                                return r;
                        TAKE_PTR(n);
                }
        }

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

int name_to_uid_offline(
                const char *root,
                const char *user,
                uid_t *ret_uid,
                Hashmap **cache) {

        void *found;
        int r;

        assert(user);
        assert(ret_uid);
        assert(cache);

        if (!*cache) {
                r = populate_uid_cache(root, cache);
                if (r < 0)
                        return r;
        }

        found = hashmap_get(*cache, user);
        if (!found)
                return -ESRCH;

        *ret_uid = PTR_TO_UID(found);
        return 0;
}

int name_to_gid_offline(
                const char *root,
                const char *group,
                gid_t *ret_gid,
                Hashmap **cache) {

        void *found;
        int r;

        assert(group);
        assert(ret_gid);
        assert(cache);

        if (!*cache) {
                r = populate_gid_cache(root, cache);
                if (r < 0)
                        return r;
        }

        found = hashmap_get(*cache, group);
        if (!found)
                return -ESRCH;

        *ret_gid = PTR_TO_GID(found);
        return 0;
}
