blob: 73289d576ea59deb8fef72100212250e391af00b [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]
11output preset file
12module grp
13[clinic start generated code]*/
14/*[clinic end generated code: output=da39a3ee5e6b4b0d input=68180a9a9efb8506]*/
15
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000016static PyStructSequence_Field struct_group_type_fields[] = {
17 {"gr_name", "group name"},
18 {"gr_passwd", "password"},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019 {"gr_gid", "group id"},
Mark Dickinsonfb29a162013-08-05 17:57:01 +010020 {"gr_mem", "group members"},
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000021 {0}
22};
23
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000024PyDoc_STRVAR(struct_group__doc__,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000025"grp.struct_group: Results from getgr*() routines.\n\n\
26This object may be accessed either as a tuple of\n\
27 (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028or via the object attributes as named in the above tuple.\n");
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000029
30static PyStructSequence_Desc struct_group_type_desc = {
31 "grp.struct_group",
32 struct_group__doc__,
33 struct_group_type_fields,
34 4,
35};
36
37
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000038static int initialized;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000039static PyTypeObject StructGrpType;
Fred Drake51b6bc52000-07-08 16:56:26 +000040
41static PyObject *
42mkgrent(struct group *p)
Guido van Rossum20882d51994-06-23 11:15:44 +000043{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000044 int setIndex = 0;
45 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
Fred Drake51b6bc52000-07-08 16:56:26 +000046 char **member;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000047
48 if (v == NULL)
49 return NULL;
50
Fred Drake51b6bc52000-07-08 16:56:26 +000051 if ((w = PyList_New(0)) == NULL) {
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000052 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000053 return NULL;
54 }
55 for (member = p->gr_mem; *member != NULL; member++) {
Victor Stinner97c18ab2010-05-07 16:34:53 +000056 PyObject *x = PyUnicode_DecodeFSDefault(*member);
Fred Drake51b6bc52000-07-08 16:56:26 +000057 if (x == NULL || PyList_Append(w, x) != 0) {
58 Py_XDECREF(x);
59 Py_DECREF(w);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000060 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000061 return NULL;
62 }
63 Py_DECREF(x);
64 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000065
66#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
Victor Stinner97c18ab2010-05-07 16:34:53 +000067 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000068 if (p->gr_passwd)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000070 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 SET(setIndex++, Py_None);
72 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000073 }
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020074 SET(setIndex++, _PyLong_FromGid(p->gr_gid));
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000075 SET(setIndex++, w);
76#undef SET
77
78 if (PyErr_Occurred()) {
79 Py_DECREF(v);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000080 return NULL;
81 }
82
Fred Drake51b6bc52000-07-08 16:56:26 +000083 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000084}
85
Brett Cannon8fb7bb22014-08-22 11:52:46 -040086/*[clinic input]
87grp.getgrgid
88
89 id: object
90
91Return the group database entry for the given numeric group ID.
92
93If id is not valid, raise KeyError.
94[clinic start generated code]*/
95
Fred Drake51b6bc52000-07-08 16:56:26 +000096static PyObject *
Brett Cannon8fb7bb22014-08-22 11:52:46 -040097grp_getgrgid_impl(PyModuleDef *module, PyObject *id)
98/*[clinic end generated code: output=8a11f5fdeb8c78a0 input=15fa0e2ccf5cda25]*/
Guido van Rossum20882d51994-06-23 11:15:44 +000099{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000100 PyObject *py_int_id;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200101 gid_t gid;
Fred Drake51b6bc52000-07-08 16:56:26 +0000102 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000103
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400104 py_int_id = PyNumber_Long(id);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000105 if (!py_int_id)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200107 if (!_Py_Gid_Converter(py_int_id, &gid)) {
108 Py_DECREF(py_int_id);
109 return NULL;
110 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000111 Py_DECREF(py_int_id);
112
Fred Drake51b6bc52000-07-08 16:56:26 +0000113 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200114 PyObject *gid_obj = _PyLong_FromGid(gid);
115 if (gid_obj == NULL)
116 return NULL;
117 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
118 Py_DECREF(gid_obj);
Fred Drake51b6bc52000-07-08 16:56:26 +0000119 return NULL;
120 }
121 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000122}
123
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400124/*[clinic input]
125grp.getgrnam
Thomas Wouters477c8d52006-05-27 19:21:47 +0000126
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400127 name: unicode
128
129Return the group database entry for the given group name.
130
131If name is not valid, raise KeyError.
132[clinic start generated code]*/
133
134static PyObject *
135grp_getgrnam_impl(PyModuleDef *module, PyObject *name)
136/*[clinic end generated code: output=cd47511f4854da8e input=08ded29affa3c863]*/
137{
138 char *name_chars;
139 struct group *p;
140 PyObject *bytes, *retval = NULL;
141
142 if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000143 return NULL;
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400144 if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000145 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400147 if ((p = getgrnam(name_chars)) == NULL) {
148 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000149 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000150 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000151 retval = mkgrent(p);
152out:
153 Py_DECREF(bytes);
154 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000155}
156
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400157/*[clinic input]
158grp.getgrall
159
160Return a list of all available group entries, in arbitrary order.
161
162An entry whose name starts with '+' or '-' represents an instruction
163to use YP/NIS and may not be accessible via getgrnam or getgrgid.
164[clinic start generated code]*/
165
Fred Drake51b6bc52000-07-08 16:56:26 +0000166static PyObject *
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400167grp_getgrall_impl(PyModuleDef *module)
168/*[clinic end generated code: output=add9037a20c202de input=d7df76c825c367df]*/
Guido van Rossum20882d51994-06-23 11:15:44 +0000169{
Fred Drake51b6bc52000-07-08 16:56:26 +0000170 PyObject *d;
171 struct group *p;
172
Fred Drake51b6bc52000-07-08 16:56:26 +0000173 if ((d = PyList_New(0)) == NULL)
174 return NULL;
175 setgrent();
176 while ((p = getgrent()) != NULL) {
177 PyObject *v = mkgrent(p);
178 if (v == NULL || PyList_Append(d, v) != 0) {
179 Py_XDECREF(v);
180 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000181 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000182 return NULL;
183 }
184 Py_DECREF(v);
185 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000186 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000187 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000188}
189
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000190static PyMethodDef grp_methods[] = {
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400191 GRP_GETGRGID_METHODDEF
192 GRP_GETGRNAM_METHODDEF
193 GRP_GETGRALL_METHODDEF
194 {NULL, NULL}
Guido van Rossum20882d51994-06-23 11:15:44 +0000195};
196
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000197PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000198"Access to the Unix group database.\n\
199\n\
200Group entries are reported as 4-tuples containing the following fields\n\
201from the group database, in order:\n\
202\n\
203 name - name of the group\n\
204 passwd - group password (encrypted); often empty\n\
205 gid - numeric ID of the group\n\
206 mem - list of members\n\
207\n\
208The gid is an integer, name and password are strings. (Note that most\n\
209users are not explicitly listed as members of the groups they are in\n\
210according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000211complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000212
213
Martin v. Löwis1a214512008-06-11 05:26:20 +0000214
215static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 PyModuleDef_HEAD_INIT,
217 "grp",
218 grp__doc__,
219 -1,
220 grp_methods,
221 NULL,
222 NULL,
223 NULL,
224 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000225};
226
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000227PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000228PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000229{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000230 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000231 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000232 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000233 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000234 d = PyModule_GetDict(m);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200235 if (!initialized) {
236 if (PyStructSequence_InitType2(&StructGrpType,
237 &struct_group_type_desc) < 0)
238 return NULL;
239 }
240 if (PyDict_SetItemString(d, "struct_group",
241 (PyObject *)&StructGrpType) < 0)
242 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000243 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000244 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000245}