| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 14:01:56 -04:00
										 |  |  | #include "clinic/spwdmodule.c.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | module spwd | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2015-04-03 23:53:51 +03:00
										 |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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[] = { | 
					
						
							| 
									
										
										
										
											2013-11-03 19:54:05 -05:00
										 |  |  |     {"sp_namp", "login name"}, | 
					
						
							|  |  |  |     {"sp_pwdp", "encrypted password"}, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"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"}, | 
					
						
							| 
									
										
										
										
											2013-11-03 19:54:05 -05:00
										 |  |  |     {"sp_inact", "#days after pw expires until account is disabled"}, | 
					
						
							|  |  |  |     {"sp_expire", "#days since 1970-01-01 when account expires"}, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"sp_flag", "reserved"}, | 
					
						
							| 
									
										
										
										
											2013-11-03 19:54:05 -05:00
										 |  |  |     {"sp_nam", "login name; deprecated"}, /* Backward compatibility */ | 
					
						
							|  |  |  |     {"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {0} | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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\ | 
					
						
							| 
									
										
										
										
											2013-11-03 19:54:05 -05:00
										 |  |  |   (sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | or via the object attributes as named in the above tuple."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyStructSequence_Desc struct_spwd_type_desc = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     "spwd.struct_spwd", | 
					
						
							|  |  |  |     struct_spwd__doc__, | 
					
						
							|  |  |  |     struct_spwd_type_fields, | 
					
						
							|  |  |  |     9, | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int initialized; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | static PyTypeObject StructSpwdType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2007-08-24 23:26:23 +00:00
										 |  |  | sets(PyObject *v, int i, const char* val) | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-29 15:23:17 +00:00
										 |  |  |   if (val) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |       PyObject *o = PyUnicode_DecodeFSDefault(val); | 
					
						
							|  |  |  |       PyStructSequence_SET_ITEM(v, i, o); | 
					
						
							| 
									
										
										
										
											2009-05-29 15:23:17 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |       PyStructSequence_SET_ITEM(v, i, Py_None); | 
					
						
							|  |  |  |       Py_INCREF(Py_None); | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *mkspent(struct spwd *p) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     int setIndex = 0; | 
					
						
							|  |  |  |     PyObject *v = PyStructSequence_New(&StructSpwdType); | 
					
						
							|  |  |  |     if (v == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-02 14:31:20 +00:00
										 |  |  | #define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
 | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | #define SETS(i,val) sets(v, i, val)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     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); | 
					
						
							| 
									
										
										
										
											2013-11-03 19:54:05 -05:00
										 |  |  |     SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */ | 
					
						
							|  |  |  |     SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef SETS
 | 
					
						
							|  |  |  | #undef SETI
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         Py_DECREF(v); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return v; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_GETSPNAM
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | spwd.getspnam | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  |     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 * | 
					
						
							| 
									
										
										
										
											2016-07-07 17:35:15 +03:00
										 |  |  | spwd_getspnam_impl(PyObject *module, PyObject *arg) | 
					
						
							|  |  |  | /*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     char *name; | 
					
						
							|  |  |  |     struct spwd *p; | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  |     PyObject *bytes, *retval = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-15 16:27:27 +00:00
										 |  |  |     if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-06-28 08:30:06 +03:00
										 |  |  |     /* check for embedded null bytes */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) | 
					
						
							|  |  |  |         goto out; | 
					
						
							|  |  |  |     if ((p = getspnam(name)) == NULL) { | 
					
						
							| 
									
										
										
										
											2016-03-19 11:44:17 +02:00
										 |  |  |         if (errno != 0) | 
					
						
							|  |  |  |             PyErr_SetFromErrno(PyExc_OSError); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         goto out; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     retval = mkspent(p); | 
					
						
							| 
									
										
										
										
											2009-05-29 15:23:17 +00:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_DECREF(bytes); | 
					
						
							|  |  |  |     return retval; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-24 23:33:50 +00:00
										 |  |  | #endif /* HAVE_GETSPNAM */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_GETSPENT
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  | /*[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]*/ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2016-07-07 17:35:15 +03:00
										 |  |  | spwd_getspall_impl(PyObject *module) | 
					
						
							|  |  |  | /*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* HAVE_GETSPENT */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef spwd_methods[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | #ifdef HAVE_GETSPNAM
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  |     SPWD_GETSPNAM_METHODDEF | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_GETSPENT
 | 
					
						
							| 
									
										
										
										
											2014-08-22 13:59:24 -04:00
										 |  |  |     SPWD_GETSPALL_METHODDEF | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {NULL,              NULL}           /* sentinel */ | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef spwdmodule = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     "spwd", | 
					
						
							|  |  |  |     spwd__doc__, | 
					
						
							|  |  |  |     -1, | 
					
						
							|  |  |  |     spwd_methods, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | PyMODINIT_FUNC | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | PyInit_spwd(void) | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *m; | 
					
						
							|  |  |  |     m=PyModule_Create(&spwdmodule); | 
					
						
							|  |  |  |     if (m == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2013-07-22 22:24:54 +02:00
										 |  |  |     if (!initialized) { | 
					
						
							|  |  |  |         if (PyStructSequence_InitType2(&StructSpwdType, | 
					
						
							|  |  |  |                                        &struct_spwd_type_desc) < 0) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_INCREF((PyObject *) &StructSpwdType); | 
					
						
							|  |  |  |     PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); | 
					
						
							|  |  |  |     initialized = 1; | 
					
						
							|  |  |  |     return m; | 
					
						
							| 
									
										
										
										
											2005-01-23 09:27:24 +00:00
										 |  |  | } |