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 10 static 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 21 PyDoc_STRVAR(struct_passwd__doc__, 22 "pwd.struct_passwd: Results from getpw*() routines.\n\n\ 23 This 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\ 25 or via the object attributes as named in the above tuple."); 26 27 static PyStructSequence_Desc struct_pwd_type_desc = { 28 "pwd.struct_passwd", 29 struct_passwd__doc__, 30 struct_pwd_type_fields, 31 7, 32 }; 33 34 PyDoc_STRVAR(pwd__doc__, 35 "This module provides access to the Unix password database.\n\ 36 It is available on all Unix versions.\n\ 37 \n\ 38 Password database entries are reported as 7-tuples containing the following\n\ 39 items from the password database (see `<pwd.h>'), in order:\n\ 40 pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\ 41 The uid and gid items are integers, all others are strings. An\n\ 42 exception is raised if the entry asked for cannot be found."); 43 44 45 static int initialized; 46 static PyTypeObject StructPwdType; 47 48 static void 49 sets(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 59 static PyObject * 60 mkpwent(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 97 PyDoc_STRVAR(pwd_getpwuid__doc__, 98 "getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\ 99 pw_gid,pw_gecos,pw_dir,pw_shell)\n\ 100 Return the password database entry for the given numeric user ID.\n\ 101 See help(pwd) for more on password database entries."); 102 103 static PyObject * 104 pwd_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 126 PyDoc_STRVAR(pwd_getpwnam__doc__, 127 "getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\ 128 pw_gid,pw_gecos,pw_dir,pw_shell)\n\ 129 Return the password database entry for the given user name.\n\ 130 See help(pwd) for more on password database entries."); 131 132 static PyObject * 133 pwd_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 148 PyDoc_STRVAR(pwd_getpwall__doc__, 149 "getpwall() -> list_of_entries\n\ 150 Return a list of all available password database entries, \ 151 in arbitrary order.\n\ 152 See help(pwd) for more on password database entries."); 153 154 static PyObject * 155 pwd_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 181 static 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 191 PyMODINIT_FUNC 192 initpwd(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