blob: e5b9f4708c67879bdaf21f5ea5e822940ee68541 [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
Martin v. Löwis19ab6c92006-04-16 18:55:50 +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++) {
50 PyObject *x = PyString_FromString(*member);
51 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)
61 SET(setIndex++, PyString_FromString(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)
67 SET(setIndex++, PyString_FromString(p->gr_passwd));
68 else {
69 SET(setIndex++, Py_None);
70 Py_INCREF(Py_None);
71 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000072#endif
Martin v. Löwisdbd55b32002-03-01 10:38:44 +000073 SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
74 SET(setIndex++, w);
75#undef SET
76
77 if (PyErr_Occurred()) {
78 Py_DECREF(v);
79 Py_DECREF(w);
80 return NULL;
81 }
82
Fred Drake51b6bc52000-07-08 16:56:26 +000083 return v;
Guido van Rossum20882d51994-06-23 11:15:44 +000084}
85
Fred Drake51b6bc52000-07-08 16:56:26 +000086static PyObject *
Brett Cannon4c803f12006-05-25 22:00:14 +000087grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000088{
Brett Cannon4c803f12006-05-25 22:00:14 +000089 PyObject *py_int_id;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000090 unsigned int gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000091 struct group *p;
Brett Cannon4c803f12006-05-25 22:00:14 +000092
93 py_int_id = PyNumber_Int(pyo_id);
94 if (!py_int_id)
95 return NULL;
96 gid = PyInt_AS_LONG(py_int_id);
97 Py_DECREF(py_int_id);
98
Fred Drake51b6bc52000-07-08 16:56:26 +000099 if ((p = getgrgid(gid)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000100 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
Fred Drake51b6bc52000-07-08 16:56:26 +0000101 return NULL;
102 }
103 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000104}
105
Fred Drake51b6bc52000-07-08 16:56:26 +0000106static PyObject *
Brett Cannon4c803f12006-05-25 22:00:14 +0000107grp_getgrnam(PyObject *self, PyObject *pyo_name)
Guido van Rossum20882d51994-06-23 11:15:44 +0000108{
Brett Cannon4c803f12006-05-25 22:00:14 +0000109 PyObject *py_str_name;
Fred Drake51b6bc52000-07-08 16:56:26 +0000110 char *name;
111 struct group *p;
Brett Cannon4c803f12006-05-25 22:00:14 +0000112
113 py_str_name = PyObject_Str(pyo_name);
114 if (!py_str_name)
115 return NULL;
116 name = PyString_AS_STRING(py_str_name);
117
Fred Drake51b6bc52000-07-08 16:56:26 +0000118 if ((p = getgrnam(name)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000119 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Brett Cannon4c803f12006-05-25 22:00:14 +0000120 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000121 return NULL;
122 }
Brett Cannon4c803f12006-05-25 22:00:14 +0000123
124 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000125 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000126}
127
Fred Drake51b6bc52000-07-08 16:56:26 +0000128static PyObject *
Brett Cannon4c803f12006-05-25 22:00:14 +0000129grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000130{
Fred Drake51b6bc52000-07-08 16:56:26 +0000131 PyObject *d;
132 struct group *p;
133
Fred Drake51b6bc52000-07-08 16:56:26 +0000134 if ((d = PyList_New(0)) == NULL)
135 return NULL;
136 setgrent();
137 while ((p = getgrent()) != NULL) {
138 PyObject *v = mkgrent(p);
139 if (v == NULL || PyList_Append(d, v) != 0) {
140 Py_XDECREF(v);
141 Py_DECREF(d);
142 return NULL;
143 }
144 Py_DECREF(v);
145 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000146 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000147 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000148}
149
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000150static PyMethodDef grp_methods[] = {
Brett Cannon4c803f12006-05-25 22:00:14 +0000151 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000152 "getgrgid(id) -> tuple\n\
153Return the group database entry for the given numeric group ID. If\n\
154id is not valid, raise KeyError."},
Brett Cannon4c803f12006-05-25 22:00:14 +0000155 {"getgrnam", grp_getgrnam, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000156 "getgrnam(name) -> tuple\n\
157Return the group database entry for the given group name. If\n\
158name is not valid, raise KeyError."},
Brett Cannon4c803f12006-05-25 22:00:14 +0000159 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000160 "getgrall() -> list of tuples\n\
161Return a list of all available group entries, in arbitrary order."},
162 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000163};
164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000165PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000166"Access to the Unix group database.\n\
167\n\
168Group entries are reported as 4-tuples containing the following fields\n\
169from the group database, in order:\n\
170\n\
171 name - name of the group\n\
172 passwd - group password (encrypted); often empty\n\
173 gid - numeric ID of the group\n\
174 mem - list of members\n\
175\n\
176The gid is an integer, name and password are strings. (Note that most\n\
177users are not explicitly listed as members of the groups they are in\n\
178according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000180
181
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000182PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000183initgrp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000184{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000185 PyObject *m, *d;
186 m = Py_InitModule3("grp", grp_methods, grp__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000187 if (m == NULL)
188 return;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000189 d = PyModule_GetDict(m);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +0000190 if (!initialized)
191 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000192 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +0000193 initialized = 1;
Guido van Rossum20882d51994-06-23 11:15:44 +0000194}