blob: b95b9146f7e0babfc1df51d9313ba392e2caee40 [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
13#include "allobjects.h"
14#include "modsupport.h"
15#include "ceval.h"
16
Guido van Rossum9de7a011992-08-12 14:57:12 +000017#include <sys/time.h>
18#include <sys/types.h>
19#include <rpc/rpc.h>
20#include <rpcsvc/yp_prot.h>
Guido van Rossum8a170cb1996-08-08 19:11:41 +000021#include <rpcsvc/ypclnt.h>
Guido van Rossum9de7a011992-08-12 14:57:12 +000022
Guido van Rossum259552d1996-12-09 18:46:28 +000023#ifdef __sgi
24/* This is missing from rpcsvc/ypclnt.h */
25extern int yp_get_default_domain();
26#endif
27
Guido van Rossum3562d521992-08-12 15:26:16 +000028static object *NisError;
29
30static object *
31nis_error (err)
32 int err;
33{
34 err_setstr(NisError, yperr_string(err));
35 return NULL;
36}
37
Guido van Rossum9de7a011992-08-12 14:57:12 +000038static struct nis_map {
39 char *alias;
40 char *map;
41} aliases [] = {
Guido van Rossum3562d521992-08-12 15:26:16 +000042 {"passwd", "passwd.byname"},
43 {"group", "group.byname"},
44 {"networks", "networks.byaddr"},
45 {"hosts", "hosts.byname"},
46 {"protocols", "protocols.bynumber"},
47 {"services", "services.byname"},
48 {"aliases", "mail.aliases"},
49 {"ethers", "ethers.byname"},
50 {0L, 0L}
Guido van Rossum9de7a011992-08-12 14:57:12 +000051};
52
53static char *
54nis_mapname (map)
Guido van Rossum3562d521992-08-12 15:26:16 +000055 char *map;
Guido van Rossum9de7a011992-08-12 14:57:12 +000056{
Guido van Rossum3562d521992-08-12 15:26:16 +000057 int i;
Guido van Rossum9de7a011992-08-12 14:57:12 +000058
59 for (i=0; aliases[i].alias != 0L; i++)
60 if (!strcmp (aliases[i].alias, map))
61 map = aliases[i].map;
62 return map;
63}
64
Guido van Rossumb6775db1994-08-01 11:34:53 +000065typedef int (*foreachfunc) PROTO((int, char *, int, char *, int, char *));
66
Guido van Rossum9de7a011992-08-12 14:57:12 +000067static int
Guido van Rossum3562d521992-08-12 15:26:16 +000068nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
69 int instatus;
70 char *inkey;
71 int inkeylen;
72 char *inval;
73 int invallen;
74 object *indata;
Guido van Rossum9de7a011992-08-12 14:57:12 +000075{
76 if (instatus == YP_TRUE) {
Guido van Rossume77a7571993-11-03 15:01:26 +000077 object *key = newsizedstringobject(inkey, inkeylen);
78 object *val = newsizedstringobject(inval, invallen);
79 int err;
80 if (key == NULL || val == NULL) {
81 /* XXX error -- don't know how to handle */
82 err_clear();
83 XDECREF(key);
84 XDECREF(val);
85 return 1;
86 }
87 err = mappinginsert(indata, key, val);
88 DECREF(key);
89 DECREF(val);
90 if (err != 0) {
91 err_clear();
92 return 1;
93 }
Guido van Rossum9de7a011992-08-12 14:57:12 +000094 return 0;
95 }
96 return 1;
97}
98
99static object *
100nis_match (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000101 object *self;
102 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000103{
Guido van Rossum3562d521992-08-12 15:26:16 +0000104 char *match;
105 char *domain;
Guido van Rossume77a7571993-11-03 15:01:26 +0000106 int keylen, len;
Guido van Rossum3562d521992-08-12 15:26:16 +0000107 char *key, *map;
108 int err;
109 object *res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000110
Guido van Rossume77a7571993-11-03 15:01:26 +0000111 if (!getargs(args, "(s#s)", &key, &keylen, &map))
Guido van Rossum9de7a011992-08-12 14:57:12 +0000112 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000113 if ((err = yp_get_default_domain(&domain)) != 0)
114 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000115 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000116 map = nis_mapname (map);
Guido van Rossume77a7571993-11-03 15:01:26 +0000117 err = yp_match (domain, map, key, keylen, &match, &len);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000118 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000119 if (err != 0)
120 return nis_error(err);
121 res = newsizedstringobject (match, len);
122 free (match);
123 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000124}
125
126static object *
127nis_cat (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000128 object *self;
129 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000130{
Guido van Rossum3562d521992-08-12 15:26:16 +0000131 char *domain;
132 char *map;
133 struct ypall_callback cb;
134 object *cat;
135 int err;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000136
137 if (!getstrarg(args, &map))
138 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000139 if ((err = yp_get_default_domain(&domain)) != 0)
140 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000141 cat = newdictobject ();
142 if (cat == NULL)
143 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000144 cb.foreach = (foreachfunc)nis_foreach;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000145 cb.data = (char *)cat;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000146 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000147 map = nis_mapname (map);
148 err = yp_all (domain, map, &cb);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000149 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000150 if (err != 0) {
151 DECREF(cat);
152 return nis_error(err);
153 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000154 return cat;
155}
156
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157/* These should be u_long on Sun h/w but not on 64-bit h/w.
158 This is not portable to machines with 16-bit ints and no prototypes */
159#ifndef YPPROC_MAPLIST
160#define YPPROC_MAPLIST 11
161#endif
162#ifndef YPPROG
163#define YPPROG 100004
164#endif
165#ifndef YPVERS
166#define YPVERS 2
167#endif
Guido van Rossum9de7a011992-08-12 14:57:12 +0000168
169typedef char *domainname;
170typedef char *mapname;
171
172enum nisstat {
173 NIS_TRUE = 1,
174 NIS_NOMORE = 2,
175 NIS_FALSE = 0,
176 NIS_NOMAP = -1,
177 NIS_NODOM = -2,
178 NIS_NOKEY = -3,
179 NIS_BADOP = -4,
180 NIS_BADDB = -5,
181 NIS_YPERR = -6,
182 NIS_BADARGS = -7,
183 NIS_VERS = -8
184};
185typedef enum nisstat nisstat;
186
187struct nismaplist {
188 mapname map;
189 struct nismaplist *next;
190};
191typedef struct nismaplist nismaplist;
192
193struct nisresp_maplist {
194 nisstat stat;
195 nismaplist *maps;
196};
197typedef struct nisresp_maplist nisresp_maplist;
198
199static struct timeval TIMEOUT = { 25, 0 };
200
201static
202bool_t
203nis_xdr_domainname(xdrs, objp)
204 XDR *xdrs;
205 domainname *objp;
206{
207 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
208 return (FALSE);
209 }
210 return (TRUE);
211}
212
213static
214bool_t
215nis_xdr_mapname(xdrs, objp)
216 XDR *xdrs;
217 mapname *objp;
218{
219 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
220 return (FALSE);
221 }
222 return (TRUE);
223}
224
225static
226bool_t
227nis_xdr_ypmaplist(xdrs, objp)
228 XDR *xdrs;
229 nismaplist *objp;
230{
231 if (!nis_xdr_mapname(xdrs, &objp->map)) {
232 return (FALSE);
233 }
234 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
235 return (FALSE);
236 }
237 return (TRUE);
238}
239
240static
241bool_t
242nis_xdr_ypstat(xdrs, objp)
243 XDR *xdrs;
244 nisstat *objp;
245{
246 if (!xdr_enum(xdrs, (enum_t *)objp)) {
247 return (FALSE);
248 }
249 return (TRUE);
250}
251
252
253static
254bool_t
255nis_xdr_ypresp_maplist(xdrs, objp)
256 XDR *xdrs;
257 nisresp_maplist *objp;
258{
259 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
260 return (FALSE);
261 }
262 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
263 return (FALSE);
264 }
265 return (TRUE);
266}
267
268
269static
270nisresp_maplist *
271nisproc_maplist_2(argp, clnt)
272 domainname *argp;
273 CLIENT *clnt;
274{
275 static nisresp_maplist res;
276
Guido van Rossum9de7a011992-08-12 14:57:12 +0000277 memset(&res, 0, sizeof(res));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
279 nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
280 != RPC_SUCCESS) {
Guido van Rossum9de7a011992-08-12 14:57:12 +0000281 return (NULL);
282 }
283 return (&res);
284}
285
286static
287nismaplist *
288nis_maplist ()
289{
Guido van Rossum3562d521992-08-12 15:26:16 +0000290 nisresp_maplist *list;
291 char *dom;
292 CLIENT *cl, *clnt_create();
293 char *server;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000294
295 yp_get_default_domain (&dom);
296 yp_master (dom, aliases[0].map, &server);
297 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
298 if (cl == NULL) {
299 clnt_pcreateerror(server);
300 return NULL;
301 }
302 list = nisproc_maplist_2 (&dom, cl);
303 if (list == NULL)
304 return NULL;
305 if (list->stat != NIS_TRUE)
306 return NULL;
307 return list->maps;
308}
309
310static object *
311nis_maps (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000312 object *self;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000313 object *args;
314{
Guido van Rossum3562d521992-08-12 15:26:16 +0000315 nismaplist *maps;
316 object *list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000317
318 if ((maps = nis_maplist ()) == NULL)
319 return NULL;
320 if ((list = newlistobject(0)) == NULL)
321 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000322 for (maps = maps->next; maps; maps = maps->next) {
323 if (addlistitem (list, newstringobject (maps->map)) < 0) {
324 DECREF(list);
325 list = NULL;
326 break;
327 }
328 }
329 /* XXX Shouldn't we free the list of maps now? */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000330 return list;
331}
332
333static struct methodlist nis_methods[] = {
334 {"match", nis_match},
335 {"cat", nis_cat},
336 {"maps", nis_maps},
337 {NULL, NULL} /* Sentinel */
338};
339
340void
341initnis ()
342{
Guido van Rossum3562d521992-08-12 15:26:16 +0000343 object *m, *d;
344 m = initmodule("nis", nis_methods);
345 d = getmoduledict(m);
346 NisError = newstringobject("nis.error");
347 if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
348 fatal("Cannot define nis.error");
Guido van Rossum9de7a011992-08-12 14:57:12 +0000349}