
/* UNIX shadow password file access module */
/* A lot of code has been taken from pwdmodule.c */
/* For info also see http://www.unixpapa.com/incnote/passwd.html */

#include "Python.h"

#include <sys/types.h>
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif

#include "clinic/spwdmodule.c.h"

/*[clinic input]
module spwd
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/

PyDoc_STRVAR(spwd__doc__,
"This module provides access to the Unix shadow password database.\n\
It is available on various Unix versions.\n\
\n\
Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
containing the following items from the password database (see `<shadow.h>'):\n\
sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
The sp_namp and sp_pwdp are strings, the rest are integers.\n\
An exception is raised if the entry asked for cannot be found.\n\
You have to be root to be able to use this module.");


#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)

static PyStructSequence_Field struct_spwd_type_fields[] = {
    {"sp_namp", "login name"},
    {"sp_pwdp", "encrypted password"},
    {"sp_lstchg", "date of last change"},
    {"sp_min", "min #days between changes"},
    {"sp_max", "max #days between changes"},
    {"sp_warn", "#days before pw expires to warn user about it"},
    {"sp_inact", "#days after pw expires until account is disabled"},
    {"sp_expire", "#days since 1970-01-01 when account expires"},
    {"sp_flag", "reserved"},
    {"sp_nam", "login name; deprecated"}, /* Backward compatibility */
    {"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */
    {0}
};

PyDoc_STRVAR(struct_spwd__doc__,
"spwd.struct_spwd: Results from getsp*() routines.\n\n\
This object may be accessed either as a 9-tuple of\n\
  (sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
or via the object attributes as named in the above tuple.");

static PyStructSequence_Desc struct_spwd_type_desc = {
    "spwd.struct_spwd",
    struct_spwd__doc__,
    struct_spwd_type_fields,
    9,
};

typedef struct {
    PyTypeObject *StructSpwdType;
} spwdmodulestate;

static inline spwdmodulestate*
get_spwd_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (spwdmodulestate *)state;
}

static struct PyModuleDef spwdmodule;

static void
sets(PyObject *v, int i, const char* val)
{
  if (val) {
      PyObject *o = PyUnicode_DecodeFSDefault(val);
      PyStructSequence_SET_ITEM(v, i, o);
  } else {
      PyStructSequence_SET_ITEM(v, i, Py_None);
      Py_INCREF(Py_None);
  }
}

static PyObject *mkspent(PyObject *module, struct spwd *p)
{
    int setIndex = 0;
    PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType);
    if (v == NULL)
        return NULL;

#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
#define SETS(i,val) sets(v, i, val)

    SETS(setIndex++, p->sp_namp);
    SETS(setIndex++, p->sp_pwdp);
    SETI(setIndex++, p->sp_lstchg);
    SETI(setIndex++, p->sp_min);
    SETI(setIndex++, p->sp_max);
    SETI(setIndex++, p->sp_warn);
    SETI(setIndex++, p->sp_inact);
    SETI(setIndex++, p->sp_expire);
    SETI(setIndex++, p->sp_flag);
    SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */
    SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */

#undef SETS
#undef SETI

    if (PyErr_Occurred()) {
        Py_DECREF(v);
        return NULL;
    }

    return v;
}

#endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */


#ifdef HAVE_GETSPNAM

/*[clinic input]
spwd.getspnam

    arg: unicode
    /

Return the shadow password database entry for the given user name.

See `help(spwd)` for more on shadow password database entries.
[clinic start generated code]*/

static PyObject *
spwd_getspnam_impl(PyObject *module, PyObject *arg)
/*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/
{
    char *name;
    struct spwd *p;
    PyObject *bytes, *retval = NULL;

    if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
        return NULL;
    /* check for embedded null bytes */
    if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
        goto out;
    if ((p = getspnam(name)) == NULL) {
        if (errno != 0)
            PyErr_SetFromErrno(PyExc_OSError);
        else
            PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
        goto out;
    }
    retval = mkspent(module, p);
out:
    Py_DECREF(bytes);
    return retval;
}

#endif /* HAVE_GETSPNAM */

#ifdef HAVE_GETSPENT

/*[clinic input]
spwd.getspall

Return a list of all available shadow password database entries, in arbitrary order.

See `help(spwd)` for more on shadow password database entries.
[clinic start generated code]*/

static PyObject *
spwd_getspall_impl(PyObject *module)
/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/
{
    PyObject *d;
    struct spwd *p;
    if ((d = PyList_New(0)) == NULL)
        return NULL;
    setspent();
    while ((p = getspent()) != NULL) {
        PyObject *v = mkspent(module, p);
        if (v == NULL || PyList_Append(d, v) != 0) {
            Py_XDECREF(v);
            Py_DECREF(d);
            endspent();
            return NULL;
        }
        Py_DECREF(v);
    }
    endspent();
    return d;
}

#endif /* HAVE_GETSPENT */

static PyMethodDef spwd_methods[] = {
#ifdef HAVE_GETSPNAM
    SPWD_GETSPNAM_METHODDEF
#endif
#ifdef HAVE_GETSPENT
    SPWD_GETSPALL_METHODDEF
#endif
    {NULL,              NULL}           /* sentinel */
};

static int
spwdmodule_exec(PyObject *module)
{
    spwdmodulestate *state = get_spwd_state(module);

    state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc);
    if (state->StructSpwdType == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->StructSpwdType) < 0) {
        return -1;
    }
    return 0;
}

static PyModuleDef_Slot spwdmodule_slots[] = {
    {Py_mod_exec, spwdmodule_exec},
    {0, NULL}
};

static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) {
    Py_VISIT(get_spwd_state(m)->StructSpwdType);
    return 0;
}

static int spwdmodule_clear(PyObject *m) {
    Py_CLEAR(get_spwd_state(m)->StructSpwdType);
    return 0;
}

static void spwdmodule_free(void *m) {
    spwdmodule_clear((PyObject *)m);
}

static struct PyModuleDef spwdmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "spwd",
    .m_doc = spwd__doc__,
    .m_size = sizeof(spwdmodulestate),
    .m_methods = spwd_methods,
    .m_slots = spwdmodule_slots,
    .m_traverse = spwdmodule_traverse,
    .m_clear = spwdmodule_clear,
    .m_free = spwdmodule_free,
};

PyMODINIT_FUNC
PyInit_spwd(void)
{
    return PyModuleDef_Init(&spwdmodule);
}
