]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* $OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $ */ | |
25 | ||
26 | /* | |
27 | * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se> | |
28 | * All rights reserved. | |
29 | * | |
30 | * Redistribution and use in source and binary forms, with or without | |
31 | * modification, are permitted provided that the following conditions | |
32 | * are met: | |
33 | * 1. Redistributions of source code must retain the above copyright | |
34 | * notice, this list of conditions and the following disclaimer. | |
35 | * 2. Redistributions in binary form must reproduce the above copyright | |
36 | * notice, this list of conditions and the following disclaimer in the | |
37 | * documentation and/or other materials provided with the distribution. | |
38 | * 3. All advertising materials mentioning features or use of this software | |
39 | * must display the following acknowledgement: | |
40 | * This product includes software developed by Mats O Jansson | |
41 | * 4. The name of the author may not be used to endorse or promote products | |
42 | * derived from this software without specific prior written permission. | |
43 | * | |
44 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |
45 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
46 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
47 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
53 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
54 | * SUCH DAMAGE. | |
55 | */ | |
56 | ||
57 | #ifndef LINT | |
58 | static char rcsid[] = "$OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $"; | |
59 | #endif | |
60 | ||
61 | #include <rpc/rpc.h> | |
62 | #include "yp.h" | |
63 | #include "ypv1.h" | |
64 | #include <rpcsvc/ypclnt.h> | |
65 | #include <sys/stat.h> | |
66 | #include <sys/socket.h> | |
67 | #include <sys/param.h> | |
68 | #include <netinet/in.h> | |
69 | #include <arpa/inet.h> | |
70 | #include "ypdb.h" | |
71 | #include <fcntl.h> | |
72 | #include <dirent.h> | |
73 | #include <stdio.h> | |
74 | #include <string.h> | |
75 | #include <unistd.h> | |
76 | #include <stdlib.h> | |
77 | #include "yplog.h" | |
78 | #include "ypdef.h" | |
79 | ||
80 | #ifdef DEBUG | |
81 | #define YPLOG yplog | |
82 | #else /* DEBUG */ | |
83 | #define YPLOG if (!ok) yplog | |
84 | #endif /* DEBUG */ | |
85 | ||
86 | extern ypresp_val ypdb_get_record(); | |
87 | extern ypresp_key_val ypdb_get_first(); | |
88 | extern ypresp_key_val ypdb_get_next(); | |
89 | extern ypresp_order ypdb_get_order(); | |
90 | extern ypresp_master ypdb_get_master(); | |
91 | extern bool_t ypdb_xdr_get_all(); | |
92 | extern void ypdb_close_all(); | |
93 | extern int ypdb_secure(); | |
94 | ||
95 | static char *True = "true"; | |
96 | static char *False = "FALSE"; | |
97 | #define TORF(N) ((N) ? True : False) | |
98 | void * | |
99 | ypproc_null_2_svc(argp, rqstp) | |
100 | void *argp; | |
101 | struct svc_req *rqstp; | |
102 | { | |
103 | static char *result; | |
104 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
105 | int ok = yp_acl_check_host(&caller->sin_addr); | |
106 | ||
107 | YPLOG("null_2: caller=[%s].%d, auth_ok=%s", | |
108 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok)); | |
109 | ||
110 | if (!ok) { | |
111 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
112 | return(NULL); | |
113 | } | |
114 | ||
115 | result = NULL; | |
116 | ||
117 | return ((void *)&result); | |
118 | } | |
119 | ||
120 | bool_t * | |
121 | ypproc_domain_2_svc(argp, rqstp) | |
122 | domainname *argp; | |
123 | struct svc_req *rqstp; | |
124 | { | |
125 | static bool_t result; /* is domain_served? */ | |
126 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
127 | int ok = yp_acl_check_host(&caller->sin_addr); | |
128 | static char domain_path[MAXPATHLEN]; | |
129 | struct stat finfo; | |
130 | ||
131 | if (strchr(*argp, '/')) | |
132 | goto bail; | |
133 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
134 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
135 | (finfo.st_mode & S_IFDIR)); | |
136 | ||
137 | YPLOG("domain_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
138 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
139 | TORF(ok), *argp, TORF(result)); | |
140 | ||
141 | if (!ok) { | |
142 | bail: | |
143 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
144 | return(NULL); | |
145 | } | |
146 | ||
147 | return (&result); | |
148 | } | |
149 | ||
150 | bool_t * | |
151 | ypproc_domain_nonack_2_svc(argp, rqstp) | |
152 | domainname *argp; | |
153 | struct svc_req *rqstp; | |
154 | { | |
155 | static bool_t result; /* is domain served? */ | |
156 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
157 | int ok = yp_acl_check_host(&caller->sin_addr); | |
158 | static char domain_path[MAXPATHLEN]; | |
159 | struct stat finfo; | |
160 | ||
161 | if (strchr(*argp, '/')) | |
162 | goto bail; | |
163 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
164 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
165 | (finfo.st_mode & S_IFDIR)); | |
166 | ||
167 | YPLOG( | |
168 | "domain_nonack_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
169 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
170 | *argp, TORF(result)); | |
171 | ||
172 | if (!ok) { | |
173 | bail: | |
174 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
175 | return(NULL); | |
176 | } | |
177 | ||
178 | if (!result) { | |
179 | return(NULL); /* don't send nack */ | |
180 | } | |
181 | ||
182 | return (&result); | |
183 | } | |
184 | ||
185 | ypresp_val * | |
186 | ypproc_match_2_svc(argp, rqstp) | |
187 | ypreq_key *argp; | |
188 | struct svc_req *rqstp; | |
189 | { | |
190 | static ypresp_val res; | |
191 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
192 | int ok = yp_acl_check_host(&caller->sin_addr); | |
193 | int secure = ypdb_secure(argp->domain,argp->map); | |
194 | ||
195 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
196 | goto bail; | |
197 | YPLOG( | |
198 | "match_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
199 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
200 | TORF(ok), TORF(secure), | |
201 | argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val); | |
202 | ||
203 | if (!ok) { | |
204 | bail: | |
205 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
206 | return(NULL); | |
207 | } | |
208 | ||
209 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
210 | res.stat = YP_YPERR; | |
211 | } else { | |
212 | res = ypdb_get_record(argp->domain,argp->map,argp->key, FALSE); | |
213 | } | |
214 | ||
215 | #ifdef DEBUG | |
216 | yplog(" match2_status: %s", yperr_string(ypprot_err(res.stat))); | |
217 | #endif | |
218 | ||
219 | return (&res); | |
220 | } | |
221 | ||
222 | ypresp_key_val * | |
223 | ypproc_first_2_svc(argp, rqstp) | |
224 | ypreq_nokey *argp; | |
225 | struct svc_req *rqstp; | |
226 | { | |
227 | static ypresp_key_val res; | |
228 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
229 | int ok = yp_acl_check_host(&caller->sin_addr); | |
230 | int secure = ypdb_secure(argp->domain,argp->map); | |
231 | ||
232 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
233 | goto bail; | |
234 | YPLOG( "first_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
235 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
236 | TORF(ok), TORF(secure), | |
237 | argp->domain, argp->map); | |
238 | ||
239 | if (!ok) { | |
240 | bail: | |
241 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
242 | return(NULL); | |
243 | } | |
244 | ||
245 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
246 | res.stat = YP_YPERR; | |
247 | } else { | |
248 | res = ypdb_get_first(argp->domain,argp->map,FALSE); | |
249 | } | |
250 | ||
251 | #ifdef DEBUG | |
252 | yplog(" first2_status: %s", yperr_string(ypprot_err(res.stat))); | |
253 | #endif | |
254 | ||
255 | return (&res); | |
256 | } | |
257 | ||
258 | ypresp_key_val * | |
259 | ypproc_next_2_svc(argp, rqstp) | |
260 | ypreq_key *argp; | |
261 | struct svc_req *rqstp; | |
262 | { | |
263 | static ypresp_key_val res; | |
264 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
265 | int ok = yp_acl_check_host(&caller->sin_addr); | |
266 | int secure = ypdb_secure(argp->domain,argp->map); | |
267 | ||
268 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
269 | goto bail; | |
270 | YPLOG( | |
271 | "next_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
272 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
273 | TORF(ok), TORF(secure), | |
274 | argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val); | |
275 | ||
276 | if (!ok) { | |
277 | bail: | |
278 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
279 | return(NULL); | |
280 | } | |
281 | ||
282 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
283 | res.stat = YP_YPERR; | |
284 | } else { | |
285 | res = ypdb_get_next(argp->domain,argp->map,argp->key,FALSE); | |
286 | } | |
287 | ||
288 | #ifdef DEBUG | |
289 | yplog(" next2_status: %s", yperr_string(ypprot_err(res.stat))); | |
290 | #endif | |
291 | ||
292 | return (&res); | |
293 | } | |
294 | ||
295 | ypresp_xfr * | |
296 | ypproc_xfr_2_svc(argp, rqstp) | |
297 | ypreq_xfr *argp; | |
298 | struct svc_req *rqstp; | |
299 | { | |
300 | static ypresp_xfr res; | |
301 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
302 | int ok = yp_acl_check_host(&caller->sin_addr); | |
303 | pid_t pid; | |
304 | char tid[11]; | |
305 | char prog[11]; | |
306 | char port[11]; | |
307 | char ypxfr_proc[] = YPXFR_PROC; | |
308 | char *ipadd; | |
309 | ||
310 | bzero((char *)&res, sizeof(res)); | |
311 | ||
312 | YPLOG("xfr_2: caller=[%s].%d, auth_ok=%s, domain=%s, tid=%d, prog=%d", | |
313 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
314 | argp->map_parms.domain, argp->transid, argp->prog); | |
315 | YPLOG(" ipadd=%s, port=%d, map=%s", inet_ntoa(caller->sin_addr), | |
316 | argp->port, argp->map_parms.map); | |
317 | ||
318 | if (strchr(argp->map_parms.domain, '/') || | |
319 | strchr(argp->map_parms.map, '/') || | |
320 | ntohs(caller->sin_port) >= IPPORT_RESERVED) { | |
321 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
322 | return(NULL); | |
323 | } | |
324 | ||
325 | snprintf(tid, sizeof(tid), "%d",argp->transid); | |
326 | snprintf(prog, sizeof(prog), "%d", argp->prog); | |
327 | snprintf(port, sizeof(port), "%d", argp->port); | |
328 | ipadd = inet_ntoa(caller->sin_addr); | |
329 | ||
330 | pid = vfork(); | |
331 | if (pid == -1) { | |
332 | svcerr_systemerr(rqstp->rq_xprt); | |
333 | return(NULL); | |
334 | } | |
335 | if (pid == 0) { | |
336 | execl(ypxfr_proc, "ypxfr", "-d", argp->map_parms.domain, | |
337 | "-C",tid, prog, ipadd, port, argp->map_parms.map, NULL); | |
338 | _exit(1); | |
339 | } | |
340 | ||
341 | /* | |
342 | * XXX: fill in res | |
343 | */ | |
344 | return (&res); | |
345 | } | |
346 | ||
347 | void * | |
348 | ypproc_clear_2_svc(argp, rqstp) | |
349 | void *argp; | |
350 | struct svc_req *rqstp; | |
351 | { | |
352 | static char *res; | |
353 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
354 | int ok = yp_acl_check_host(&caller->sin_addr); | |
355 | ||
356 | YPLOG( "clear_2: caller=[%s].%d, auth_ok=%s, opt=%s", | |
357 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
358 | #ifdef OPTDB | |
359 | True | |
360 | #else | |
361 | False | |
362 | #endif | |
363 | ); | |
364 | ||
365 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
366 | ok = FALSE; | |
367 | ||
368 | if (!ok) { | |
369 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
370 | return(NULL); | |
371 | } | |
372 | ||
373 | res = NULL; | |
374 | ||
375 | #ifdef OPTDB | |
376 | ypdb_close_all(); | |
377 | #endif | |
378 | ||
379 | return ((void *)&res); | |
380 | } | |
381 | ||
382 | ypresp_all * | |
383 | ypproc_all_2_svc(argp, rqstp) | |
384 | ypreq_nokey *argp; | |
385 | struct svc_req *rqstp; | |
386 | { | |
387 | static ypresp_all res; | |
388 | pid_t pid; | |
389 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
390 | int ok = yp_acl_check_host(&caller->sin_addr); | |
391 | int secure = ypdb_secure(argp->domain,argp->map); | |
392 | ||
393 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
394 | goto bail; | |
395 | YPLOG( "all_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
396 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
397 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
398 | ||
399 | if (!ok) { | |
400 | bail: | |
401 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
402 | return(NULL); | |
403 | } | |
404 | ||
405 | bzero((char *)&res, sizeof(res)); | |
406 | ||
407 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
408 | res.ypresp_all_u.val.stat = YP_YPERR; | |
409 | return(&res); | |
410 | } | |
411 | ||
412 | pid = fork(); | |
413 | ||
414 | if (pid) { | |
415 | ||
416 | if (pid == -1) { | |
417 | /* XXXCDC An error has occurred */ | |
418 | } | |
419 | ||
420 | return(NULL); /* PARENT: continue */ | |
421 | ||
422 | } | |
423 | /* CHILD: send result, then exit */ | |
424 | ||
425 | if (!svc_sendreply(rqstp->rq_xprt, ypdb_xdr_get_all, (char *) argp)) { | |
426 | svcerr_systemerr(rqstp->rq_xprt); | |
427 | } | |
428 | ||
429 | /* note: no need to free args, we are exiting */ | |
430 | ||
431 | exit(0); | |
432 | } | |
433 | ||
434 | ypresp_master * | |
435 | ypproc_master_2_svc(argp, rqstp) | |
436 | ypreq_nokey *argp; | |
437 | struct svc_req *rqstp; | |
438 | { | |
439 | static ypresp_master res; | |
440 | static peername nopeer = ""; | |
441 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
442 | int ok = yp_acl_check_host(&caller->sin_addr); | |
443 | int secure = ypdb_secure(argp->domain,argp->map); | |
444 | ||
445 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
446 | goto bail; | |
447 | YPLOG( "master_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
448 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
449 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
450 | ||
451 | if (!ok) { | |
452 | bail: | |
453 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
454 | return(NULL); | |
455 | } | |
456 | ||
457 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
458 | res.stat = YP_YPERR; | |
459 | } else { | |
460 | res = ypdb_get_master(argp->domain,argp->map); | |
461 | } | |
462 | ||
463 | #ifdef DEBUG | |
464 | yplog(" master2_status: %s", yperr_string(ypprot_err(res.stat))); | |
465 | #endif | |
466 | ||
467 | /* This code was added because a yppoll <unknown-domain> */ | |
468 | /* from a sun crashed the server in xdr_string, trying */ | |
469 | /* to access the peer through a NULL-pointer. yppoll in */ | |
470 | /* this server start asking for order. If order is ok */ | |
471 | /* then it will ask for master. SunOS 4 asks for both */ | |
472 | /* always. I'm not sure this is the best place for the */ | |
473 | /* fix, but for now it will do. xdr_peername or */ | |
474 | /* xdr_string in ypserv_xdr.c may be a better place? */ | |
475 | ||
476 | if (res.peer == NULL) { | |
477 | res.peer = nopeer; | |
478 | } | |
479 | ||
480 | /* End of fix */ | |
481 | ||
482 | return (&res); | |
483 | } | |
484 | ||
485 | ||
486 | ypresp_order * | |
487 | ypproc_order_2_svc(argp, rqstp) | |
488 | ypreq_nokey *argp; | |
489 | struct svc_req *rqstp; | |
490 | { | |
491 | static ypresp_order res; | |
492 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
493 | int ok = yp_acl_check_host(&caller->sin_addr); | |
494 | int secure = ypdb_secure(argp->domain,argp->map); | |
495 | ||
496 | if (strchr(argp->domain, '/')) | |
497 | goto bail; | |
498 | YPLOG( "order_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
499 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
500 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
501 | ||
502 | if (!ok) { | |
503 | bail: | |
504 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
505 | return(NULL); | |
506 | } | |
507 | ||
508 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
509 | res.stat = YP_YPERR; | |
510 | } else if (strchr(argp->map, '/')) { | |
511 | res.stat = YP_NOMAP; | |
512 | } else { | |
513 | res = ypdb_get_order(argp->domain,argp->map); | |
514 | } | |
515 | ||
516 | #ifdef DEBUG | |
517 | yplog(" order2_status: %s", yperr_string(ypprot_err(res.stat))); | |
518 | #endif | |
519 | ||
520 | return (&res); | |
521 | } | |
522 | ||
523 | ||
524 | ypresp_maplist * | |
525 | ypproc_maplist_2_svc(argp, rqstp) | |
526 | domainname *argp; | |
527 | struct svc_req *rqstp; | |
528 | { | |
529 | static ypresp_maplist res; | |
530 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
531 | int ok = yp_acl_check_host(&caller->sin_addr); | |
532 | static char domain_path[MAXPATHLEN]; | |
533 | struct stat finfo; | |
534 | DIR *dirp = NULL; | |
535 | struct dirent *dp; | |
536 | char *suffix; | |
537 | ypstat status; | |
538 | struct ypmaplist *m; | |
539 | char *map_name; | |
540 | ||
541 | if (strchr(*argp, '/')) | |
542 | goto bail; | |
543 | YPLOG("maplist_2: caller=[%s].%d, auth_ok=%s, domain=%s", | |
544 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
545 | *argp); | |
546 | ||
547 | if (!ok) { | |
548 | bail: | |
549 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
550 | return(NULL); | |
551 | } | |
552 | ||
553 | bzero((char *)&res, sizeof(res)); | |
554 | ||
555 | snprintf(domain_path,MAXPATHLEN, "%s/%s",YP_DB_PATH,*argp); | |
556 | ||
557 | status = YP_TRUE; | |
558 | ||
559 | res.maps = NULL; | |
560 | ||
561 | if (!((stat(domain_path, &finfo) == 0) && | |
562 | ((finfo.st_mode & S_IFMT) == S_IFDIR))) | |
563 | status = YP_NODOM; | |
564 | ||
565 | if (status >= 0) { | |
566 | if ((dirp = opendir(domain_path)) == NULL) { | |
567 | status = YP_NODOM; | |
568 | } | |
569 | } | |
570 | ||
571 | if (status >= 0) { | |
572 | for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { | |
573 | if ((!strcmp(dp->d_name, ".")) || | |
574 | ((!strcmp(dp->d_name, ".."))) || | |
575 | (dp->d_namlen < 4)) | |
576 | continue; | |
577 | suffix = (char *) &dp->d_name[dp->d_namlen-3]; | |
578 | if (strcmp(suffix,".db") == 0) { | |
579 | ||
580 | if ((m = (struct ypmaplist *) | |
581 | malloc((unsigned) sizeof(struct ypmaplist))) == NULL) { | |
582 | status = YP_YPERR; | |
583 | break; | |
584 | } | |
585 | ||
586 | if ((map_name = (char *) | |
587 | malloc((unsigned) dp->d_namlen - 2)) == NULL) { | |
588 | status = YP_YPERR; | |
589 | break; | |
590 | } | |
591 | ||
592 | m->next = res.maps; | |
593 | m->map = map_name; | |
594 | res.maps = m; | |
595 | strncpy(map_name, dp->d_name, dp->d_namlen - 3); | |
596 | m->map[dp->d_namlen - 3] = '\0'; | |
597 | ||
598 | } | |
599 | } | |
600 | } | |
601 | ||
602 | if (dirp != NULL) { | |
603 | closedir(dirp); | |
604 | } | |
605 | ||
606 | res.stat = status; | |
607 | ||
608 | #ifdef DEBUG | |
609 | yplog(" maplist_status: %s", yperr_string(ypprot_err(res.stat))); | |
610 | #endif | |
611 | ||
612 | return (&res); | |
613 | } | |
614 | ||
615 | void * | |
616 | ypproc_null_1_svc(argp, rqstp) | |
617 | void *argp; | |
618 | struct svc_req *rqstp; | |
619 | { | |
620 | static char *result; | |
621 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
622 | int ok = yp_acl_check_host(&caller->sin_addr); | |
623 | ||
624 | YPLOG("null_1: caller=[%s].%d, auth_ok=%s", | |
625 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok)); | |
626 | ||
627 | if (!ok) { | |
628 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
629 | return(NULL); | |
630 | } | |
631 | ||
632 | result = NULL; | |
633 | ||
634 | return ((void *)&result); | |
635 | } | |
636 | ||
637 | bool_t * | |
638 | ypproc_domain_1_svc(argp, rqstp) | |
639 | domainname *argp; | |
640 | struct svc_req *rqstp; | |
641 | { | |
642 | static bool_t result; /* is domain_served? */ | |
643 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
644 | int ok = yp_acl_check_host(&caller->sin_addr); | |
645 | static char domain_path[MAXPATHLEN]; | |
646 | struct stat finfo; | |
647 | ||
648 | if (strchr(*argp, '/')) | |
649 | goto bail; | |
650 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
651 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
652 | (finfo.st_mode & S_IFDIR)); | |
653 | ||
654 | YPLOG("domain_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
655 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
656 | TORF(ok), *argp, TORF(result)); | |
657 | ||
658 | if (!ok) { | |
659 | bail: | |
660 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
661 | return(NULL); | |
662 | } | |
663 | ||
664 | return (&result); | |
665 | } | |
666 | ||
667 | bool_t * | |
668 | ypproc_domain_nonack_1_svc(argp, rqstp) | |
669 | domainname *argp; | |
670 | struct svc_req *rqstp; | |
671 | { | |
672 | static bool_t result; /* is domain served? */ | |
673 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
674 | int ok = yp_acl_check_host(&caller->sin_addr); | |
675 | static char domain_path[MAXPATHLEN]; | |
676 | struct stat finfo; | |
677 | ||
678 | if (strchr(*argp, '/')) | |
679 | goto bail; | |
680 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
681 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
682 | (finfo.st_mode & S_IFDIR)); | |
683 | ||
684 | YPLOG( | |
685 | "domain_nonack_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
686 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
687 | *argp, TORF(result)); | |
688 | ||
689 | if (!ok) { | |
690 | bail: | |
691 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
692 | return(NULL); | |
693 | } | |
694 | ||
695 | if (!result) { | |
696 | return(NULL); /* don't send nack */ | |
697 | } | |
698 | ||
699 | return (&result); | |
700 | } | |
701 | ||
702 | ypresponse * | |
703 | ypproc_match_1_svc(argp, rqstp) | |
704 | yprequest *argp; | |
705 | struct svc_req *rqstp; | |
706 | { | |
707 | static ypresponse res; | |
708 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
709 | int ok = yp_acl_check_host(&caller->sin_addr); | |
710 | int secure; | |
711 | ||
712 | if (strchr(argp->ypmatch_req_domain, '/') || | |
713 | strchr(argp->ypmatch_req_map, '/')) | |
714 | goto bail; | |
715 | res.yp_resptype = YPMATCH_RESPTYPE; | |
716 | res.ypmatch_resp_valptr = ""; | |
717 | res.ypmatch_resp_valsize = 0; | |
718 | ||
719 | if (argp->yp_reqtype != YPMATCH_REQTYPE) { | |
720 | res.ypmatch_resp_status = YP_BADARGS; | |
721 | return(&res); | |
722 | } | |
723 | ||
724 | secure = ypdb_secure(argp->ypmatch_req_domain, argp->ypmatch_req_map); | |
725 | ||
726 | YPLOG( | |
727 | "match_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
728 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
729 | TORF(ok), TORF(secure), | |
730 | argp->ypmatch_req_domain, argp->ypmatch_req_map, | |
731 | argp->ypmatch_req_keysize, argp->ypmatch_req_keyptr); | |
732 | ||
733 | if (!ok) { | |
734 | bail: | |
735 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
736 | return(NULL); | |
737 | } | |
738 | ||
739 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
740 | res.ypmatch_resp_status = YP_YPERR; | |
741 | } else { | |
742 | res.ypmatch_resp_val = | |
743 | ypdb_get_record(argp->ypmatch_req_domain, | |
744 | argp->ypmatch_req_map, | |
745 | argp->ypmatch_req_keydat, | |
746 | FALSE); | |
747 | } | |
748 | ||
749 | #ifdef DEBUG | |
750 | yplog(" match1_status: %s", | |
751 | yperr_string(ypprot_err(res.ypmatch_resp_status))); | |
752 | #endif | |
753 | ||
754 | return (&res); | |
755 | } | |
756 | ||
757 | ypresponse * | |
758 | ypproc_first_1_svc(argp, rqstp) | |
759 | yprequest *argp; | |
760 | struct svc_req *rqstp; | |
761 | { | |
762 | static ypresponse res; | |
763 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
764 | int ok = yp_acl_check_host(&caller->sin_addr); | |
765 | int secure; | |
766 | ||
767 | if (strchr(argp->ypfirst_req_domain, '/') || | |
768 | strchr(argp->ypfirst_req_map, '/')) | |
769 | goto bail; | |
770 | res.yp_resptype = YPFIRST_RESPTYPE; | |
771 | res.ypfirst_resp_valptr = res.ypfirst_resp_keyptr = ""; | |
772 | res.ypfirst_resp_valsize = res.ypfirst_resp_keysize = 0; | |
773 | ||
774 | if (argp->yp_reqtype != YPREQ_NOKEY) { | |
775 | res.ypfirst_resp_status = YP_BADARGS; | |
776 | return(&res); | |
777 | } | |
778 | ||
779 | secure = ypdb_secure(argp->ypfirst_req_domain, argp->ypfirst_req_map); | |
780 | ||
781 | YPLOG( "first_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
782 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
783 | TORF(ok), TORF(secure), | |
784 | argp->ypfirst_req_domain, argp->ypfirst_req_map); | |
785 | ||
786 | if (!ok) { | |
787 | bail: | |
788 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
789 | return(NULL); | |
790 | } | |
791 | ||
792 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
793 | res.ypfirst_resp_status = YP_YPERR; | |
794 | } else { | |
795 | res.ypfirst_resp_val = | |
796 | ypdb_get_first(argp->ypfirst_req_domain, | |
797 | argp->ypfirst_req_map, | |
798 | FALSE); | |
799 | } | |
800 | ||
801 | #ifdef DEBUG | |
802 | yplog(" first1_status: %s", | |
803 | yperr_string(ypprot_err(res.ypfirst_resp_status))); | |
804 | #endif | |
805 | ||
806 | return (&res); | |
807 | } | |
808 | ||
809 | ypresponse * | |
810 | ypproc_next_1_svc(argp, rqstp) | |
811 | yprequest *argp; | |
812 | struct svc_req *rqstp; | |
813 | { | |
814 | static ypresponse res; | |
815 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
816 | int ok = yp_acl_check_host(&caller->sin_addr); | |
817 | int secure; | |
818 | ||
819 | if (strchr(argp->ypnext_req_domain, '/') || | |
820 | strchr(argp->ypnext_req_map, '/')) | |
821 | goto bail; | |
822 | res.yp_resptype = YPNEXT_RESPTYPE; | |
823 | res.ypnext_resp_valptr = res.ypnext_resp_keyptr = ""; | |
824 | res.ypnext_resp_valsize = res.ypnext_resp_keysize = 0; | |
825 | ||
826 | if (argp->yp_reqtype != YPNEXT_REQTYPE) { | |
827 | res.ypnext_resp_status = YP_BADARGS; | |
828 | return(&res); | |
829 | } | |
830 | ||
831 | secure = ypdb_secure(argp->ypnext_req_domain, argp->ypnext_req_map); | |
832 | ||
833 | YPLOG( | |
834 | "next_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
835 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
836 | TORF(ok), TORF(secure), | |
837 | argp->ypnext_req_domain, argp->ypnext_req_map, | |
838 | argp->ypnext_req_keysize, argp->ypnext_req_keyptr); | |
839 | ||
840 | if (!ok) { | |
841 | bail: | |
842 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
843 | return(NULL); | |
844 | } | |
845 | ||
846 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
847 | res.ypnext_resp_status = YP_YPERR; | |
848 | } else { | |
849 | res.ypnext_resp_val = | |
850 | ypdb_get_next(argp->ypnext_req_domain, | |
851 | argp->ypnext_req_map, | |
852 | argp->ypnext_req_keydat, | |
853 | FALSE); | |
854 | } | |
855 | ||
856 | #ifdef DEBUG | |
857 | yplog(" next1_status: %s", | |
858 | yperr_string(ypprot_err(res.ypnext_resp_status))); | |
859 | #endif | |
860 | ||
861 | return (&res); | |
862 | } | |
863 | ||
864 | ypresponse * | |
865 | ypproc_poll_1_svc(argp, rqstp) | |
866 | yprequest *argp; | |
867 | struct svc_req *rqstp; | |
868 | { | |
869 | static ypresponse res; | |
870 | ypresp_order order; | |
871 | ypresp_master master; | |
872 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
873 | int ok = yp_acl_check_host(&caller->sin_addr); | |
874 | int secure; | |
875 | ||
876 | if (strchr(argp->yppoll_req_domain, '/') || | |
877 | strchr(argp->yppoll_req_map, '/')) | |
878 | goto bail; | |
879 | res.yp_resptype = YPPOLL_RESPTYPE; | |
880 | res.yppoll_resp_domain = argp->yppoll_req_domain; | |
881 | res.yppoll_resp_map = argp->yppoll_req_map; | |
882 | res.yppoll_resp_ordernum = 0; | |
883 | res.yppoll_resp_owner = ""; | |
884 | ||
885 | if (argp->yp_reqtype != YPPOLL_REQTYPE) { | |
886 | return(&res); | |
887 | } | |
888 | ||
889 | secure = ypdb_secure(argp->yppoll_req_domain, argp->yppoll_req_map); | |
890 | ||
891 | YPLOG( "poll_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
892 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
893 | TORF(ok), TORF(secure), | |
894 | argp->yppoll_req_domain, argp->yppoll_req_map); | |
895 | ||
896 | if (!ok) { | |
897 | bail: | |
898 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
899 | return(NULL); | |
900 | } | |
901 | ||
902 | if (!(secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED))) { | |
903 | order = ypdb_get_order(argp->yppoll_req_domain, | |
904 | argp->yppoll_req_map); | |
905 | master = ypdb_get_master(argp->yppoll_req_domain, | |
906 | argp->yppoll_req_map); | |
907 | res.yppoll_resp_ordernum = order.ordernum; | |
908 | res.yppoll_resp_owner = master.peer; | |
909 | } | |
910 | ||
911 | #ifdef DEBUG | |
912 | yplog(" poll1_status: %s", "none"); | |
913 | #endif | |
914 | return (&res); | |
915 | } | |
916 | ||
917 | void * | |
918 | ypproc_push_1_svc(argp, rqstp) | |
919 | yprequest *argp; | |
920 | struct svc_req *rqstp; | |
921 | { | |
922 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
923 | int ok = yp_acl_check_host(&caller->sin_addr); | |
924 | int secure; | |
925 | pid_t pid; | |
926 | char yppush_proc[] = YPPUSH_PROC; | |
927 | ||
928 | if (strchr(argp->yppush_req_domain, '/') || | |
929 | strchr(argp->yppush_req_map, '/')) | |
930 | goto bail; | |
931 | if (argp->yp_reqtype != YPPUSH_REQTYPE) { | |
932 | return(NULL); | |
933 | } | |
934 | ||
935 | secure = ypdb_secure(argp->yppush_req_domain, argp->yppush_req_map); | |
936 | ||
937 | YPLOG( "push_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
938 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
939 | TORF(ok), TORF(secure), | |
940 | argp->yppush_req_domain, argp->yppush_req_map); | |
941 | ||
942 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
943 | ok = FALSE; | |
944 | ||
945 | if (!ok) { | |
946 | bail: | |
947 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
948 | return(NULL); | |
949 | } | |
950 | ||
951 | pid = vfork(); | |
952 | if (pid == -1) { | |
953 | svcerr_systemerr(rqstp->rq_xprt); | |
954 | return(NULL); | |
955 | } | |
956 | if (pid == 0) { | |
957 | execl(yppush_proc, "yppush", "-d", argp->yppush_req_domain, | |
958 | argp->yppush_req_map, NULL); | |
959 | _exit(1); | |
960 | } | |
961 | ||
962 | return (NULL); | |
963 | } | |
964 | ||
965 | void * | |
966 | ypproc_pull_1_svc(argp, rqstp) | |
967 | yprequest *argp; | |
968 | struct svc_req *rqstp; | |
969 | { | |
970 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
971 | int ok = yp_acl_check_host(&caller->sin_addr); | |
972 | int secure; | |
973 | pid_t pid; | |
974 | char ypxfr_proc[] = YPXFR_PROC; | |
975 | ||
976 | if (strchr(argp->yppull_req_domain, '/') || | |
977 | strchr(argp->yppull_req_map, '/')) | |
978 | goto bail; | |
979 | if (argp->yp_reqtype != YPPULL_REQTYPE) { | |
980 | return(NULL); | |
981 | } | |
982 | ||
983 | secure = ypdb_secure(argp->yppull_req_domain, argp->yppull_req_map); | |
984 | ||
985 | YPLOG( "pull_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
986 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
987 | TORF(ok), TORF(secure), | |
988 | argp->yppull_req_domain, argp->yppull_req_map); | |
989 | ||
990 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
991 | ok = FALSE; | |
992 | ||
993 | if (!ok) { | |
994 | bail: | |
995 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
996 | return(NULL); | |
997 | } | |
998 | ||
999 | pid = vfork(); | |
1000 | if (pid == -1) { | |
1001 | svcerr_systemerr(rqstp->rq_xprt); | |
1002 | return(NULL); | |
1003 | } | |
1004 | if (pid == 0) { | |
1005 | execl(ypxfr_proc, "ypxfr", "-d", argp->yppull_req_domain, | |
1006 | argp->yppull_req_map, NULL); | |
1007 | _exit(1); | |
1008 | } | |
1009 | ||
1010 | return (NULL); | |
1011 | } | |
1012 | ||
1013 | void * | |
1014 | ypproc_get_1_svc(argp, rqstp) | |
1015 | yprequest *argp; | |
1016 | struct svc_req *rqstp; | |
1017 | { | |
1018 | char *res; | |
1019 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
1020 | int ok = yp_acl_check_host(&caller->sin_addr); | |
1021 | int secure; | |
1022 | pid_t pid; | |
1023 | char ypxfr_proc[] = YPXFR_PROC; | |
1024 | ||
1025 | if (strchr(argp->ypget_req_domain, '/') || | |
1026 | strchr(argp->ypget_req_map, '/')) | |
1027 | goto bail; | |
1028 | if (argp->yp_reqtype != YPGET_REQTYPE) { | |
1029 | return(NULL); | |
1030 | } | |
1031 | ||
1032 | secure = ypdb_secure(argp->ypget_req_domain, argp->ypget_req_map); | |
1033 | ||
1034 | YPLOG( "get_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, owner=%s", | |
1035 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
1036 | TORF(ok), TORF(secure), | |
1037 | argp->ypget_req_domain, argp->ypget_req_map, | |
1038 | argp->ypget_req_owner); | |
1039 | ||
1040 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
1041 | ok = FALSE; | |
1042 | ||
1043 | if (!ok) { | |
1044 | bail: | |
1045 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
1046 | return(NULL); | |
1047 | } | |
1048 | ||
1049 | pid = vfork(); | |
1050 | if (pid == -1) { | |
1051 | svcerr_systemerr(rqstp->rq_xprt); | |
1052 | return(NULL); | |
1053 | } | |
1054 | if (pid == 0) { | |
1055 | execl(ypxfr_proc, "ypxfr", "-d", argp->ypget_req_domain, "-h", | |
1056 | argp->ypget_req_owner, argp->yppush_req_map, NULL); | |
1057 | _exit(1); | |
1058 | } | |
1059 | ||
1060 | return (NULL); | |
1061 | } |