blob: e642731f834027b9351892704413ace67a9d3182 [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 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +000049#define FSDECODE(val) PyUnicode_Decode(val, strlen(val),\
50 Py_FileSystemDefaultEncoding,\
51 "surrogateescape")
Fred Drake51b6bc52000-07-08 16:56:26 +000052 for (member = p->gr_mem; *member != NULL; member++) {
Martin v. Löwisb6a748b2009-05-29 15:23:17 +000053 PyObject *x = FSDECODE(*member);
Fred Drake51b6bc52000-07-08 16:56:26 +000054 if (x == NULL || PyList_Append(w, x) != 0) {
55 Py_XDECREF(x);
56 Py_DECREF(w);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000057 Py_DECREF(v);
Fred Drake51b6bc52000-07-08 16:56:26 +000058 return NULL;
59 }
60 Py_DECREF(x);
61 }
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000062
63#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +000064 SET(setIndex++, FSDECODE(p->gr_name));
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000065#ifdef __VMS
66 SET(setIndex++, Py_None);
67 Py_INCREF(Py_None);
68#else
Martin v. Löwisceb7c182002-09-17 07:05:25 +000069 if (p->gr_passwd)
Martin v. Löwisb6a748b2009-05-29 15:23:17 +000070 SET(setIndex++, FSDECODE(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000071 else {
72 SET(setIndex++, Py_None);
73 Py_INCREF(Py_None);
74 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000075#endif
Christian Heimes217cfd12007-12-02 14:31:20 +000076 SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000077 SET(setIndex++, w);
78#undef SET
79
80 if (PyErr_Occurred()) {
81 Py_DECREF(v);
82 Py_DECREF(w);
83 return NULL;
84 }
85
Fred Drake51b6bc52000-07-08 16:56:26 +000086 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000087}
88
Fred Drake51b6bc52000-07-08 16:56:26 +000089static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000090grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000091{
Thomas Wouters477c8d52006-05-27 19:21:47 +000092 PyObject *py_int_id;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000093 unsigned int gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000094 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000095
Mark Dickinson17c7cd82009-01-17 21:57:11 +000096 py_int_id = PyNumber_Long(pyo_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000097 if (!py_int_id)
98 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000099 gid = PyLong_AS_LONG(py_int_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000100 Py_DECREF(py_int_id);
101
Fred Drake51b6bc52000-07-08 16:56:26 +0000102 if ((p = getgrgid(gid)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000103 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
Fred Drake51b6bc52000-07-08 16:56:26 +0000104 return NULL;
105 }
106 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000107}
108
Fred Drake51b6bc52000-07-08 16:56:26 +0000109static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000110grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000111{
Fred Drake51b6bc52000-07-08 16:56:26 +0000112 char *name;
113 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000114 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000115
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000116 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
117 return NULL;
118 if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding,
119 "surrogateescape")) == NULL)
120 return NULL;
121 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
122 goto out;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000123
Fred Drake51b6bc52000-07-08 16:56:26 +0000124 if ((p = getgrnam(name)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000125 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000126 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000127 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000128 retval = mkgrent(p);
129out:
130 Py_DECREF(bytes);
131 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000132}
133
Fred Drake51b6bc52000-07-08 16:56:26 +0000134static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000135grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000136{
Fred Drake51b6bc52000-07-08 16:56:26 +0000137 PyObject *d;
138 struct group *p;
139
Fred Drake51b6bc52000-07-08 16:56:26 +0000140 if ((d = PyList_New(0)) == NULL)
141 return NULL;
142 setgrent();
143 while ((p = getgrent()) != NULL) {
144 PyObject *v = mkgrent(p);
145 if (v == NULL || PyList_Append(d, v) != 0) {
146 Py_XDECREF(v);
147 Py_DECREF(d);
148 return NULL;
149 }
150 Py_DECREF(v);
151 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000152 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000153 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000154}
155
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000156static PyMethodDef grp_methods[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000157 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000158 "getgrgid(id) -> tuple\n\
159Return the group database entry for the given numeric group ID. If\n\
160id is not valid, raise KeyError."},
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000161 {"getgrnam", grp_getgrnam, METH_VARARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000162 "getgrnam(name) -> tuple\n\
163Return the group database entry for the given group name. If\n\
164name is not valid, raise KeyError."},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000165 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000166 "getgrall() -> list of tuples\n\
167Return a list of all available group entries, in arbitrary order."},
168 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000169};
170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000171PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000172"Access to the Unix group database.\n\
173\n\
174Group entries are reported as 4-tuples containing the following fields\n\
175from the group database, in order:\n\
176\n\
177 name - name of the group\n\
178 passwd - group password (encrypted); often empty\n\
179 gid - numeric ID of the group\n\
180 mem - list of members\n\
181\n\
182The gid is an integer, name and password are strings. (Note that most\n\
183users are not explicitly listed as members of the groups they are in\n\
184according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000185complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000186
187
Martin v. Löwis1a214512008-06-11 05:26:20 +0000188
189static struct PyModuleDef grpmodule = {
190 PyModuleDef_HEAD_INIT,
191 "grp",
192 grp__doc__,
193 -1,
194 grp_methods,
195 NULL,
196 NULL,
197 NULL,
198 NULL
199};
200
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000201PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000202PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000203{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000204 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000205 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000206 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000207 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000208 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209 if (!initialized)
210 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000211 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000212 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000213 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000214}