1 2/* UNIX password file access module */ 3 4#include "Python.h" 5#include "structseq.h" 6 7#include <sys/types.h> 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 SETI(setIndex++, p->pw_uid); 77 SETI(setIndex++, 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 unsigned int uid; 107 struct passwd *p; 108 if (!PyArg_ParseTuple(args, "I:getpwuid", &uid)) 109 return NULL; 110 if ((p = getpwuid(uid)) == NULL) { 111 PyErr_Format(PyExc_KeyError, 112 "getpwuid(): uid not found: %d", uid); 113 return NULL; 114 } 115 return mkpwent(p); 116} 117 118PyDoc_STRVAR(pwd_getpwnam__doc__, 119"getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\ 120 pw_gid,pw_gecos,pw_dir,pw_shell)\n\ 121Return the password database entry for the given user name.\n\ 122See help(pwd) for more on password database entries."); 123 124static PyObject * 125pwd_getpwnam(PyObject *self, PyObject *args) 126{ 127 char *name; 128 struct passwd *p; 129 if (!PyArg_ParseTuple(args, "s:getpwnam", &name)) 130 return NULL; 131 if ((p = getpwnam(name)) == NULL) { 132 PyErr_Format(PyExc_KeyError, 133 "getpwnam(): name not found: %s", name); 134 return NULL; 135 } 136 return mkpwent(p); 137} 138 139#ifdef HAVE_GETPWENT 140PyDoc_STRVAR(pwd_getpwall__doc__, 141"getpwall() -> list_of_entries\n\ 142Return a list of all available password database entries, \ 143in arbitrary order.\n\ 144See help(pwd) for more on password database entries."); 145 146static PyObject * 147pwd_getpwall(PyObject *self) 148{ 149 PyObject *d; 150 struct passwd *p; 151 if ((d = PyList_New(0)) == NULL) 152 return NULL; 153#if defined(PYOS_OS2) && defined(PYCC_GCC) 154 if ((p = getpwuid(0)) != NULL) { 155#else 156 setpwent(); 157 while ((p = getpwent()) != NULL) { 158#endif 159 PyObject *v = mkpwent(p); 160 if (v == NULL || PyList_Append(d, v) != 0) { 161 Py_XDECREF(v); 162 Py_DECREF(d); 163 endpwent(); 164 return NULL; 165 } 166 Py_DECREF(v); 167 } 168 endpwent(); 169 return d; 170} 171#endif 172 173static PyMethodDef pwd_methods[] = { 174 {"getpwuid", pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__}, 175 {"getpwnam", pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__}, 176#ifdef HAVE_GETPWENT 177 {"getpwall", (PyCFunction)pwd_getpwall, 178 METH_NOARGS, pwd_getpwall__doc__}, 179#endif 180 {NULL, NULL} /* sentinel */ 181}; 182 183PyMODINIT_FUNC 184initpwd(void) 185{ 186 PyObject *m; 187 m = Py_InitModule3("pwd", pwd_methods, pwd__doc__); 188 if (m == NULL) 189 return; 190 191 if (!initialized) 192 PyStructSequence_InitType(&StructPwdType, 193 &struct_pwd_type_desc); 194 Py_INCREF((PyObject *) &StructPwdType); 195 PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType); 196 /* And for b/w compatibility (this was defined by mistake): */ 197 Py_INCREF((PyObject *) &StructPwdType); 198 PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType); 199 initialized = 1; 200} 201