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

#include "env-util.h"
#include "fd-util.h"
#include "nss-systemd.h"
#include "strv.h"
#include "user-record-nss.h"
#include "user-record.h"
#include "user-util.h"
#include "userdb-glue.h"
#include "userdb.h"

UserDBFlags nss_glue_userdb_flags(void) {
        UserDBFlags flags = USERDB_EXCLUDE_NSS;

        /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
        if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                flags |= USERDB_EXCLUDE_DYNAMIC_USER;

        return flags;
}

int nss_pack_user_record(
                UserRecord *hr,
                struct passwd *pwd,
                char *buffer,
                size_t buflen) {

        const char *rn, *hd, *shell;
        size_t required;

        assert(hr);
        assert(pwd);

        assert(hr->user_name);
        required = strlen(hr->user_name) + 1;

        required += 2; /* strlen(PASSWORD_SEE_SHADOW) + 1 */

        assert_se(rn = user_record_real_name(hr));
        required += strlen(rn) + 1;

        assert_se(hd = user_record_home_directory(hr));
        required += strlen(hd) + 1;

        assert_se(shell = user_record_shell(hr));
        required += strlen(shell) + 1;

        if (buflen < required)
                return -ERANGE;

        *pwd = (struct passwd) {
                .pw_name = buffer,
                .pw_uid = hr->uid,
                .pw_gid = user_record_gid(hr),
        };

        assert(buffer);

        pwd->pw_passwd = stpcpy(pwd->pw_name, hr->user_name) + 1;
        pwd->pw_gecos = stpcpy(pwd->pw_passwd, PASSWORD_SEE_SHADOW) + 1;
        pwd->pw_dir = stpcpy(pwd->pw_gecos, rn) + 1;
        pwd->pw_shell = stpcpy(pwd->pw_dir, hd) + 1;
        strcpy(pwd->pw_shell, shell);

        return 0;
}

