blob: d64c14285734c175faa40cc51c5158620afab38d [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"},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 {"gr_gid", "group id"},
14 {"gr_mem", "group memebers"},
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000015 {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++) {
Victor Stinner97c18ab2010-05-07 16:34:53 +000050 PyObject *x = PyUnicode_DecodeFSDefault(*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)
Victor Stinner97c18ab2010-05-07 16:34:53 +000061 SET(setIndex++, PyUnicode_DecodeFSDefault(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)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000068 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 SET(setIndex++, Py_None);
70 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000071 }
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);
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
Fred Drake51b6bc52000-07-08 16:56:26 +000085static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000086grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000087{
Thomas Wouters477c8d52006-05-27 19:21:47 +000088 PyObject *py_int_id;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000089 unsigned int gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000090 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000091
Mark Dickinson17c7cd82009-01-17 21:57:11 +000092 py_int_id = PyNumber_Long(pyo_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000093 if (!py_int_id)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000095 gid = PyLong_AS_LONG(py_int_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000096 Py_DECREF(py_int_id);
97
Fred Drake51b6bc52000-07-08 16:56:26 +000098 if ((p = getgrgid(gid)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
Fred Drake51b6bc52000-07-08 16:56:26 +0000100 return NULL;
101 }
102 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000103}
104
Fred Drake51b6bc52000-07-08 16:56:26 +0000105static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000106grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000107{
Fred Drake51b6bc52000-07-08 16:56:26 +0000108 char *name;
109 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000110 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000111
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000112 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
113 return NULL;
Victor Stinnerae6265f2010-05-15 16:27:27 +0000114 if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000115 return NULL;
116 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
117 goto out;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118
Fred Drake51b6bc52000-07-08 16:56:26 +0000119 if ((p = getgrnam(name)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000121 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000122 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000123 retval = mkgrent(p);
124out:
125 Py_DECREF(bytes);
126 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000127}
128
Fred Drake51b6bc52000-07-08 16:56:26 +0000129static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000130grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000131{
Fred Drake51b6bc52000-07-08 16:56:26 +0000132 PyObject *d;
133 struct group *p;
134
Fred Drake51b6bc52000-07-08 16:56:26 +0000135 if ((d = PyList_New(0)) == NULL)
136 return NULL;
137 setgrent();
138 while ((p = getgrent()) != NULL) {
139 PyObject *v = mkgrent(p);
140 if (v == NULL || PyList_Append(d, v) != 0) {
141 Py_XDECREF(v);
142 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000143 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000144 return NULL;
145 }
146 Py_DECREF(v);
147 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000148 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000149 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000150}
151
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000152static PyMethodDef grp_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000154 "getgrgid(id) -> tuple\n\
155Return the group database entry for the given numeric group ID. If\n\
156id is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 {"getgrnam", grp_getgrnam, METH_VARARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000158 "getgrnam(name) -> tuple\n\
159Return the group database entry for the given group name. If\n\
160name is not valid, raise KeyError."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000162 "getgrall() -> list of tuples\n\
163Return a list of all available group entries, in arbitrary order."},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000165};
166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000167PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000168"Access to the Unix group database.\n\
169\n\
170Group entries are reported as 4-tuples containing the following fields\n\
171from the group database, in order:\n\
172\n\
173 name - name of the group\n\
174 passwd - group password (encrypted); often empty\n\
175 gid - numeric ID of the group\n\
176 mem - list of members\n\
177\n\
178The gid is an integer, name and password are strings. (Note that most\n\
179users are not explicitly listed as members of the groups they are in\n\
180according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000181complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000182
183
Martin v. Löwis1a214512008-06-11 05:26:20 +0000184
185static struct PyModuleDef grpmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 PyModuleDef_HEAD_INIT,
187 "grp",
188 grp__doc__,
189 -1,
190 grp_methods,
191 NULL,
192 NULL,
193 NULL,
194 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000195};
196
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000197PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000198PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000199{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000200 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000201 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000202 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000203 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000204 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000205 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000207 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000209 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000210}