blob: f85cdd46fc02ecbda092c6f1aa3d348b6d1bb7a6 [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"},
13 {"gr_mem", "group memebers"},
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öwisc16f3bd2003-05-03 09:14:54 +000061#ifdef __VMS
62 SET(setIndex++, Py_None);
63 Py_INCREF(Py_None);
64#else
Martin v. Löwisceb7c182002-09-17 07:05:25 +000065 if (p->gr_passwd)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000067 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 SET(setIndex++, Py_None);
69 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000070 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000071#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020072 SET(setIndex++, _PyLong_FromGid(p->gr_gid));
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000073 SET(setIndex++, w);
74#undef SET
75
76 if (PyErr_Occurred()) {
77 Py_DECREF(v);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000078 return NULL;
79 }
80
Fred Drake51b6bc52000-07-08 16:56:26 +000081 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000082}
83
Fred Drake51b6bc52000-07-08 16:56:26 +000084static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000085grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000086{
Thomas Wouters477c8d52006-05-27 19:21:47 +000087 PyObject *py_int_id;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020088 gid_t gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000089 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000090
Mark Dickinson17c7cd82009-01-17 21:57:11 +000091 py_int_id = PyNumber_Long(pyo_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000092 if (!py_int_id)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020094 if (!_Py_Gid_Converter(py_int_id, &gid)) {
95 Py_DECREF(py_int_id);
96 return NULL;
97 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000098 Py_DECREF(py_int_id);
99
Fred Drake51b6bc52000-07-08 16:56:26 +0000100 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200101 PyObject *gid_obj = _PyLong_FromGid(gid);
102 if (gid_obj == NULL)
103 return NULL;
104 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
105 Py_DECREF(gid_obj);
Fred Drake51b6bc52000-07-08 16:56:26 +0000106 return NULL;
107 }
108 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000109}
110
Fred Drake51b6bc52000-07-08 16:56:26 +0000111static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000112grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000113{
Fred Drake51b6bc52000-07-08 16:56:26 +0000114 char *name;
115 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000116 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000117
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000118 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
119 return NULL;
Victor Stinnerae6265f2010-05-15 16:27:27 +0000120 if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000121 return NULL;
122 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
123 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124
Fred Drake51b6bc52000-07-08 16:56:26 +0000125 if ((p = getgrnam(name)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000127 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000128 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000129 retval = mkgrent(p);
130out:
131 Py_DECREF(bytes);
132 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000133}
134
Fred Drake51b6bc52000-07-08 16:56:26 +0000135static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000136grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000137{
Fred Drake51b6bc52000-07-08 16:56:26 +0000138 PyObject *d;
139 struct group *p;
140
Fred Drake51b6bc52000-07-08 16:56:26 +0000141 if ((d = PyList_New(0)) == NULL)
142 return NULL;
143 setgrent();
144 while ((p = getgrent()) != NULL) {
145 PyObject *v = mkgrent(p);
146 if (v == NULL || PyList_Append(d, v) != 0) {
147 Py_XDECREF(v);
148 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000149 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000150 return NULL;
151 }
152 Py_DECREF(v);
153 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000154 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000155 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000156}
157
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000158static PyMethodDef grp_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000160 "getgrgid(id) -> tuple\n\
161Return the group database entry for the given numeric group ID. If\n\
162id is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 {"getgrnam", grp_getgrnam, METH_VARARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000164 "getgrnam(name) -> tuple\n\
165Return the group database entry for the given group name. If\n\
166name is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000168 "getgrall() -> list of tuples\n\
R. David Murrayec073312010-12-14 16:20:53 +0000169Return a list of all available group entries, in arbitrary order.\n\
170An entry whose name starts with '+' or '-' represents an instruction\n\
171to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000173};
174
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000175PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000176"Access to the Unix group database.\n\
177\n\
178Group entries are reported as 4-tuples containing the following fields\n\
179from the group database, in order:\n\
180\n\
181 name - name of the group\n\
182 passwd - group password (encrypted); often empty\n\
183 gid - numeric ID of the group\n\
184 mem - list of members\n\
185\n\
186The gid is an integer, name and password are strings. (Note that most\n\
187users are not explicitly listed as members of the groups they are in\n\
188according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000189complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000190
191
Martin v. Löwis1a214512008-06-11 05:26:20 +0000192
193static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 PyModuleDef_HEAD_INIT,
195 "grp",
196 grp__doc__,
197 -1,
198 grp_methods,
199 NULL,
200 NULL,
201 NULL,
202 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000203};
204
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000205PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000206PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000207{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000208 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000209 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000210 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000211 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000212 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000213 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000215 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
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}