blob: b5aeae2d1fff7a301d738fcbfdb8d70a93ca6234 [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
23static struct nis_map {
24 char *alias;
25 char *map;
26} aliases [] = {
27{"passwd", "passwd.byname"},
28{"group", "group.byname"},
29{"networks", "networks.byaddr"},
30{"hosts", "hosts.byname"},
31{"protocols", "protocols.bynumber"},
32{"services", "services.byname"},
33{"aliases", "mail.aliases"},
34{"ethers", "ethers.byname"},
35{0L, 0L}
36};
37
38static char *
39nis_mapname (map)
40char *map;
41{
42int i;
43
44 for (i=0; aliases[i].alias != 0L; i++)
45 if (!strcmp (aliases[i].alias, map))
46 map = aliases[i].map;
47 return map;
48}
49
50static int
51nis_foreach (instatus, inkey, inkeylen, inval, invallen,indata)
52int instatus;
53char *inkey;
54int inkeylen;
55char *inval;
56int invallen;
57object *indata;
58{
59 if (instatus == YP_TRUE) {
60 inkey[inkeylen]=0;
61 inval[invallen]=0;
62 dictinsert (indata, inkey, newstringobject (inval));
63 return 0;
64 }
65 return 1;
66}
67
68static object *
69nis_match (self, args)
70object *self;
71object *args;
72{
73char *match;
74char *domain;
75int len;
76char *key, *map;
77
78 if (!getstrstrarg(args, &key, &map))
79 return NULL;
80 map = nis_mapname (map);
81 BGN_SAVE
82 yp_get_default_domain(&domain);
83 if (yp_match (domain, map, key, strlen (key), &match, &len) == 0)
84 match[len] = 0;
85 END_SAVE
86 return newstringobject (match);
87}
88
89static object *
90nis_cat (self, args)
91object *self;
92object *args;
93{
94char *domain;
95char *map;
96struct ypall_callback cb;
97object *cat;
98
99 if (!getstrarg(args, &map))
100 return NULL;
101 cat = newdictobject ();
102 if (cat == NULL)
103 return NULL;
104 map = nis_mapname (map);
105 cb.foreach = nis_foreach;
106 cb.data = (char *)cat;
107 yp_get_default_domain(&domain);
108 BGN_SAVE
109 yp_all (domain, map, &cb);
110 END_SAVE
111 return cat;
112}
113
114#define YPPROC_MAPLIST ((u_long)11)
115#define YPPROG ((u_long)100004)
116#define YPVERS ((u_long)2)
117
118typedef char *domainname;
119typedef char *mapname;
120
121enum nisstat {
122 NIS_TRUE = 1,
123 NIS_NOMORE = 2,
124 NIS_FALSE = 0,
125 NIS_NOMAP = -1,
126 NIS_NODOM = -2,
127 NIS_NOKEY = -3,
128 NIS_BADOP = -4,
129 NIS_BADDB = -5,
130 NIS_YPERR = -6,
131 NIS_BADARGS = -7,
132 NIS_VERS = -8
133};
134typedef enum nisstat nisstat;
135
136struct nismaplist {
137 mapname map;
138 struct nismaplist *next;
139};
140typedef struct nismaplist nismaplist;
141
142struct nisresp_maplist {
143 nisstat stat;
144 nismaplist *maps;
145};
146typedef struct nisresp_maplist nisresp_maplist;
147
148static struct timeval TIMEOUT = { 25, 0 };
149
150static
151bool_t
152nis_xdr_domainname(xdrs, objp)
153 XDR *xdrs;
154 domainname *objp;
155{
156 if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
157 return (FALSE);
158 }
159 return (TRUE);
160}
161
162static
163bool_t
164nis_xdr_mapname(xdrs, objp)
165 XDR *xdrs;
166 mapname *objp;
167{
168 if (!xdr_string(xdrs, objp, YPMAXMAP)) {
169 return (FALSE);
170 }
171 return (TRUE);
172}
173
174static
175bool_t
176nis_xdr_ypmaplist(xdrs, objp)
177 XDR *xdrs;
178 nismaplist *objp;
179{
180 if (!nis_xdr_mapname(xdrs, &objp->map)) {
181 return (FALSE);
182 }
183 if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
184 return (FALSE);
185 }
186 return (TRUE);
187}
188
189static
190bool_t
191nis_xdr_ypstat(xdrs, objp)
192 XDR *xdrs;
193 nisstat *objp;
194{
195 if (!xdr_enum(xdrs, (enum_t *)objp)) {
196 return (FALSE);
197 }
198 return (TRUE);
199}
200
201
202static
203bool_t
204nis_xdr_ypresp_maplist(xdrs, objp)
205 XDR *xdrs;
206 nisresp_maplist *objp;
207{
208 if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
209 return (FALSE);
210 }
211 if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
212 return (FALSE);
213 }
214 return (TRUE);
215}
216
217
218static
219nisresp_maplist *
220nisproc_maplist_2(argp, clnt)
221 domainname *argp;
222 CLIENT *clnt;
223{
224 static nisresp_maplist res;
225
226#ifdef hpux
227 memset(&res, 0, sizeof(res));
228#else hpux
229 memset(&res, sizeof(res));
230#endif hpux
231 if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, argp, nis_xdr_ypresp_maplist
232, &res, TIMEOUT) != RPC_SUCCESS) {
233 return (NULL);
234 }
235 return (&res);
236}
237
238static
239nismaplist *
240nis_maplist ()
241{
242nisresp_maplist *list;
243char *dom;
244CLIENT *cl, *clnt_create();
245char *server;
246
247 yp_get_default_domain (&dom);
248 yp_master (dom, aliases[0].map, &server);
249 cl = clnt_create(server, YPPROG, YPVERS, "tcp");
250 if (cl == NULL) {
251 clnt_pcreateerror(server);
252 return NULL;
253 }
254 list = nisproc_maplist_2 (&dom, cl);
255 if (list == NULL)
256 return NULL;
257 if (list->stat != NIS_TRUE)
258 return NULL;
259 return list->maps;
260}
261
262static object *
263nis_maps (self, args)
264 object *self;
265 object *args;
266{
267nismaplist *maps;
268object *list;
269
270 if ((maps = nis_maplist ()) == NULL)
271 return NULL;
272 if ((list = newlistobject(0)) == NULL)
273 return NULL;
274 BGN_SAVE
275 for (maps = maps->next; maps; maps = maps->next)
276 addlistitem (list, newstringobject (maps->map));
277 END_SAVE
278 return list;
279}
280
281static struct methodlist nis_methods[] = {
282 {"match", nis_match},
283 {"cat", nis_cat},
284 {"maps", nis_maps},
285 {NULL, NULL} /* Sentinel */
286};
287
288void
289initnis ()
290{
291 (void) initmodule("nis", nis_methods);
292}