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