blob: b02753f9323e9241bbd5c343cd2eec9d0d361b91 [file] [log] [blame]
Guido van Rossum864407d1991-04-10 19:48:25 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* UNIX password file access module */
Guido van Rossum864407d1991-04-10 19:48:25 +00003
Barry Warsaw50c5cf11996-12-11 16:54:40 +00004#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005#include "posixmodule.h"
Guido van Rossum864407d1991-04-10 19:48:25 +00006
Guido van Rossum864407d1991-04-10 19:48:25 +00007#include <pwd.h>
Guido van Rossum864407d1991-04-10 19:48:25 +00008
Brett Cannon3d25e162014-08-22 14:03:51 -04009#include "clinic/pwdmodule.c.h"
10/*[clinic input]
11output preset file
12module pwd
13[clinic start generated code]*/
14/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bbcf68b1f549f917]*/
15
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000016static PyStructSequence_Field struct_pwd_type_fields[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 {"pw_name", "user name"},
18 {"pw_passwd", "password"},
19 {"pw_uid", "user id"},
20 {"pw_gid", "group id"},
21 {"pw_gecos", "real name"},
22 {"pw_dir", "home directory"},
23 {"pw_shell", "shell program"},
24 {0}
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000025};
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027PyDoc_STRVAR(struct_passwd__doc__,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000028"pwd.struct_passwd: Results from getpw*() routines.\n\n\
29This object may be accessed either as a tuple of\n\
30 (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031or via the object attributes as named in the above tuple.");
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000032
33static PyStructSequence_Desc struct_pwd_type_desc = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 "pwd.struct_passwd",
35 struct_passwd__doc__,
36 struct_pwd_type_fields,
37 7,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000038};
39
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040PyDoc_STRVAR(pwd__doc__,
41"This module provides access to the Unix password database.\n\
Guido van Rossum3e79c441998-03-03 22:03:26 +000042It is available on all Unix versions.\n\
43\n\
44Password database entries are reported as 7-tuples containing the following\n\
45items from the password database (see `<pwd.h>'), in order:\n\
46pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\
47The uid and gid items are integers, all others are strings. An\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048exception is raised if the entry asked for cannot be found.");
Guido van Rossum3e79c441998-03-03 22:03:26 +000049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000051static int initialized;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000052static PyTypeObject StructPwdType;
53
Martin v. Löwis29275c92002-09-17 09:34:06 +000054static void
Neal Norwitzeb8b3a62007-08-24 23:26:23 +000055sets(PyObject *v, int i, const char* val)
Martin v. Löwis29275c92002-09-17 09:34:06 +000056{
Neal Norwitz3d7a90d2007-10-27 05:40:06 +000057 if (val) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 PyObject *o = PyUnicode_DecodeFSDefault(val);
59 PyStructSequence_SET_ITEM(v, i, o);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +000060 }
Martin v. Löwis29275c92002-09-17 09:34:06 +000061 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 PyStructSequence_SET_ITEM(v, i, Py_None);
63 Py_INCREF(Py_None);
Martin v. Löwis29275c92002-09-17 09:34:06 +000064 }
65}
66
Barry Warsaw50c5cf11996-12-11 16:54:40 +000067static PyObject *
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +000068mkpwent(struct passwd *p)
Guido van Rossum864407d1991-04-10 19:48:25 +000069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 int setIndex = 0;
71 PyObject *v = PyStructSequence_New(&StructPwdType);
72 if (v == NULL)
73 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000074
Christian Heimes217cfd12007-12-02 14:31:20 +000075#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
Martin v. Löwis29275c92002-09-17 09:34:06 +000076#define SETS(i,val) sets(v, i, val)
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 SETS(setIndex++, p->pw_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 SETS(setIndex++, p->pw_passwd);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020080 PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid));
81 PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 SETS(setIndex++, p->pw_gecos);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 SETS(setIndex++, p->pw_dir);
84 SETS(setIndex++, p->pw_shell);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000085
86#undef SETS
87#undef SETI
88
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 if (PyErr_Occurred()) {
90 Py_XDECREF(v);
91 return NULL;
92 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 return v;
Guido van Rossum864407d1991-04-10 19:48:25 +000095}
96
Brett Cannon3d25e162014-08-22 14:03:51 -040097/*[clinic input]
98pwd.getpwuid
99
100 uidobj: object
101 /
102
103Return the password database entry for the given numeric user ID.
104
105See `help(pwd)` for more on password database entries.
106[clinic start generated code]*/
Guido van Rossum3e79c441998-03-03 22:03:26 +0000107
Barry Warsaw50c5cf11996-12-11 16:54:40 +0000108static PyObject *
Brett Cannon3d25e162014-08-22 14:03:51 -0400109pwd_getpwuid(PyModuleDef *module, PyObject *uidobj)
110/*[clinic end generated code: output=cba29ae4c2bcb8e1 input=ae64d507a1c6d3e8]*/
Guido van Rossum864407d1991-04-10 19:48:25 +0000111{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200112 uid_t uid;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 struct passwd *p;
Brett Cannon3d25e162014-08-22 14:03:51 -0400114
115 if (!_Py_Uid_Converter(uidobj, &uid)) {
Serhiy Storchaka55e22382013-02-11 20:32:47 +0200116 if (PyErr_ExceptionMatches(PyExc_OverflowError))
117 PyErr_Format(PyExc_KeyError,
118 "getpwuid(): uid not found");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 return NULL;
Serhiy Storchaka55e22382013-02-11 20:32:47 +0200120 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 if ((p = getpwuid(uid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200122 PyObject *uid_obj = _PyLong_FromUid(uid);
123 if (uid_obj == NULL)
124 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 PyErr_Format(PyExc_KeyError,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200126 "getpwuid(): uid not found: %S", uid_obj);
127 Py_DECREF(uid_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 return NULL;
129 }
130 return mkpwent(p);
Guido van Rossum864407d1991-04-10 19:48:25 +0000131}
132
Brett Cannon3d25e162014-08-22 14:03:51 -0400133/*[clinic input]
134pwd.getpwnam
135
136 arg: unicode
137 /
138
139Return the password database entry for the given user name.
140
141See `help(pwd)` for more on password database entries.
142[clinic start generated code]*/
Guido van Rossum3e79c441998-03-03 22:03:26 +0000143
Barry Warsaw50c5cf11996-12-11 16:54:40 +0000144static PyObject *
Brett Cannon3d25e162014-08-22 14:03:51 -0400145pwd_getpwnam_impl(PyModuleDef *module, PyObject *arg)
146/*[clinic end generated code: output=66848d42d386fca3 input=d5f7e700919b02d3]*/
Guido van Rossum864407d1991-04-10 19:48:25 +0000147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 char *name;
149 struct passwd *p;
Brett Cannon3d25e162014-08-22 14:03:51 -0400150 PyObject *bytes, *retval = NULL;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000151
Victor Stinnerae6265f2010-05-15 16:27:27 +0000152 if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 return NULL;
154 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
155 goto out;
156 if ((p = getpwnam(name)) == NULL) {
157 PyErr_Format(PyExc_KeyError,
158 "getpwnam(): name not found: %s", name);
159 goto out;
160 }
161 retval = mkpwent(p);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000162out:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 Py_DECREF(bytes);
164 return retval;
Guido van Rossum864407d1991-04-10 19:48:25 +0000165}
166
Guido van Rossum1171ee61997-08-22 20:42:00 +0000167#ifdef HAVE_GETPWENT
Brett Cannon3d25e162014-08-22 14:03:51 -0400168/*[clinic input]
169pwd.getpwall
170
171Return a list of all available password database entries, in arbitrary order.
172
173See help(pwd) for more on password database entries.
174[clinic start generated code]*/
Guido van Rossum3e79c441998-03-03 22:03:26 +0000175
Barry Warsaw50c5cf11996-12-11 16:54:40 +0000176static PyObject *
Brett Cannon3d25e162014-08-22 14:03:51 -0400177pwd_getpwall_impl(PyModuleDef *module)
178/*[clinic end generated code: output=ab30e37bf26d431d input=d7ecebfd90219b85]*/
Guido van Rossum864407d1991-04-10 19:48:25 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 PyObject *d;
181 struct passwd *p;
182 if ((d = PyList_New(0)) == NULL)
183 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 setpwent();
185 while ((p = getpwent()) != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 PyObject *v = mkpwent(p);
187 if (v == NULL || PyList_Append(d, v) != 0) {
188 Py_XDECREF(v);
189 Py_DECREF(d);
190 endpwent();
191 return NULL;
192 }
193 Py_DECREF(v);
194 }
195 endpwent();
196 return d;
Guido van Rossum864407d1991-04-10 19:48:25 +0000197}
Guido van Rossum1171ee61997-08-22 20:42:00 +0000198#endif
Guido van Rossum864407d1991-04-10 19:48:25 +0000199
Barry Warsaw50c5cf11996-12-11 16:54:40 +0000200static PyMethodDef pwd_methods[] = {
Brett Cannon3d25e162014-08-22 14:03:51 -0400201 PWD_GETPWUID_METHODDEF
202 PWD_GETPWNAM_METHODDEF
Guido van Rossum1171ee61997-08-22 20:42:00 +0000203#ifdef HAVE_GETPWENT
Brett Cannon3d25e162014-08-22 14:03:51 -0400204 PWD_GETPWALL_METHODDEF
Guido van Rossum1171ee61997-08-22 20:42:00 +0000205#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 {NULL, NULL} /* sentinel */
Guido van Rossum864407d1991-04-10 19:48:25 +0000207};
208
Martin v. Löwis1a214512008-06-11 05:26:20 +0000209static struct PyModuleDef pwdmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 PyModuleDef_HEAD_INIT,
211 "pwd",
212 pwd__doc__,
213 -1,
214 pwd_methods,
215 NULL,
216 NULL,
217 NULL,
218 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000219};
220
221
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000222PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000223PyInit_pwd(void)
Guido van Rossum864407d1991-04-10 19:48:25 +0000224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 PyObject *m;
226 m = PyModule_Create(&pwdmodule);
227 if (m == NULL)
228 return NULL;
Fred Drake88c93442002-04-13 21:07:45 +0000229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 if (!initialized) {
Victor Stinner1c8f0592013-07-22 22:24:54 +0200231 if (PyStructSequence_InitType2(&StructPwdType,
232 &struct_pwd_type_desc) < 0)
233 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 initialized = 1;
235 }
236 Py_INCREF((PyObject *) &StructPwdType);
237 PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType);
238 return m;
Guido van Rossum864407d1991-04-10 19:48:25 +0000239}