diff options
author | AlexSm <alex@ydb.tech> | 2024-03-05 10:40:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-05 12:40:59 +0300 |
commit | 1ac13c847b5358faba44dbb638a828e24369467b (patch) | |
tree | 07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Modules/spwdmodule.c | |
parent | ffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff) | |
download | ydb-1ac13c847b5358faba44dbb638a828e24369467b.tar.gz |
Library import 16 (#2433)
Co-authored-by: robot-piglet <robot-piglet@yandex-team.com>
Co-authored-by: deshevoy <deshevoy@yandex-team.com>
Co-authored-by: robot-contrib <robot-contrib@yandex-team.com>
Co-authored-by: thegeorg <thegeorg@yandex-team.com>
Co-authored-by: robot-ya-builder <robot-ya-builder@yandex-team.com>
Co-authored-by: svidyuk <svidyuk@yandex-team.com>
Co-authored-by: shadchin <shadchin@yandex-team.com>
Co-authored-by: robot-ratatosk <robot-ratatosk@yandex-team.com>
Co-authored-by: innokentii <innokentii@yandex-team.com>
Co-authored-by: arkady-e1ppa <arkady-e1ppa@yandex-team.com>
Co-authored-by: snermolaev <snermolaev@yandex-team.com>
Co-authored-by: dimdim11 <dimdim11@yandex-team.com>
Co-authored-by: kickbutt <kickbutt@yandex-team.com>
Co-authored-by: abdullinsaid <abdullinsaid@yandex-team.com>
Co-authored-by: korsunandrei <korsunandrei@yandex-team.com>
Co-authored-by: petrk <petrk@yandex-team.com>
Co-authored-by: miroslav2 <miroslav2@yandex-team.com>
Co-authored-by: serjflint <serjflint@yandex-team.com>
Co-authored-by: akhropov <akhropov@yandex-team.com>
Co-authored-by: prettyboy <prettyboy@yandex-team.com>
Co-authored-by: ilikepugs <ilikepugs@yandex-team.com>
Co-authored-by: hiddenpath <hiddenpath@yandex-team.com>
Co-authored-by: mikhnenko <mikhnenko@yandex-team.com>
Co-authored-by: spreis <spreis@yandex-team.com>
Co-authored-by: andreyshspb <andreyshspb@yandex-team.com>
Co-authored-by: dimaandreev <dimaandreev@yandex-team.com>
Co-authored-by: rashid <rashid@yandex-team.com>
Co-authored-by: robot-ydb-importer <robot-ydb-importer@yandex-team.com>
Co-authored-by: r-vetrov <r-vetrov@yandex-team.com>
Co-authored-by: ypodlesov <ypodlesov@yandex-team.com>
Co-authored-by: zaverden <zaverden@yandex-team.com>
Co-authored-by: vpozdyayev <vpozdyayev@yandex-team.com>
Co-authored-by: robot-cozmo <robot-cozmo@yandex-team.com>
Co-authored-by: v-korovin <v-korovin@yandex-team.com>
Co-authored-by: arikon <arikon@yandex-team.com>
Co-authored-by: khoden <khoden@yandex-team.com>
Co-authored-by: psydmm <psydmm@yandex-team.com>
Co-authored-by: robot-javacom <robot-javacom@yandex-team.com>
Co-authored-by: dtorilov <dtorilov@yandex-team.com>
Co-authored-by: sennikovmv <sennikovmv@yandex-team.com>
Co-authored-by: hcpp <hcpp@ydb.tech>
Diffstat (limited to 'contrib/tools/python3/Modules/spwdmodule.c')
-rw-r--r-- | contrib/tools/python3/Modules/spwdmodule.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/contrib/tools/python3/Modules/spwdmodule.c b/contrib/tools/python3/Modules/spwdmodule.c new file mode 100644 index 0000000000..13f1115fee --- /dev/null +++ b/contrib/tools/python3/Modules/spwdmodule.c @@ -0,0 +1,268 @@ + +/* 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}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {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) +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'spwd' is deprecated and slated for removal in " + "Python 3.13", + 7)) { + return NULL; + } + + return PyModuleDef_Init(&spwdmodule); +} |