blob: 4ab5547fddbc19352b52817871cedc1cec4b8e02 [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 Pitrou7f14f0d2010-05-09 16:14:21 +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 }
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)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000070 SET(setIndex++, FSDECODE(p->gr_passwd));
Martin v. Löwisceb7c182002-09-17 07:05:25 +000071 else {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000072 SET(setIndex++, Py_None);
73 Py_INCREF(Py_None);
Martin v. Löwisceb7c182002-09-17 07:05:25 +000074 }
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);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000082 return NULL;
83 }
84
Fred Drake51b6bc52000-07-08 16:56:26 +000085 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000086}
87
Fred Drake51b6bc52000-07-08 16:56:26 +000088static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +000089grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000090{
Thomas Wouters477c8d52006-05-27 19:21:47 +000091 PyObject *py_int_id;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000092 unsigned int gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000093 struct group *p;
Thomas Wouters477c8d52006-05-27 19:21:47 +000094
Mark Dickinson17c7cd82009-01-17 21:57:11 +000095 py_int_id = PyNumber_Long(pyo_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000096 if (!py_int_id)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000097 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +000098 gid = PyLong_AS_LONG(py_int_id);
Thomas Wouters477c8d52006-05-27 19:21:47 +000099 Py_DECREF(py_int_id);
100
Fred Drake51b6bc52000-07-08 16:56:26 +0000101 if ((p = getgrgid(gid)) == NULL) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000102 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
Fred Drake51b6bc52000-07-08 16:56:26 +0000103 return NULL;
104 }
105 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000106}
107
Fred Drake51b6bc52000-07-08 16:56:26 +0000108static PyObject *
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000109grp_getgrnam(PyObject *self, PyObject *args)
Guido van Rossum20882d51994-06-23 11:15:44 +0000110{
Fred Drake51b6bc52000-07-08 16:56:26 +0000111 char *name;
112 struct group *p;
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000113 PyObject *arg, *bytes, *retval = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000115 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
116 return NULL;
117 if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding,
118 "surrogateescape")) == NULL)
119 return NULL;
120 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
121 goto out;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000122
Fred Drake51b6bc52000-07-08 16:56:26 +0000123 if ((p = getgrnam(name)) == NULL) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000124 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000125 goto out;
Fred Drake51b6bc52000-07-08 16:56:26 +0000126 }
Martin v. Löwisb6a748b2009-05-29 15:23:17 +0000127 retval = mkgrent(p);
128out:
129 Py_DECREF(bytes);
130 return retval;
Guido van Rossum20882d51994-06-23 11:15:44 +0000131}
132
Fred Drake51b6bc52000-07-08 16:56:26 +0000133static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000134grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000135{
Fred Drake51b6bc52000-07-08 16:56:26 +0000136 PyObject *d;
137 struct group *p;
138
Fred Drake51b6bc52000-07-08 16:56:26 +0000139 if ((d = PyList_New(0)) == NULL)
140 return NULL;
141 setgrent();
142 while ((p = getgrent()) != NULL) {
143 PyObject *v = mkgrent(p);
144 if (v == NULL || PyList_Append(d, v) != 0) {
145 Py_XDECREF(v);
146 Py_DECREF(d);
Martin v. Löwise23c8682009-05-29 16:01:34 +0000147 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000148 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[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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."},
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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."},
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000165 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000166 "getgrall() -> list of tuples\n\
R. David Murrayd8fec5f2010-12-14 16:24:18 +0000167Return a list of all available group entries, in arbitrary order.\n\
168An entry whose name starts with '+' or '-' represents an instruction\n\
169to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000170 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000171};
172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000173PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000174"Access to the Unix group database.\n\
175\n\
176Group entries are reported as 4-tuples containing the following fields\n\
177from the group database, in order:\n\
178\n\
179 name - name of the group\n\
180 passwd - group password (encrypted); often empty\n\
181 gid - numeric ID of the group\n\
182 mem - list of members\n\
183\n\
184The gid is an integer, name and password are strings. (Note that most\n\
185users are not explicitly listed as members of the groups they are in\n\
186according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000187complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000188
189
Martin v. Löwis1a214512008-06-11 05:26:20 +0000190
191static struct PyModuleDef grpmodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000192 PyModuleDef_HEAD_INIT,
193 "grp",
194 grp__doc__,
195 -1,
196 grp_methods,
197 NULL,
198 NULL,
199 NULL,
200 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000201};
202
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000203PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000204PyInit_grp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000205{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000206 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000207 m = PyModule_Create(&grpmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000208 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000209 return NULL;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000210 d = PyModule_GetDict(m);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211 if (!initialized)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000212 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000213 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000214 initialized = 1;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000215 return m;
Guido van Rossum20882d51994-06-23 11:15:44 +0000216}