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