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