blob: da78253ccba9a1b52a251e5d0e550302e581d0d6 [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
Martin v. Löwisdbd55b32002-03-01 10:38:44 +00009static PyStructSequence_Field struct_group_type_fields[] = {
10 {"gr_name", "group name"},
11 {"gr_passwd", "password"},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000012 {"gr_gid", "group id"},
Mark Dickinsonfb29a162013-08-05 17:57:01 +010013 {"gr_mem", "group members"},
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000014 {0}
15};
16
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000017PyDoc_STRVAR(struct_group__doc__,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000018"grp.struct_group: Results from getgr*() routines.\n\n\
19This object may be accessed either as a tuple of\n\
20 (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000021or via the object attributes as named in the above tuple.\n");
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000022
23static PyStructSequence_Desc struct_group_type_desc = {
24 "grp.struct_group",
25 struct_group__doc__,
26 struct_group_type_fields,
27 4,
28};
29
30
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000031static int initialized;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000032static PyTypeObject StructGrpType;
Fred Drake51b6bc52000-07-08 16:56:26 +000033
34static PyObject *
35mkgrent(struct group *p)
Guido van Rossum20882d51994-06-23 11:15:44 +000036{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000037 int setIndex = 0;
38 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
Fred Drake51b6bc52000-07-08 16:56:26 +000039 char **member;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000040
41 if (v == NULL)
42 return NULL;
43
Fred Drake51b6bc52000-07-08 16:56:26 +000044 if ((w = PyList_New(0)) == NULL) {
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000045 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000046 return NULL;
47 }
48 for (member = p->gr_mem; *member != NULL; member++) {
Victor Stinner97c18ab2010-05-07 16:34:53 +000049 PyObject *x = PyUnicode_DecodeFSDefault(*member);
Fred Drake51b6bc52000-07-08 16:56:26 +000050 if (x == NULL || PyList_Append(w, x) != 0) {
51 Py_XDECREF(x);
52 Py_DECREF(w);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000053 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000054 return NULL;
55 }
56 Py_DECREF(x);
57 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000058
59#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
Victor Stinner97c18ab2010-05-07 16:34:53 +000060 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000061 if (p->gr_passwd)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000063 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 SET(setIndex++, Py_None);
65 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000066 }
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020067 SET(setIndex++, _PyLong_FromGid(p->gr_gid));
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000068 SET(setIndex++, w);
69#undef SET
70
71 if (PyErr_Occurred()) {
72 Py_DECREF(v);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000073 return NULL;
74 }
75
Fred Drake51b6bc52000-07-08 16:56:26 +000076 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000077}
78
Fred Drake51b6bc52000-07-08 16:56:26 +000079static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000080grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000081{
Thomas Wouters477c8d52006-05-27 19:21:47 +000082 PyObject *py_int_id;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020083 gid_t gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000084 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000085
Mark Dickinson17c7cd82009-01-17 21:57:11 +000086 py_int_id = PyNumber_Long(pyo_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000087 if (!py_int_id)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020089 if (!_Py_Gid_Converter(py_int_id, &gid)) {
90 Py_DECREF(py_int_id);
91 return NULL;
92 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000093 Py_DECREF(py_int_id);
94
Fred Drake51b6bc52000-07-08 16:56:26 +000095 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020096 PyObject *gid_obj = _PyLong_FromGid(gid);
97 if (gid_obj == NULL)
98 return NULL;
99 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
100 Py_DECREF(gid_obj);
Fred Drake51b6bc52000-07-08 16:56:26 +0000101 return NULL;
102 }
103 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000104}
105
Fred Drake51b6bc52000-07-08 16:56:26 +0000106static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000107grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000108{
Fred Drake51b6bc52000-07-08 16:56:26 +0000109 char *name;
110 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000111 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000113 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
114 return NULL;
Victor Stinnerae6265f2010-05-15 16:27:27 +0000115 if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000116 return NULL;
117 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
118 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119
Fred Drake51b6bc52000-07-08 16:56:26 +0000120 if ((p = getgrnam(name)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000122 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000123 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000124 retval = mkgrent(p);
125out:
126 Py_DECREF(bytes);
127 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000128}
129
Fred Drake51b6bc52000-07-08 16:56:26 +0000130static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000131grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000132{
Fred Drake51b6bc52000-07-08 16:56:26 +0000133 PyObject *d;
134 struct group *p;
135
Fred Drake51b6bc52000-07-08 16:56:26 +0000136 if ((d = PyList_New(0)) == NULL)
137 return NULL;
138 setgrent();
139 while ((p = getgrent()) != NULL) {
140 PyObject *v = mkgrent(p);
141 if (v == NULL || PyList_Append(d, v) != 0) {
142 Py_XDECREF(v);
143 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000144 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000145 return NULL;
146 }
147 Py_DECREF(v);
148 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000149 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000150 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000151}
152
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000153static PyMethodDef grp_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 {"getgrgid", grp_getgrgid, METH_O,
Georg Brandl41ea1f42014-10-02 08:34:41 +0200155 "getgrgid(id) -> (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000156Return the group database entry for the given numeric group ID. If\n\
157id is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 {"getgrnam", grp_getgrnam, METH_VARARGS,
Georg Brandl41ea1f42014-10-02 08:34:41 +0200159 "getgrnam(name) -> (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000160Return the group database entry for the given group name. If\n\
161name is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000163 "getgrall() -> list of tuples\n\
R. David Murrayec073312010-12-14 16:20:53 +0000164Return a list of all available group entries, in arbitrary order.\n\
165An entry whose name starts with '+' or '-' represents an instruction\n\
166to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000168};
169
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000170PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000171"Access to the Unix group database.\n\
172\n\
173Group entries are reported as 4-tuples containing the following fields\n\
174from the group database, in order:\n\
175\n\
Georg Brandl41ea1f42014-10-02 08:34:41 +0200176 gr_name - name of the group\n\
177 gr_passwd - group password (encrypted); often empty\n\
178 gr_gid - numeric ID of the group\n\
179 gr_mem - list of members\n\
Fred Drake51b6bc52000-07-08 16:56:26 +0000180\n\
181The gid is an integer, name and password are strings. (Note that most\n\
182users are not explicitly listed as members of the groups they are in\n\
183according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000184complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000185
186
Martin v. Löwis1a214512008-06-11 05:26:20 +0000187
188static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 PyModuleDef_HEAD_INIT,
190 "grp",
191 grp__doc__,
192 -1,
193 grp_methods,
194 NULL,
195 NULL,
196 NULL,
197 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000198};
199
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000200PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000201PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000202{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000203 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000204 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000205 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000206 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000207 d = PyModule_GetDict(m);
Victor Stinner1c8f0592013-07-22 22:24:54 +0200208 if (!initialized) {
209 if (PyStructSequence_InitType2(&StructGrpType,
210 &struct_group_type_desc) < 0)
211 return NULL;
212 }
213 if (PyDict_SetItemString(d, "struct_group",
214 (PyObject *)&StructGrpType) < 0)
215 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000216 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000217 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000218}