blob: 912d1397045eb26ed86017dbcfb5907e321f9c8d [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++) {
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)
Victor Stinner97c18ab2010-05-07 16:34:53 +000067 SET(setIndex++, PyUnicode_DecodeFSDefault(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);
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)
94 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) {
Barry Warsawc7a77092004-01-20 21:06:00 +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;
114 if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding,
115 "surrogateescape")) == NULL)
116 return NULL;
117 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
118 goto out;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000119
Fred Drake51b6bc52000-07-08 16:56:26 +0000120 if ((p = getgrnam(name)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +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[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000154 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000155 "getgrgid(id) -> tuple\n\
156Return the group database entry for the given numeric group ID. If\n\
157id is not valid, raise KeyError."},
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000158 {"getgrnam", grp_getgrnam, METH_VARARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000159 "getgrnam(name) -> tuple\n\
160Return the group database entry for the given group name. If\n\
161name is not valid, raise KeyError."},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000162 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000163 "getgrall() -> list of tuples\n\
164Return a list of all available group entries, in arbitrary order."},
165 {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 = {
187 PyModuleDef_HEAD_INIT,
188 "grp",
189 grp__doc__,
190 -1,
191 grp_methods,
192 NULL,
193 NULL,
194 NULL,
195 NULL
196};
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)
207 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}