Line data Source code
1 :
2 : /* UNIX shadow password file access module */
3 : /* A lot of code has been taken from pwdmodule.c */
4 : /* For info also see http://www.unixpapa.com/incnote/passwd.html */
5 :
6 : #include "Python.h"
7 :
8 : #include <sys/types.h>
9 : #ifdef HAVE_SHADOW_H
10 : #include <shadow.h>
11 : #endif
12 :
13 :
14 : PyDoc_STRVAR(spwd__doc__,
15 : "This module provides access to the Unix shadow password database.\n\
16 : It is available on various Unix versions.\n\
17 : \n\
18 : Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
19 : containing the following items from the password database (see `<shadow.h>'):\n\
20 : sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
21 : The sp_namp and sp_pwdp are strings, the rest are integers.\n\
22 : An exception is raised if the entry asked for cannot be found.\n\
23 : You have to be root to be able to use this module.");
24 :
25 :
26 : #if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
27 :
28 : static PyStructSequence_Field struct_spwd_type_fields[] = {
29 : {"sp_nam", "login name"},
30 : {"sp_pwd", "encrypted password"},
31 : {"sp_lstchg", "date of last change"},
32 : {"sp_min", "min #days between changes"},
33 : {"sp_max", "max #days between changes"},
34 : {"sp_warn", "#days before pw expires to warn user about it"},
35 : {"sp_inact", "#days after pw expires until account is blocked"},
36 : {"sp_expire", "#days since 1970-01-01 until account is disabled"},
37 : {"sp_flag", "reserved"},
38 : {0}
39 : };
40 :
41 : PyDoc_STRVAR(struct_spwd__doc__,
42 : "spwd.struct_spwd: Results from getsp*() routines.\n\n\
43 : This object may be accessed either as a 9-tuple of\n\
44 : (sp_nam,sp_pwd,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
45 : or via the object attributes as named in the above tuple.");
46 :
47 : static PyStructSequence_Desc struct_spwd_type_desc = {
48 : "spwd.struct_spwd",
49 : struct_spwd__doc__,
50 : struct_spwd_type_fields,
51 : 9,
52 : };
53 :
54 : static int initialized;
55 : static PyTypeObject StructSpwdType;
56 :
57 :
58 : static void
59 0 : sets(PyObject *v, int i, const char* val)
60 : {
61 0 : if (val) {
62 0 : PyObject *o = PyUnicode_DecodeFSDefault(val);
63 0 : PyStructSequence_SET_ITEM(v, i, o);
64 : } else {
65 0 : PyStructSequence_SET_ITEM(v, i, Py_None);
66 0 : Py_INCREF(Py_None);
67 : }
68 0 : }
69 :
70 0 : static PyObject *mkspent(struct spwd *p)
71 : {
72 0 : int setIndex = 0;
73 0 : PyObject *v = PyStructSequence_New(&StructSpwdType);
74 0 : if (v == NULL)
75 0 : return NULL;
76 :
77 : #define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
78 : #define SETS(i,val) sets(v, i, val)
79 :
80 0 : SETS(setIndex++, p->sp_namp);
81 0 : SETS(setIndex++, p->sp_pwdp);
82 0 : SETI(setIndex++, p->sp_lstchg);
83 0 : SETI(setIndex++, p->sp_min);
84 0 : SETI(setIndex++, p->sp_max);
85 0 : SETI(setIndex++, p->sp_warn);
86 0 : SETI(setIndex++, p->sp_inact);
87 0 : SETI(setIndex++, p->sp_expire);
88 0 : SETI(setIndex++, p->sp_flag);
89 :
90 : #undef SETS
91 : #undef SETI
92 :
93 0 : if (PyErr_Occurred()) {
94 0 : Py_DECREF(v);
95 0 : return NULL;
96 : }
97 :
98 0 : return v;
99 : }
100 :
101 : #endif /* HAVE_GETSPNAM || HAVE_GETSPENT */
102 :
103 :
104 : #ifdef HAVE_GETSPNAM
105 :
106 : PyDoc_STRVAR(spwd_getspnam__doc__,
107 : "getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\
108 : sp_warn, sp_inact, sp_expire, sp_flag)\n\
109 : Return the shadow password database entry for the given user name.\n\
110 : See spwd.__doc__ for more on shadow password database entries.");
111 :
112 0 : static PyObject* spwd_getspnam(PyObject *self, PyObject *args)
113 : {
114 : char *name;
115 : struct spwd *p;
116 0 : PyObject *arg, *bytes, *retval = NULL;
117 :
118 0 : if (!PyArg_ParseTuple(args, "U:getspnam", &arg))
119 0 : return NULL;
120 0 : if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
121 0 : return NULL;
122 0 : if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
123 0 : goto out;
124 0 : if ((p = getspnam(name)) == NULL) {
125 0 : PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
126 0 : goto out;
127 : }
128 0 : retval = mkspent(p);
129 : out:
130 0 : Py_DECREF(bytes);
131 0 : return retval;
132 : }
133 :
134 : #endif /* HAVE_GETSPNAM */
135 :
136 : #ifdef HAVE_GETSPENT
137 :
138 : PyDoc_STRVAR(spwd_getspall__doc__,
139 : "getspall() -> list_of_entries\n\
140 : Return a list of all available shadow password database entries, \
141 : in arbitrary order.\n\
142 : See spwd.__doc__ for more on shadow password database entries.");
143 :
144 : static PyObject *
145 0 : spwd_getspall(PyObject *self, PyObject *args)
146 : {
147 : PyObject *d;
148 : struct spwd *p;
149 0 : if ((d = PyList_New(0)) == NULL)
150 0 : return NULL;
151 0 : setspent();
152 0 : while ((p = getspent()) != NULL) {
153 0 : PyObject *v = mkspent(p);
154 0 : if (v == NULL || PyList_Append(d, v) != 0) {
155 0 : Py_XDECREF(v);
156 0 : Py_DECREF(d);
157 0 : endspent();
158 0 : return NULL;
159 : }
160 0 : Py_DECREF(v);
161 : }
162 0 : endspent();
163 0 : return d;
164 : }
165 :
166 : #endif /* HAVE_GETSPENT */
167 :
168 : static PyMethodDef spwd_methods[] = {
169 : #ifdef HAVE_GETSPNAM
170 : {"getspnam", spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__},
171 : #endif
172 : #ifdef HAVE_GETSPENT
173 : {"getspall", spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
174 : #endif
175 : {NULL, NULL} /* sentinel */
176 : };
177 :
178 :
179 :
180 : static struct PyModuleDef spwdmodule = {
181 : PyModuleDef_HEAD_INIT,
182 : "spwd",
183 : spwd__doc__,
184 : -1,
185 : spwd_methods,
186 : NULL,
187 : NULL,
188 : NULL,
189 : NULL
190 : };
191 :
192 : PyMODINIT_FUNC
193 0 : PyInit_spwd(void)
194 : {
195 : PyObject *m;
196 0 : m=PyModule_Create(&spwdmodule);
197 0 : if (m == NULL)
198 0 : return NULL;
199 0 : if (!initialized)
200 0 : PyStructSequence_InitType(&StructSpwdType,
201 : &struct_spwd_type_desc);
202 0 : Py_INCREF((PyObject *) &StructSpwdType);
203 0 : PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
204 0 : initialized = 1;
205 0 : return m;
206 : }
|