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