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