blob: eb97dee85cf8cdc01f0168f659b41361df8028c8 [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) {
70 inkey[inkeylen]=0;
71 inval[invallen]=0;
72 dictinsert (indata, inkey, newstringobject (inval));
73 return 0;
74 }
75 return 1;
76}
77
78static object *
79nis_match (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +000080 object *self;
81 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +000082{
Guido van Rossum3562d521992-08-12 15:26:16 +000083 char *match;
84 char *domain;
85 int len;
86 char *key, *map;
87 int err;
88 object *res;
Guido van Rossum9de7a011992-08-12 14:57:12 +000089
90 if (!getstrstrarg(args, &key, &map))
91 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +000092 if ((err = yp_get_default_domain(&domain)) != 0)
93 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +000094 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +000095 map = nis_mapname (map);
96 err = yp_match (domain, map, key, strlen (key), &match, &len);
Guido van Rossum9de7a011992-08-12 14:57:12 +000097 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +000098 if (err != 0)
99 return nis_error(err);
100 res = newsizedstringobject (match, len);
101 free (match);
102 return res;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000103}
104
105static object *
106nis_cat (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000107 object *self;
108 object *args;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000109{
Guido van Rossum3562d521992-08-12 15:26:16 +0000110 char *domain;
111 char *map;
112 struct ypall_callback cb;
113 object *cat;
114 int err;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000115
116 if (!getstrarg(args, &map))
117 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000118 if ((err = yp_get_default_domain(&domain)) != 0)
119 return nis_error(err);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000120 cat = newdictobject ();
121 if (cat == NULL)
122 return NULL;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000123 cb.foreach = nis_foreach;
124 cb.data = (char *)cat;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000125 BGN_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000126 map = nis_mapname (map);
127 err = yp_all (domain, map, &cb);
Guido van Rossum9de7a011992-08-12 14:57:12 +0000128 END_SAVE
Guido van Rossum3562d521992-08-12 15:26:16 +0000129 if (err != 0) {
130 DECREF(cat);
131 return nis_error(err);
132 }
Guido van Rossum9de7a011992-08-12 14:57:12 +0000133 return cat;
134}
135
136#define YPPROC_MAPLIST ((u_long)11)
137#define YPPROG ((u_long)100004)
138#define YPVERS ((u_long)2)
139
140typedef char *domainname;
141typedef char *mapname;
142
143enum nisstat {
144 NIS_TRUE = 1,
145 NIS_NOMORE = 2,
146 NIS_FALSE = 0,
147 NIS_NOMAP = -1,
148 NIS_NODOM = -2,
149 NIS_NOKEY = -3,
150 NIS_BADOP = -4,
151 NIS_BADDB = -5,
152 NIS_YPERR = -6,
153 NIS_BADARGS = -7,
154 NIS_VERS = -8
155};
156typedef enum nisstat nisstat;
157
158struct nismaplist {
159 mapname map;
160 struct nismaplist *next;
161};
162typedef struct nismaplist nismaplist;
163
164struct nisresp_maplist {
165 nisstat stat;
166 nismaplist *maps;
167};
168typedef struct nisresp_maplist nisresp_maplist;
169
170static struct timeval TIMEOUT = { 25, 0 };
171
172static
173bool_t
174nis_xdr_domainname(xdrs, objp)
175 XDR *xdrs;
176 domainname *objp;
177{
178 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
179 return (FALSE);
180 }
181 return (TRUE);
182}
183
184static
185bool_t
186nis_xdr_mapname(xdrs, objp)
187 XDR *xdrs;
188 mapname *objp;
189{
190 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
191 return (FALSE);
192 }
193 return (TRUE);
194}
195
196static
197bool_t
198nis_xdr_ypmaplist(xdrs, objp)
199 XDR *xdrs;
200 nismaplist *objp;
201{
202 if (!nis_xdr_mapname(xdrs, &objp->map)) {
203 return (FALSE);
204 }
205 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
206 return (FALSE);
207 }
208 return (TRUE);
209}
210
211static
212bool_t
213nis_xdr_ypstat(xdrs, objp)
214 XDR *xdrs;
215 nisstat *objp;
216{
217 if (!xdr_enum(xdrs, (enum_t *)objp)) {
218 return (FALSE);
219 }
220 return (TRUE);
221}
222
223
224static
225bool_t
226nis_xdr_ypresp_maplist(xdrs, objp)
227 XDR *xdrs;
228 nisresp_maplist *objp;
229{
230 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
231 return (FALSE);
232 }
233 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
234 return (FALSE);
235 }
236 return (TRUE);
237}
238
239
240static
241nisresp_maplist *
242nisproc_maplist_2(argp, clnt)
243 domainname *argp;
244 CLIENT *clnt;
245{
246 static nisresp_maplist res;
247
Guido van Rossum9de7a011992-08-12 14:57:12 +0000248 memset(&res, 0, sizeof(res));
Guido van Rossum9de7a011992-08-12 14:57:12 +0000249 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, argp, nis_xdr_ypresp_maplist
250, &res, TIMEOUT) != RPC_SUCCESS) {
251 return (NULL);
252 }
253 return (&res);
254}
255
256static
257nismaplist *
258nis_maplist ()
259{
Guido van Rossum3562d521992-08-12 15:26:16 +0000260 nisresp_maplist *list;
261 char *dom;
262 CLIENT *cl, *clnt_create();
263 char *server;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000264
265 yp_get_default_domain (&dom);
266 yp_master (dom, aliases[0].map, &server);
267 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
268 if (cl == NULL) {
269 clnt_pcreateerror(server);
270 return NULL;
271 }
272 list = nisproc_maplist_2 (&dom, cl);
273 if (list == NULL)
274 return NULL;
275 if (list->stat != NIS_TRUE)
276 return NULL;
277 return list->maps;
278}
279
280static object *
281nis_maps (self, args)
Guido van Rossum3562d521992-08-12 15:26:16 +0000282 object *self;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000283 object *args;
284{
Guido van Rossum3562d521992-08-12 15:26:16 +0000285 nismaplist *maps;
286 object *list;
Guido van Rossum9de7a011992-08-12 14:57:12 +0000287
288 if ((maps = nis_maplist ()) == NULL)
289 return NULL;
290 if ((list = newlistobject(0)) == NULL)
291 return NULL;
Guido van Rossum3562d521992-08-12 15:26:16 +0000292 for (maps = maps->next; maps; maps = maps->next) {
293 if (addlistitem (list, newstringobject (maps->map)) < 0) {
294 DECREF(list);
295 list = NULL;
296 break;
297 }
298 }
299 /* XXX Shouldn't we free the list of maps now? */
Guido van Rossum9de7a011992-08-12 14:57:12 +0000300 return list;
301}
302
303static struct methodlist nis_methods[] = {
304 {"match", nis_match},
305 {"cat", nis_cat},
306 {"maps", nis_maps},
307 {NULL, NULL} /* Sentinel */
308};
309
310void
311initnis ()
312{
Guido van Rossum3562d521992-08-12 15:26:16 +0000313 object *m, *d;
314 m = initmodule("nis", nis_methods);
315 d = getmoduledict(m);
316 NisError = newstringobject("nis.error");
317 if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
318 fatal("Cannot define nis.error");
Guido van Rossum9de7a011992-08-12 14:57:12 +0000319}