blob: 5db26f4fec51d49408fa181ae3b3124619cd1378 [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
60static int
Guido van Rossum3562d521992-08-12 15:26:16 +000061nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
62 int instatus;
63 char *inkey;
64 int inkeylen;
65 char *inval;
66 int invallen;
67 object *indata;
Guido van Rossum9de7a011992-08-12 14:57:12 +000068{
69 if (instatus == YP_TRUE) {
Guido van Rossume77a7571993-11-03 15:01:26 +000070 object *key = newsizedstringobject(inkey, inkeylen);
71 object *val = newsizedstringobject(inval, invallen);
72 int err;
73 if (key == NULL || val == NULL) {
74 /* XXX error -- don't know how to handle */
75 err_clear();
76 XDECREF(key);
77 XDECREF(val);
78 return 1;
79 }
80 err = mappinginsert(indata, key, val);
81 DECREF(key);
82 DECREF(val);
83 if (err != 0) {
84 err_clear();
85 return 1;
86 }
Guido van Rossum9de7a011992-08-12 14:57:12 +000087 return 0;
88 }
89 return 1;
90}
91
92static object *
93nis_match (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +000094 object *self;
95 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +000096{
Guido van Rossum3562d521992-08-12 15:26:16 +000097 char *match;
98 char *domain;
Guido van Rossume77a7571993-11-03 15:01:26 +000099 int keylen, len;
Guido van Rossum3562d521992-08-12 15:26:16 +0000100 char *key, *map;
101 int err;
102 object *res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000103
Guido van Rossume77a7571993-11-03 15:01:26 +0000104 if (!getargs(args, "(s#s)", &key, &keylen, &map))
Guido van Rossum9de7a011992-08-12 14:57:12 +0000105 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000106 if ((err = yp_get_default_domain(&domain)) != 0)
107 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000108 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000109 map = nis_mapname (map);
Guido van Rossume77a7571993-11-03 15:01:26 +0000110 err = yp_match (domain, map, key, keylen, &match, &len);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000111 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000112 if (err != 0)
113 return nis_error(err);
114 res = newsizedstringobject (match, len);
115 free (match);
116 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000117}
118
119static object *
120nis_cat (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000121 object *self;
122 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000123{
Guido van Rossum3562d521992-08-12 15:26:16 +0000124 char *domain;
125 char *map;
126 struct ypall_callback cb;
127 object *cat;
128 int err;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000129
130 if (!getstrarg(args, &map))
131 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000132 if ((err = yp_get_default_domain(&domain)) != 0)
133 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000134 cat = newdictobject ();
135 if (cat == NULL)
136 return NULL;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000137 cb.foreach = nis_foreach;
138 cb.data = (char *)cat;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000139 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000140 map = nis_mapname (map);
141 err = yp_all (domain, map, &cb);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000142 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000143 if (err != 0) {
144 DECREF(cat);
145 return nis_error(err);
146 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000147 return cat;
148}
149
150#define YPPROC_MAPLIST ((u_long)11)
151#define YPPROG ((u_long)100004)
152#define YPVERS ((u_long)2)
153
154typedef char *domainname;
155typedef char *mapname;
156
157enum nisstat {
158 NIS_TRUE = 1,
159 NIS_NOMORE = 2,
160 NIS_FALSE = 0,
161 NIS_NOMAP = -1,
162 NIS_NODOM = -2,
163 NIS_NOKEY = -3,
164 NIS_BADOP = -4,
165 NIS_BADDB = -5,
166 NIS_YPERR = -6,
167 NIS_BADARGS = -7,
168 NIS_VERS = -8
169};
170typedef enum nisstat nisstat;
171
172struct nismaplist {
173 mapname map;
174 struct nismaplist *next;
175};
176typedef struct nismaplist nismaplist;
177
178struct nisresp_maplist {
179 nisstat stat;
180 nismaplist *maps;
181};
182typedef struct nisresp_maplist nisresp_maplist;
183
184static struct timeval TIMEOUT = { 25, 0 };
185
186static
187bool_t
188nis_xdr_domainname(xdrs, objp)
189 XDR *xdrs;
190 domainname *objp;
191{
192 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
193 return (FALSE);
194 }
195 return (TRUE);
196}
197
198static
199bool_t
200nis_xdr_mapname(xdrs, objp)
201 XDR *xdrs;
202 mapname *objp;
203{
204 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
205 return (FALSE);
206 }
207 return (TRUE);
208}
209
210static
211bool_t
212nis_xdr_ypmaplist(xdrs, objp)
213 XDR *xdrs;
214 nismaplist *objp;
215{
216 if (!nis_xdr_mapname(xdrs, &objp->map)) {
217 return (FALSE);
218 }
219 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
220 return (FALSE);
221 }
222 return (TRUE);
223}
224
225static
226bool_t
227nis_xdr_ypstat(xdrs, objp)
228 XDR *xdrs;
229 nisstat *objp;
230{
231 if (!xdr_enum(xdrs, (enum_t *)objp)) {
232 return (FALSE);
233 }
234 return (TRUE);
235}
236
237
238static
239bool_t
240nis_xdr_ypresp_maplist(xdrs, objp)
241 XDR *xdrs;
242 nisresp_maplist *objp;
243{
244 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
245 return (FALSE);
246 }
247 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
248 return (FALSE);
249 }
250 return (TRUE);
251}
252
253
254static
255nisresp_maplist *
256nisproc_maplist_2(argp, clnt)
257 domainname *argp;
258 CLIENT *clnt;
259{
260 static nisresp_maplist res;
261
Guido van Rossum9de7a011992-08-12 14:57:12 +0000262 memset(&res, 0, sizeof(res));
Guido van Rossum9de7a011992-08-12 14:57:12 +0000263 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, argp, nis_xdr_ypresp_maplist
264, &res, TIMEOUT) != RPC_SUCCESS) {
265 return (NULL);
266 }
267 return (&res);
268}
269
270static
271nismaplist *
272nis_maplist ()
273{
Guido van Rossum3562d521992-08-12 15:26:16 +0000274 nisresp_maplist *list;
275 char *dom;
276 CLIENT *cl, *clnt_create();
277 char *server;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000278
279 yp_get_default_domain (&dom);
280 yp_master (dom, aliases[0].map, &server);
281 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
282 if (cl == NULL) {
283 clnt_pcreateerror(server);
284 return NULL;
285 }
286 list = nisproc_maplist_2 (&dom, cl);
287 if (list == NULL)
288 return NULL;
289 if (list->stat != NIS_TRUE)
290 return NULL;
291 return list->maps;
292}
293
294static object *
295nis_maps (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000296 object *self;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000297 object *args;
298{
Guido van Rossum3562d521992-08-12 15:26:16 +0000299 nismaplist *maps;
300 object *list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000301
302 if ((maps = nis_maplist ()) == NULL)
303 return NULL;
304 if ((list = newlistobject(0)) == NULL)
305 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000306 for (maps = maps->next; maps; maps = maps->next) {
307 if (addlistitem (list, newstringobject (maps->map)) < 0) {
308 DECREF(list);
309 list = NULL;
310 break;
311 }
312 }
313 /* XXX Shouldn't we free the list of maps now? */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000314 return list;
315}
316
317static struct methodlist nis_methods[] = {
318 {"match", nis_match},
319 {"cat", nis_cat},
320 {"maps", nis_maps},
321 {NULL, NULL} /* Sentinel */
322};
323
324void
325initnis ()
326{
Guido van Rossum3562d521992-08-12 15:26:16 +0000327 object *m, *d;
328 m = initmodule("nis", nis_methods);
329 d = getmoduledict(m);
330 NisError = newstringobject("nis.error");
331 if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
332 fatal("Cannot define nis.error");
Guido van Rossum9de7a011992-08-12 14:57:12 +0000333}