blob: 040d8b0b100ff925bc5fcfbb633b35ba17b7404b [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"
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006#include "posixmodule.h"
Guido van Rossum20882d51994-06-23 11:15:44 +00007
Guido van Rossum20882d51994-06-23 11:15:44 +00008#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"},
Serhiy Storchaka083c0aa2013-02-12 09:20:19 +020013 {"gr_gid", "group id"},
Mark Dickinson5ad35142013-08-05 17:56:17 +010014 {"gr_mem", "group members"},
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
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++) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +000050 PyObject *x = PyString_FromString(*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)
Gregory P. Smithdd96db62008-06-09 04:58:54 +000061 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)
Gregory P. Smithdd96db62008-06-09 04:58:54 +000067 SET(setIndex++, PyString_FromString(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
Serhiy Storchakada5c2a02013-02-12 09:27:53 +020073 SET(setIndex++, _PyInt_FromGid(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 *
Brett Cannon4c803f12006-05-25 22:00:14 +000086grp_getgrgid(PyObject *self, PyObject *pyo_id)
Guido van Rossum20882d51994-06-23 11:15:44 +000087{
Brett Cannon4c803f12006-05-25 22:00:14 +000088 PyObject *py_int_id;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +020089 gid_t gid;
Fred Drake51b6bc52000-07-08 16:56:26 +000090 struct group *p;
Brett Cannon4c803f12006-05-25 22:00:14 +000091
92 py_int_id = PyNumber_Int(pyo_id);
93 if (!py_int_id)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +020094 return NULL;
95 if (!_Py_Gid_Converter(py_int_id, &gid)) {
96 Py_DECREF(py_int_id);
97 return NULL;
98 }
Brett Cannon4c803f12006-05-25 22:00:14 +000099 Py_DECREF(py_int_id);
100
Fred Drake51b6bc52000-07-08 16:56:26 +0000101 if ((p = getgrgid(gid)) == NULL) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200102 if (gid < 0)
103 PyErr_Format(PyExc_KeyError,
104 "getgrgid(): gid not found: %ld", (long)gid);
105 else
106 PyErr_Format(PyExc_KeyError,
107 "getgrgid(): gid not found: %lu", (unsigned long)gid);
Fred Drake51b6bc52000-07-08 16:56:26 +0000108 return NULL;
109 }
110 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000111}
112
Fred Drake51b6bc52000-07-08 16:56:26 +0000113static PyObject *
Brett Cannon4c803f12006-05-25 22:00:14 +0000114grp_getgrnam(PyObject *self, PyObject *pyo_name)
Guido van Rossum20882d51994-06-23 11:15:44 +0000115{
Brett Cannon4c803f12006-05-25 22:00:14 +0000116 PyObject *py_str_name;
Fred Drake51b6bc52000-07-08 16:56:26 +0000117 char *name;
118 struct group *p;
Brett Cannon4c803f12006-05-25 22:00:14 +0000119
120 py_str_name = PyObject_Str(pyo_name);
121 if (!py_str_name)
122 return NULL;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000123 name = PyString_AS_STRING(py_str_name);
Serhiy Storchaka083c0aa2013-02-12 09:20:19 +0200124
Fred Drake51b6bc52000-07-08 16:56:26 +0000125 if ((p = getgrnam(name)) == NULL) {
Barry Warsawc7a77092004-01-20 21:06:00 +0000126 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
Brett Cannon4c803f12006-05-25 22:00:14 +0000127 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000128 return NULL;
129 }
Brett Cannon4c803f12006-05-25 22:00:14 +0000130
131 Py_DECREF(py_str_name);
Fred Drake51b6bc52000-07-08 16:56:26 +0000132 return mkgrent(p);
Guido van Rossum20882d51994-06-23 11:15:44 +0000133}
134
Fred Drake51b6bc52000-07-08 16:56:26 +0000135static PyObject *
Brett Cannon4c803f12006-05-25 22:00:14 +0000136grp_getgrall(PyObject *self, PyObject *ignore)
Guido van Rossum20882d51994-06-23 11:15:44 +0000137{
Fred Drake51b6bc52000-07-08 16:56:26 +0000138 PyObject *d;
139 struct group *p;
140
Fred Drake51b6bc52000-07-08 16:56:26 +0000141 if ((d = PyList_New(0)) == NULL)
142 return NULL;
143 setgrent();
144 while ((p = getgrent()) != NULL) {
145 PyObject *v = mkgrent(p);
146 if (v == NULL || PyList_Append(d, v) != 0) {
147 Py_XDECREF(v);
148 Py_DECREF(d);
Martin v. Löwis4f16d3b2009-05-29 15:58:08 +0000149 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000150 return NULL;
151 }
152 Py_DECREF(v);
153 }
Fred Drake8e68eb62001-03-11 03:03:07 +0000154 endgrent();
Fred Drake51b6bc52000-07-08 16:56:26 +0000155 return d;
Guido van Rossum20882d51994-06-23 11:15:44 +0000156}
157
Roger E. Masseb2b44e51996-12-18 19:37:32 +0000158static PyMethodDef grp_methods[] = {
Brett Cannon4c803f12006-05-25 22:00:14 +0000159 {"getgrgid", grp_getgrgid, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000160 "getgrgid(id) -> tuple\n\
161Return the group database entry for the given numeric group ID. If\n\
162id is not valid, raise KeyError."},
Brett Cannon4c803f12006-05-25 22:00:14 +0000163 {"getgrnam", grp_getgrnam, METH_O,
Fred Drake51b6bc52000-07-08 16:56:26 +0000164 "getgrnam(name) -> tuple\n\
165Return the group database entry for the given group name. If\n\
166name is not valid, raise KeyError."},
Brett Cannon4c803f12006-05-25 22:00:14 +0000167 {"getgrall", grp_getgrall, METH_NOARGS,
Fred Drake51b6bc52000-07-08 16:56:26 +0000168 "getgrall() -> list of tuples\n\
R. David Murrayf8a63912010-12-14 16:26:30 +0000169Return a list of all available group entries, in arbitrary order.\n\
170An entry whose name starts with '+' or '-' represents an instruction\n\
171to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
Fred Drake51b6bc52000-07-08 16:56:26 +0000172 {NULL, NULL} /* sentinel */
Guido van Rossum20882d51994-06-23 11:15:44 +0000173};
174
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000175PyDoc_STRVAR(grp__doc__,
Fred Drake51b6bc52000-07-08 16:56:26 +0000176"Access to the Unix group database.\n\
177\n\
178Group entries are reported as 4-tuples containing the following fields\n\
179from the group database, in order:\n\
180\n\
181 name - name of the group\n\
182 passwd - group password (encrypted); often empty\n\
183 gid - numeric ID of the group\n\
184 mem - list of members\n\
185\n\
186The gid is an integer, name and password are strings. (Note that most\n\
187users are not explicitly listed as members of the groups they are in\n\
188according to the password database. Check both databases to get\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000189complete membership information.)");
Fred Drake51b6bc52000-07-08 16:56:26 +0000190
191
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000192PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000193initgrp(void)
Guido van Rossum20882d51994-06-23 11:15:44 +0000194{
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000195 PyObject *m, *d;
196 m = Py_InitModule3("grp", grp_methods, grp__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000197 if (m == NULL)
198 return;
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000199 d = PyModule_GetDict(m);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +0000200 if (!initialized)
201 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
Martin v. Löwisdbd55b32002-03-01 10:38:44 +0000202 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +0000203 initialized = 1;
Guido van Rossum20882d51994-06-23 11:15:44 +0000204}