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

#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

#include "alloc-util.h"
#include "def.h"
#include "errno.h"
#include "fd-util.h"
#include "fileio.h"
#include "mkdir.h"
#include "nspawn-setuid.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
#include "util.h"

static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
        int pipe_fds[2], r;
        pid_t pid;

        assert(database);
        assert(key);
        assert(rpid);

        if (pipe2(pipe_fds, O_CLOEXEC) < 0)
                return log_error_errno(errno, "Failed to allocate pipe: %m");

        r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
        if (r < 0) {
                safe_close_pair(pipe_fds);
                return r;
        }
        if (r == 0) {
                char *empty_env = NULL;

                safe_close(pipe_fds[0]);

                if (rearrange_stdio(-1, pipe_fds[1], -1) < 0)
                        _exit(EXIT_FAILURE);

                (void) close_all_fds(NULL, 0);

                (void) rlimit_nofile_safe();

                execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
                execle("/bin/getent", "getent", database, key, NULL, &empty_env);
                _exit(EXIT_FAILURE);
        }

        pipe_fds[1] = safe_close(pipe_fds[1]);

        *rpid = pid;

        return pipe_fds[0];
}

int change_uid_gid_raw(
                uid_t uid,
                gid_t gid,
                const gid_t *supplementary_gids,
                size_t n_supplementary_gids,
                bool chown_stdio) {

        if (!uid_is_valid(uid))
                uid = 0;
        if (!gid_is_valid(gid))
                gid = 0;

        if (chown_stdio) {
                (void) fchown(STDIN_FILENO, uid, gid);
                (void) fchown(STDOUT_FILENO, uid, gid);
                (void) fchown(STDERR_FILENO, uid, gid);
        }

        if (setgroups(n_supplementary_gids, supplementary_gids) < 0)
                return log_error_errno(errno, "Failed to set auxiliary groups: %m");

        if (setresgid(gid, gid, gid) < 0)
                return log_error_errno(errno, "setresgid() failed: %m");

        if (setresuid(uid, uid, uid) < 0)
                return log_error_errno(errno, "setresuid() failed: %m");

        return 0;
}

int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
        char *x, *u, *g, *h;
        _cleanup_free_ gid_t *gids = NULL;
        _cleanup_free_ char *home = NULL, *line = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_close_ int fd = -1;
        unsigned n_gids = 0;
        uid_t uid;
        gid_t gid;
        pid_t pid;
        int r;

        assert(ret_home);

        if (!user || STR_IN_SET(user, "root", "0")) {
                /* Reset everything fully to 0, just in case */

                r = reset_uid_gid();
                if (r < 0)
                        return log_error_errno(r, "Failed to become root: %m");

                *ret_home = NULL;
                return 0;
        }

        /* First, get user credentials */
        fd = spawn_getent("passwd", user, &pid);
        if (fd < 0)
                return fd;

        f = take_fdopen(&fd, "r");
        if (!f)
                return log_oom();

        r = read_line(f, LONG_LINE_MAX, &line);
        if (r == 0)
                return log_error_errno(SYNTHETIC_ERRNO(ESRCH),
                                       "Failed to resolve user %s.", user);
        if (r < 0)
                return log_error_errno(r, "Failed to read from getent: %m");

        (void) wait_for_terminate_and_check("getent passwd", pid, WAIT_LOG);

        x = strchr(line, ':');
        if (!x)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid user field.");

        u = strchr(x+1, ':');
        if (!u)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid password field.");

        u++;
        g = strchr(u, ':');
        if (!g)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid UID field.");

        *g = 0;
        g++;
        x = strchr(g, ':');
        if (!x)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid GID field.");

        *x = 0;
        h = strchr(x+1, ':');
        if (!h)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid GECOS field.");

        h++;
        x = strchr(h, ':');
        if (!x)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "/etc/passwd entry has invalid home directory field.");

        *x = 0;

        r = parse_uid(u, &uid);
        if (r < 0)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "Failed to parse UID of user.");

        r = parse_gid(g, &gid);
        if (r < 0)
                return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                       "Failed to parse GID of user.");

        home = strdup(h);
        if (!home)
                return log_oom();

        f = safe_fclose(f);
        line = mfree(line);

        /* Second, get group memberships */
        fd = spawn_getent("initgroups", user, &pid);
        if (fd < 0)
                return fd;

        f = take_fdopen(&fd, "r");
        if (!f)
                return log_oom();

        r = read_line(f, LONG_LINE_MAX, &line);
        if (r == 0)
                return log_error_errno(SYNTHETIC_ERRNO(ESRCH),
                                       "Failed to resolve user %s.", user);
        if (r < 0)
                return log_error_errno(r, "Failed to read from getent: %m");

        (void) wait_for_terminate_and_check("getent initgroups", pid, WAIT_LOG);

        /* Skip over the username and subsequent separator whitespace */
        x = line;
        x += strcspn(x, WHITESPACE);
        x += strspn(x, WHITESPACE);

        for (const char *p = x;;) {
               _cleanup_free_ char *word = NULL;

                r = extract_first_word(&p, &word, NULL, 0);
                if (r < 0)
                        return log_error_errno(r, "Failed to parse group data from getent: %m");
                if (r == 0)
                        break;

                if (!GREEDY_REALLOC(gids, n_gids+1))
                        return log_oom();

                r = parse_gid(word, &gids[n_gids++]);
                if (r < 0)
                        return log_error_errno(r, "Failed to parse group data from getent: %m");
        }

        r = mkdir_parents(home, 0775);
        if (r < 0)
                return log_error_errno(r, "Failed to make home root directory: %m");

        r = mkdir_safe(home, 0755, uid, gid, 0);
        if (r < 0 && !IN_SET(r, -EEXIST, -ENOTDIR))
                return log_error_errno(r, "Failed to make home directory: %m");

        r = change_uid_gid_raw(uid, gid, gids, n_gids, chown_stdio);
        if (r < 0)
                return r;

        if (ret_home)
                *ret_home = TAKE_PTR(home);

        return 0;
}
