Line data Source code
1 :
2 : /* UNIX password file access module */
3 :
4 : #include "Python.h"
5 :
6 : #include <sys/types.h>
7 : #include <pwd.h>
8 :
9 : static PyStructSequence_Field struct_pwd_type_fields[] = {
10 : {"pw_name", "user name"},
11 : {"pw_passwd", "password"},
12 : {"pw_uid", "user id"},
13 : {"pw_gid", "group id"},
14 : {"pw_gecos", "real name"},
15 : {"pw_dir", "home directory"},
16 : {"pw_shell", "shell program"},
17 : {0}
18 : };
19 :
20 : PyDoc_STRVAR(struct_passwd__doc__,
21 : "pwd.struct_passwd: Results from getpw*() routines.\n\n\
22 : This object may be accessed either as a tuple of\n\
23 : (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\
24 : or via the object attributes as named in the above tuple.");
25 :
26 : static PyStructSequence_Desc struct_pwd_type_desc = {
27 : "pwd.struct_passwd",
28 : struct_passwd__doc__,
29 : struct_pwd_type_fields,
30 : 7,
31 : };
32 :
33 : PyDoc_STRVAR(pwd__doc__,
34 : "This module provides access to the Unix password database.\n\
35 : It is available on all Unix versions.\n\
36 : \n\
37 : Password database entries are reported as 7-tuples containing the following\n\
38 : items from the password database (see `<pwd.h>'), in order:\n\
39 : pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\
40 : The uid and gid items are integers, all others are strings. An\n\
41 : exception is raised if the entry asked for cannot be found.");
42 :
43 :
44 : static int initialized;
45 : static PyTypeObject StructPwdType;
46 :
47 : static void
48 0 : sets(PyObject *v, int i, const char* val)
49 : {
50 0 : if (val) {
51 0 : PyObject *o = PyUnicode_DecodeFSDefault(val);
52 0 : PyStructSequence_SET_ITEM(v, i, o);
53 : }
54 : else {
55 0 : PyStructSequence_SET_ITEM(v, i, Py_None);
56 0 : Py_INCREF(Py_None);
57 : }
58 0 : }
59 :
60 : static PyObject *
61 0 : mkpwent(struct passwd *p)
62 : {
63 0 : int setIndex = 0;
64 0 : PyObject *v = PyStructSequence_New(&StructPwdType);
65 0 : if (v == NULL)
66 0 : return NULL;
67 :
68 : #define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
69 : #define SETS(i,val) sets(v, i, val)
70 :
71 0 : SETS(setIndex++, p->pw_name);
72 : #ifdef __VMS
73 : SETS(setIndex++, "");
74 : #else
75 0 : SETS(setIndex++, p->pw_passwd);
76 : #endif
77 0 : SETI(setIndex++, p->pw_uid);
78 0 : SETI(setIndex++, p->pw_gid);
79 : #ifdef __VMS
80 : SETS(setIndex++, "");
81 : #else
82 0 : SETS(setIndex++, p->pw_gecos);
83 : #endif
84 0 : SETS(setIndex++, p->pw_dir);
85 0 : SETS(setIndex++, p->pw_shell);
86 :
87 : #undef SETS
88 : #undef SETI
89 :
90 0 : if (PyErr_Occurred()) {
91 0 : Py_XDECREF(v);
92 0 : return NULL;
93 : }
94 :
95 0 : return v;
96 : }
97 :
98 : PyDoc_STRVAR(pwd_getpwuid__doc__,
99 : "getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\
100 : pw_gid,pw_gecos,pw_dir,pw_shell)\n\
101 : Return the password database entry for the given numeric user ID.\n\
102 : See help(pwd) for more on password database entries.");
103 :
104 : static PyObject *
105 0 : pwd_getpwuid(PyObject *self, PyObject *args)
106 : {
107 : unsigned int uid;
108 : struct passwd *p;
109 0 : if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
110 0 : return NULL;
111 0 : if ((p = getpwuid(uid)) == NULL) {
112 0 : PyErr_Format(PyExc_KeyError,
113 : "getpwuid(): uid not found: %d", uid);
114 0 : return NULL;
115 : }
116 0 : return mkpwent(p);
117 : }
118 :
119 : PyDoc_STRVAR(pwd_getpwnam__doc__,
120 : "getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\
121 : pw_gid,pw_gecos,pw_dir,pw_shell)\n\
122 : Return the password database entry for the given user name.\n\
123 : See help(pwd) for more on password database entries.");
124 :
125 : static PyObject *
126 0 : pwd_getpwnam(PyObject *self, PyObject *args)
127 : {
128 : char *name;
129 : struct passwd *p;
130 0 : PyObject *arg, *bytes, *retval = NULL;
131 :
132 0 : if (!PyArg_ParseTuple(args, "U:getpwnam", &arg))
133 0 : return NULL;
134 0 : if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
135 0 : return NULL;
136 0 : if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
137 0 : goto out;
138 0 : if ((p = getpwnam(name)) == NULL) {
139 0 : PyErr_Format(PyExc_KeyError,
140 : "getpwnam(): name not found: %s", name);
141 0 : goto out;
142 : }
143 0 : retval = mkpwent(p);
144 : out:
145 0 : Py_DECREF(bytes);
146 0 : return retval;
147 : }
148 :
149 : #ifdef HAVE_GETPWENT
150 : PyDoc_STRVAR(pwd_getpwall__doc__,
151 : "getpwall() -> list_of_entries\n\
152 : Return a list of all available password database entries, \
153 : in arbitrary order.\n\
154 : See help(pwd) for more on password database entries.");
155 :
156 : static PyObject *
157 0 : pwd_getpwall(PyObject *self)
158 : {
159 : PyObject *d;
160 : struct passwd *p;
161 0 : if ((d = PyList_New(0)) == NULL)
162 0 : return NULL;
163 : #if defined(PYOS_OS2) && defined(PYCC_GCC)
164 : if ((p = getpwuid(0)) != NULL) {
165 : #else
166 0 : setpwent();
167 0 : while ((p = getpwent()) != NULL) {
168 : #endif
169 0 : PyObject *v = mkpwent(p);
170 0 : if (v == NULL || PyList_Append(d, v) != 0) {
171 0 : Py_XDECREF(v);
172 0 : Py_DECREF(d);
173 0 : endpwent();
174 0 : return NULL;
175 : }
176 0 : Py_DECREF(v);
177 : }
178 0 : endpwent();
179 0 : return d;
180 : }
181 : #endif
182 :
183 : static PyMethodDef pwd_methods[] = {
184 : {"getpwuid", pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__},
185 : {"getpwnam", pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__},
186 : #ifdef HAVE_GETPWENT
187 : {"getpwall", (PyCFunction)pwd_getpwall,
188 : METH_NOARGS, pwd_getpwall__doc__},
189 : #endif
190 : {NULL, NULL} /* sentinel */
191 : };
192 :
193 : static struct PyModuleDef pwdmodule = {
194 : PyModuleDef_HEAD_INIT,
195 : "pwd",
196 : pwd__doc__,
197 : -1,
198 : pwd_methods,
199 : NULL,
200 : NULL,
201 : NULL,
202 : NULL
203 : };
204 :
205 :
206 : PyMODINIT_FUNC
207 0 : PyInit_pwd(void)
208 : {
209 : PyObject *m;
210 0 : m = PyModule_Create(&pwdmodule);
211 0 : if (m == NULL)
212 0 : return NULL;
213 :
214 0 : if (!initialized) {
215 0 : PyStructSequence_InitType(&StructPwdType,
216 : &struct_pwd_type_desc);
217 0 : initialized = 1;
218 : }
219 0 : Py_INCREF((PyObject *) &StructPwdType);
220 0 : PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType);
221 0 : return m;
222 : }
|