blob: 6655451ebd2fbf7bd84fad8ff729f7be73e9243e [file] [log] [blame]
Guido van Rossum9de7a011992-08-12 14:57:12 +00001/***********************************************************
2 Written by:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003 Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
4 B&O group,
5 Faculteit der Informatica,
6 Universiteit Twente,
7 Enschede,
8 the Netherlands.
Guido van Rossum9de7a011992-08-12 14:57:12 +00009******************************************************************/
10
11/* NIS module implementation */
12
Barry Warsawadbf4e61996-12-11 00:15:58 +000013#include "Python.h"
Guido van Rossum9de7a011992-08-12 14:57:12 +000014
Guido van Rossum9de7a011992-08-12 14:57:12 +000015#include <sys/time.h>
16#include <sys/types.h>
17#include <rpc/rpc.h>
18#include <rpcsvc/yp_prot.h>
Guido van Rossum8a170cb1996-08-08 19:11:41 +000019#include <rpcsvc/ypclnt.h>
Guido van Rossum9de7a011992-08-12 14:57:12 +000020
Guido van Rossum259552d1996-12-09 18:46:28 +000021#ifdef __sgi
22/* This is missing from rpcsvc/ypclnt.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000023extern int yp_get_default_domain(char **);
Guido van Rossum259552d1996-12-09 18:46:28 +000024#endif
25
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026PyDoc_STRVAR(get_default_domain__doc__,
Martin v. Löwis57a34e82006-02-04 19:12:37 +000027"get_default_domain() -> str\n\
28Corresponds to the C library yp_get_default_domain() call, returning\n\
29the default NIS domain.\n");
30
31PyDoc_STRVAR(match__doc__,
32"match(key, map, domain = defaultdomain)\n\
33Corresponds to the C library yp_match() call, returning the value of\n\
34key in the given map. Optionally domain can be specified but it\n\
35defaults to the system default domain.\n");
36
37PyDoc_STRVAR(cat__doc__,
38"cat(map, domain = defaultdomain)\n\
39Returns the entire map as a dictionary. Optionally domain can be\n\
40specified but it defaults to the system default domain.\n");
41
42PyDoc_STRVAR(maps__doc__,
43"maps(domain = defaultdomain)\n\
44Returns an array of all available NIS maps within a domain. If domain\n\
45is not specified it defaults to the system default domain.\n");
46
Dong-hee Naddef3bd2020-06-12 11:26:00 +090047typedef struct {
48 PyObject *nis_error;
49} nis_state;
50
51static inline nis_state*
52get_nis_state(PyObject *module)
53{
54 void *state = PyModule_GetState(module);
55 assert(state != NULL);
56 return (nis_state *)state;
57}
58
59static int
60nis_clear(PyObject *m)
61{
62 Py_CLEAR(get_nis_state(m)->nis_error);
63 return 0;
64}
65
66static int
67nis_traverse(PyObject *m, visitproc visit, void *arg)
68{
69 Py_VISIT(get_nis_state(m)->nis_error);
70 return 0;
71}
72
73static void
74nis_free(void *m)
75{
76 nis_clear((PyObject *) m);
77}
Guido van Rossum3562d521992-08-12 15:26:16 +000078
Barry Warsawadbf4e61996-12-11 00:15:58 +000079static PyObject *
Dong-hee Naddef3bd2020-06-12 11:26:00 +090080nis_error(nis_state *state, int err)
Guido van Rossum3562d521992-08-12 15:26:16 +000081{
Dong-hee Naddef3bd2020-06-12 11:26:00 +090082 PyErr_SetString(state->nis_error, yperr_string(err));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +000084}
85
Guido van Rossum9de7a011992-08-12 14:57:12 +000086static struct nis_map {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 char *alias;
88 char *map;
89 int fix;
Guido van Rossum9de7a011992-08-12 14:57:12 +000090} aliases [] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 {"passwd", "passwd.byname", 0},
92 {"group", "group.byname", 0},
93 {"networks", "networks.byaddr", 0},
94 {"hosts", "hosts.byname", 0},
95 {"protocols", "protocols.bynumber", 0},
96 {"services", "services.byname", 0},
97 {"aliases", "mail.aliases", 1}, /* created with 'makedbm -a' */
98 {"ethers", "ethers.byname", 0},
99 {0L, 0L, 0}
Guido van Rossum9de7a011992-08-12 14:57:12 +0000100};
101
102static char *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900103nis_mapname(char *map, int *pfix)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 int i;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 *pfix = 0;
108 for (i=0; aliases[i].alias != 0L; i++) {
Raymond Hettinger9f4b8602015-07-24 00:43:44 -0400109 if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 *pfix = aliases[i].fix;
111 return aliases[i].map;
112 }
113 }
Guido van Rossum61b705a2000-02-29 15:52:40 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 return map;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000116}
117
Amaury Forgeot d'Arc783f86e2009-07-07 06:51:26 +0000118#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
Brett Cannonf6067ec2004-07-10 00:57:37 +0000119typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
120#else
Tim Petersdbd9ba62000-07-09 03:09:57 +0000121typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
Brett Cannonf6067ec2004-07-10 00:57:37 +0000122#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000123
Guido van Rossum61b705a2000-02-29 15:52:40 +0000124struct ypcallback_data {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 PyObject *dict;
126 int fix;
127 PyThreadState *state;
Guido van Rossum61b705a2000-02-29 15:52:40 +0000128};
129
Guido van Rossum9de7a011992-08-12 14:57:12 +0000130static int
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900131nis_foreach(int instatus, char *inkey, int inkeylen, char *inval,
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000132 int invallen, struct ypcallback_data *indata)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 if (instatus == YP_TRUE) {
135 PyObject *key;
136 PyObject *val;
137 int err;
Guido van Rossum61b705a2000-02-29 15:52:40 +0000138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 PyEval_RestoreThread(indata->state);
140 if (indata->fix) {
141 if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
142 inkeylen--;
143 if (invallen > 0 && inval[invallen-1] == '\0')
144 invallen--;
145 }
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000146 key = PyUnicode_DecodeFSDefaultAndSize(inkey, inkeylen);
147 val = PyUnicode_DecodeFSDefaultAndSize(inval, invallen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 if (key == NULL || val == NULL) {
149 /* XXX error -- don't know how to handle */
150 PyErr_Clear();
151 Py_XDECREF(key);
152 Py_XDECREF(val);
Martin v. Löwisdfaf9ec2010-08-18 16:12:23 +0000153 indata->state = PyEval_SaveThread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 return 1;
155 }
156 err = PyDict_SetItem(indata->dict, key, val);
157 Py_DECREF(key);
158 Py_DECREF(val);
159 if (err != 0)
160 PyErr_Clear();
161 indata->state = PyEval_SaveThread();
162 if (err != 0)
163 return 1;
164 return 0;
165 }
166 return 1;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000167}
168
Barry Warsawadbf4e61996-12-11 00:15:58 +0000169static PyObject *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900170nis_get_default_domain(PyObject *module, PyObject *Py_UNUSED(ignored))
Martin v. Löwis57a34e82006-02-04 19:12:37 +0000171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 char *domain;
173 int err;
174 PyObject *res;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900175 nis_state *state = get_nis_state(module);
176 if ((err = yp_get_default_domain(&domain)) != 0) {
177 return nis_error(state, err);
178 }
Martin v. Löwis57a34e82006-02-04 19:12:37 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 res = PyUnicode_FromStringAndSize (domain, strlen(domain));
181 return res;
Martin v. Löwis57a34e82006-02-04 19:12:37 +0000182}
183
184static PyObject *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900185nis_match(PyObject *module, PyObject *args, PyObject *kwdict)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 char *match;
188 char *domain = NULL;
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000189 Py_ssize_t keylen;
190 int len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 char *key, *map;
192 int err;
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000193 PyObject *ukey, *bkey, *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 int fix;
195 static char *kwlist[] = {"key", "map", "domain", NULL};
Guido van Rossum9de7a011992-08-12 14:57:12 +0000196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000198 "Us|s:match", kwlist,
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900199 &ukey, &map, &domain)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 return NULL;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900201 }
202 if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) {
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000203 return NULL;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900204 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300205 /* check for embedded null bytes */
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000206 if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) {
207 Py_DECREF(bkey);
208 return NULL;
209 }
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900210
211 nis_state *state = get_nis_state(module);
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000212 if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) {
213 Py_DECREF(bkey);
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900214 return nis_error(state, err);
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000215 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 map = nis_mapname (map, &fix);
217 if (fix)
218 keylen++;
219 Py_BEGIN_ALLOW_THREADS
220 err = yp_match (domain, map, key, keylen, &match, &len);
221 Py_END_ALLOW_THREADS
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000222 Py_DECREF(bkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 if (fix)
224 len--;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900225 if (err != 0) {
226 return nis_error(state, err);
227 }
Martin v. Löwis5ea823c2010-08-19 09:11:51 +0000228 res = PyUnicode_DecodeFSDefaultAndSize(match, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 free (match);
230 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000231}
232
Barry Warsawadbf4e61996-12-11 00:15:58 +0000233static PyObject *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900234nis_cat(PyObject *module, PyObject *args, PyObject *kwdict)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 char *domain = NULL;
237 char *map;
238 struct ypall_callback cb;
239 struct ypcallback_data data;
240 PyObject *dict;
241 int err;
242 static char *kwlist[] = {"map", "domain", NULL};
Guido van Rossum9de7a011992-08-12 14:57:12 +0000243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900245 kwlist, &map, &domain)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 return NULL;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900247 }
248 nis_state *state = get_nis_state(module);
249 if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) {
250 return nis_error(state, err);
251 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 dict = PyDict_New ();
253 if (dict == NULL)
254 return NULL;
255 cb.foreach = (foreachfunc)nis_foreach;
256 data.dict = dict;
257 map = nis_mapname (map, &data.fix);
258 cb.data = (char *)&data;
259 data.state = PyEval_SaveThread();
260 err = yp_all (domain, map, &cb);
261 PyEval_RestoreThread(data.state);
262 if (err != 0) {
263 Py_DECREF(dict);
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900264 return nis_error(state, err);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 }
266 return dict;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000267}
268
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269/* These should be u_long on Sun h/w but not on 64-bit h/w.
270 This is not portable to machines with 16-bit ints and no prototypes */
271#ifndef YPPROC_MAPLIST
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272#define YPPROC_MAPLIST 11
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#endif
274#ifndef YPPROG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275#define YPPROG 100004
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276#endif
277#ifndef YPVERS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278#define YPVERS 2
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#endif
Guido van Rossum9de7a011992-08-12 14:57:12 +0000280
281typedef char *domainname;
282typedef char *mapname;
283
284enum nisstat {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 NIS_TRUE = 1,
286 NIS_NOMORE = 2,
287 NIS_FALSE = 0,
288 NIS_NOMAP = -1,
289 NIS_NODOM = -2,
290 NIS_NOKEY = -3,
291 NIS_BADOP = -4,
292 NIS_BADDB = -5,
293 NIS_YPERR = -6,
294 NIS_BADARGS = -7,
295 NIS_VERS = -8
Guido van Rossum9de7a011992-08-12 14:57:12 +0000296};
297typedef enum nisstat nisstat;
298
299struct nismaplist {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 mapname map;
301 struct nismaplist *next;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000302};
303typedef struct nismaplist nismaplist;
304
305struct nisresp_maplist {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 nisstat stat;
307 nismaplist *maps;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000308};
309typedef struct nisresp_maplist nisresp_maplist;
310
311static struct timeval TIMEOUT = { 25, 0 };
312
313static
314bool_t
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000315nis_xdr_domainname(XDR *xdrs, domainname *objp)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
318 return (FALSE);
319 }
320 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000321}
322
323static
324bool_t
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000325nis_xdr_mapname(XDR *xdrs, mapname *objp)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
328 return (FALSE);
329 }
330 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000331}
332
333static
334bool_t
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000335nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 if (!nis_xdr_mapname(xdrs, &objp->map)) {
338 return (FALSE);
339 }
340 if (!xdr_pointer(xdrs, (char **)&objp->next,
341 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
342 {
343 return (FALSE);
344 }
345 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000346}
347
348static
349bool_t
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000350nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 if (!xdr_enum(xdrs, (enum_t *)objp)) {
353 return (FALSE);
354 }
355 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000356}
357
358
359static
360bool_t
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000361nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
364 return (FALSE);
365 }
366 if (!xdr_pointer(xdrs, (char **)&objp->maps,
367 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
368 {
369 return (FALSE);
370 }
371 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000372}
373
374
375static
376nisresp_maplist *
Peter Schneider-Kamp39e0e5a2000-07-10 13:12:27 +0000377nisproc_maplist_2(domainname *argp, CLIENT *clnt)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 static nisresp_maplist res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 memset(&res, 0, sizeof(res));
382 if (clnt_call(clnt, YPPROC_MAPLIST,
383 (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
384 (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
385 TIMEOUT) != RPC_SUCCESS)
386 {
387 return (NULL);
388 }
389 return (&res);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000390}
391
392static
393nismaplist *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900394nis_maplist(nis_state *state, char *dom)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 nisresp_maplist *list;
397 CLIENT *cl;
398 char *server = NULL;
399 int mapi = 0;
Barry Warsaw3696c521996-12-11 00:29:14 +0000400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 while (!server && aliases[mapi].map != 0L) {
402 yp_master (dom, aliases[mapi].map, &server);
403 mapi++;
404 }
405 if (!server) {
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900406 PyErr_SetString(state->nis_error, "No NIS master found for any map");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 return NULL;
408 }
409 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
410 if (cl == NULL) {
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900411 PyErr_SetString(state->nis_error, clnt_spcreateerror(server));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 goto finally;
413 }
414 list = nisproc_maplist_2 (&dom, cl);
415 clnt_destroy(cl);
416 if (list == NULL)
417 goto finally;
418 if (list->stat != NIS_TRUE)
419 goto finally;
Barry Warsaw4bc9d391997-01-09 22:22:05 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 free(server);
422 return list->maps;
Barry Warsaw4bc9d391997-01-09 22:22:05 +0000423
424 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 free(server);
426 return NULL;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000427}
428
Barry Warsawadbf4e61996-12-11 00:15:58 +0000429static PyObject *
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900430nis_maps (PyObject *module, PyObject *args, PyObject *kwdict)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 char *domain = NULL;
433 nismaplist *maps;
434 PyObject *list;
435 int err;
436 static char *kwlist[] = {"domain", NULL};
Guido van Rossum9de7a011992-08-12 14:57:12 +0000437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 if (!PyArg_ParseTupleAndKeywords(args, kwdict,
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900439 "|s:maps", kwlist, &domain)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 return NULL;
441 }
Martin v. Löwis57a34e82006-02-04 19:12:37 +0000442
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900443 nis_state *state = get_nis_state(module);
444 if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
445 nis_error(state, err);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 return NULL;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900447 }
448
449 if ((maps = nis_maplist(state, domain)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 return NULL;
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900451 }
452 if ((list = PyList_New(0)) == NULL) {
453 return NULL;
454 }
Brett Cannoneb175c42011-06-06 20:24:11 -0700455 for (; maps; maps = maps->next) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 PyObject *str = PyUnicode_FromString(maps->map);
457 if (!str || PyList_Append(list, str) < 0)
458 {
Zackery Spytza2e35852018-11-30 00:40:16 -0700459 Py_XDECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 Py_DECREF(list);
461 list = NULL;
462 break;
463 }
464 Py_DECREF(str);
465 }
466 /* XXX Shouldn't we free the list of maps now? */
467 return list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000468}
469
Barry Warsawadbf4e61996-12-11 00:15:58 +0000470static PyMethodDef nis_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200471 {"match", (PyCFunction)(void(*)(void))nis_match,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 METH_VARARGS | METH_KEYWORDS,
473 match__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200474 {"cat", (PyCFunction)(void(*)(void))nis_cat,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 METH_VARARGS | METH_KEYWORDS,
476 cat__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200477 {"maps", (PyCFunction)(void(*)(void))nis_maps,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 METH_VARARGS | METH_KEYWORDS,
479 maps__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530480 {"get_default_domain", nis_get_default_domain,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 METH_NOARGS,
482 get_default_domain__doc__},
483 {NULL, NULL} /* Sentinel */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000484};
485
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900486static int
487nis_exec(PyObject *module)
488{
489 nis_state* state = get_nis_state(module);
490 state->nis_error = PyErr_NewException("nis.error", NULL, NULL);
491 if (state->nis_error == NULL) {
492 return -1;
493 }
494
495 Py_INCREF(state->nis_error);
496 if (PyModule_AddObject(module, "error", state->nis_error) < 0) {
497 Py_DECREF(state->nis_error);
498 return -1;
499 }
500 return 0;
501}
502
503static PyModuleDef_Slot nis_slots[] = {
504 {Py_mod_exec, nis_exec},
505 {0, NULL}
506};
507
Martin v. Löwis57a34e82006-02-04 19:12:37 +0000508PyDoc_STRVAR(nis__doc__,
509"This module contains functions for accessing NIS maps.\n");
510
Martin v. Löwis1a214512008-06-11 05:26:20 +0000511static struct PyModuleDef nismodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 PyModuleDef_HEAD_INIT,
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900513 .m_name = "nis",
514 .m_doc = nis__doc__,
515 .m_size = sizeof(nis_state),
516 .m_methods = nis_methods,
517 .m_traverse = nis_traverse,
518 .m_clear = nis_clear,
519 .m_free = nis_free,
520 .m_slots = nis_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +0000521};
522
Victor Stinnerf024d262015-03-17 17:48:27 +0100523PyMODINIT_FUNC
524PyInit_nis(void)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000525{
Dong-hee Naddef3bd2020-06-12 11:26:00 +0900526 return PyModuleDef_Init(&nismodule);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000527}