blob: 00c35616bfec213870dc7bf9a3f7617090723dbd [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
17#include <rpcsvc/ypclnt.h>
18#include <sys/time.h>
19#include <sys/types.h>
20#include <rpc/rpc.h>
21#include <rpcsvc/yp_prot.h>
22
Guido van Rossum3562d521992-08-12 15:26:16 +000023static object *NisError;
24
25static object *
26nis_error (err)
27 int err;
28{
29 err_setstr(NisError, yperr_string(err));
30 return NULL;
31}
32
Guido van Rossum9de7a011992-08-12 14:57:12 +000033static struct nis_map {
34 char *alias;
35 char *map;
36} aliases [] = {
Guido van Rossum3562d521992-08-12 15:26:16 +000037 {"passwd", "passwd.byname"},
38 {"group", "group.byname"},
39 {"networks", "networks.byaddr"},
40 {"hosts", "hosts.byname"},
41 {"protocols", "protocols.bynumber"},
42 {"services", "services.byname"},
43 {"aliases", "mail.aliases"},
44 {"ethers", "ethers.byname"},
45 {0L, 0L}
Guido van Rossum9de7a011992-08-12 14:57:12 +000046};
47
48static char *
49nis_mapname (map)
Guido van Rossum3562d521992-08-12 15:26:16 +000050 char *map;
Guido van Rossum9de7a011992-08-12 14:57:12 +000051{
Guido van Rossum3562d521992-08-12 15:26:16 +000052 int i;
Guido van Rossum9de7a011992-08-12 14:57:12 +000053
54 for (i=0; aliases[i].alias != 0L; i++)
55 if (!strcmp (aliases[i].alias, map))
56 map = aliases[i].map;
57 return map;
58}
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060typedef int (*foreachfunc) PROTO((int, char *, int, char *, int, char *));
61
Guido van Rossum9de7a011992-08-12 14:57:12 +000062static int
Guido van Rossum3562d521992-08-12 15:26:16 +000063nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
64 int instatus;
65 char *inkey;
66 int inkeylen;
67 char *inval;
68 int invallen;
69 object *indata;
Guido van Rossum9de7a011992-08-12 14:57:12 +000070{
71 if (instatus == YP_TRUE) {
Guido van Rossume77a7571993-11-03 15:01:26 +000072 object *key = newsizedstringobject(inkey, inkeylen);
73 object *val = newsizedstringobject(inval, invallen);
74 int err;
75 if (key == NULL || val == NULL) {
76 /* XXX error -- don't know how to handle */
77 err_clear();
78 XDECREF(key);
79 XDECREF(val);
80 return 1;
81 }
82 err = mappinginsert(indata, key, val);
83 DECREF(key);
84 DECREF(val);
85 if (err != 0) {
86 err_clear();
87 return 1;
88 }
Guido van Rossum9de7a011992-08-12 14:57:12 +000089 return 0;
90 }
91 return 1;
92}
93
94static object *
95nis_match (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +000096 object *self;
97 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +000098{
Guido van Rossum3562d521992-08-12 15:26:16 +000099 char *match;
100 char *domain;
Guido van Rossume77a7571993-11-03 15:01:26 +0000101 int keylen, len;
Guido van Rossum3562d521992-08-12 15:26:16 +0000102 char *key, *map;
103 int err;
104 object *res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000105
Guido van Rossume77a7571993-11-03 15:01:26 +0000106 if (!getargs(args, "(s#s)", &key, &keylen, &map))
Guido van Rossum9de7a011992-08-12 14:57:12 +0000107 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000108 if ((err = yp_get_default_domain(&domain)) != 0)
109 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000110 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000111 map = nis_mapname (map);
Guido van Rossume77a7571993-11-03 15:01:26 +0000112 err = yp_match (domain, map, key, keylen, &match, &len);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000113 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000114 if (err != 0)
115 return nis_error(err);
116 res = newsizedstringobject (match, len);
117 free (match);
118 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000119}
120
121static object *
122nis_cat (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000123 object *self;
124 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000125{
Guido van Rossum3562d521992-08-12 15:26:16 +0000126 char *domain;
127 char *map;
128 struct ypall_callback cb;
129 object *cat;
130 int err;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000131
132 if (!getstrarg(args, &map))
133 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000134 if ((err = yp_get_default_domain(&domain)) != 0)
135 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000136 cat = newdictobject ();
137 if (cat == NULL)
138 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000139 cb.foreach = (foreachfunc)nis_foreach;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000140 cb.data = (char *)cat;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000141 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000142 map = nis_mapname (map);
143 err = yp_all (domain, map, &cb);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000144 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000145 if (err != 0) {
146 DECREF(cat);
147 return nis_error(err);
148 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000149 return cat;
150}
151
Guido van Rossumb6775db1994-08-01 11:34:53 +0000152/* These should be u_long on Sun h/w but not on 64-bit h/w.
153 This is not portable to machines with 16-bit ints and no prototypes */
154#ifndef YPPROC_MAPLIST
155#define YPPROC_MAPLIST 11
156#endif
157#ifndef YPPROG
158#define YPPROG 100004
159#endif
160#ifndef YPVERS
161#define YPVERS 2
162#endif
Guido van Rossum9de7a011992-08-12 14:57:12 +0000163
164typedef char *domainname;
165typedef char *mapname;
166
167enum nisstat {
168 NIS_TRUE = 1,
169 NIS_NOMORE = 2,
170 NIS_FALSE = 0,
171 NIS_NOMAP = -1,
172 NIS_NODOM = -2,
173 NIS_NOKEY = -3,
174 NIS_BADOP = -4,
175 NIS_BADDB = -5,
176 NIS_YPERR = -6,
177 NIS_BADARGS = -7,
178 NIS_VERS = -8
179};
180typedef enum nisstat nisstat;
181
182struct nismaplist {
183 mapname map;
184 struct nismaplist *next;
185};
186typedef struct nismaplist nismaplist;
187
188struct nisresp_maplist {
189 nisstat stat;
190 nismaplist *maps;
191};
192typedef struct nisresp_maplist nisresp_maplist;
193
194static struct timeval TIMEOUT = { 25, 0 };
195
196static
197bool_t
198nis_xdr_domainname(xdrs, objp)
199 XDR *xdrs;
200 domainname *objp;
201{
202 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
203 return (FALSE);
204 }
205 return (TRUE);
206}
207
208static
209bool_t
210nis_xdr_mapname(xdrs, objp)
211 XDR *xdrs;
212 mapname *objp;
213{
214 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
215 return (FALSE);
216 }
217 return (TRUE);
218}
219
220static
221bool_t
222nis_xdr_ypmaplist(xdrs, objp)
223 XDR *xdrs;
224 nismaplist *objp;
225{
226 if (!nis_xdr_mapname(xdrs, &objp->map)) {
227 return (FALSE);
228 }
229 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
230 return (FALSE);
231 }
232 return (TRUE);
233}
234
235static
236bool_t
237nis_xdr_ypstat(xdrs, objp)
238 XDR *xdrs;
239 nisstat *objp;
240{
241 if (!xdr_enum(xdrs, (enum_t *)objp)) {
242 return (FALSE);
243 }
244 return (TRUE);
245}
246
247
248static
249bool_t
250nis_xdr_ypresp_maplist(xdrs, objp)
251 XDR *xdrs;
252 nisresp_maplist *objp;
253{
254 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
255 return (FALSE);
256 }
257 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
258 return (FALSE);
259 }
260 return (TRUE);
261}
262
263
264static
265nisresp_maplist *
266nisproc_maplist_2(argp, clnt)
267 domainname *argp;
268 CLIENT *clnt;
269{
270 static nisresp_maplist res;
271
Guido van Rossum9de7a011992-08-12 14:57:12 +0000272 memset(&res, 0, sizeof(res));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
274 nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
275 != RPC_SUCCESS) {
Guido van Rossum9de7a011992-08-12 14:57:12 +0000276 return (NULL);
277 }
278 return (&res);
279}
280
281static
282nismaplist *
283nis_maplist ()
284{
Guido van Rossum3562d521992-08-12 15:26:16 +0000285 nisresp_maplist *list;
286 char *dom;
287 CLIENT *cl, *clnt_create();
288 char *server;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000289
290 yp_get_default_domain (&dom);
291 yp_master (dom, aliases[0].map, &server);
292 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
293 if (cl == NULL) {
294 clnt_pcreateerror(server);
295 return NULL;
296 }
297 list = nisproc_maplist_2 (&dom, cl);
298 if (list == NULL)
299 return NULL;
300 if (list->stat != NIS_TRUE)
301 return NULL;
302 return list->maps;
303}
304
305static object *
306nis_maps (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000307 object *self;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000308 object *args;
309{
Guido van Rossum3562d521992-08-12 15:26:16 +0000310 nismaplist *maps;
311 object *list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000312
313 if ((maps = nis_maplist ()) == NULL)
314 return NULL;
315 if ((list = newlistobject(0)) == NULL)
316 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000317 for (maps = maps->next; maps; maps = maps->next) {
318 if (addlistitem (list, newstringobject (maps->map)) < 0) {
319 DECREF(list);
320 list = NULL;
321 break;
322 }
323 }
324 /* XXX Shouldn't we free the list of maps now? */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000325 return list;
326}
327
328static struct methodlist nis_methods[] = {
329 {"match", nis_match},
330 {"cat", nis_cat},
331 {"maps", nis_maps},
332 {NULL, NULL} /* Sentinel */
333};
334
335void
336initnis ()
337{
Guido van Rossum3562d521992-08-12 15:26:16 +0000338 object *m, *d;
339 m = initmodule("nis", nis_methods);
340 d = getmoduledict(m);
341 NisError = newstringobject("nis.error");
342 if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
343 fatal("Cannot define nis.error");
Guido van Rossum9de7a011992-08-12 14:57:12 +0000344}