xref: /freebsd/usr.sbin/ypserv/yp_server.c (revision b5ebd8bb4e90b810c834aabb78c87054ab84db8e)
1df57947fSPedro F. Giffuni /*-
2df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
3df57947fSPedro F. Giffuni  *
4778c7b1cSBill Paul  * Copyright (c) 1995
5778c7b1cSBill Paul  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6778c7b1cSBill Paul  *
7778c7b1cSBill Paul  * Redistribution and use in source and binary forms, with or without
8778c7b1cSBill Paul  * modification, are permitted provided that the following conditions
9778c7b1cSBill Paul  * are met:
10778c7b1cSBill Paul  * 1. Redistributions of source code must retain the above copyright
11778c7b1cSBill Paul  *    notice, this list of conditions and the following disclaimer.
12778c7b1cSBill Paul  * 2. Redistributions in binary form must reproduce the above copyright
13778c7b1cSBill Paul  *    notice, this list of conditions and the following disclaimer in the
14778c7b1cSBill Paul  *    documentation and/or other materials provided with the distribution.
15778c7b1cSBill Paul  * 3. All advertising materials mentioning features or use of this software
16778c7b1cSBill Paul  *    must display the following acknowledgement:
17778c7b1cSBill Paul  *	This product includes software developed by Bill Paul.
18778c7b1cSBill Paul  * 4. Neither the name of the author nor the names of any co-contributors
19778c7b1cSBill Paul  *    may be used to endorse or promote products derived from this software
20778c7b1cSBill Paul  *    without specific prior written permission.
21778c7b1cSBill Paul  *
22778c7b1cSBill Paul  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23778c7b1cSBill Paul  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24778c7b1cSBill Paul  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25778c7b1cSBill Paul  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
26778c7b1cSBill Paul  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27778c7b1cSBill Paul  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28778c7b1cSBill Paul  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29778c7b1cSBill Paul  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30778c7b1cSBill Paul  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31778c7b1cSBill Paul  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32778c7b1cSBill Paul  * SUCH DAMAGE.
33778c7b1cSBill Paul  *
34778c7b1cSBill Paul  */
35778c7b1cSBill Paul 
36b728350eSDavid E. O'Brien #include <sys/cdefs.h>
37778c7b1cSBill Paul #include "yp.h"
38180807d2SBill Paul #include "yp_extern.h"
39778c7b1cSBill Paul #include <dirent.h>
4098834523SPhilippe Charnier #include <errno.h>
4198834523SPhilippe Charnier #include <stdlib.h>
42778c7b1cSBill Paul #include <sys/stat.h>
43778c7b1cSBill Paul #include <sys/param.h>
44778c7b1cSBill Paul #include <sys/types.h>
45778c7b1cSBill Paul #include <sys/socket.h>
46778c7b1cSBill Paul #include <netinet/in.h>
47778c7b1cSBill Paul #include <arpa/inet.h>
4877732bc5SBill Paul #include <rpc/rpc.h>
49778c7b1cSBill Paul 
50778c7b1cSBill Paul int children = 0;
510485539eSBill Paul 
520485539eSBill Paul #define	MASTER_STRING	"YP_MASTER_NAME"
530485539eSBill Paul #define	MASTER_SZ	sizeof(MASTER_STRING) - 1
540485539eSBill Paul #define	ORDER_STRING	"YP_LAST_MODIFIED"
550485539eSBill Paul #define	ORDER_SZ	sizeof(ORDER_STRING) - 1
56b2264be8SBill Paul 
57dc584ddbSDag-Erling Smørgrav static pid_t
yp_fork(void)58dc584ddbSDag-Erling Smørgrav yp_fork(void)
592dfb116aSBill Paul {
602dfb116aSBill Paul 	if (yp_pid != getpid()) {
612dfb116aSBill Paul 		yp_error("child %d trying to fork!", getpid());
622dfb116aSBill Paul 		errno = EEXIST;
632dfb116aSBill Paul 		return(-1);
642dfb116aSBill Paul 	}
652dfb116aSBill Paul 
662dfb116aSBill Paul 	return(fork());
672dfb116aSBill Paul }
682dfb116aSBill Paul 
699573c1f1SBill Paul /*
709573c1f1SBill Paul  * NIS v2 support. This is where most of the action happens.
719573c1f1SBill Paul  */
729573c1f1SBill Paul 
73778c7b1cSBill Paul void *
ypproc_null_2_svc(void * argp,struct svc_req * rqstp)74778c7b1cSBill Paul ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
75778c7b1cSBill Paul {
76778c7b1cSBill Paul 	static char * result;
77778c7b1cSBill Paul 	static char rval = 0;
78778c7b1cSBill Paul 
7944519760SBill Paul #ifdef DB_CACHE
8044519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
8144519760SBill Paul #else
82778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
8344519760SBill Paul #endif
84778c7b1cSBill Paul 		return(NULL);
85778c7b1cSBill Paul 
86778c7b1cSBill Paul 	result = &rval;
87778c7b1cSBill Paul 
88778c7b1cSBill Paul 	return((void *) &result);
89778c7b1cSBill Paul }
90778c7b1cSBill Paul 
91778c7b1cSBill Paul bool_t *
ypproc_domain_2_svc(domainname * argp,struct svc_req * rqstp)92778c7b1cSBill Paul ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
93778c7b1cSBill Paul {
94778c7b1cSBill Paul 	static bool_t  result;
95778c7b1cSBill Paul 
9644519760SBill Paul #ifdef DB_CACHE
9744519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) {
9844519760SBill Paul #else
99778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
10044519760SBill Paul #endif
101778c7b1cSBill Paul 		result = FALSE;
102778c7b1cSBill Paul 		return (&result);
103778c7b1cSBill Paul 	}
104778c7b1cSBill Paul 
105778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
106778c7b1cSBill Paul 		result = FALSE;
107778c7b1cSBill Paul 	else
108778c7b1cSBill Paul 		result = TRUE;
109778c7b1cSBill Paul 
110778c7b1cSBill Paul 	return (&result);
111778c7b1cSBill Paul }
112778c7b1cSBill Paul 
113778c7b1cSBill Paul bool_t *
114778c7b1cSBill Paul ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
115778c7b1cSBill Paul {
116778c7b1cSBill Paul 	static bool_t  result;
117778c7b1cSBill Paul 
11844519760SBill Paul #ifdef DB_CACHE
11944519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
12044519760SBill Paul #else
121778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
12244519760SBill Paul #endif
123778c7b1cSBill Paul 		return (NULL);
124778c7b1cSBill Paul 
125778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
126778c7b1cSBill Paul 		return (NULL);
127778c7b1cSBill Paul 	else
128778c7b1cSBill Paul 		result = TRUE;
129778c7b1cSBill Paul 
130778c7b1cSBill Paul 	return (&result);
131778c7b1cSBill Paul }
132778c7b1cSBill Paul 
133778c7b1cSBill Paul ypresp_val *
134778c7b1cSBill Paul ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
135778c7b1cSBill Paul {
136778c7b1cSBill Paul 	static ypresp_val  result;
137778c7b1cSBill Paul 
13811504a40SBill Paul 	result.val.valdat_val = "";
13911504a40SBill Paul 	result.val.valdat_len = 0;
14011504a40SBill Paul 
14144519760SBill Paul #ifdef DB_CACHE
14244519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
14344519760SBill Paul #else
144778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
14544519760SBill Paul #endif
146778c7b1cSBill Paul 		result.stat = YP_YPERR;
147778c7b1cSBill Paul 		return (&result);
148778c7b1cSBill Paul 	}
149778c7b1cSBill Paul 
150778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
151778c7b1cSBill Paul 		result.stat = YP_BADARGS;
152778c7b1cSBill Paul 		return (&result);
153778c7b1cSBill Paul 	}
154778c7b1cSBill Paul 
1550d15a950SBill Paul 	if (yp_select_map(argp->map, argp->domain, NULL, 1) != YP_TRUE) {
156180807d2SBill Paul 		result.stat = yp_errno;
157180807d2SBill Paul 		return(&result);
158778c7b1cSBill Paul 	}
159778c7b1cSBill Paul 
160180807d2SBill Paul 	result.stat = yp_getbykey(&argp->key, &result.val);
161180807d2SBill Paul 
162778c7b1cSBill Paul 	/*
163778c7b1cSBill Paul 	 * Do DNS lookups for hosts maps if database lookup failed.
164778c7b1cSBill Paul 	 */
165778c7b1cSBill Paul 
16644519760SBill Paul #ifdef DB_CACHE
1678ef09875SMaxim Konovalov 	if (do_dns && result.stat != YP_TRUE &&
16844519760SBill Paul 	    (yp_testflag(argp->map, argp->domain, YP_INTERDOMAIN) ||
1698ef09875SMaxim Konovalov 	    (strstr(argp->map, "hosts") || strstr(argp->map, "ipnodes")))) {
17044519760SBill Paul #else
1714e5a7758SHajimu UMEMOTO 	if (do_dns && result.stat != YP_TRUE &&
172322b2173SHajimu UMEMOTO 	    (strstr(argp->map, "hosts") || strstr(argp->map, "ipnodes"))) {
17344519760SBill Paul #endif
174*6b462d27SKonstantin Belousov 		char *nbuf;
175778c7b1cSBill Paul 
176*6b462d27SKonstantin Belousov 		nbuf = alloca(argp->key.keydat_len + 1);
177180807d2SBill Paul 		/* NUL terminate! NUL terminate!! NUL TERMINATE!!! */
1789ecc3726SBill Paul 		bcopy(argp->key.keydat_val, nbuf, argp->key.keydat_len);
1799ecc3726SBill Paul 		nbuf[argp->key.keydat_len] = '\0';
180778c7b1cSBill Paul 
181778c7b1cSBill Paul 		if (debug)
18298834523SPhilippe Charnier 			yp_error("doing DNS lookup of %s", nbuf);
183778c7b1cSBill Paul 
184778c7b1cSBill Paul 		if (!strcmp(argp->map, "hosts.byname"))
1854e5a7758SHajimu UMEMOTO 			result.stat = yp_async_lookup_name(rqstp, nbuf,
1864e5a7758SHajimu UMEMOTO 			    AF_INET);
187778c7b1cSBill Paul 		else if (!strcmp(argp->map, "hosts.byaddr"))
1884e5a7758SHajimu UMEMOTO 			result.stat = yp_async_lookup_addr(rqstp, nbuf,
1894e5a7758SHajimu UMEMOTO 			    AF_INET);
1904e5a7758SHajimu UMEMOTO 		else if (!strcmp(argp->map, "ipnodes.byname"))
1914e5a7758SHajimu UMEMOTO 			result.stat = yp_async_lookup_name(rqstp, nbuf,
1924e5a7758SHajimu UMEMOTO 			    AF_INET6);
1934e5a7758SHajimu UMEMOTO 		else if (!strcmp(argp->map, "ipnodes.byaddr"))
1944e5a7758SHajimu UMEMOTO 			result.stat = yp_async_lookup_addr(rqstp, nbuf,
1954e5a7758SHajimu UMEMOTO 			    AF_INET6);
196778c7b1cSBill Paul 
197180807d2SBill Paul 		if (result.stat == YP_TRUE)
198180807d2SBill Paul 			return(NULL);
199778c7b1cSBill Paul 	}
200778c7b1cSBill Paul 
201778c7b1cSBill Paul 	return (&result);
202778c7b1cSBill Paul }
203778c7b1cSBill Paul 
204778c7b1cSBill Paul ypresp_key_val *
205778c7b1cSBill Paul ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
206778c7b1cSBill Paul {
207778c7b1cSBill Paul 	static ypresp_key_val  result;
208778c7b1cSBill Paul 
20911504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
21011504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
21111504a40SBill Paul 
21244519760SBill Paul #ifdef DB_CACHE
21344519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
21444519760SBill Paul #else
215778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
21644519760SBill Paul #endif
217778c7b1cSBill Paul 		result.stat = YP_YPERR;
218778c7b1cSBill Paul 		return (&result);
219778c7b1cSBill Paul 	}
220778c7b1cSBill Paul 
221778c7b1cSBill Paul 	if (argp->domain == NULL) {
222778c7b1cSBill Paul 		result.stat = YP_BADARGS;
223778c7b1cSBill Paul 		return (&result);
224778c7b1cSBill Paul 	}
225778c7b1cSBill Paul 
2260d15a950SBill Paul 	if (yp_select_map(argp->map, argp->domain, NULL, 0) != YP_TRUE) {
227778c7b1cSBill Paul 		result.stat = yp_errno;
228778c7b1cSBill Paul 		return(&result);
229778c7b1cSBill Paul 	}
230778c7b1cSBill Paul 
231180807d2SBill Paul 	result.stat = yp_firstbykey(&result.key, &result.val);
232778c7b1cSBill Paul 
233778c7b1cSBill Paul 	return (&result);
234778c7b1cSBill Paul }
235778c7b1cSBill Paul 
236778c7b1cSBill Paul ypresp_key_val *
237778c7b1cSBill Paul ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
238778c7b1cSBill Paul {
239778c7b1cSBill Paul 	static ypresp_key_val  result;
240778c7b1cSBill Paul 
24111504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
24211504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
24311504a40SBill Paul 
24444519760SBill Paul #ifdef DB_CACHE
24544519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
24644519760SBill Paul #else
247778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
24844519760SBill Paul #endif
249778c7b1cSBill Paul 		result.stat = YP_YPERR;
250778c7b1cSBill Paul 		return (&result);
251778c7b1cSBill Paul 	}
252778c7b1cSBill Paul 
253778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
254778c7b1cSBill Paul 		result.stat = YP_BADARGS;
255778c7b1cSBill Paul 		return (&result);
256778c7b1cSBill Paul 	}
257778c7b1cSBill Paul 
258180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &argp->key, 0) != YP_TRUE) {
259778c7b1cSBill Paul 		result.stat = yp_errno;
260778c7b1cSBill Paul 		return(&result);
261778c7b1cSBill Paul 	}
262778c7b1cSBill Paul 
263180807d2SBill Paul 	result.key.keydat_len = argp->key.keydat_len;
264180807d2SBill Paul 	result.key.keydat_val = argp->key.keydat_val;
265778c7b1cSBill Paul 
266180807d2SBill Paul 	result.stat = yp_nextbykey(&result.key, &result.val);
267180807d2SBill Paul 
268778c7b1cSBill Paul 	return (&result);
269778c7b1cSBill Paul }
270778c7b1cSBill Paul 
271dc584ddbSDag-Erling Smørgrav static void
272dc584ddbSDag-Erling Smørgrav ypxfr_callback(ypxfrstat rval, struct sockaddr_in *addr, unsigned int transid,
273dc584ddbSDag-Erling Smørgrav     unsigned int prognum, unsigned long port)
27477732bc5SBill Paul {
27577732bc5SBill Paul 	CLIENT *clnt;
27677732bc5SBill Paul 	int sock = RPC_ANYSOCK;
27777732bc5SBill Paul 	struct timeval timeout;
27877732bc5SBill Paul 	yppushresp_xfr ypxfr_resp;
279009790d1SBill Paul 	struct rpc_err err;
28077732bc5SBill Paul 
281009790d1SBill Paul 	timeout.tv_sec = 5;
28277732bc5SBill Paul 	timeout.tv_usec = 0;
28377732bc5SBill Paul 	addr->sin_port = htons(port);
28477732bc5SBill Paul 
285746c49fbSBill Paul 	if ((clnt = clntudp_create(addr,prognum,1,timeout,&sock)) == NULL) {
286746c49fbSBill Paul 		yp_error("%s: %s", inet_ntoa(addr->sin_addr),
287746c49fbSBill Paul 		  clnt_spcreateerror("failed to establish callback handle"));
288746c49fbSBill Paul 		return;
289746c49fbSBill Paul 	}
29077732bc5SBill Paul 
29177732bc5SBill Paul 	ypxfr_resp.status = rval;
29277732bc5SBill Paul 	ypxfr_resp.transid = transid;
29377732bc5SBill Paul 
294009790d1SBill Paul 	/* Turn the timeout off -- we don't want to block. */
295009790d1SBill Paul 	timeout.tv_sec = 0;
296f249dbccSDag-Erling Smørgrav 	if (clnt_control(clnt, CLSET_TIMEOUT, &timeout) == FALSE)
297009790d1SBill Paul 		yp_error("failed to set timeout on ypproc_xfr callback");
298009790d1SBill Paul 
299009790d1SBill Paul 	if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
300009790d1SBill Paul 		clnt_geterr(clnt, &err);
301009790d1SBill Paul 		if (err.re_status != RPC_SUCCESS &&
302009790d1SBill Paul 		    err.re_status != RPC_TIMEDOUT)
303009790d1SBill Paul 			yp_error("%s", clnt_sperror(clnt,
304009790d1SBill Paul 				"ypxfr callback failed"));
305009790d1SBill Paul 	}
30677732bc5SBill Paul 
30777732bc5SBill Paul 	clnt_destroy(clnt);
30877732bc5SBill Paul }
30977732bc5SBill Paul 
310b2264be8SBill Paul #define YPXFR_RETURN(CODE) 						\
311b2264be8SBill Paul 	/* Order is important: send regular RPC reply, then callback */	\
312b2264be8SBill Paul 	result.xfrstat = CODE; 						\
313f249dbccSDag-Erling Smørgrav 	svc_sendreply(rqstp->rq_xprt, (xdrproc_t)xdr_ypresp_xfr, &result); \
314b2264be8SBill Paul 	ypxfr_callback(CODE,rqhost,argp->transid, 			\
315b2264be8SBill Paul 					argp->prog,argp->port); 	\
316b2264be8SBill Paul 	return(NULL);
317b2264be8SBill Paul 
318778c7b1cSBill Paul ypresp_xfr *
319778c7b1cSBill Paul ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
320778c7b1cSBill Paul {
321778c7b1cSBill Paul 	static ypresp_xfr  result;
32277732bc5SBill Paul 	struct sockaddr_in *rqhost;
32383203508SBill Paul 	ypresp_master *mres;
32483203508SBill Paul 	ypreq_nokey mreq;
325778c7b1cSBill Paul 
326009790d1SBill Paul 	result.transid = argp->transid;
327009790d1SBill Paul 	rqhost = svc_getcaller(rqstp->rq_xprt);
328009790d1SBill Paul 
32944519760SBill Paul #ifdef DB_CACHE
33044519760SBill Paul 	if (yp_access(argp->map_parms.map,
33144519760SBill Paul 			argp->map_parms.domain, (struct svc_req *)rqstp)) {
33244519760SBill Paul #else
333778c7b1cSBill Paul 	if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
33444519760SBill Paul #endif
33583203508SBill Paul 		YPXFR_RETURN(YPXFR_REFUSED)
336778c7b1cSBill Paul 	}
337778c7b1cSBill Paul 
33883203508SBill Paul 
339778c7b1cSBill Paul 	if (argp->map_parms.domain == NULL) {
34083203508SBill Paul 		YPXFR_RETURN(YPXFR_BADARGS)
341778c7b1cSBill Paul 	}
342778c7b1cSBill Paul 
343778c7b1cSBill Paul 	if (yp_validdomain(argp->map_parms.domain)) {
34483203508SBill Paul 		YPXFR_RETURN(YPXFR_NODOM)
34583203508SBill Paul 	}
34683203508SBill Paul 
34783203508SBill Paul 	/*
34883203508SBill Paul 	 * Determine the master host ourselves. The caller may
34983203508SBill Paul 	 * be up to no good. This has the side effect of verifying
35083203508SBill Paul 	 * that the requested map and domain actually exist.
35183203508SBill Paul 	 */
35283203508SBill Paul 
35383203508SBill Paul 	mreq.domain = argp->map_parms.domain;
35483203508SBill Paul 	mreq.map = argp->map_parms.map;
35583203508SBill Paul 
35683203508SBill Paul 	mres = ypproc_master_2_svc(&mreq, rqstp);
35783203508SBill Paul 
35883203508SBill Paul 	if (mres->stat != YP_TRUE) {
35983203508SBill Paul 		yp_error("couldn't find master for map %s@%s",
36083203508SBill Paul 						argp->map_parms.map,
36183203508SBill Paul 						argp->map_parms.domain);
36283203508SBill Paul 		yp_error("host at %s (%s) may be pulling my leg",
36383203508SBill Paul 						argp->map_parms.peer,
36483203508SBill Paul 						inet_ntoa(rqhost->sin_addr));
36583203508SBill Paul 		YPXFR_RETURN(YPXFR_REFUSED)
366778c7b1cSBill Paul 	}
367778c7b1cSBill Paul 
3682dfb116aSBill Paul 	switch (yp_fork()) {
369778c7b1cSBill Paul 	case 0:
370778c7b1cSBill Paul 	{
371778c7b1cSBill Paul 		char g[11], t[11], p[11];
372778c7b1cSBill Paul 		char ypxfr_command[MAXPATHLEN + 2];
373778c7b1cSBill Paul 
374e29261eaSKris Kennaway 		snprintf (ypxfr_command, sizeof(ypxfr_command), "%sypxfr", _PATH_LIBEXEC);
375e29261eaSKris Kennaway 		snprintf (t, sizeof(t), "%u", argp->transid);
376e29261eaSKris Kennaway 		snprintf (g, sizeof(g), "%u", argp->prog);
377e29261eaSKris Kennaway 		snprintf (p, sizeof(p), "%u", argp->port);
378c6c5d975SBill Paul 		if (debug) {
37977732bc5SBill Paul 			close(0); close(1); close(2);
380c6c5d975SBill Paul 		}
38177732bc5SBill Paul 		if (strcmp(yp_dir, _PATH_YP)) {
38211504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
38311504a40SBill Paul 			"-d", argp->map_parms.domain,
38483203508SBill Paul 		      	"-h", mres->peer,
38511504a40SBill Paul 			"-p", yp_dir, "-C", t,
38611504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
38711504a40SBill Paul 			p, argp->map_parms.map,
388f249dbccSDag-Erling Smørgrav 		      	NULL);
38977732bc5SBill Paul 		} else {
39011504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
39111504a40SBill Paul 			"-d", argp->map_parms.domain,
39283203508SBill Paul 		      	"-h", mres->peer,
39311504a40SBill Paul 			"-C", t,
39411504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
39511504a40SBill Paul 			p, argp->map_parms.map,
396f249dbccSDag-Erling Smørgrav 		      	NULL);
39777732bc5SBill Paul 		}
398b2264be8SBill Paul 		yp_error("ypxfr execl(%s): %s", ypxfr_command, strerror(errno));
39983203508SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR)
400dc273a2fSBill Paul 		/*
401dc273a2fSBill Paul 		 * Just to safe, prevent PR #10970 from biting us in
402dc273a2fSBill Paul 		 * the unlikely case that execing ypxfr fails. We don't
403dc273a2fSBill Paul 		 * want to have any child processes spawned from this
404dc273a2fSBill Paul 		 * child process.
405dc273a2fSBill Paul 		 */
406dc273a2fSBill Paul 		_exit(0);
40777732bc5SBill Paul 		break;
408778c7b1cSBill Paul 	}
409778c7b1cSBill Paul 	case -1:
410778c7b1cSBill Paul 		yp_error("ypxfr fork(): %s", strerror(errno));
41183203508SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR)
412778c7b1cSBill Paul 		break;
413778c7b1cSBill Paul 	default:
414009790d1SBill Paul 		result.xfrstat = YPXFR_SUCC;
41577732bc5SBill Paul 		children++;
416778c7b1cSBill Paul 		break;
417778c7b1cSBill Paul 	}
418009790d1SBill Paul 
419009790d1SBill Paul 	return (&result);
420778c7b1cSBill Paul }
421b2264be8SBill Paul #undef YPXFR_RETURN
422778c7b1cSBill Paul 
423778c7b1cSBill Paul void *
424778c7b1cSBill Paul ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
425778c7b1cSBill Paul {
426778c7b1cSBill Paul 	static char * result;
427778c7b1cSBill Paul 	static char rval = 0;
428778c7b1cSBill Paul 
42944519760SBill Paul #ifdef DB_CACHE
43044519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
43144519760SBill Paul #else
432778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
43344519760SBill Paul #endif
434778c7b1cSBill Paul 		return (NULL);
435b2264be8SBill Paul #ifdef DB_CACHE
436b2264be8SBill Paul 	/* clear out the database cache */
437b2264be8SBill Paul 	yp_flush_all();
438b2264be8SBill Paul #endif
439f7f470a8SBill Paul 	/* Re-read the securenets database for the hell of it. */
440f7f470a8SBill Paul 	load_securenets();
441f7f470a8SBill Paul 
442778c7b1cSBill Paul 	result = &rval;
443778c7b1cSBill Paul 	return((void *) &result);
444778c7b1cSBill Paul }
445778c7b1cSBill Paul 
446778c7b1cSBill Paul /*
447778c7b1cSBill Paul  * For ypproc_all, we have to send a stream of ypresp_all structures
448778c7b1cSBill Paul  * via TCP, but the XDR filter generated from the yp.x protocol
449778c7b1cSBill Paul  * definition file only serializes one such structure. This means that
450778c7b1cSBill Paul  * to send the whole stream, you need a wrapper which feeds all the
451778c7b1cSBill Paul  * records into the underlying XDR routine until it hits an 'EOF.'
452778c7b1cSBill Paul  * But to use the wrapper, you have to violate the boundaries between
453778c7b1cSBill Paul  * RPC layers by calling svc_sendreply() directly from the ypproc_all
454778c7b1cSBill Paul  * service routine instead of letting the RPC dispatcher do it.
455778c7b1cSBill Paul  *
456778c7b1cSBill Paul  * Bleah.
457778c7b1cSBill Paul  */
458778c7b1cSBill Paul 
459778c7b1cSBill Paul /*
4604c69e7b9SBill Paul  * Custom XDR routine for serialzing results of ypproc_all: keep
4614c69e7b9SBill Paul  * reading from the database and spew until we run out of records
4624c69e7b9SBill Paul  * or encounter an error.
463778c7b1cSBill Paul  */
464778c7b1cSBill Paul static bool_t
465778c7b1cSBill Paul xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp)
466778c7b1cSBill Paul {
4674c69e7b9SBill Paul 	while (1) {
4684c69e7b9SBill Paul 		/* Get a record. */
4694c69e7b9SBill Paul 		if ((objp->ypresp_all_u.val.stat =
470180807d2SBill Paul 			yp_nextbykey(&objp->ypresp_all_u.val.key,
471180807d2SBill Paul 				     &objp->ypresp_all_u.val.val)) == YP_TRUE) {
4724c69e7b9SBill Paul 			objp->more = TRUE;
4734c69e7b9SBill Paul 		} else {
4744c69e7b9SBill Paul 			objp->more = FALSE;
4754c69e7b9SBill Paul 		}
4764c69e7b9SBill Paul 
4774c69e7b9SBill Paul 		/* Serialize. */
4784c69e7b9SBill Paul 		if (!xdr_ypresp_all(xdrs, objp))
479778c7b1cSBill Paul 			return(FALSE);
4804c69e7b9SBill Paul 		if (objp->more == FALSE)
4814c69e7b9SBill Paul 			return(TRUE);
4824c69e7b9SBill Paul 	}
483778c7b1cSBill Paul }
484778c7b1cSBill Paul 
485778c7b1cSBill Paul ypresp_all *
486778c7b1cSBill Paul ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
487778c7b1cSBill Paul {
488778c7b1cSBill Paul 	static ypresp_all  result;
489778c7b1cSBill Paul 
490778c7b1cSBill Paul 	/*
491778c7b1cSBill Paul 	 * Set this here so that the client will be forced to make
492778c7b1cSBill Paul 	 * at least one attempt to read from us even if all we're
493778c7b1cSBill Paul 	 * doing is returning an error.
494778c7b1cSBill Paul 	 */
495778c7b1cSBill Paul 	result.more = TRUE;
49611504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_len = 0;
49711504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_val = "";
498778c7b1cSBill Paul 
49944519760SBill Paul #ifdef DB_CACHE
50044519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
50144519760SBill Paul #else
502778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
50344519760SBill Paul #endif
504778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_YPERR;
505778c7b1cSBill Paul 		return (&result);
506778c7b1cSBill Paul 	}
507778c7b1cSBill Paul 
508778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
509778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_BADARGS;
510778c7b1cSBill Paul 		return (&result);
511778c7b1cSBill Paul 	}
512778c7b1cSBill Paul 
5134c69e7b9SBill Paul 	/*
5149c171de0SBill Paul 	 * XXX If we hit the child limit, fail the request.
5159c171de0SBill Paul 	 * If we don't, and the map is large, we could block for
5169c171de0SBill Paul 	 * a long time in the parent.
5179c171de0SBill Paul 	 */
5189c171de0SBill Paul 	if (children >= MAX_CHILDREN) {
5199c171de0SBill Paul 		result.ypresp_all_u.val.stat = YP_YPERR;
5209c171de0SBill Paul 		return(&result);
5219c171de0SBill Paul 	}
5229c171de0SBill Paul 
5239c171de0SBill Paul 	/*
5244c69e7b9SBill Paul 	 * The ypproc_all procedure can take a while to complete.
5254c69e7b9SBill Paul 	 * Best to handle it in a subprocess so the parent doesn't
5264c69e7b9SBill Paul 	 * block. (Is there a better way to do this? Maybe with
5274c69e7b9SBill Paul 	 * async socket I/O?)
5284c69e7b9SBill Paul 	 */
529eb822b56SBill Paul 	if (!debug) {
5302dfb116aSBill Paul 		switch (yp_fork()) {
531eb822b56SBill Paul 		case 0:
532eb822b56SBill Paul 			break;
533eb822b56SBill Paul 		case -1:
534eb822b56SBill Paul 			yp_error("ypall fork(): %s", strerror(errno));
535eb822b56SBill Paul 			result.ypresp_all_u.val.stat = YP_YPERR;
536eb822b56SBill Paul 			return(&result);
537eb822b56SBill Paul 			break;
538eb822b56SBill Paul 		default:
5394c69e7b9SBill Paul 			children++;
5404c69e7b9SBill Paul 			return (NULL);
541eb822b56SBill Paul 			break;
542eb822b56SBill Paul 		}
5434c69e7b9SBill Paul 	}
5444c69e7b9SBill Paul 
545c167b71aSBill Paul 	/*
546c167b71aSBill Paul 	 * Fix for PR #10971: don't let the child ypserv share
547c167b71aSBill Paul 	 * DB handles with the parent process.
548c167b71aSBill Paul 	 */
549c167b71aSBill Paul #ifdef DB_CACHE
550c167b71aSBill Paul 	yp_flush_all();
551c167b71aSBill Paul #endif
552c167b71aSBill Paul 
553180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain,
554180807d2SBill Paul 				&result.ypresp_all_u.val.key, 0) != YP_TRUE) {
555778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = yp_errno;
556778c7b1cSBill Paul 		return(&result);
557778c7b1cSBill Paul 	}
558778c7b1cSBill Paul 
559778c7b1cSBill Paul 	/* Kick off the actual data transfer. */
560f249dbccSDag-Erling Smørgrav 	svc_sendreply(rqstp->rq_xprt, (xdrproc_t)xdr_my_ypresp_all, &result);
5614c69e7b9SBill Paul 
562778c7b1cSBill Paul 	/*
563dc273a2fSBill Paul 	 * Proper fix for PR #10970: exit here so that we don't risk
564dc273a2fSBill Paul 	 * having a child spawned from this sub-process.
565778c7b1cSBill Paul 	 */
5668fbf0713SJun Kuriyama 	if (!debug)
567dc273a2fSBill Paul 		_exit(0);
5688fbf0713SJun Kuriyama 
5698fbf0713SJun Kuriyama 	return &result;
570778c7b1cSBill Paul }
571778c7b1cSBill Paul 
572778c7b1cSBill Paul ypresp_master *
573778c7b1cSBill Paul ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
574778c7b1cSBill Paul {
575778c7b1cSBill Paul 	static ypresp_master  result;
576b2264be8SBill Paul 	static char ypvalbuf[YPMAXRECORD];
5770485539eSBill Paul 	keydat key = { MASTER_SZ, MASTER_STRING };
578180807d2SBill Paul 	valdat val;
579778c7b1cSBill Paul 
58045da6d16SBill Paul 	result.peer = "";
58145da6d16SBill Paul 
58244519760SBill Paul #ifdef DB_CACHE
58344519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
58444519760SBill Paul #else
58544519760SBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
58644519760SBill Paul #endif
587778c7b1cSBill Paul 		result.stat = YP_YPERR;
588778c7b1cSBill Paul 		return(&result);
589778c7b1cSBill Paul 	}
590778c7b1cSBill Paul 
591778c7b1cSBill Paul 	if (argp->domain == NULL) {
592778c7b1cSBill Paul 		result.stat = YP_BADARGS;
593778c7b1cSBill Paul 		return (&result);
594778c7b1cSBill Paul 	}
595778c7b1cSBill Paul 
596180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) {
597180807d2SBill Paul 		result.stat = yp_errno;
598180807d2SBill Paul 		return(&result);
599180807d2SBill Paul 	}
600180807d2SBill Paul 
601b2264be8SBill Paul 	/*
602b2264be8SBill Paul 	 * Note that we copy the data retrieved from the database to
603b2264be8SBill Paul 	 * a private buffer and NUL terminate the buffer rather than
604b2264be8SBill Paul 	 * terminating the data in place. We do this because by stuffing
605b2264be8SBill Paul 	 * a '\0' into data.data, we will actually be corrupting memory
606b2264be8SBill Paul 	 * allocated by the DB package. This is a bad thing now that we
607b2264be8SBill Paul 	 * cache DB handles rather than closing the database immediately.
608b2264be8SBill Paul 	 */
609180807d2SBill Paul 	result.stat = yp_getbykey(&key, &val);
610180807d2SBill Paul 	if (result.stat == YP_TRUE) {
611f249dbccSDag-Erling Smørgrav 		bcopy(val.valdat_val, &ypvalbuf, val.valdat_len);
612180807d2SBill Paul 		ypvalbuf[val.valdat_len] = '\0';
613f249dbccSDag-Erling Smørgrav 		result.peer = ypvalbuf;
614778c7b1cSBill Paul 	} else
615778c7b1cSBill Paul 		result.peer = "";
616778c7b1cSBill Paul 
617778c7b1cSBill Paul 	return (&result);
618778c7b1cSBill Paul }
619778c7b1cSBill Paul 
620778c7b1cSBill Paul ypresp_order *
621778c7b1cSBill Paul ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
622778c7b1cSBill Paul {
623778c7b1cSBill Paul 	static ypresp_order  result;
6240485539eSBill Paul 	keydat key = { ORDER_SZ, ORDER_STRING };
625180807d2SBill Paul 	valdat val;
626778c7b1cSBill Paul 
62711504a40SBill Paul 	result.ordernum = 0;
62811504a40SBill Paul 
62944519760SBill Paul #ifdef DB_CACHE
63044519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
63144519760SBill Paul #else
63244519760SBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
63344519760SBill Paul #endif
634778c7b1cSBill Paul 		result.stat = YP_YPERR;
635778c7b1cSBill Paul 		return(&result);
636778c7b1cSBill Paul 	}
637778c7b1cSBill Paul 
638778c7b1cSBill Paul 	if (argp->domain == NULL) {
639778c7b1cSBill Paul 		result.stat = YP_BADARGS;
640778c7b1cSBill Paul 		return (&result);
641778c7b1cSBill Paul 	}
642778c7b1cSBill Paul 
643778c7b1cSBill Paul 	/*
644778c7b1cSBill Paul 	 * We could just check the timestamp on the map file,
645778c7b1cSBill Paul 	 * but that's a hack: we'll only know the last time the file
646778c7b1cSBill Paul 	 * was touched, not the last time the database contents were
647778c7b1cSBill Paul 	 * updated.
648778c7b1cSBill Paul 	 */
649778c7b1cSBill Paul 
650180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) {
651180807d2SBill Paul 		result.stat = yp_errno;
652180807d2SBill Paul 		return(&result);
653180807d2SBill Paul 	}
654180807d2SBill Paul 
655180807d2SBill Paul 	result.stat = yp_getbykey(&key, &val);
656180807d2SBill Paul 
657180807d2SBill Paul 	if (result.stat == YP_TRUE)
658f249dbccSDag-Erling Smørgrav 		result.ordernum = atoi(val.valdat_val);
659778c7b1cSBill Paul 	else
660778c7b1cSBill Paul 		result.ordernum = 0;
661778c7b1cSBill Paul 
662778c7b1cSBill Paul 	return (&result);
663778c7b1cSBill Paul }
664778c7b1cSBill Paul 
665dc584ddbSDag-Erling Smørgrav static void yp_maplist_free(struct ypmaplist *yp_maplist)
666778c7b1cSBill Paul {
667778c7b1cSBill Paul 	register struct ypmaplist *next;
668778c7b1cSBill Paul 
669778c7b1cSBill Paul 	while (yp_maplist) {
670778c7b1cSBill Paul 		next = yp_maplist->next;
671778c7b1cSBill Paul 		free(yp_maplist->map);
672778c7b1cSBill Paul 		free(yp_maplist);
673778c7b1cSBill Paul 		yp_maplist = next;
674778c7b1cSBill Paul 	}
675778c7b1cSBill Paul }
676778c7b1cSBill Paul 
677dc584ddbSDag-Erling Smørgrav static struct ypmaplist *
678dc584ddbSDag-Erling Smørgrav yp_maplist_create(const char *domain)
679778c7b1cSBill Paul {
680778c7b1cSBill Paul 	char yp_mapdir[MAXPATHLEN + 2];
681778c7b1cSBill Paul 	char yp_mapname[MAXPATHLEN + 2];
682778c7b1cSBill Paul 	struct ypmaplist *cur = NULL;
683778c7b1cSBill Paul 	struct ypmaplist *yp_maplist = NULL;
684778c7b1cSBill Paul 	DIR *dird;
685778c7b1cSBill Paul 	struct dirent *dirp;
686778c7b1cSBill Paul 	struct stat statbuf;
687778c7b1cSBill Paul 
688778c7b1cSBill Paul 	snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain);
689778c7b1cSBill Paul 
690778c7b1cSBill Paul 	if ((dird = opendir(yp_mapdir)) == NULL) {
691c0b36ac2SBill Paul 		yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno));
692778c7b1cSBill Paul 		return(NULL);
693778c7b1cSBill Paul 	}
694778c7b1cSBill Paul 
695778c7b1cSBill Paul 	while ((dirp = readdir(dird)) != NULL) {
696778c7b1cSBill Paul 		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) {
69711504a40SBill Paul 			snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",
69811504a40SBill Paul 							yp_mapdir,dirp->d_name);
69911504a40SBill Paul 			if (stat(yp_mapname, &statbuf) < 0 ||
70011504a40SBill Paul 						!S_ISREG(statbuf.st_mode))
701778c7b1cSBill Paul 				continue;
70211504a40SBill Paul 			if ((cur = (struct ypmaplist *)
7031fbdac93SBill Paul 				malloc(sizeof(struct ypmaplist))) == NULL) {
70498834523SPhilippe Charnier 				yp_error("malloc() failed");
705778c7b1cSBill Paul 				closedir(dird);
706778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
707778c7b1cSBill Paul 				return(NULL);
708778c7b1cSBill Paul 			}
709f249dbccSDag-Erling Smørgrav 			if ((cur->map = strdup(dirp->d_name)) == NULL) {
710778c7b1cSBill Paul 				yp_error("strdup() failed: %s",strerror(errno));
711778c7b1cSBill Paul 				closedir(dird);
712778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
713a23f17d3SDon Lewis 				free(cur);
714778c7b1cSBill Paul 				return(NULL);
715778c7b1cSBill Paul 			}
716778c7b1cSBill Paul 			cur->next = yp_maplist;
717778c7b1cSBill Paul 			yp_maplist = cur;
718778c7b1cSBill Paul 			if (debug)
719778c7b1cSBill Paul 				yp_error("map: %s", yp_maplist->map);
720778c7b1cSBill Paul 		}
721778c7b1cSBill Paul 
722778c7b1cSBill Paul 	}
723778c7b1cSBill Paul 	closedir(dird);
724778c7b1cSBill Paul 	return(yp_maplist);
725778c7b1cSBill Paul }
726778c7b1cSBill Paul 
727778c7b1cSBill Paul ypresp_maplist *
728778c7b1cSBill Paul ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
729778c7b1cSBill Paul {
730b2264be8SBill Paul 	static ypresp_maplist  result = { 0, NULL };
73111504a40SBill Paul 
73244519760SBill Paul #ifdef DB_CACHE
73344519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) {
73444519760SBill Paul #else
735778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
73644519760SBill Paul #endif
737778c7b1cSBill Paul 		result.stat = YP_YPERR;
738778c7b1cSBill Paul 		return(&result);
739778c7b1cSBill Paul 	}
740778c7b1cSBill Paul 
741778c7b1cSBill Paul 	if (argp == NULL) {
742778c7b1cSBill Paul 		result.stat = YP_BADARGS;
743778c7b1cSBill Paul 		return (&result);
744778c7b1cSBill Paul 	}
745778c7b1cSBill Paul 
746778c7b1cSBill Paul 	if (yp_validdomain(*argp)) {
747778c7b1cSBill Paul 		result.stat = YP_NODOM;
748778c7b1cSBill Paul 		return (&result);
749778c7b1cSBill Paul 	}
750778c7b1cSBill Paul 
751778c7b1cSBill Paul 	/*
752778c7b1cSBill Paul 	 * We have to construct a linked list for the ypproc_maplist
753778c7b1cSBill Paul 	 * procedure using dynamically allocated memory. Since the XDR
754778c7b1cSBill Paul 	 * layer won't free this list for us, we have to deal with it
755778c7b1cSBill Paul 	 * ourselves. We call yp_maplist_free() first to free any
756778c7b1cSBill Paul 	 * previously allocated data we may have accumulated to insure
757778c7b1cSBill Paul 	 * that we have only one linked list in memory at any given
758778c7b1cSBill Paul 	 * time.
759778c7b1cSBill Paul 	 */
760778c7b1cSBill Paul 
761778c7b1cSBill Paul 	yp_maplist_free(result.maps);
762778c7b1cSBill Paul 
763778c7b1cSBill Paul 	if ((result.maps = yp_maplist_create(*argp)) == NULL) {
764778c7b1cSBill Paul 		yp_error("yp_maplist_create failed");
765778c7b1cSBill Paul 		result.stat = YP_YPERR;
766778c7b1cSBill Paul 		return(&result);
767778c7b1cSBill Paul 	} else
768778c7b1cSBill Paul 		result.stat = YP_TRUE;
769778c7b1cSBill Paul 
770778c7b1cSBill Paul 	return (&result);
771778c7b1cSBill Paul }
7729573c1f1SBill Paul 
7739573c1f1SBill Paul /*
7749573c1f1SBill Paul  * NIS v1 support. The nullproc, domain and domain_nonack
7759573c1f1SBill Paul  * functions from v1 are identical to those in v2, so all
7769573c1f1SBill Paul  * we have to do is hand off to them.
7779573c1f1SBill Paul  *
7789573c1f1SBill Paul  * The other functions are mostly just wrappers around their v2
7799573c1f1SBill Paul  * counterparts. For example, for the v1 'match' procedure, we
7809573c1f1SBill Paul  * crack open the argument structure, make a request to the v2
7819573c1f1SBill Paul  * 'match' function, repackage the data into a v1 response and
7829573c1f1SBill Paul  * then send it on its way.
7839573c1f1SBill Paul  *
7849573c1f1SBill Paul  * Note that we don't support the pull, push and get procedures.
7859573c1f1SBill Paul  * There's little documentation available to show what they
7869573c1f1SBill Paul  * do, and I suspect they're meant largely for map transfers
7879573c1f1SBill Paul  * between master and slave servers.
7889573c1f1SBill Paul  */
7899573c1f1SBill Paul 
7909573c1f1SBill Paul void *
7919573c1f1SBill Paul ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp)
7929573c1f1SBill Paul {
7939573c1f1SBill Paul 	return(ypproc_null_2_svc(argp, rqstp));
7949573c1f1SBill Paul }
7959573c1f1SBill Paul 
7969573c1f1SBill Paul bool_t *
7979573c1f1SBill Paul ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp)
7989573c1f1SBill Paul {
7999573c1f1SBill Paul 	return(ypproc_domain_2_svc(argp, rqstp));
8009573c1f1SBill Paul }
8019573c1f1SBill Paul 
8029573c1f1SBill Paul bool_t *
8039573c1f1SBill Paul ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp)
8049573c1f1SBill Paul {
8059573c1f1SBill Paul 	return (ypproc_domain_nonack_2_svc(argp, rqstp));
8069573c1f1SBill Paul }
8079573c1f1SBill Paul 
80811504a40SBill Paul /*
80911504a40SBill Paul  * the 'match' procedure sends a response of type YPRESP_VAL
81011504a40SBill Paul  */
8119573c1f1SBill Paul ypresponse *
8129573c1f1SBill Paul ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp)
8139573c1f1SBill Paul {
8149573c1f1SBill Paul 	static ypresponse  result;
8159573c1f1SBill Paul 	ypresp_val *v2_result;
8169573c1f1SBill Paul 
8179573c1f1SBill Paul 	result.yp_resptype = YPRESP_VAL;
81811504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_val = "";
81911504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_len = 0;
8209573c1f1SBill Paul 
8219573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
8229573c1f1SBill Paul 		result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS;
8239573c1f1SBill Paul 		return(&result);
8249573c1f1SBill Paul 	}
8259573c1f1SBill Paul 
8269573c1f1SBill Paul 	v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
8279573c1f1SBill Paul 	if (v2_result == NULL)
8289573c1f1SBill Paul 		return(NULL);
8299573c1f1SBill Paul 
830f249dbccSDag-Erling Smørgrav 	bcopy(v2_result, &result.ypresponse_u.yp_resp_valtype,
8319573c1f1SBill Paul 	      sizeof(ypresp_val));
8329573c1f1SBill Paul 
8339573c1f1SBill Paul 	return (&result);
8349573c1f1SBill Paul }
8359573c1f1SBill Paul 
83611504a40SBill Paul /*
83711504a40SBill Paul  * the 'first' procedure sends a response of type YPRESP_KEY_VAL
83811504a40SBill Paul  */
8399573c1f1SBill Paul ypresponse *
8409573c1f1SBill Paul ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp)
8419573c1f1SBill Paul {
8429573c1f1SBill Paul 	static ypresponse  result;
8439573c1f1SBill Paul 	ypresp_key_val *v2_result;
8449573c1f1SBill Paul 
8459573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
84611504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
84711504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
84811504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
84911504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
8509573c1f1SBill Paul 
8519573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_NOKEY) {
8529573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
8539573c1f1SBill Paul 		return(&result);
8549573c1f1SBill Paul 	}
8559573c1f1SBill Paul 
8569573c1f1SBill Paul 	v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8579573c1f1SBill Paul 									rqstp);
8589573c1f1SBill Paul 	if (v2_result == NULL)
8599573c1f1SBill Paul 		return(NULL);
8609573c1f1SBill Paul 
861f249dbccSDag-Erling Smørgrav 	bcopy(v2_result, &result.ypresponse_u.yp_resp_key_valtype,
8629573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8639573c1f1SBill Paul 
8649573c1f1SBill Paul 	return (&result);
8659573c1f1SBill Paul }
8669573c1f1SBill Paul 
86711504a40SBill Paul /*
86811504a40SBill Paul  * the 'next' procedure sends a response of type YPRESP_KEY_VAL
86911504a40SBill Paul  */
8709573c1f1SBill Paul ypresponse *
8719573c1f1SBill Paul ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp)
8729573c1f1SBill Paul {
8739573c1f1SBill Paul 	static ypresponse  result;
8749573c1f1SBill Paul 	ypresp_key_val *v2_result;
8759573c1f1SBill Paul 
8769573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
87711504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
87811504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
87911504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
88011504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
8819573c1f1SBill Paul 
8829573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
8839573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
8849573c1f1SBill Paul 		return(&result);
8859573c1f1SBill Paul 	}
8869573c1f1SBill Paul 
8879573c1f1SBill Paul 	v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
8889573c1f1SBill Paul 	if (v2_result == NULL)
8899573c1f1SBill Paul 		return(NULL);
8909573c1f1SBill Paul 
891f249dbccSDag-Erling Smørgrav 	bcopy(v2_result, &result.ypresponse_u.yp_resp_key_valtype,
8929573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8939573c1f1SBill Paul 
8949573c1f1SBill Paul 	return (&result);
8959573c1f1SBill Paul }
8969573c1f1SBill Paul 
89711504a40SBill Paul /*
89811504a40SBill Paul  * the 'poll' procedure sends a response of type YPRESP_MAP_PARMS
89911504a40SBill Paul  */
9009573c1f1SBill Paul ypresponse *
9019573c1f1SBill Paul ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp)
9029573c1f1SBill Paul {
9039573c1f1SBill Paul 	static ypresponse  result;
9049573c1f1SBill Paul 	ypresp_master *v2_result1;
9059573c1f1SBill Paul 	ypresp_order *v2_result2;
9069573c1f1SBill Paul 
9079573c1f1SBill Paul 	result.yp_resptype = YPRESP_MAP_PARMS;
9089573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.domain =
9099573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.domain;
9109573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.map =
9119573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.map;
9129573c1f1SBill Paul 	/*
9139573c1f1SBill Paul 	 * Hmm... there is no 'status' value in the
9149573c1f1SBill Paul 	 * yp_resp_map_parmstype structure, so I have to
9159573c1f1SBill Paul 	 * guess at what to do to indicate a failure.
9169573c1f1SBill Paul 	 * I hope this is right.
9179573c1f1SBill Paul 	 */
9189573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0;
9199573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer = "";
9209573c1f1SBill Paul 
9219573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_MAP_PARMS) {
9229573c1f1SBill Paul 		return(&result);
9239573c1f1SBill Paul 	}
9249573c1f1SBill Paul 
9259573c1f1SBill Paul 	v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype,
9269573c1f1SBill Paul 									rqstp);
9279573c1f1SBill Paul 	if (v2_result1 == NULL)
9289573c1f1SBill Paul 		return(NULL);
9299573c1f1SBill Paul 
9309573c1f1SBill Paul 	if (v2_result1->stat != YP_TRUE) {
9319573c1f1SBill Paul 		return(&result);
9329573c1f1SBill Paul 	}
9339573c1f1SBill Paul 
9349573c1f1SBill Paul 	v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype,
9359573c1f1SBill Paul 									rqstp);
9369573c1f1SBill Paul 	if (v2_result2 == NULL)
9379573c1f1SBill Paul 		return(NULL);
9389573c1f1SBill Paul 
9399573c1f1SBill Paul 	if (v2_result2->stat != YP_TRUE) {
9409573c1f1SBill Paul 		return(&result);
9419573c1f1SBill Paul 	}
9429573c1f1SBill Paul 
9439573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer =
9449573c1f1SBill Paul 		v2_result1->peer;
9459573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum =
9469573c1f1SBill Paul 		v2_result2->ordernum;
9479573c1f1SBill Paul 
9489573c1f1SBill Paul 	return (&result);
9499573c1f1SBill Paul }
9509573c1f1SBill Paul 
9519573c1f1SBill Paul ypresponse *
9529573c1f1SBill Paul ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp)
9539573c1f1SBill Paul {
9549573c1f1SBill Paul 	static ypresponse  result;
9559573c1f1SBill Paul 
9569573c1f1SBill Paul 	/*
9579573c1f1SBill Paul 	 * Not implemented.
9589573c1f1SBill Paul 	 */
9599573c1f1SBill Paul 
9609573c1f1SBill Paul 	return (&result);
9619573c1f1SBill Paul }
9629573c1f1SBill Paul 
9639573c1f1SBill Paul ypresponse *
9649573c1f1SBill Paul ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp)
9659573c1f1SBill Paul {
9669573c1f1SBill Paul 	static ypresponse  result;
9679573c1f1SBill Paul 
9689573c1f1SBill Paul 	/*
9699573c1f1SBill Paul 	 * Not implemented.
9709573c1f1SBill Paul 	 */
9719573c1f1SBill Paul 
9729573c1f1SBill Paul 	return (&result);
9739573c1f1SBill Paul }
9749573c1f1SBill Paul 
9759573c1f1SBill Paul ypresponse *
9769573c1f1SBill Paul ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp)
9779573c1f1SBill Paul {
9789573c1f1SBill Paul 	static ypresponse  result;
9799573c1f1SBill Paul 
9809573c1f1SBill Paul 	/*
9819573c1f1SBill Paul 	 * Not implemented.
9829573c1f1SBill Paul 	 */
9839573c1f1SBill Paul 
9849573c1f1SBill Paul 	return (&result);
9859573c1f1SBill Paul }
986