blob: aa38e95782ac85f564152e32a8ce00eda8395653 [file] [log] [blame]
Guido van Rossum9de7a011992-08-12 14:57:12 +00001/***********************************************************
2 Written by:
3 Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
4 Vakgroep Spa,
5 Faculteit der Informatica,
6 Universiteit Twente,
7 Enschede,
8 the Netherlands.
9******************************************************************/
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 */
23extern int yp_get_default_domain();
24#endif
25
Barry Warsawadbf4e61996-12-11 00:15:58 +000026static PyObject *NisError;
Guido van Rossum3562d521992-08-12 15:26:16 +000027
Barry Warsawadbf4e61996-12-11 00:15:58 +000028static PyObject *
Guido van Rossum3562d521992-08-12 15:26:16 +000029nis_error (err)
30 int err;
31{
Barry Warsawadbf4e61996-12-11 00:15:58 +000032 PyErr_SetString(NisError, yperr_string(err));
Guido van Rossum3562d521992-08-12 15:26:16 +000033 return NULL;
34}
35
Guido van Rossum9de7a011992-08-12 14:57:12 +000036static struct nis_map {
37 char *alias;
38 char *map;
39} aliases [] = {
Guido van Rossum3562d521992-08-12 15:26:16 +000040 {"passwd", "passwd.byname"},
41 {"group", "group.byname"},
42 {"networks", "networks.byaddr"},
43 {"hosts", "hosts.byname"},
44 {"protocols", "protocols.bynumber"},
45 {"services", "services.byname"},
46 {"aliases", "mail.aliases"},
47 {"ethers", "ethers.byname"},
48 {0L, 0L}
Guido van Rossum9de7a011992-08-12 14:57:12 +000049};
50
51static char *
52nis_mapname (map)
Guido van Rossum3562d521992-08-12 15:26:16 +000053 char *map;
Guido van Rossum9de7a011992-08-12 14:57:12 +000054{
Guido van Rossum3562d521992-08-12 15:26:16 +000055 int i;
Guido van Rossum9de7a011992-08-12 14:57:12 +000056
57 for (i=0; aliases[i].alias != 0L; i++)
58 if (!strcmp (aliases[i].alias, map))
59 map = aliases[i].map;
60 return map;
61}
62
Barry Warsawadbf4e61996-12-11 00:15:58 +000063typedef int (*foreachfunc) Py_PROTO((int, char *, int, char *, int, char *));
Guido van Rossumb6775db1994-08-01 11:34:53 +000064
Guido van Rossum9de7a011992-08-12 14:57:12 +000065static int
Guido van Rossum3562d521992-08-12 15:26:16 +000066nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
67 int instatus;
68 char *inkey;
69 int inkeylen;
70 char *inval;
71 int invallen;
Barry Warsawadbf4e61996-12-11 00:15:58 +000072 PyObject *indata;
Guido van Rossum9de7a011992-08-12 14:57:12 +000073{
74 if (instatus == YP_TRUE) {
Barry Warsawadbf4e61996-12-11 00:15:58 +000075 PyObject *key = PyString_FromStringAndSize(inkey, inkeylen);
76 PyObject *val = PyString_FromStringAndSize(inval, invallen);
Guido van Rossume77a7571993-11-03 15:01:26 +000077 int err;
78 if (key == NULL || val == NULL) {
79 /* XXX error -- don't know how to handle */
Barry Warsawadbf4e61996-12-11 00:15:58 +000080 PyErr_Clear();
81 Py_XDECREF(key);
82 Py_XDECREF(val);
Guido van Rossume77a7571993-11-03 15:01:26 +000083 return 1;
84 }
Barry Warsawadbf4e61996-12-11 00:15:58 +000085 err = PyDict_SetItem(indata, key, val);
86 Py_DECREF(key);
87 Py_DECREF(val);
Guido van Rossume77a7571993-11-03 15:01:26 +000088 if (err != 0) {
Barry Warsawadbf4e61996-12-11 00:15:58 +000089 PyErr_Clear();
Guido van Rossume77a7571993-11-03 15:01:26 +000090 return 1;
91 }
Guido van Rossum9de7a011992-08-12 14:57:12 +000092 return 0;
93 }
94 return 1;
95}
96
Barry Warsawadbf4e61996-12-11 00:15:58 +000097static PyObject *
Guido van Rossum9de7a011992-08-12 14:57:12 +000098nis_match (self, args)
Barry Warsawadbf4e61996-12-11 00:15:58 +000099 PyObject *self;
100 PyObject *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000101{
Guido van Rossum3562d521992-08-12 15:26:16 +0000102 char *match;
103 char *domain;
Guido van Rossume77a7571993-11-03 15:01:26 +0000104 int keylen, len;
Guido van Rossum3562d521992-08-12 15:26:16 +0000105 char *key, *map;
106 int err;
Barry Warsawadbf4e61996-12-11 00:15:58 +0000107 PyObject *res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000108
Barry Warsawadbf4e61996-12-11 00:15:58 +0000109 if (!PyArg_Parse(args, "(s#s)", &key, &keylen, &map))
Guido van Rossum9de7a011992-08-12 14:57:12 +0000110 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000111 if ((err = yp_get_default_domain(&domain)) != 0)
112 return nis_error(err);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000113 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3562d521992-08-12 15:26:16 +0000114 map = nis_mapname (map);
Guido van Rossume77a7571993-11-03 15:01:26 +0000115 err = yp_match (domain, map, key, keylen, &match, &len);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000116 Py_END_ALLOW_THREADS
Guido van Rossum3562d521992-08-12 15:26:16 +0000117 if (err != 0)
118 return nis_error(err);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000119 res = PyString_FromStringAndSize (match, len);
Guido van Rossum3562d521992-08-12 15:26:16 +0000120 free (match);
121 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000122}
123
Barry Warsawadbf4e61996-12-11 00:15:58 +0000124static PyObject *
Guido van Rossum9de7a011992-08-12 14:57:12 +0000125nis_cat (self, args)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000126 PyObject *self;
127 PyObject *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000128{
Guido van Rossum3562d521992-08-12 15:26:16 +0000129 char *domain;
130 char *map;
131 struct ypall_callback cb;
Barry Warsawadbf4e61996-12-11 00:15:58 +0000132 PyObject *cat;
Guido van Rossum3562d521992-08-12 15:26:16 +0000133 int err;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000134
Barry Warsawadbf4e61996-12-11 00:15:58 +0000135 if (!PyArg_Parse(args, "s", &map))
Guido van Rossum9de7a011992-08-12 14:57:12 +0000136 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000137 if ((err = yp_get_default_domain(&domain)) != 0)
138 return nis_error(err);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000139 cat = PyDict_New ();
Guido van Rossum9de7a011992-08-12 14:57:12 +0000140 if (cat == NULL)
141 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000142 cb.foreach = (foreachfunc)nis_foreach;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000143 cb.data = (char *)cat;
Barry Warsawadbf4e61996-12-11 00:15:58 +0000144 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3562d521992-08-12 15:26:16 +0000145 map = nis_mapname (map);
146 err = yp_all (domain, map, &cb);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000147 Py_END_ALLOW_THREADS
Guido van Rossum3562d521992-08-12 15:26:16 +0000148 if (err != 0) {
Barry Warsawadbf4e61996-12-11 00:15:58 +0000149 Py_DECREF(cat);
Guido van Rossum3562d521992-08-12 15:26:16 +0000150 return nis_error(err);
151 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000152 return cat;
153}
154
Guido van Rossumb6775db1994-08-01 11:34:53 +0000155/* These should be u_long on Sun h/w but not on 64-bit h/w.
156 This is not portable to machines with 16-bit ints and no prototypes */
157#ifndef YPPROC_MAPLIST
158#define YPPROC_MAPLIST 11
159#endif
160#ifndef YPPROG
161#define YPPROG 100004
162#endif
163#ifndef YPVERS
164#define YPVERS 2
165#endif
Guido van Rossum9de7a011992-08-12 14:57:12 +0000166
167typedef char *domainname;
168typedef char *mapname;
169
170enum nisstat {
Barry Warsawadbf4e61996-12-11 00:15:58 +0000171 NIS_TRUE = 1,
172 NIS_NOMORE = 2,
173 NIS_FALSE = 0,
174 NIS_NOMAP = -1,
175 NIS_NODOM = -2,
176 NIS_NOKEY = -3,
177 NIS_BADOP = -4,
178 NIS_BADDB = -5,
179 NIS_YPERR = -6,
180 NIS_BADARGS = -7,
181 NIS_VERS = -8
Guido van Rossum9de7a011992-08-12 14:57:12 +0000182};
183typedef enum nisstat nisstat;
184
185struct nismaplist {
Barry Warsawadbf4e61996-12-11 00:15:58 +0000186 mapname map;
187 struct nismaplist *next;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000188};
189typedef struct nismaplist nismaplist;
190
191struct nisresp_maplist {
192 nisstat stat;
193 nismaplist *maps;
194};
195typedef struct nisresp_maplist nisresp_maplist;
196
197static struct timeval TIMEOUT = { 25, 0 };
198
199static
200bool_t
201nis_xdr_domainname(xdrs, objp)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000202 XDR *xdrs;
203 domainname *objp;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000204{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000205 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
206 return (FALSE);
207 }
208 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000209}
210
211static
212bool_t
213nis_xdr_mapname(xdrs, objp)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000214 XDR *xdrs;
215 mapname *objp;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000216{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000217 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
218 return (FALSE);
219 }
220 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000221}
222
223static
224bool_t
225nis_xdr_ypmaplist(xdrs, objp)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000226 XDR *xdrs;
227 nismaplist *objp;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000228{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000229 if (!nis_xdr_mapname(xdrs, &objp->map)) {
230 return (FALSE);
231 }
232 if (!xdr_pointer(xdrs, (char **)&objp->next,
233 sizeof(nismaplist), nis_xdr_ypmaplist))
234 {
235 return (FALSE);
236 }
237 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000238}
239
240static
241bool_t
242nis_xdr_ypstat(xdrs, objp)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000243 XDR *xdrs;
244 nisstat *objp;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000245{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000246 if (!xdr_enum(xdrs, (enum_t *)objp)) {
247 return (FALSE);
248 }
249 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000250}
251
252
253static
254bool_t
255nis_xdr_ypresp_maplist(xdrs, objp)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000256 XDR *xdrs;
257 nisresp_maplist *objp;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000258{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000259 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
260 return (FALSE);
261 }
262 if (!xdr_pointer(xdrs, (char **)&objp->maps,
263 sizeof(nismaplist), nis_xdr_ypmaplist))
264 {
265 return (FALSE);
266 }
267 return (TRUE);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000268}
269
270
271static
272nisresp_maplist *
273nisproc_maplist_2(argp, clnt)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000274 domainname *argp;
275 CLIENT *clnt;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000276{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000277 static nisresp_maplist res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000278
Barry Warsawadbf4e61996-12-11 00:15:58 +0000279 memset(&res, 0, sizeof(res));
280 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
281 nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
282 != RPC_SUCCESS) {
283 return (NULL);
284 }
285 return (&res);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000286}
287
288static
289nismaplist *
290nis_maplist ()
291{
Guido van Rossum3562d521992-08-12 15:26:16 +0000292 nisresp_maplist *list;
293 char *dom;
294 CLIENT *cl, *clnt_create();
Barry Warsawadbf4e61996-12-11 00:15:58 +0000295 char *server = "";
296 int mapi = 0;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000297
298 yp_get_default_domain (&dom);
Barry Warsawadbf4e61996-12-11 00:15:58 +0000299 while (!strcmp("", server) && aliases[mapi].map != 0L) {
300 yp_master (dom, aliases[mapi].map, &server);
301 mapi++;
302 }
303 if (!strcmp("", server)) {
304 PyErr_SetString(NisError, "No NIS master found for any map");
305 return NULL;
306 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000307 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
308 if (cl == NULL) {
Barry Warsawadbf4e61996-12-11 00:15:58 +0000309 PyErr_SetString(NisError, clnt_spcreateerror(server));
Guido van Rossum9de7a011992-08-12 14:57:12 +0000310 return NULL;
311 }
312 list = nisproc_maplist_2 (&dom, cl);
313 if (list == NULL)
314 return NULL;
315 if (list->stat != NIS_TRUE)
316 return NULL;
317 return list->maps;
318}
319
Barry Warsawadbf4e61996-12-11 00:15:58 +0000320static PyObject *
Guido van Rossum9de7a011992-08-12 14:57:12 +0000321nis_maps (self, args)
Barry Warsawadbf4e61996-12-11 00:15:58 +0000322 PyObject *self;
323 PyObject *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000324{
Guido van Rossum3562d521992-08-12 15:26:16 +0000325 nismaplist *maps;
Barry Warsawadbf4e61996-12-11 00:15:58 +0000326 PyObject *list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000327
328 if ((maps = nis_maplist ()) == NULL)
329 return NULL;
Barry Warsawadbf4e61996-12-11 00:15:58 +0000330 if ((list = PyList_New(0)) == NULL)
Guido van Rossum9de7a011992-08-12 14:57:12 +0000331 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000332 for (maps = maps->next; maps; maps = maps->next) {
Barry Warsawadbf4e61996-12-11 00:15:58 +0000333 if (PyList_Append (list, PyString_FromString (maps->map)) < 0)
334 {
335 Py_DECREF(list);
Guido van Rossum3562d521992-08-12 15:26:16 +0000336 list = NULL;
337 break;
338 }
339 }
340 /* XXX Shouldn't we free the list of maps now? */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000341 return list;
342}
343
Barry Warsawadbf4e61996-12-11 00:15:58 +0000344static PyMethodDef nis_methods[] = {
Guido van Rossum9de7a011992-08-12 14:57:12 +0000345 {"match", nis_match},
346 {"cat", nis_cat},
347 {"maps", nis_maps},
348 {NULL, NULL} /* Sentinel */
349};
350
351void
352initnis ()
353{
Barry Warsawadbf4e61996-12-11 00:15:58 +0000354 PyObject *m, *d;
355 m = Py_InitModule("nis", nis_methods);
356 d = PyModule_GetDict(m);
357 NisError = PyString_FromString("nis.error");
358 if (NisError == NULL ||
359 PyDict_SetItemString(d, "error", NisError) != 0)
360 Py_FatalError("Cannot define nis.error");
Guido van Rossum9de7a011992-08-12 14:57:12 +0000361}