Home | History | Annotate | Download | only in Modules
      1 
      2 /* UNIX group file access module */
      3 
      4 #include "Python.h"
      5 #include "structseq.h"
      6 #include "posixmodule.h"
      7 
      8 #include <grp.h>
      9 
     10 static PyStructSequence_Field struct_group_type_fields[] = {
     11    {"gr_name", "group name"},
     12    {"gr_passwd", "password"},
     13    {"gr_gid", "group id"},
     14    {"gr_mem", "group members"},
     15    {0}
     16 };
     17 
     18 PyDoc_STRVAR(struct_group__doc__,
     19 "grp.struct_group: Results from getgr*() routines.\n\n\
     20 This object may be accessed either as a tuple of\n\
     21   (gr_name,gr_passwd,gr_gid,gr_mem)\n\
     22 or via the object attributes as named in the above tuple.\n");
     23 
     24 static PyStructSequence_Desc struct_group_type_desc = {
     25    "grp.struct_group",
     26    struct_group__doc__,
     27    struct_group_type_fields,
     28    4,
     29 };
     30 
     31 
     32 static int initialized;
     33 static PyTypeObject StructGrpType;
     34 
     35 static PyObject *
     36 mkgrent(struct group *p)
     37 {
     38     int setIndex = 0;
     39     PyObject *v = PyStructSequence_New(&StructGrpType), *w;
     40     char **member;
     41 
     42     if (v == NULL)
     43         return NULL;
     44 
     45     if ((w = PyList_New(0)) == NULL) {
     46         Py_DECREF(v);
     47         return NULL;
     48     }
     49     for (member = p->gr_mem; *member != NULL; member++) {
     50         PyObject *x = PyString_FromString(*member);
     51         if (x == NULL || PyList_Append(w, x) != 0) {
     52             Py_XDECREF(x);
     53             Py_DECREF(w);
     54             Py_DECREF(v);
     55             return NULL;
     56         }
     57         Py_DECREF(x);
     58     }
     59 
     60 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
     61     SET(setIndex++, PyString_FromString(p->gr_name));
     62 #ifdef __VMS
     63     SET(setIndex++, Py_None);
     64     Py_INCREF(Py_None);
     65 #else
     66     if (p->gr_passwd)
     67 	    SET(setIndex++, PyString_FromString(p->gr_passwd));
     68     else {
     69 	    SET(setIndex++, Py_None);
     70 	    Py_INCREF(Py_None);
     71     }
     72 #endif
     73     SET(setIndex++, _PyInt_FromGid(p->gr_gid));
     74     SET(setIndex++, w);
     75 #undef SET
     76 
     77     if (PyErr_Occurred()) {
     78         Py_DECREF(v);
     79         return NULL;
     80     }
     81 
     82     return v;
     83 }
     84 
     85 static PyObject *
     86 grp_getgrgid(PyObject *self, PyObject *pyo_id)
     87 {
     88     PyObject *py_int_id;
     89     gid_t gid;
     90     struct group *p;
     91 
     92     py_int_id = PyNumber_Int(pyo_id);
     93     if (!py_int_id)
     94             return NULL;
     95     if (!_Py_Gid_Converter(py_int_id, &gid)) {
     96         Py_DECREF(py_int_id);
     97         return NULL;
     98     }
     99     Py_DECREF(py_int_id);
    100 
    101     if ((p = getgrgid(gid)) == NULL) {
    102         if (gid < 0)
    103             PyErr_Format(PyExc_KeyError,
    104                          "getgrgid(): gid not found: %ld", (long)gid);
    105         else
    106             PyErr_Format(PyExc_KeyError,
    107                          "getgrgid(): gid not found: %lu", (unsigned long)gid);
    108         return NULL;
    109     }
    110     return mkgrent(p);
    111 }
    112 
    113 static PyObject *
    114 grp_getgrnam(PyObject *self, PyObject *pyo_name)
    115 {
    116     PyObject *py_str_name;
    117     char *name;
    118     struct group *p;
    119 
    120     py_str_name = PyObject_Str(pyo_name);
    121     if (!py_str_name)
    122 	    return NULL;
    123     name = PyString_AS_STRING(py_str_name);
    124 
    125     if ((p = getgrnam(name)) == NULL) {
    126 	PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
    127 	Py_DECREF(py_str_name);
    128         return NULL;
    129     }
    130 
    131     Py_DECREF(py_str_name);
    132     return mkgrent(p);
    133 }
    134 
    135 static PyObject *
    136 grp_getgrall(PyObject *self, PyObject *ignore)
    137 {
    138     PyObject *d;
    139     struct group *p;
    140 
    141     if ((d = PyList_New(0)) == NULL)
    142         return NULL;
    143     setgrent();
    144     while ((p = getgrent()) != NULL) {
    145         PyObject *v = mkgrent(p);
    146         if (v == NULL || PyList_Append(d, v) != 0) {
    147             Py_XDECREF(v);
    148             Py_DECREF(d);
    149             endgrent();
    150             return NULL;
    151         }
    152         Py_DECREF(v);
    153     }
    154     endgrent();
    155     return d;
    156 }
    157 
    158 static PyMethodDef grp_methods[] = {
    159     {"getgrgid",	grp_getgrgid,	METH_O,
    160      "getgrgid(id) -> (gr_name,gr_passwd,gr_gid,gr_mem)\n\
    161 Return the group database entry for the given numeric group ID.  If\n\
    162 id is not valid, raise KeyError."},
    163     {"getgrnam",	grp_getgrnam,	METH_O,
    164      "getgrnam(name) -> (gr_name,gr_passwd,gr_gid,gr_mem)\n\
    165 Return the group database entry for the given group name.  If\n\
    166 name is not valid, raise KeyError."},
    167     {"getgrall",	grp_getgrall,	METH_NOARGS,
    168      "getgrall() -> list of tuples\n\
    169 Return a list of all available group entries, in arbitrary order.\n\
    170 An entry whose name starts with '+' or '-' represents an instruction\n\
    171 to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
    172     {NULL,		NULL}		/* sentinel */
    173 };
    174 
    175 PyDoc_STRVAR(grp__doc__,
    176 "Access to the Unix group database.\n\
    177 \n\
    178 Group entries are reported as 4-tuples containing the following fields\n\
    179 from the group database, in order:\n\
    180 \n\
    181   gr_name   - name of the group\n\
    182   gr_passwd - group password (encrypted); often empty\n\
    183   gr_gid    - numeric ID of the group\n\
    184   gr_mem    - list of members\n\
    185 \n\
    186 The gid is an integer, name and password are strings.  (Note that most\n\
    187 users are not explicitly listed as members of the groups they are in\n\
    188 according to the password database.  Check both databases to get\n\
    189 complete membership information.)");
    190 
    191 
    192 PyMODINIT_FUNC
    193 initgrp(void)
    194 {
    195     PyObject *m, *d;
    196     m = Py_InitModule3("grp", grp_methods, grp__doc__);
    197     if (m == NULL)
    198         return;
    199     d = PyModule_GetDict(m);
    200     if (!initialized)
    201 	    PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
    202     PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
    203     initialized = 1;
    204 }
    205