blob: 039f7941eb4a06b723481e4e3b40366c7b47dff7 [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"
Martin v. Löwisdbd55b32002-03-01 10:38:44 +00005#include "structseq.h"
Guido van Rossum20882d51994-06-23 11:15:44 +00006
7#include <sys/types.h>
8#include <grp.h>
9
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000010static PyStructSequence_Field struct_group_type_fields[] = {
11 {"gr_name", "group name"},
12 {"gr_passwd", "password"},
13 {"gr_gid", "group id"},
14 {"gr_mem", "group memebers"},
15 {0}
16};
17
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000018PyDoc_STRVAR(struct_group__doc__,
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000019"grp.struct_group: Results from getgr*() routines.\n\n\
20This object may be accessed either as a tuple of\n\
21 (gr_name,gr_passwd,gr_gid,gr_mem)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000022or via the object attributes as named in the above tuple.\n");
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000023
24static PyStructSequence_Desc struct_group_type_desc = {
25 "grp.struct_group",
26 struct_group__doc__,
27 struct_group_type_fields,
28 4,
29};
30
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032static int initialized;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000033static PyTypeObject StructGrpType;
Fred Drake51b6bc52000-07-08 16:56:26 +000034
35static PyObject *
36mkgrent(struct group *p)
Guido van Rossum20882d51994-06-23 11:15:44 +000037{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000038 int setIndex = 0;
39 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
Fred Drake51b6bc52000-07-08 16:56:26 +000040 char **member;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000041
42 if (v == NULL)
43 return NULL;
44
Fred Drake51b6bc52000-07-08 16:56:26 +000045 if ((w = PyList_New(0)) == NULL) {
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000046 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000047 return NULL;
48 }
49 for (member = p->gr_mem; *member != NULL; member++) {
Neal Norwitz6777c852007-08-26 02:54:31 +000050 PyObject *x = PyUnicode_FromString(*member);
Fred Drake51b6bc52000-07-08 16:56:26 +000051 if (x == NULL || PyList_Append(w, x) != 0) {
52 Py_XDECREF(x);
53 Py_DECREF(w);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000054 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000055 return NULL;
56 }
57 Py_DECREF(x);
58 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000059
60#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
Neal Norwitz6777c852007-08-26 02:54:31 +000061 SET(setIndex++, PyUnicode_FromString(p->gr_name));
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000062#ifdef __VMS
63 SET(setIndex++, Py_None);
64 Py_INCREF(Py_None);
65#else
Martin v. Löwisceb7c182002-09-17 07:05:25 +000066 if (p->gr_passwd)
Neal Norwitz6777c852007-08-26 02:54:31 +000067 SET(setIndex++, PyUnicode_FromString(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000068 else {
69 SET(setIndex++, Py_None);
70 Py_INCREF(Py_None);
71 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000072#endif
Christian Heimes217cfd12007-12-02 14:31:20 +000073 SET(setIndex++, PyLong_FromLong((long) 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);
79 Py_DECREF(w);
80 return NULL;
81 }
82
Fred Drake51b6bc52000-07-08 16:56:26 +000083 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000084}
85
Fred Drake51b6bc52000-07-08 16:56:26 +000086static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000087grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000088{
Thomas Wouters477c8d52006-05-27 19:21:47 +000089 PyObject *py_int_id;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000090 unsigned int gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000091 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000092
93 py_int_id = PyNumber_Int(pyo_id);
94 if (!py_int_id)
95 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000096 gid = PyLong_AS_LONG(py_int_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000097 Py_DECREF(py_int_id);
98
Fred Drake51b6bc52000-07-08 16:56:26 +000099 if ((p = getgrgid(gid)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000100 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
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 *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000107grp_getgrnam(PyObject *self, PyObject *pyo_name)
Guido van Rossum20882d51994-06-23 11:15:44 +0000108{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109 PyObject *py_str_name;
Fred Drake51b6bc52000-07-08 16:56:26 +0000110 char *name;
111 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112
Thomas Heller519a0422007-11-15 20:48:54 +0000113 py_str_name = PyObject_Str(pyo_name);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 if (!py_str_name)
115 return NULL;
Neal Norwitz6777c852007-08-26 02:54:31 +0000116 name = PyUnicode_AsString(py_str_name);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000117
Fred Drake51b6bc52000-07-08 16:56:26 +0000118 if ((p = getgrnam(name)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000119 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000120 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000121 return NULL;
122 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000123
124 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000125 return mkgrent(p);
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);
142 return NULL;
143 }
144 Py_DECREF(v);
145 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000146 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000147 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000148}
149
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000150static PyMethodDef grp_methods[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000151 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000152 "getgrgid(id) -> tuple\n\
153Return the group database entry for the given numeric group ID. If\n\
154id is not valid, raise KeyError."},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000155 {"getgrnam", grp_getgrnam, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000156 "getgrnam(name) -> tuple\n\
157Return the group database entry for the given group name. If\n\
158name is not valid, raise KeyError."},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000159 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000160 "getgrall() -> list of tuples\n\
161Return a list of all available group entries, in arbitrary order."},
162 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000163};
164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000165PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000166"Access to the Unix group database.\n\
167\n\
168Group entries are reported as 4-tuples containing the following fields\n\
169from the group database, in order:\n\
170\n\
171 name - name of the group\n\
172 passwd - group password (encrypted); often empty\n\
173 gid - numeric ID of the group\n\
174 mem - list of members\n\
175\n\
176The gid is an integer, name and password are strings. (Note that most\n\
177users are not explicitly listed as members of the groups they are in\n\
178according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000180
181
Martin v. Löwis1a214512008-06-11 05:26:20 +0000182
183static struct PyModuleDef grpmodule = {
184 PyModuleDef_HEAD_INIT,
185 "grp",
186 grp__doc__,
187 -1,
188 grp_methods,
189 NULL,
190 NULL,
191 NULL,
192 NULL
193};
194
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000195PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000196PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000197{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000198 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000199 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000200 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000201 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000202 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000203 if (!initialized)
204 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000205 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000206 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000207 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000208}