blob: ca3a3583f81742bfb02b99bf8bd66d5ce868f011 [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\
167Return a list of all available group entries, in arbitrary order."},
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000168 {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 = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000190 PyModuleDef_HEAD_INIT,
191 "grp",
192 grp__doc__,
193 -1,
194 grp_methods,
195 NULL,
196 NULL,
197 NULL,
198 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000199};
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)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000210 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}