Home | History | Annotate | Download | only in Modules
      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