blob: 9437ae7a5b1a14ea5d542302448bf9a5de7ccea9 [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;
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400154 if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000155 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400157 if ((p = getgrnam(name_chars)) == NULL) {
158 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000159 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000160 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000161 retval = mkgrent(p);
162out:
163 Py_DECREF(bytes);
164 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000165}
166
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400167/*[clinic input]
168grp.getgrall
169
170Return a list of all available group entries, in arbitrary order.
171
172An entry whose name starts with '+' or '-' represents an instruction
173to use YP/NIS and may not be accessible via getgrnam or getgrgid.
174[clinic start generated code]*/
175
Fred Drake51b6bc52000-07-08 16:56:26 +0000176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300177grp_getgrall_impl(PyObject *module)
178/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
Guido van Rossum20882d51994-06-23 11:15:44 +0000179{
Fred Drake51b6bc52000-07-08 16:56:26 +0000180 PyObject *d;
181 struct group *p;
182
Fred Drake51b6bc52000-07-08 16:56:26 +0000183 if ((d = PyList_New(0)) == NULL)
184 return NULL;
185 setgrent();
186 while ((p = getgrent()) != NULL) {
187 PyObject *v = mkgrent(p);
188 if (v == NULL || PyList_Append(d, v) != 0) {
189 Py_XDECREF(v);
190 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000191 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000192 return NULL;
193 }
194 Py_DECREF(v);
195 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000196 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000197 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000198}
199
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000200static PyMethodDef grp_methods[] = {
Brett Cannon8fb7bb22014-08-22 11:52:46 -0400201 GRP_GETGRGID_METHODDEF
202 GRP_GETGRNAM_METHODDEF
203 GRP_GETGRALL_METHODDEF
204 {NULL, NULL}
Guido van Rossum20882d51994-06-23 11:15:44 +0000205};
206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000207PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000208"Access to the Unix group database.\n\
209\n\
210Group entries are reported as 4-tuples containing the following fields\n\
211from the group database, in order:\n\
212\n\
Georg Brandl41ea1f42014-10-02 08:34:41 +0200213 gr_name - name of the group\n\
214 gr_passwd - group password (encrypted); often empty\n\
215 gr_gid - numeric ID of the group\n\
216 gr_mem - list of members\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000217\n\
218The gid is an integer, name and password are strings. (Note that most\n\
219users are not explicitly listed as members of the groups they are in\n\
220according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000221complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000222
223
Martin v. Löwis1a214512008-06-11 05:26:20 +0000224
225static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 PyModuleDef_HEAD_INIT,
227 "grp",
228 grp__doc__,
229 -1,
230 grp_methods,
231 NULL,
232 NULL,
233 NULL,
234 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000235};
236
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000237PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000238PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000239{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000240 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000241 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000242 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000243 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000244 d = PyModule_GetDict(m);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200245 if (!initialized) {
246 if (PyStructSequence_InitType2(&StructGrpType,
247 &struct_group_type_desc) < 0)
248 return NULL;
249 }
250 if (PyDict_SetItemString(d, "struct_group",
251 (PyObject *)&StructGrpType) < 0)
252 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000254 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000255}