blob: f577fd3ab4ec3baeabcd09499d62229d457ad273 [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
Serhiy Storchaka9cc4ed52016-01-18 18:49:57 +0200103 if (!_Py_Gid_Converter(id, &gid)) {
104 if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 return NULL;
Serhiy Storchaka9cc4ed52016-01-18 18:49:57 +0200106 }
107 PyErr_Clear();
108 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
109 "group id must be int, not %.200",
110 id->ob_type->tp_name) < 0) {
111 return NULL;
112 }
113 py_int_id = PyNumber_Long(id);
114 if (!py_int_id)
115 return NULL;
116 if (!_Py_Gid_Converter(py_int_id, &gid)) {
117 Py_DECREF(py_int_id);
118 return NULL;
119 }
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200120 Py_DECREF(py_int_id);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200121 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000122
Fred Drake51b6bc52000-07-08 16:56:26 +0000123 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200124 PyObject *gid_obj = _PyLong_FromGid(gid);
125 if (gid_obj == NULL)
126 return NULL;
127 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
128 Py_DECREF(gid_obj);
Fred Drake51b6bc52000-07-08 16:56:26 +0000129 return NULL;
130 }
131 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000132}
133
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400134/*[clinic input]
135grp.getgrnam
Thomas Wouters477c8d52006-05-27 19:21:47 +0000136
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400137 name: unicode
138
139Return the group database entry for the given group name.
140
141If name is not valid, raise KeyError.
142[clinic start generated code]*/
143
144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300145grp_getgrnam_impl(PyObject *module, PyObject *name)
146/*[clinic end generated code: output=67905086f403c21c input=08ded29affa3c863]*/
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400147{
148 char *name_chars;
149 struct group *p;
150 PyObject *bytes, *retval = NULL;
151
152 if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000153 return NULL;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300154 /* check for embedded null bytes */
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400155 if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000156 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400158 if ((p = getgrnam(name_chars)) == NULL) {
159 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000160 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000161 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000162 retval = mkgrent(p);
163out:
164 Py_DECREF(bytes);
165 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000166}
167
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400168/*[clinic input]
169grp.getgrall
170
171Return a list of all available group entries, in arbitrary order.
172
173An entry whose name starts with '+' or '-' represents an instruction
174to use YP/NIS and may not be accessible via getgrnam or getgrgid.
175[clinic start generated code]*/
176
Fred Drake51b6bc52000-07-08 16:56:26 +0000177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300178grp_getgrall_impl(PyObject *module)
179/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
Guido van Rossum20882d51994-06-23 11:15:44 +0000180{
Fred Drake51b6bc52000-07-08 16:56:26 +0000181 PyObject *d;
182 struct group *p;
183
Fred Drake51b6bc52000-07-08 16:56:26 +0000184 if ((d = PyList_New(0)) == NULL)
185 return NULL;
186 setgrent();
187 while ((p = getgrent()) != NULL) {
188 PyObject *v = mkgrent(p);
189 if (v == NULL || PyList_Append(d, v) != 0) {
190 Py_XDECREF(v);
191 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000192 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000193 return NULL;
194 }
195 Py_DECREF(v);
196 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000197 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000198 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000199}
200
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000201static PyMethodDef grp_methods[] = {
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400202 GRP_GETGRGID_METHODDEF
203 GRP_GETGRNAM_METHODDEF
204 GRP_GETGRALL_METHODDEF
205 {NULL, NULL}
Guido van Rossum20882d51994-06-23 11:15:44 +0000206};
207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000208PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000209"Access to the Unix group database.\n\
210\n\
211Group entries are reported as 4-tuples containing the following fields\n\
212from the group database, in order:\n\
213\n\
Georg Brandl41ea1f42014-10-02 08:34:41 +0200214 gr_name - name of the group\n\
215 gr_passwd - group password (encrypted); often empty\n\
216 gr_gid - numeric ID of the group\n\
217 gr_mem - list of members\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000218\n\
219The gid is an integer, name and password are strings. (Note that most\n\
220users are not explicitly listed as members of the groups they are in\n\
221according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000222complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000223
224
Martin v. Löwis1a214512008-06-11 05:26:20 +0000225
226static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 PyModuleDef_HEAD_INIT,
228 "grp",
229 grp__doc__,
230 -1,
231 grp_methods,
232 NULL,
233 NULL,
234 NULL,
235 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000236};
237
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000238PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000239PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000240{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000241 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000242 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000243 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000244 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000245 d = PyModule_GetDict(m);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200246 if (!initialized) {
247 if (PyStructSequence_InitType2(&StructGrpType,
248 &struct_group_type_desc) < 0)
249 return NULL;
250 }
251 if (PyDict_SetItemString(d, "struct_group",
252 (PyObject *)&StructGrpType) < 0)
253 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000254 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000255 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000256}