blob: 7dfda280c777ad5720996da6e768b3457213da5e [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"
Guido van Rossum20882d51994-06-23 11:15:44 +00005
6#include <sys/types.h>
7#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
Christian Heimes217cfd12007-12-02 14:31:20 +000072 SET(setIndex++, PyLong_FromLong((long) 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;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000088 unsigned int 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;
Christian Heimes217cfd12007-12-02 14:31:20 +000094 gid = PyLong_AS_LONG(py_int_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000095 Py_DECREF(py_int_id);
96
Fred Drake51b6bc52000-07-08 16:56:26 +000097 if ((p = getgrgid(gid)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
Fred Drake51b6bc52000-07-08 16:56:26 +000099 return NULL;
100 }
101 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000102}
103
Fred Drake51b6bc52000-07-08 16:56:26 +0000104static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000105grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000106{
Fred Drake51b6bc52000-07-08 16:56:26 +0000107 char *name;
108 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000109 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000111 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
112 return NULL;
Victor Stinnerae6265f2010-05-15 16:27:27 +0000113 if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000114 return NULL;
115 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
116 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117
Fred Drake51b6bc52000-07-08 16:56:26 +0000118 if ((p = getgrnam(name)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000120 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000121 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000122 retval = mkgrent(p);
123out:
124 Py_DECREF(bytes);
125 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000126}
127
Fred Drake51b6bc52000-07-08 16:56:26 +0000128static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000129grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000130{
Fred Drake51b6bc52000-07-08 16:56:26 +0000131 PyObject *d;
132 struct group *p;
133
Fred Drake51b6bc52000-07-08 16:56:26 +0000134 if ((d = PyList_New(0)) == NULL)
135 return NULL;
136 setgrent();
137 while ((p = getgrent()) != NULL) {
138 PyObject *v = mkgrent(p);
139 if (v == NULL || PyList_Append(d, v) != 0) {
140 Py_XDECREF(v);
141 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000142 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000143 return NULL;
144 }
145 Py_DECREF(v);
146 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000147 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000148 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000149}
150
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000151static PyMethodDef grp_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000153 "getgrgid(id) -> tuple\n\
154Return the group database entry for the given numeric group ID. If\n\
155id is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 {"getgrnam", grp_getgrnam, METH_VARARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000157 "getgrnam(name) -> tuple\n\
158Return the group database entry for the given group name. If\n\
159name is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000161 "getgrall() -> list of tuples\n\
R. David Murrayec073312010-12-14 16:20:53 +0000162Return a list of all available group entries, in arbitrary order.\n\
163An entry whose name starts with '+' or '-' represents an instruction\n\
164to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000166};
167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000168PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000169"Access to the Unix group database.\n\
170\n\
171Group entries are reported as 4-tuples containing the following fields\n\
172from the group database, in order:\n\
173\n\
174 name - name of the group\n\
175 passwd - group password (encrypted); often empty\n\
176 gid - numeric ID of the group\n\
177 mem - list of members\n\
178\n\
179The gid is an integer, name and password are strings. (Note that most\n\
180users are not explicitly listed as members of the groups they are in\n\
181according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000182complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000183
184
Martin v. Löwis1a214512008-06-11 05:26:20 +0000185
186static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 PyModuleDef_HEAD_INIT,
188 "grp",
189 grp__doc__,
190 -1,
191 grp_methods,
192 NULL,
193 NULL,
194 NULL,
195 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000196};
197
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000198PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000199PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000200{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000201 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000202 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000203 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000204 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000205 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000206 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000208 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000210 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000211}