enum nss_status userdb_getpwnam(
                const char *name,
                struct passwd *pwd,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
        int r;

        assert(pwd);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = userdb_by_name(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &hr);
        if (r == -ESRCH)
                return NSS_STATUS_NOTFOUND;
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        r = nss_pack_user_record(hr, pwd, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}

enum nss_status userdb_getpwuid(
                uid_t uid,
                struct passwd *pwd,
                char *buffer,
                size_t buflen,
                int *errnop) {

        _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
        int r;

        assert(pwd);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = userdb_by_uid(uid, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &hr);
        if (r == -ESRCH)
                return NSS_STATUS_NOTFOUND;
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        r = nss_pack_user_record(hr, pwd, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}

int nss_pack_user_record_shadow(
                UserRecord *hr,
                struct spwd *spwd,
                char *buffer,
                size_t buflen) {

        const char *hashed;
        size_t required;

        assert(hr);
        assert(spwd);

        assert(hr->user_name);
        required = strlen(hr->user_name) + 1;

        assert_se(hashed = strv_isempty(hr->hashed_password) ? PASSWORD_LOCKED_AND_INVALID : hr->hashed_password[0]);
        required += strlen(hashed) + 1;

        if (buflen < required)
                return -ERANGE;

        *spwd = (struct spwd) {
                .sp_namp = buffer,
                .sp_lstchg = hr->last_password_change_usec == 0 ? 1 :               /* map 0 to 1, since 0 means please change password on next login */
                             hr->last_password_change_usec == UINT64_MAX ? -1 :
                             (long int) (hr->last_password_change_usec / USEC_PER_DAY),
                .sp_min = hr->password_change_min_usec != UINT64_MAX ? (long int) (hr->password_change_min_usec / USEC_PER_DAY) : -1,
                .sp_max = hr->password_change_max_usec != UINT64_MAX ? (long int) (hr->password_change_max_usec / USEC_PER_DAY) : -1,
                .sp_warn = hr->password_change_warn_usec != UINT64_MAX ? (long int) (hr->password_change_warn_usec / USEC_PER_DAY) : -1,
                .sp_inact = hr->password_change_inactive_usec != UINT64_MAX ? (long int) (hr->password_change_inactive_usec / USEC_PER_DAY) : -1,
                .sp_expire = hr->locked > 0 || hr->not_after_usec == 0 ? 1 : /* already expired/locked */
                             hr->not_after_usec == UINT64_MAX ? -1 :
                             (long int) (hr->not_after_usec / USEC_PER_DAY),
                .sp_flag = ULONG_MAX,
        };

        assert(buffer);

        spwd->sp_pwdp = stpcpy(spwd->sp_namp, hr->user_name) + 1;
        strcpy(spwd->sp_pwdp, hashed);

        return 0;
}

enum nss_status userdb_getspnam(
                const char *name,
                struct spwd *spwd,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
        int r;

        assert(spwd);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = userdb_by_name(name, nss_glue_userdb_flags(), &hr);
        if (r == -ESRCH)
                return NSS_STATUS_NOTFOUND;
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        if (hr->incomplete) /* protected records missing? */
                return NSS_STATUS_NOTFOUND;

        r = nss_pack_user_record_shadow(hr, spwd, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}

int nss_pack_group_record(
                GroupRecord *g,
                char **extra_members,
                struct group *gr,
                char *buffer,
                size_t buflen) {

        char **array = NULL, *p, **m;
        size_t required, n = 0, i = 0;

        assert(g);
        assert(gr);

        assert(g->group_name);
        required = strlen(g->group_name) + 1;

        STRV_FOREACH(m, g->members) {
                required += sizeof(char*);  /* space for ptr array entry */
                required += strlen(*m) + 1;
                n++;
        }
        STRV_FOREACH(m, extra_members) {
                if (strv_contains(g->members, *m))
                        continue;

                required += sizeof(char*);
                required += strlen(*m) + 1;
                n++;
        }

        required += sizeof(char*); /* trailing NULL in ptr array entry */

        if (buflen < required)
                return -ERANGE;

        array = (char**) buffer; /* place ptr array at beginning of buffer, under assumption buffer is aligned */
        p = buffer + sizeof(void*) * (n + 1); /* place member strings right after the ptr array */

        STRV_FOREACH(m, g->members) {
                array[i++] = p;
                p = stpcpy(p, *m) + 1;
        }
        STRV_FOREACH(m, extra_members) {
                if (strv_contains(g->members, *m))
                        continue;

                array[i++] = p;
                p = stpcpy(p, *m) + 1;
        }

        assert_se(i == n);
        array[n] = NULL;

        *gr = (struct group) {
                .gr_name = strcpy(p, g->group_name),
                .gr_gid = g->gid,
                .gr_passwd = (char*) PASSWORD_SEE_SHADOW,
                .gr_mem = array,
        };

        return 0;
}

enum nss_status userdb_getgrnam(
                const char *name,
                struct group *gr,
                char *buffer,
                size_t buflen,
                int *errnop) {

        _cleanup_(group_record_unrefp) GroupRecord *g = NULL;
        _cleanup_strv_free_ char **members = NULL;
        int r;

        assert(gr);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = groupdb_by_name(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &g);
        if (r < 0 && r != -ESRCH) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        r = membershipdb_by_group_strv(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &members);
        if (r < 0 && r != -ESRCH) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        if (!g) {
                _unused_ _cleanup_(_nss_systemd_unblockp) bool blocked = false;

                if (strv_isempty(members))
                        return NSS_STATUS_NOTFOUND;

                /* Grmbl, so we are supposed to extend a group entry, but the group entry itself is not
                 * accessible via non-NSS. Hence let's do what we have to do, and query NSS after all to
                 * acquire it, so that we can extend it (that's because glibc's group merging feature will
                 * merge groups only if both GID and name match and thus we need to have both first). It
                 * sucks behaving recursively likely this, but it's apparently what everybody does. We break
                 * the recursion for ourselves via the _nss_systemd_block_nss() lock. */

                r = _nss_systemd_block(true);
                if (r < 0)
                        return r;

                blocked = true;

                r = nss_group_record_by_name(name, false, &g);
                if (r == -ESRCH)
                        return NSS_STATUS_NOTFOUND;
                if (r < 0) {
                        *errnop = -r;
                        return NSS_STATUS_UNAVAIL;
                }
        }

        r = nss_pack_group_record(g, members, gr, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}

enum nss_status userdb_getgrgid(
                gid_t gid,
                struct group *gr,
                char *buffer,
                size_t buflen,
                int *errnop) {


        _cleanup_(group_record_unrefp) GroupRecord *g = NULL;
        _cleanup_strv_free_ char **members = NULL;
        bool from_nss;
        int r;

        assert(gr);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = groupdb_by_gid(gid, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &g);
        if (r < 0 && r != -ESRCH) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        if (!g) {
                _unused_ _cleanup_(_nss_systemd_unblockp) bool blocked = false;

                /* So, quite possibly we have to extend an existing group record with additional members. But
                 * to do this we need to know the group name first. The group didn't exist via non-NSS
                 * queries though, hence let's try to acquire it here recursively via NSS. */

                r = _nss_systemd_block(true);
                if (r < 0)
                        return r;

                blocked = true;

                r = nss_group_record_by_gid(gid, false, &g);
                if (r == -ESRCH)
                        return NSS_STATUS_NOTFOUND;
                if (r < 0) {
                        *errnop = -r;
                        return NSS_STATUS_UNAVAIL;
                }

                from_nss = true;
        } else
                from_nss = false;

        r = membershipdb_by_group_strv(g->group_name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &members);
        if (r < 0 && r != -ESRCH) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        /* If we acquired the record via NSS then there's no reason to respond unless we have to augment the
         * list of members of the group */
        if (from_nss && strv_isempty(members))
                return NSS_STATUS_NOTFOUND;

        r = nss_pack_group_record(g, members, gr, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}

int nss_pack_group_record_shadow(
                GroupRecord *hr,
                struct sgrp *sgrp,
                char *buffer,
                size_t buflen) {

        const char *hashed;
        size_t required;

        assert(hr);
        assert(sgrp);

        assert(hr->group_name);
        required = strlen(hr->group_name) + 1;

        assert_se(hashed = strv_isempty(hr->hashed_password) ? PASSWORD_LOCKED_AND_INVALID : hr->hashed_password[0]);
        required += strlen(hashed) + 1;

        if (buflen < required)
                return -ERANGE;

        *sgrp = (struct sgrp) {
                .sg_namp = buffer,
        };

        assert(buffer);

        sgrp->sg_passwd = stpcpy(sgrp->sg_namp, hr->group_name) + 1;
        strcpy(sgrp->sg_passwd, hashed);

        return 0;
}

enum nss_status userdb_getsgnam(
                const char *name,
                struct sgrp *sgrp,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(group_record_unrefp) GroupRecord *hr = NULL;
        int r;

        assert(sgrp);
        assert(errnop);

        if (_nss_systemd_is_blocked())
                return NSS_STATUS_NOTFOUND;

        r = groupdb_by_name(name, nss_glue_userdb_flags(), &hr);
        if (r == -ESRCH)
                return NSS_STATUS_NOTFOUND;
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_UNAVAIL;
        }

        if (hr->incomplete) /* protected records missing? */
                return NSS_STATUS_NOTFOUND;

        r = nss_pack_group_record_shadow(hr, sgrp, buffer, buflen);
        if (r < 0) {
                *errnop = -r;
                return NSS_STATUS_TRYAGAIN;
        }

        return NSS_STATUS_SUCCESS;
}
