blob: 3a134a0333e71a7eed269c7573cd9908fb716677 [file] [log] [blame]
Guido van Rossum20882d51994-06-23 11:15:44 +00001
2/* UNIX group file access module */
3
Roger E. Masseb2b44e51996-12-18 19:37:32 +00004#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005#include "posixmodule.h"
Guido van Rossum20882d51994-06-23 11:15:44 +00006
Guido van Rossum20882d51994-06-23 11:15:44 +00007#include <grp.h>
8
Brett Cannon8fb7bb22014-08-22 11:52:46 -04009#include "clinic/grpmodule.c.h"
10/*[clinic input]
Brett Cannon8fb7bb22014-08-22 11:52:46 -040011module grp
12[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030013/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cade63f2ed1bd9f8]*/
Brett Cannon8fb7bb22014-08-22 11:52:46 -040014
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000015static PyStructSequence_Field struct_group_type_fields[] = {
16 {"gr_name", "group name"},
17 {"gr_passwd", "password"},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 {"gr_gid", "group id"},
Mark Dickinsonfb29a162013-08-05 17:57:01 +010019 {"gr_mem", "group members"},
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000020 {0}
21};
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(struct_group__doc__,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000024"grp.struct_group: Results from getgr*() routines.\n\n\
25This object may be accessed either as a tuple of\n\
26 (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027or via the object attributes as named in the above tuple.\n");
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000028
29static PyStructSequence_Desc struct_group_type_desc = {
30 "grp.struct_group",
31 struct_group__doc__,
32 struct_group_type_fields,
33 4,
34};
35
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037static int initialized;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000038static PyTypeObject StructGrpType;
Fred Drake51b6bc52000-07-08 16:56:26 +000039
40static PyObject *
41mkgrent(struct group *p)
Guido van Rossum20882d51994-06-23 11:15:44 +000042{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000043 int setIndex = 0;
44 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
Fred Drake51b6bc52000-07-08 16:56:26 +000045 char **member;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000046
47 if (v == NULL)
48 return NULL;
49
Fred Drake51b6bc52000-07-08 16:56:26 +000050 if ((w = PyList_New(0)) == NULL) {
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000051 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000052 return NULL;
53 }
54 for (member = p->gr_mem; *member != NULL; member++) {
Victor Stinner97c18ab2010-05-07 16:34:53 +000055 PyObject *x = PyUnicode_DecodeFSDefault(*member);
Fred Drake51b6bc52000-07-08 16:56:26 +000056 if (x == NULL || PyList_Append(w, x) != 0) {
57 Py_XDECREF(x);
58 Py_DECREF(w);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000059 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000060 return NULL;
61 }
62 Py_DECREF(x);
63 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000064
65#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
Victor Stinner97c18ab2010-05-07 16:34:53 +000066 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000067 if (p->gr_passwd)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000069 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 SET(setIndex++, Py_None);
71 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000072 }
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020073 SET(setIndex++, _PyLong_FromGid(p->gr_gid));
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000074 SET(setIndex++, w);
75#undef SET
76
77 if (PyErr_Occurred()) {
78 Py_DECREF(v);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000079 return NULL;
80 }
81
Fred Drake51b6bc52000-07-08 16:56:26 +000082 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000083}
84
Brett Cannon8fb7bb22014-08-22 11:52:46 -040085/*[clinic input]
86grp.getgrgid
87
88 id: object
89
90Return the group database entry for the given numeric group ID.
91
92If id is not valid, raise KeyError.
93[clinic start generated code]*/
94
Fred Drake51b6bc52000-07-08 16:56:26 +000095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030096grp_getgrgid_impl(PyObject *module, PyObject *id)
97/*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/
Guido van Rossum20882d51994-06-23 11:15:44 +000098{
Thomas Wouters477c8d52006-05-27 19:21:47 +000099 PyObject *py_int_id;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200100 gid_t gid;
Fred Drake51b6bc52000-07-08 16:56:26 +0000101 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000102
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400103 py_int_id = PyNumber_Long(id);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000104 if (!py_int_id)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200106 if (!_Py_Gid_Converter(py_int_id, &gid)) {
107 Py_DECREF(py_int_id);
108 return NULL;
109 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110 Py_DECREF(py_int_id);
111
Fred Drake51b6bc52000-07-08 16:56:26 +0000112 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200113 PyObject *gid_obj = _PyLong_FromGid(gid);
114 if (gid_obj == NULL)
115 return NULL;
116 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
117 Py_DECREF(gid_obj);
Fred Drake51b6bc52000-07-08 16:56:26 +0000118 return NULL;
119 }
120 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000121}
122
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400123/*[clinic input]
124grp.getgrnam
Thomas Wouters477c8d52006-05-27 19:21:47 +0000125
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400126 name: unicode
127
128Return the group database entry for the given group name.
129
130If name is not valid, raise KeyError.
131[clinic start generated code]*/
132
133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300134grp_getgrnam_impl(PyObject *module, PyObject *name)
135/*[clinic end generated code: output=67905086f403c21c input=08ded29affa3c863]*/
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400136{
137 char *name_chars;
138 struct group *p;
139 PyObject *bytes, *retval = NULL;
140
141 if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000142 return NULL;
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400143 if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000144 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400146 if ((p = getgrnam(name_chars)) == NULL) {
147 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000148 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000149 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000150 retval = mkgrent(p);
151out:
152 Py_DECREF(bytes);
153 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000154}
155
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400156/*[clinic input]
157grp.getgrall
158
159Return a list of all available group entries, in arbitrary order.
160
161An entry whose name starts with '+' or '-' represents an instruction
162to use YP/NIS and may not be accessible via getgrnam or getgrgid.
163[clinic start generated code]*/
164
Fred Drake51b6bc52000-07-08 16:56:26 +0000165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300166grp_getgrall_impl(PyObject *module)
167/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
Guido van Rossum20882d51994-06-23 11:15:44 +0000168{
Fred Drake51b6bc52000-07-08 16:56:26 +0000169 PyObject *d;
170 struct group *p;
171
Fred Drake51b6bc52000-07-08 16:56:26 +0000172 if ((d = PyList_New(0)) == NULL)
173 return NULL;
174 setgrent();
175 while ((p = getgrent()) != NULL) {
176 PyObject *v = mkgrent(p);
177 if (v == NULL || PyList_Append(d, v) != 0) {
178 Py_XDECREF(v);
179 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000180 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000181 return NULL;
182 }
183 Py_DECREF(v);
184 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000185 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000186 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000187}
188
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000189static PyMethodDef grp_methods[] = {
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400190 GRP_GETGRGID_METHODDEF
191 GRP_GETGRNAM_METHODDEF
192 GRP_GETGRALL_METHODDEF
193 {NULL, NULL}
Guido van Rossum20882d51994-06-23 11:15:44 +0000194};
195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000196PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000197"Access to the Unix group database.\n\
198\n\
199Group entries are reported as 4-tuples containing the following fields\n\
200from the group database, in order:\n\
201\n\
Georg Brandl41ea1f42014-10-02 08:34:41 +0200202 gr_name - name of the group\n\
203 gr_passwd - group password (encrypted); often empty\n\
204 gr_gid - numeric ID of the group\n\
205 gr_mem - list of members\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000206\n\
207The gid is an integer, name and password are strings. (Note that most\n\
208users are not explicitly listed as members of the groups they are in\n\
209according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000210complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000211
212
Martin v. Löwis1a214512008-06-11 05:26:20 +0000213
214static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 PyModuleDef_HEAD_INIT,
216 "grp",
217 grp__doc__,
218 -1,
219 grp_methods,
220 NULL,
221 NULL,
222 NULL,
223 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000224};
225
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000226PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000227PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000228{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000229 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000230 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000231 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000232 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000233 d = PyModule_GetDict(m);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200234 if (!initialized) {
235 if (PyStructSequence_InitType2(&StructGrpType,
236 &struct_group_type_desc) < 0)
237 return NULL;
238 }
239 if (PyDict_SetItemString(d, "struct_group",
240 (PyObject *)&StructGrpType) < 0)
241 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000242 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000243 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000244}