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