|  | 
 | /* 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 "structseq.h" | 
 |  | 
 | #include <sys/types.h> | 
 | #ifdef HAVE_SHADOW_H | 
 | #include <shadow.h> | 
 | #endif | 
 |  | 
 |  | 
 | 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_nam", "login name"}, | 
 | 	{"sp_pwd", "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 blocked"}, | 
 | 	{"sp_expire", "#days since 1970-01-01 until account is disabled"}, | 
 | 	{"sp_flag", "reserved"}, | 
 | 	{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_nam,sp_pwd,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, | 
 | }; | 
 |  | 
 | static int initialized; | 
 | static PyTypeObject StructSpwdType; | 
 |  | 
 |  | 
 | static void | 
 | sets(PyObject *v, int i, const char* val) | 
 | { | 
 |   if (val) | 
 | 	  PyStructSequence_SET_ITEM(v, i, PyUnicode_FromString(val)); | 
 |   else { | 
 | 	  PyStructSequence_SET_ITEM(v, i, Py_None); | 
 | 	  Py_INCREF(Py_None); | 
 |   } | 
 | } | 
 |  | 
 | static PyObject *mkspent(struct spwd *p) | 
 | { | 
 | 	int setIndex = 0; | 
 | 	PyObject *v = PyStructSequence_New(&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); | 
 |  | 
 | #undef SETS | 
 | #undef SETI | 
 |  | 
 | 	if (PyErr_Occurred()) { | 
 | 		Py_DECREF(v); | 
 | 		return NULL; | 
 | 	} | 
 |  | 
 | 	return v; | 
 | } | 
 |  | 
 | #endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */ | 
 |  | 
 |  | 
 | #ifdef HAVE_GETSPNAM | 
 |  | 
 | PyDoc_STRVAR(spwd_getspnam__doc__, | 
 | "getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\ | 
 |                     sp_warn, sp_inact, sp_expire, sp_flag)\n\ | 
 | Return the shadow password database entry for the given user name.\n\ | 
 | See spwd.__doc__ for more on shadow password database entries."); | 
 |  | 
 | static PyObject* spwd_getspnam(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	struct spwd *p; | 
 | 	if (!PyArg_ParseTuple(args, "s:getspnam", &name)) | 
 | 		return NULL; | 
 | 	if ((p = getspnam(name)) == NULL) { | 
 | 		PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); | 
 | 		return NULL; | 
 | 	} | 
 | 	return mkspent(p); | 
 | } | 
 |  | 
 | #endif /* HAVE_GETSPNAM */ | 
 |  | 
 | #ifdef HAVE_GETSPENT | 
 |  | 
 | PyDoc_STRVAR(spwd_getspall__doc__, | 
 | "getspall() -> list_of_entries\n\ | 
 | Return a list of all available shadow password database entries, \ | 
 | in arbitrary order.\n\ | 
 | See spwd.__doc__ for more on shadow password database entries."); | 
 |  | 
 | static PyObject * | 
 | spwd_getspall(PyObject *self, PyObject *args) | 
 | { | 
 | 	PyObject *d; | 
 | 	struct spwd *p; | 
 | 	if ((d = PyList_New(0)) == NULL) | 
 | 		return NULL; | 
 | 	setspent(); | 
 | 	while ((p = getspent()) != NULL) { | 
 | 		PyObject *v = mkspent(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	 | 
 | 	{"getspnam",	spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__}, | 
 | #endif | 
 | #ifdef HAVE_GETSPENT | 
 | 	{"getspall",	spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, | 
 | #endif | 
 | 	{NULL,		NULL}		/* sentinel */ | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | static struct PyModuleDef spwdmodule = { | 
 | 	PyModuleDef_HEAD_INIT, | 
 | 	"spwd", | 
 | 	spwd__doc__, | 
 | 	-1, | 
 | 	spwd_methods, | 
 | 	NULL, | 
 | 	NULL, | 
 | 	NULL, | 
 | 	NULL | 
 | }; | 
 |  | 
 | PyMODINIT_FUNC | 
 | PyInit_spwd(void) | 
 | { | 
 | 	PyObject *m; | 
 | 	m=PyModule_Create(&spwdmodule); | 
 | 	if (m == NULL) | 
 | 		return NULL; | 
 | 	if (!initialized) | 
 | 		PyStructSequence_InitType(&StructSpwdType,  | 
 | 					  &struct_spwd_type_desc); | 
 | 	Py_INCREF((PyObject *) &StructSpwdType); | 
 | 	PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); | 
 | 	initialized = 1; | 
 | 	return m; | 
 | } |