xref: /freebsd/usr.sbin/ypserv/yp_server.c (revision 9ecc3726d9fa1921eef39fd0ca6254bd8f11d6c7)
1778c7b1cSBill Paul /*
2778c7b1cSBill Paul  * Copyright (c) 1995
3778c7b1cSBill Paul  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4778c7b1cSBill Paul  *
5778c7b1cSBill Paul  * Redistribution and use in source and binary forms, with or without
6778c7b1cSBill Paul  * modification, are permitted provided that the following conditions
7778c7b1cSBill Paul  * are met:
8778c7b1cSBill Paul  * 1. Redistributions of source code must retain the above copyright
9778c7b1cSBill Paul  *    notice, this list of conditions and the following disclaimer.
10778c7b1cSBill Paul  * 2. Redistributions in binary form must reproduce the above copyright
11778c7b1cSBill Paul  *    notice, this list of conditions and the following disclaimer in the
12778c7b1cSBill Paul  *    documentation and/or other materials provided with the distribution.
13778c7b1cSBill Paul  * 3. All advertising materials mentioning features or use of this software
14778c7b1cSBill Paul  *    must display the following acknowledgement:
15778c7b1cSBill Paul  *	This product includes software developed by Bill Paul.
16778c7b1cSBill Paul  * 4. Neither the name of the author nor the names of any co-contributors
17778c7b1cSBill Paul  *    may be used to endorse or promote products derived from this software
18778c7b1cSBill Paul  *    without specific prior written permission.
19778c7b1cSBill Paul  *
20778c7b1cSBill Paul  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21778c7b1cSBill Paul  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22778c7b1cSBill Paul  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23778c7b1cSBill Paul  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24778c7b1cSBill Paul  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25778c7b1cSBill Paul  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26778c7b1cSBill Paul  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27778c7b1cSBill Paul  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28778c7b1cSBill Paul  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29778c7b1cSBill Paul  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30778c7b1cSBill Paul  * SUCH DAMAGE.
31778c7b1cSBill Paul  *
32778c7b1cSBill Paul  */
33778c7b1cSBill Paul 
34778c7b1cSBill Paul #include "yp.h"
35180807d2SBill Paul #include "yp_extern.h"
36778c7b1cSBill Paul #include <stdlib.h>
37778c7b1cSBill Paul #include <dirent.h>
38778c7b1cSBill Paul #include <sys/stat.h>
39778c7b1cSBill Paul #include <sys/param.h>
40778c7b1cSBill Paul #include <errno.h>
41778c7b1cSBill Paul #include <sys/types.h>
42778c7b1cSBill Paul #include <sys/socket.h>
43778c7b1cSBill Paul #include <netinet/in.h>
44778c7b1cSBill Paul #include <arpa/inet.h>
4577732bc5SBill Paul #include <rpc/rpc.h>
46778c7b1cSBill Paul 
47778c7b1cSBill Paul #ifndef lint
489ecc3726SBill Paul static const char rcsid[] = "$Id: yp_server.c,v 1.22 1997/04/28 14:18:38 wpaul Exp $";
49778c7b1cSBill Paul #endif /* not lint */
50778c7b1cSBill Paul 
51778c7b1cSBill Paul int forked = 0;
52778c7b1cSBill Paul int children = 0;
5344519760SBill Paul static char *master_string = "YP_MASTER_NAME";
5444519760SBill Paul static char *order_string = "YP_LAST_MODIFIED";
5544519760SBill Paul static int master_sz = sizeof("YP_MASTER_NAME") - 1;
5644519760SBill Paul static int order_sz = sizeof("YP_LAST_MODIFIED") - 1;
57b2264be8SBill Paul 
589573c1f1SBill Paul /*
599573c1f1SBill Paul  * NIS v2 support. This is where most of the action happens.
609573c1f1SBill Paul  */
619573c1f1SBill Paul 
62778c7b1cSBill Paul void *
63778c7b1cSBill Paul ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
64778c7b1cSBill Paul {
65778c7b1cSBill Paul 	static char * result;
66778c7b1cSBill Paul 	static char rval = 0;
67778c7b1cSBill Paul 
6844519760SBill Paul #ifdef DB_CACHE
6944519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
7044519760SBill Paul #else
71778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
7244519760SBill Paul #endif
73778c7b1cSBill Paul 		return(NULL);
74778c7b1cSBill Paul 
75778c7b1cSBill Paul 	result = &rval;
76778c7b1cSBill Paul 
77778c7b1cSBill Paul 	return((void *) &result);
78778c7b1cSBill Paul }
79778c7b1cSBill Paul 
80778c7b1cSBill Paul bool_t *
81778c7b1cSBill Paul ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
82778c7b1cSBill Paul {
83778c7b1cSBill Paul 	static bool_t  result;
84778c7b1cSBill Paul 
8544519760SBill Paul #ifdef DB_CACHE
8644519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) {
8744519760SBill Paul #else
88778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
8944519760SBill Paul #endif
90778c7b1cSBill Paul 		result = FALSE;
91778c7b1cSBill Paul 		return (&result);
92778c7b1cSBill Paul 	}
93778c7b1cSBill Paul 
94778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
95778c7b1cSBill Paul 		result = FALSE;
96778c7b1cSBill Paul 	else
97778c7b1cSBill Paul 		result = TRUE;
98778c7b1cSBill Paul 
99778c7b1cSBill Paul 	return (&result);
100778c7b1cSBill Paul }
101778c7b1cSBill Paul 
102778c7b1cSBill Paul bool_t *
103778c7b1cSBill Paul ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
104778c7b1cSBill Paul {
105778c7b1cSBill Paul 	static bool_t  result;
106778c7b1cSBill Paul 
10744519760SBill Paul #ifdef DB_CACHE
10844519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
10944519760SBill Paul #else
110778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
11144519760SBill Paul #endif
112778c7b1cSBill Paul 		return (NULL);
113778c7b1cSBill Paul 
114778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
115778c7b1cSBill Paul 		return (NULL);
116778c7b1cSBill Paul 	else
117778c7b1cSBill Paul 		result = TRUE;
118778c7b1cSBill Paul 
119778c7b1cSBill Paul 	return (&result);
120778c7b1cSBill Paul }
121778c7b1cSBill Paul 
122778c7b1cSBill Paul ypresp_val *
123778c7b1cSBill Paul ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
124778c7b1cSBill Paul {
125778c7b1cSBill Paul 	static ypresp_val  result;
126778c7b1cSBill Paul 
12711504a40SBill Paul 	result.val.valdat_val = "";
12811504a40SBill Paul 	result.val.valdat_len = 0;
12911504a40SBill Paul 
13044519760SBill Paul #ifdef DB_CACHE
13144519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
13244519760SBill Paul #else
133778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
13444519760SBill Paul #endif
135778c7b1cSBill Paul 		result.stat = YP_YPERR;
136778c7b1cSBill Paul 		return (&result);
137778c7b1cSBill Paul 	}
138778c7b1cSBill Paul 
139778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
140778c7b1cSBill Paul 		result.stat = YP_BADARGS;
141778c7b1cSBill Paul 		return (&result);
142778c7b1cSBill Paul 	}
143778c7b1cSBill Paul 
144180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &argp->key, 1) != YP_TRUE) {
145180807d2SBill Paul 		result.stat = yp_errno;
146180807d2SBill Paul 		return(&result);
147778c7b1cSBill Paul 	}
148778c7b1cSBill Paul 
149180807d2SBill Paul 	result.stat = yp_getbykey(&argp->key, &result.val);
150180807d2SBill Paul 
151778c7b1cSBill Paul 	/*
152778c7b1cSBill Paul 	 * Do DNS lookups for hosts maps if database lookup failed.
153778c7b1cSBill Paul 	 */
154778c7b1cSBill Paul 
15544519760SBill Paul #ifdef DB_CACHE
15644519760SBill Paul 	if (result.stat != YP_TRUE &&
15744519760SBill Paul 	    (yp_testflag(argp->map, argp->domain, YP_INTERDOMAIN) ||
15844519760SBill Paul 	    (strstr(argp->map, "hosts") && do_dns))) {
15944519760SBill Paul #else
160778c7b1cSBill Paul 	if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) {
16144519760SBill Paul #endif
1629ecc3726SBill Paul 		char			nbuf[YPMAXRECORD];
163778c7b1cSBill Paul 
164180807d2SBill Paul 		/* NUL terminate! NUL terminate!! NUL TERMINATE!!! */
1659ecc3726SBill Paul 		bcopy(argp->key.keydat_val, nbuf, argp->key.keydat_len);
1669ecc3726SBill Paul 		nbuf[argp->key.keydat_len] = '\0';
167778c7b1cSBill Paul 
168778c7b1cSBill Paul 		if (debug)
1699ecc3726SBill Paul 			yp_error("Doing DNS lookup of %s", nbuf);
170778c7b1cSBill Paul 
171778c7b1cSBill Paul 		if (!strcmp(argp->map, "hosts.byname"))
1729ecc3726SBill Paul 			result.stat = yp_async_lookup_name(rqstp, nbuf);
173778c7b1cSBill Paul 		else if (!strcmp(argp->map, "hosts.byaddr"))
1749ecc3726SBill Paul 			result.stat = yp_async_lookup_addr(rqstp, nbuf);
175778c7b1cSBill Paul 
176180807d2SBill Paul 		if (result.stat == YP_TRUE)
177180807d2SBill Paul 			return(NULL);
178778c7b1cSBill Paul 	}
179778c7b1cSBill Paul 
180778c7b1cSBill Paul 	return (&result);
181778c7b1cSBill Paul }
182778c7b1cSBill Paul 
183778c7b1cSBill Paul ypresp_key_val *
184778c7b1cSBill Paul ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
185778c7b1cSBill Paul {
186778c7b1cSBill Paul 	static ypresp_key_val  result;
187778c7b1cSBill Paul 
18811504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
18911504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
19011504a40SBill Paul 
19144519760SBill Paul #ifdef DB_CACHE
19244519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
19344519760SBill Paul #else
194778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
19544519760SBill Paul #endif
196778c7b1cSBill Paul 		result.stat = YP_YPERR;
197778c7b1cSBill Paul 		return (&result);
198778c7b1cSBill Paul 	}
199778c7b1cSBill Paul 
200778c7b1cSBill Paul 	if (argp->domain == NULL) {
201778c7b1cSBill Paul 		result.stat = YP_BADARGS;
202778c7b1cSBill Paul 		return (&result);
203778c7b1cSBill Paul 	}
204778c7b1cSBill Paul 
205180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &result.key, 0) != YP_TRUE) {
206778c7b1cSBill Paul 		result.stat = yp_errno;
207778c7b1cSBill Paul 		return(&result);
208778c7b1cSBill Paul 	}
209778c7b1cSBill Paul 
210180807d2SBill Paul 	result.stat = yp_firstbykey(&result.key, &result.val);
211778c7b1cSBill Paul 
212778c7b1cSBill Paul 	return (&result);
213778c7b1cSBill Paul }
214778c7b1cSBill Paul 
215778c7b1cSBill Paul ypresp_key_val *
216778c7b1cSBill Paul ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
217778c7b1cSBill Paul {
218778c7b1cSBill Paul 	static ypresp_key_val  result;
219778c7b1cSBill Paul 
22011504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
22111504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
22211504a40SBill Paul 
22344519760SBill Paul #ifdef DB_CACHE
22444519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
22544519760SBill Paul #else
226778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
22744519760SBill Paul #endif
228778c7b1cSBill Paul 		result.stat = YP_YPERR;
229778c7b1cSBill Paul 		return (&result);
230778c7b1cSBill Paul 	}
231778c7b1cSBill Paul 
232778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
233778c7b1cSBill Paul 		result.stat = YP_BADARGS;
234778c7b1cSBill Paul 		return (&result);
235778c7b1cSBill Paul 	}
236778c7b1cSBill Paul 
237180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &argp->key, 0) != YP_TRUE) {
238778c7b1cSBill Paul 		result.stat = yp_errno;
239778c7b1cSBill Paul 		return(&result);
240778c7b1cSBill Paul 	}
241778c7b1cSBill Paul 
242180807d2SBill Paul 	result.key.keydat_len = argp->key.keydat_len;
243180807d2SBill Paul 	result.key.keydat_val = argp->key.keydat_val;
244778c7b1cSBill Paul 
245180807d2SBill Paul 	result.stat = yp_nextbykey(&result.key, &result.val);
246180807d2SBill Paul 
247778c7b1cSBill Paul 	return (&result);
248778c7b1cSBill Paul }
249778c7b1cSBill Paul 
25077732bc5SBill Paul static void ypxfr_callback(rval,addr,transid,prognum,port)
25177732bc5SBill Paul 	ypxfrstat rval;
25277732bc5SBill Paul 	struct sockaddr_in *addr;
25377732bc5SBill Paul 	unsigned int transid;
25477732bc5SBill Paul 	unsigned int prognum;
25577732bc5SBill Paul 	unsigned long port;
25677732bc5SBill Paul {
25777732bc5SBill Paul 	CLIENT *clnt;
25877732bc5SBill Paul 	int sock = RPC_ANYSOCK;
25977732bc5SBill Paul 	struct timeval timeout;
26077732bc5SBill Paul 	yppushresp_xfr ypxfr_resp;
261009790d1SBill Paul 	struct rpc_err err;
26277732bc5SBill Paul 
263009790d1SBill Paul 	timeout.tv_sec = 5;
26477732bc5SBill Paul 	timeout.tv_usec = 0;
26577732bc5SBill Paul 	addr->sin_port = htons(port);
26677732bc5SBill Paul 
267746c49fbSBill Paul 	if ((clnt = clntudp_create(addr,prognum,1,timeout,&sock)) == NULL) {
268746c49fbSBill Paul 		yp_error("%s: %s", inet_ntoa(addr->sin_addr),
269746c49fbSBill Paul 		  clnt_spcreateerror("failed to establish callback handle"));
270746c49fbSBill Paul 		return;
271746c49fbSBill Paul 	}
27277732bc5SBill Paul 
27377732bc5SBill Paul 	ypxfr_resp.status = rval;
27477732bc5SBill Paul 	ypxfr_resp.transid = transid;
27577732bc5SBill Paul 
276009790d1SBill Paul 	/* Turn the timeout off -- we don't want to block. */
277009790d1SBill Paul 	timeout.tv_sec = 0;
278009790d1SBill Paul 	if (clnt_control(clnt, CLSET_TIMEOUT, (char *)&timeout) == FALSE)
279009790d1SBill Paul 		yp_error("failed to set timeout on ypproc_xfr callback");
280009790d1SBill Paul 
281009790d1SBill Paul 	if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
282009790d1SBill Paul 		clnt_geterr(clnt, &err);
283009790d1SBill Paul 		if (err.re_status != RPC_SUCCESS &&
284009790d1SBill Paul 		    err.re_status != RPC_TIMEDOUT)
285009790d1SBill Paul 			yp_error("%s", clnt_sperror(clnt,
286009790d1SBill Paul 				"ypxfr callback failed"));
287009790d1SBill Paul 	}
28877732bc5SBill Paul 
28977732bc5SBill Paul 	clnt_destroy(clnt);
29077732bc5SBill Paul 	return;
29177732bc5SBill Paul }
29277732bc5SBill Paul 
293b2264be8SBill Paul #define YPXFR_RETURN(CODE) 						\
294b2264be8SBill Paul 	/* Order is important: send regular RPC reply, then callback */	\
295b2264be8SBill Paul 	result.xfrstat = CODE; 						\
296b2264be8SBill Paul 	svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result); \
297b2264be8SBill Paul 	ypxfr_callback(CODE,rqhost,argp->transid, 			\
298b2264be8SBill Paul 					argp->prog,argp->port); 	\
299b2264be8SBill Paul 	return(NULL);
300b2264be8SBill Paul 
301778c7b1cSBill Paul ypresp_xfr *
302778c7b1cSBill Paul ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
303778c7b1cSBill Paul {
304778c7b1cSBill Paul 	static ypresp_xfr  result;
30577732bc5SBill Paul 	struct sockaddr_in *rqhost;
30683203508SBill Paul 	ypresp_master *mres;
30783203508SBill Paul 	ypreq_nokey mreq;
308778c7b1cSBill Paul 
309009790d1SBill Paul 	result.transid = argp->transid;
310009790d1SBill Paul 	rqhost = svc_getcaller(rqstp->rq_xprt);
311009790d1SBill Paul 
31244519760SBill Paul #ifdef DB_CACHE
31344519760SBill Paul 	if (yp_access(argp->map_parms.map,
31444519760SBill Paul 			argp->map_parms.domain, (struct svc_req *)rqstp)) {
31544519760SBill Paul #else
316778c7b1cSBill Paul 	if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
31744519760SBill Paul #endif
31883203508SBill Paul 		YPXFR_RETURN(YPXFR_REFUSED)
319778c7b1cSBill Paul 	}
320778c7b1cSBill Paul 
32183203508SBill Paul 
322778c7b1cSBill Paul 	if (argp->map_parms.domain == NULL) {
32383203508SBill Paul 		YPXFR_RETURN(YPXFR_BADARGS)
324778c7b1cSBill Paul 	}
325778c7b1cSBill Paul 
326778c7b1cSBill Paul 	if (yp_validdomain(argp->map_parms.domain)) {
32783203508SBill Paul 		YPXFR_RETURN(YPXFR_NODOM)
32883203508SBill Paul 	}
32983203508SBill Paul 
33083203508SBill Paul 	/*
33183203508SBill Paul 	 * Determine the master host ourselves. The caller may
33283203508SBill Paul 	 * be up to no good. This has the side effect of verifying
33383203508SBill Paul 	 * that the requested map and domain actually exist.
33483203508SBill Paul 	 */
33583203508SBill Paul 
33683203508SBill Paul 	mreq.domain = argp->map_parms.domain;
33783203508SBill Paul 	mreq.map = argp->map_parms.map;
33883203508SBill Paul 
33983203508SBill Paul 	mres = ypproc_master_2_svc(&mreq, rqstp);
34083203508SBill Paul 
34183203508SBill Paul 	if (mres->stat != YP_TRUE) {
34283203508SBill Paul 		yp_error("couldn't find master for map %s@%s",
34383203508SBill Paul 						argp->map_parms.map,
34483203508SBill Paul 						argp->map_parms.domain);
34583203508SBill Paul 		yp_error("host at %s (%s) may be pulling my leg",
34683203508SBill Paul 						argp->map_parms.peer,
34783203508SBill Paul 						inet_ntoa(rqhost->sin_addr));
34883203508SBill Paul 		YPXFR_RETURN(YPXFR_REFUSED)
349778c7b1cSBill Paul 	}
350778c7b1cSBill Paul 
351778c7b1cSBill Paul 	switch(fork()) {
352778c7b1cSBill Paul 	case 0:
353778c7b1cSBill Paul 	{
354778c7b1cSBill Paul 		char g[11], t[11], p[11];
355778c7b1cSBill Paul 		char ypxfr_command[MAXPATHLEN + 2];
356778c7b1cSBill Paul 
357778c7b1cSBill Paul 		sprintf (ypxfr_command, "%sypxfr", _PATH_LIBEXEC);
358778c7b1cSBill Paul 		sprintf (t, "%u", argp->transid);
359778c7b1cSBill Paul 		sprintf (g, "%u", argp->prog);
360778c7b1cSBill Paul 		sprintf (p, "%u", argp->port);
361c6c5d975SBill Paul 		if (debug) {
36277732bc5SBill Paul 			close(0); close(1); close(2);
363c6c5d975SBill Paul 		}
36477732bc5SBill Paul 		if (strcmp(yp_dir, _PATH_YP)) {
36511504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
36611504a40SBill Paul 			"-d", argp->map_parms.domain,
36783203508SBill Paul 		      	"-h", mres->peer,
36811504a40SBill Paul 			"-p", yp_dir, "-C", t,
36911504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
37011504a40SBill Paul 			p, argp->map_parms.map,
37177732bc5SBill Paul 		      	NULL);
37277732bc5SBill Paul 		} else {
37311504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
37411504a40SBill Paul 			"-d", argp->map_parms.domain,
37583203508SBill Paul 		      	"-h", mres->peer,
37611504a40SBill Paul 			"-C", t,
37711504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
37811504a40SBill Paul 			p, argp->map_parms.map,
379778c7b1cSBill Paul 		      	NULL);
38077732bc5SBill Paul 		}
38177732bc5SBill Paul 		forked++;
382b2264be8SBill Paul 		yp_error("ypxfr execl(%s): %s", ypxfr_command, strerror(errno));
38383203508SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR)
38477732bc5SBill Paul 		break;
385778c7b1cSBill Paul 	}
386778c7b1cSBill Paul 	case -1:
387778c7b1cSBill Paul 		yp_error("ypxfr fork(): %s", strerror(errno));
38883203508SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR)
389778c7b1cSBill Paul 		break;
390778c7b1cSBill Paul 	default:
391009790d1SBill Paul 		result.xfrstat = YPXFR_SUCC;
39277732bc5SBill Paul 		children++;
39377732bc5SBill Paul 		forked = 0;
394778c7b1cSBill Paul 		break;
395778c7b1cSBill Paul 	}
396009790d1SBill Paul 
397009790d1SBill Paul 	return (&result);
398778c7b1cSBill Paul }
399b2264be8SBill Paul #undef YPXFR_RETURN
400778c7b1cSBill Paul 
401778c7b1cSBill Paul void *
402778c7b1cSBill Paul ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
403778c7b1cSBill Paul {
404778c7b1cSBill Paul 	static char * result;
405778c7b1cSBill Paul 	static char rval = 0;
406778c7b1cSBill Paul 
40744519760SBill Paul #ifdef DB_CACHE
40844519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp))
40944519760SBill Paul #else
410778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
41144519760SBill Paul #endif
412778c7b1cSBill Paul 		return (NULL);
413b2264be8SBill Paul #ifdef DB_CACHE
414b2264be8SBill Paul 	/* clear out the database cache */
415b2264be8SBill Paul 	yp_flush_all();
416b2264be8SBill Paul #endif
417f7f470a8SBill Paul 	/* Re-read the securenets database for the hell of it. */
418f7f470a8SBill Paul 	load_securenets();
419f7f470a8SBill Paul 
420778c7b1cSBill Paul 	result = &rval;
421778c7b1cSBill Paul 	return((void *) &result);
422778c7b1cSBill Paul }
423778c7b1cSBill Paul 
424778c7b1cSBill Paul /*
425778c7b1cSBill Paul  * For ypproc_all, we have to send a stream of ypresp_all structures
426778c7b1cSBill Paul  * via TCP, but the XDR filter generated from the yp.x protocol
427778c7b1cSBill Paul  * definition file only serializes one such structure. This means that
428778c7b1cSBill Paul  * to send the whole stream, you need a wrapper which feeds all the
429778c7b1cSBill Paul  * records into the underlying XDR routine until it hits an 'EOF.'
430778c7b1cSBill Paul  * But to use the wrapper, you have to violate the boundaries between
431778c7b1cSBill Paul  * RPC layers by calling svc_sendreply() directly from the ypproc_all
432778c7b1cSBill Paul  * service routine instead of letting the RPC dispatcher do it.
433778c7b1cSBill Paul  *
434778c7b1cSBill Paul  * Bleah.
435778c7b1cSBill Paul  */
436778c7b1cSBill Paul 
437778c7b1cSBill Paul /*
4384c69e7b9SBill Paul  * Custom XDR routine for serialzing results of ypproc_all: keep
4394c69e7b9SBill Paul  * reading from the database and spew until we run out of records
4404c69e7b9SBill Paul  * or encounter an error.
441778c7b1cSBill Paul  */
442778c7b1cSBill Paul static bool_t
443778c7b1cSBill Paul xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp)
444778c7b1cSBill Paul {
4454c69e7b9SBill Paul 	while (1) {
4464c69e7b9SBill Paul 		/* Get a record. */
4474c69e7b9SBill Paul 		if ((objp->ypresp_all_u.val.stat =
448180807d2SBill Paul 			yp_nextbykey(&objp->ypresp_all_u.val.key,
449180807d2SBill Paul 				     &objp->ypresp_all_u.val.val)) == YP_TRUE) {
4504c69e7b9SBill Paul 			objp->more = TRUE;
4514c69e7b9SBill Paul 		} else {
4524c69e7b9SBill Paul 			objp->more = FALSE;
4534c69e7b9SBill Paul 		}
4544c69e7b9SBill Paul 
4554c69e7b9SBill Paul 		/* Serialize. */
4564c69e7b9SBill Paul 		if (!xdr_ypresp_all(xdrs, objp))
457778c7b1cSBill Paul 			return(FALSE);
4584c69e7b9SBill Paul 		if (objp->more == FALSE)
4594c69e7b9SBill Paul 			return(TRUE);
4604c69e7b9SBill Paul 	}
461778c7b1cSBill Paul }
462778c7b1cSBill Paul 
463778c7b1cSBill Paul ypresp_all *
464778c7b1cSBill Paul ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
465778c7b1cSBill Paul {
466778c7b1cSBill Paul 	static ypresp_all  result;
467778c7b1cSBill Paul 
468778c7b1cSBill Paul 	/*
469778c7b1cSBill Paul 	 * Set this here so that the client will be forced to make
470778c7b1cSBill Paul 	 * at least one attempt to read from us even if all we're
471778c7b1cSBill Paul 	 * doing is returning an error.
472778c7b1cSBill Paul 	 */
473778c7b1cSBill Paul 	result.more = TRUE;
47411504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_len = 0;
47511504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_val = "";
476778c7b1cSBill Paul 
47744519760SBill Paul #ifdef DB_CACHE
47844519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
47944519760SBill Paul #else
480778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
48144519760SBill Paul #endif
482778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_YPERR;
483778c7b1cSBill Paul 		return (&result);
484778c7b1cSBill Paul 	}
485778c7b1cSBill Paul 
486778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
487778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_BADARGS;
488778c7b1cSBill Paul 		return (&result);
489778c7b1cSBill Paul 	}
490778c7b1cSBill Paul 
4914c69e7b9SBill Paul 	/*
4929c171de0SBill Paul 	 * XXX If we hit the child limit, fail the request.
4939c171de0SBill Paul 	 * If we don't, and the map is large, we could block for
4949c171de0SBill Paul 	 * a long time in the parent.
4959c171de0SBill Paul 	 */
4969c171de0SBill Paul 	if (children >= MAX_CHILDREN) {
4979c171de0SBill Paul 		result.ypresp_all_u.val.stat = YP_YPERR;
4989c171de0SBill Paul 		return(&result);
4999c171de0SBill Paul 	}
5009c171de0SBill Paul 
5019c171de0SBill Paul 	/*
5024c69e7b9SBill Paul 	 * The ypproc_all procedure can take a while to complete.
5034c69e7b9SBill Paul 	 * Best to handle it in a subprocess so the parent doesn't
5044c69e7b9SBill Paul 	 * block. (Is there a better way to do this? Maybe with
5054c69e7b9SBill Paul 	 * async socket I/O?)
5064c69e7b9SBill Paul 	 */
5074c69e7b9SBill Paul 	if (!debug && children < MAX_CHILDREN && fork()) {
5084c69e7b9SBill Paul 		children++;
5094c69e7b9SBill Paul 		forked = 0;
5104c69e7b9SBill Paul 		return (NULL);
5114c69e7b9SBill Paul 	} else {
5124c69e7b9SBill Paul 		forked++;
5134c69e7b9SBill Paul 	}
5144c69e7b9SBill Paul 
515180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain,
516180807d2SBill Paul 				&result.ypresp_all_u.val.key, 0) != YP_TRUE) {
517778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = yp_errno;
518778c7b1cSBill Paul 		return(&result);
519778c7b1cSBill Paul 	}
520778c7b1cSBill Paul 
521778c7b1cSBill Paul 	/* Kick off the actual data transfer. */
5224c69e7b9SBill Paul 	svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result);
5234c69e7b9SBill Paul 
524778c7b1cSBill Paul 	/*
525778c7b1cSBill Paul 	 * Returning NULL prevents the dispatcher from calling
526778c7b1cSBill Paul 	 * svc_sendreply() since we already did it.
527778c7b1cSBill Paul 	 */
528778c7b1cSBill Paul 	return (NULL);
529778c7b1cSBill Paul }
530778c7b1cSBill Paul 
531778c7b1cSBill Paul ypresp_master *
532778c7b1cSBill Paul ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
533778c7b1cSBill Paul {
534778c7b1cSBill Paul 	static ypresp_master  result;
535b2264be8SBill Paul 	static char ypvalbuf[YPMAXRECORD];
536180807d2SBill Paul 	keydat key = { master_sz, master_string };
537180807d2SBill Paul 	valdat val;
538778c7b1cSBill Paul 
53945da6d16SBill Paul 	result.peer = "";
54045da6d16SBill Paul 
54144519760SBill Paul #ifdef DB_CACHE
54244519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
54344519760SBill Paul #else
54444519760SBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
54544519760SBill Paul #endif
546778c7b1cSBill Paul 		result.stat = YP_YPERR;
547778c7b1cSBill Paul 		return(&result);
548778c7b1cSBill Paul 	}
549778c7b1cSBill Paul 
550778c7b1cSBill Paul 	if (argp->domain == NULL) {
551778c7b1cSBill Paul 		result.stat = YP_BADARGS;
552778c7b1cSBill Paul 		return (&result);
553778c7b1cSBill Paul 	}
554778c7b1cSBill Paul 
555180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) {
556180807d2SBill Paul 		result.stat = yp_errno;
557180807d2SBill Paul 		return(&result);
558180807d2SBill Paul 	}
559180807d2SBill Paul 
560b2264be8SBill Paul 	/*
561b2264be8SBill Paul 	 * Note that we copy the data retrieved from the database to
562b2264be8SBill Paul 	 * a private buffer and NUL terminate the buffer rather than
563b2264be8SBill Paul 	 * terminating the data in place. We do this because by stuffing
564b2264be8SBill Paul 	 * a '\0' into data.data, we will actually be corrupting memory
565b2264be8SBill Paul 	 * allocated by the DB package. This is a bad thing now that we
566b2264be8SBill Paul 	 * cache DB handles rather than closing the database immediately.
567b2264be8SBill Paul 	 */
568180807d2SBill Paul 	result.stat = yp_getbykey(&key, &val);
569180807d2SBill Paul 	if (result.stat == YP_TRUE) {
570180807d2SBill Paul 		bcopy((char *)val.valdat_val, (char *)&ypvalbuf,
571180807d2SBill Paul 						val.valdat_len);
572180807d2SBill Paul 		ypvalbuf[val.valdat_len] = '\0';
573b2264be8SBill Paul 		result.peer = (char *)&ypvalbuf;
574778c7b1cSBill Paul 	} else
575778c7b1cSBill Paul 		result.peer = "";
576778c7b1cSBill Paul 
577778c7b1cSBill Paul 	return (&result);
578778c7b1cSBill Paul }
579778c7b1cSBill Paul 
580778c7b1cSBill Paul ypresp_order *
581778c7b1cSBill Paul ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
582778c7b1cSBill Paul {
583778c7b1cSBill Paul 	static ypresp_order  result;
584180807d2SBill Paul 	keydat key = { order_sz, order_string };
585180807d2SBill Paul 	valdat val;
586778c7b1cSBill Paul 
58711504a40SBill Paul 	result.ordernum = 0;
58811504a40SBill Paul 
58944519760SBill Paul #ifdef DB_CACHE
59044519760SBill Paul 	if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) {
59144519760SBill Paul #else
59244519760SBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
59344519760SBill Paul #endif
594778c7b1cSBill Paul 		result.stat = YP_YPERR;
595778c7b1cSBill Paul 		return(&result);
596778c7b1cSBill Paul 	}
597778c7b1cSBill Paul 
598778c7b1cSBill Paul 	if (argp->domain == NULL) {
599778c7b1cSBill Paul 		result.stat = YP_BADARGS;
600778c7b1cSBill Paul 		return (&result);
601778c7b1cSBill Paul 	}
602778c7b1cSBill Paul 
603778c7b1cSBill Paul 	/*
604778c7b1cSBill Paul 	 * We could just check the timestamp on the map file,
605778c7b1cSBill Paul 	 * but that's a hack: we'll only know the last time the file
606778c7b1cSBill Paul 	 * was touched, not the last time the database contents were
607778c7b1cSBill Paul 	 * updated.
608778c7b1cSBill Paul 	 */
609778c7b1cSBill Paul 
610180807d2SBill Paul 	if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) {
611180807d2SBill Paul 		result.stat = yp_errno;
612180807d2SBill Paul 		return(&result);
613180807d2SBill Paul 	}
614180807d2SBill Paul 
615180807d2SBill Paul 	result.stat = yp_getbykey(&key, &val);
616180807d2SBill Paul 
617180807d2SBill Paul 	if (result.stat == YP_TRUE)
618180807d2SBill Paul 		result.ordernum = atoi((char *)val.valdat_val);
619778c7b1cSBill Paul 	else
620778c7b1cSBill Paul 		result.ordernum = 0;
621778c7b1cSBill Paul 
622778c7b1cSBill Paul 	return (&result);
623778c7b1cSBill Paul }
624778c7b1cSBill Paul 
625778c7b1cSBill Paul static void yp_maplist_free(yp_maplist)
626778c7b1cSBill Paul 	struct ypmaplist *yp_maplist;
627778c7b1cSBill Paul {
628778c7b1cSBill Paul 	register struct ypmaplist *next;
629778c7b1cSBill Paul 
630778c7b1cSBill Paul 	while(yp_maplist) {
631778c7b1cSBill Paul 		next = yp_maplist->next;
632778c7b1cSBill Paul 		free(yp_maplist->map);
633778c7b1cSBill Paul 		free(yp_maplist);
634778c7b1cSBill Paul 		yp_maplist = next;
635778c7b1cSBill Paul 	}
636778c7b1cSBill Paul 	return;
637778c7b1cSBill Paul }
638778c7b1cSBill Paul 
639778c7b1cSBill Paul static struct ypmaplist *yp_maplist_create(domain)
640778c7b1cSBill Paul 	const char *domain;
641778c7b1cSBill Paul {
642778c7b1cSBill Paul 	char yp_mapdir[MAXPATHLEN + 2];
643778c7b1cSBill Paul 	char yp_mapname[MAXPATHLEN + 2];
644778c7b1cSBill Paul 	struct ypmaplist *cur = NULL;
645778c7b1cSBill Paul 	struct ypmaplist *yp_maplist = NULL;
646778c7b1cSBill Paul 	DIR *dird;
647778c7b1cSBill Paul 	struct dirent *dirp;
648778c7b1cSBill Paul 	struct stat statbuf;
649778c7b1cSBill Paul 
650778c7b1cSBill Paul 	snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain);
651778c7b1cSBill Paul 
652778c7b1cSBill Paul 	if ((dird = opendir(yp_mapdir)) == NULL) {
653c0b36ac2SBill Paul 		yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno));
654778c7b1cSBill Paul 		return(NULL);
655778c7b1cSBill Paul 	}
656778c7b1cSBill Paul 
657778c7b1cSBill Paul 	while ((dirp = readdir(dird)) != NULL) {
658778c7b1cSBill Paul 		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) {
65911504a40SBill Paul 			snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",
66011504a40SBill Paul 							yp_mapdir,dirp->d_name);
66111504a40SBill Paul 			if (stat(yp_mapname, &statbuf) < 0 ||
66211504a40SBill Paul 						!S_ISREG(statbuf.st_mode))
663778c7b1cSBill Paul 				continue;
66411504a40SBill Paul 			if ((cur = (struct ypmaplist *)
6651fbdac93SBill Paul 				malloc(sizeof(struct ypmaplist))) == NULL) {
666778c7b1cSBill Paul 				yp_error("malloc() failed: %s",strerror(errno));
667778c7b1cSBill Paul 				closedir(dird);
668778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
669778c7b1cSBill Paul 				return(NULL);
670778c7b1cSBill Paul 			}
671778c7b1cSBill Paul 			if ((cur->map = (char *)strdup(dirp->d_name)) == NULL) {
672778c7b1cSBill Paul 				yp_error("strdup() failed: %s",strerror(errno));
673778c7b1cSBill Paul 				closedir(dird);
674778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
675778c7b1cSBill Paul 				return(NULL);
676778c7b1cSBill Paul 			}
677778c7b1cSBill Paul 			cur->next = yp_maplist;
678778c7b1cSBill Paul 			yp_maplist = cur;
679778c7b1cSBill Paul 			if (debug)
680778c7b1cSBill Paul 				yp_error("map: %s", yp_maplist->map);
681778c7b1cSBill Paul 		}
682778c7b1cSBill Paul 
683778c7b1cSBill Paul 	}
684778c7b1cSBill Paul 	closedir(dird);
685778c7b1cSBill Paul 	return(yp_maplist);
686778c7b1cSBill Paul }
687778c7b1cSBill Paul 
688778c7b1cSBill Paul ypresp_maplist *
689778c7b1cSBill Paul ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
690778c7b1cSBill Paul {
691b2264be8SBill Paul 	static ypresp_maplist  result = { 0, NULL };
69211504a40SBill Paul 
69344519760SBill Paul #ifdef DB_CACHE
69444519760SBill Paul 	if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) {
69544519760SBill Paul #else
696778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
69744519760SBill Paul #endif
698778c7b1cSBill Paul 		result.stat = YP_YPERR;
699778c7b1cSBill Paul 		return(&result);
700778c7b1cSBill Paul 	}
701778c7b1cSBill Paul 
702778c7b1cSBill Paul 	if (argp == NULL) {
703778c7b1cSBill Paul 		result.stat = YP_BADARGS;
704778c7b1cSBill Paul 		return (&result);
705778c7b1cSBill Paul 	}
706778c7b1cSBill Paul 
707778c7b1cSBill Paul 	if (yp_validdomain(*argp)) {
708778c7b1cSBill Paul 		result.stat = YP_NODOM;
709778c7b1cSBill Paul 		return (&result);
710778c7b1cSBill Paul 	}
711778c7b1cSBill Paul 
712778c7b1cSBill Paul 	/*
713778c7b1cSBill Paul 	 * We have to construct a linked list for the ypproc_maplist
714778c7b1cSBill Paul 	 * procedure using dynamically allocated memory. Since the XDR
715778c7b1cSBill Paul 	 * layer won't free this list for us, we have to deal with it
716778c7b1cSBill Paul 	 * ourselves. We call yp_maplist_free() first to free any
717778c7b1cSBill Paul 	 * previously allocated data we may have accumulated to insure
718778c7b1cSBill Paul 	 * that we have only one linked list in memory at any given
719778c7b1cSBill Paul 	 * time.
720778c7b1cSBill Paul 	 */
721778c7b1cSBill Paul 
722778c7b1cSBill Paul 	yp_maplist_free(result.maps);
723778c7b1cSBill Paul 
724778c7b1cSBill Paul 	if ((result.maps = yp_maplist_create(*argp)) == NULL) {
725778c7b1cSBill Paul 		yp_error("yp_maplist_create failed");
726778c7b1cSBill Paul 		result.stat = YP_YPERR;
727778c7b1cSBill Paul 		return(&result);
728778c7b1cSBill Paul 	} else
729778c7b1cSBill Paul 		result.stat = YP_TRUE;
730778c7b1cSBill Paul 
731778c7b1cSBill Paul 	return (&result);
732778c7b1cSBill Paul }
7339573c1f1SBill Paul 
7349573c1f1SBill Paul /*
7359573c1f1SBill Paul  * NIS v1 support. The nullproc, domain and domain_nonack
7369573c1f1SBill Paul  * functions from v1 are identical to those in v2, so all
7379573c1f1SBill Paul  * we have to do is hand off to them.
7389573c1f1SBill Paul  *
7399573c1f1SBill Paul  * The other functions are mostly just wrappers around their v2
7409573c1f1SBill Paul  * counterparts. For example, for the v1 'match' procedure, we
7419573c1f1SBill Paul  * crack open the argument structure, make a request to the v2
7429573c1f1SBill Paul  * 'match' function, repackage the data into a v1 response and
7439573c1f1SBill Paul  * then send it on its way.
7449573c1f1SBill Paul  *
7459573c1f1SBill Paul  * Note that we don't support the pull, push and get procedures.
7469573c1f1SBill Paul  * There's little documentation available to show what they
7479573c1f1SBill Paul  * do, and I suspect they're meant largely for map transfers
7489573c1f1SBill Paul  * between master and slave servers.
7499573c1f1SBill Paul  */
7509573c1f1SBill Paul 
7519573c1f1SBill Paul void *
7529573c1f1SBill Paul ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp)
7539573c1f1SBill Paul {
7549573c1f1SBill Paul 	return(ypproc_null_2_svc(argp, rqstp));
7559573c1f1SBill Paul }
7569573c1f1SBill Paul 
7579573c1f1SBill Paul bool_t *
7589573c1f1SBill Paul ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp)
7599573c1f1SBill Paul {
7609573c1f1SBill Paul 	return(ypproc_domain_2_svc(argp, rqstp));
7619573c1f1SBill Paul }
7629573c1f1SBill Paul 
7639573c1f1SBill Paul bool_t *
7649573c1f1SBill Paul ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp)
7659573c1f1SBill Paul {
7669573c1f1SBill Paul 	return (ypproc_domain_nonack_2_svc(argp, rqstp));
7679573c1f1SBill Paul }
7689573c1f1SBill Paul 
76911504a40SBill Paul /*
77011504a40SBill Paul  * the 'match' procedure sends a response of type YPRESP_VAL
77111504a40SBill Paul  */
7729573c1f1SBill Paul ypresponse *
7739573c1f1SBill Paul ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp)
7749573c1f1SBill Paul {
7759573c1f1SBill Paul 	static ypresponse  result;
7769573c1f1SBill Paul 	ypresp_val *v2_result;
7779573c1f1SBill Paul 
7789573c1f1SBill Paul 	result.yp_resptype = YPRESP_VAL;
77911504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_val = "";
78011504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_len = 0;
7819573c1f1SBill Paul 
7829573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
7839573c1f1SBill Paul 		result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS;
7849573c1f1SBill Paul 		return(&result);
7859573c1f1SBill Paul 	}
7869573c1f1SBill Paul 
7879573c1f1SBill Paul 	v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
7889573c1f1SBill Paul 	if (v2_result == NULL)
7899573c1f1SBill Paul 		return(NULL);
7909573c1f1SBill Paul 
7919573c1f1SBill Paul 	bcopy((char *)v2_result,
7929573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_valtype,
7939573c1f1SBill Paul 	      sizeof(ypresp_val));
7949573c1f1SBill Paul 
7959573c1f1SBill Paul 	return (&result);
7969573c1f1SBill Paul }
7979573c1f1SBill Paul 
79811504a40SBill Paul /*
79911504a40SBill Paul  * the 'first' procedure sends a response of type YPRESP_KEY_VAL
80011504a40SBill Paul  */
8019573c1f1SBill Paul ypresponse *
8029573c1f1SBill Paul ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp)
8039573c1f1SBill Paul {
8049573c1f1SBill Paul 	static ypresponse  result;
8059573c1f1SBill Paul 	ypresp_key_val *v2_result;
8069573c1f1SBill Paul 
8079573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
80811504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
80911504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
81011504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
81111504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
8129573c1f1SBill Paul 
8139573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_NOKEY) {
8149573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
8159573c1f1SBill Paul 		return(&result);
8169573c1f1SBill Paul 	}
8179573c1f1SBill Paul 
8189573c1f1SBill Paul 	v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8199573c1f1SBill Paul 									rqstp);
8209573c1f1SBill Paul 	if (v2_result == NULL)
8219573c1f1SBill Paul 		return(NULL);
8229573c1f1SBill Paul 
8239573c1f1SBill Paul 	bcopy((char *)v2_result,
8249573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
8259573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8269573c1f1SBill Paul 
8279573c1f1SBill Paul 	return (&result);
8289573c1f1SBill Paul }
8299573c1f1SBill Paul 
83011504a40SBill Paul /*
83111504a40SBill Paul  * the 'next' procedure sends a response of type YPRESP_KEY_VAL
83211504a40SBill Paul  */
8339573c1f1SBill Paul ypresponse *
8349573c1f1SBill Paul ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp)
8359573c1f1SBill Paul {
8369573c1f1SBill Paul 	static ypresponse  result;
8379573c1f1SBill Paul 	ypresp_key_val *v2_result;
8389573c1f1SBill Paul 
8399573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
84011504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
84111504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
84211504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
84311504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
8449573c1f1SBill Paul 
8459573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
8469573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
8479573c1f1SBill Paul 		return(&result);
8489573c1f1SBill Paul 	}
8499573c1f1SBill Paul 
8509573c1f1SBill Paul 	v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
8519573c1f1SBill Paul 	if (v2_result == NULL)
8529573c1f1SBill Paul 		return(NULL);
8539573c1f1SBill Paul 
8549573c1f1SBill Paul 	bcopy((char *)v2_result,
8559573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
8569573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8579573c1f1SBill Paul 
8589573c1f1SBill Paul 	return (&result);
8599573c1f1SBill Paul }
8609573c1f1SBill Paul 
86111504a40SBill Paul /*
86211504a40SBill Paul  * the 'poll' procedure sends a response of type YPRESP_MAP_PARMS
86311504a40SBill Paul  */
8649573c1f1SBill Paul ypresponse *
8659573c1f1SBill Paul ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp)
8669573c1f1SBill Paul {
8679573c1f1SBill Paul 	static ypresponse  result;
8689573c1f1SBill Paul 	ypresp_master *v2_result1;
8699573c1f1SBill Paul 	ypresp_order *v2_result2;
8709573c1f1SBill Paul 
8719573c1f1SBill Paul 	result.yp_resptype = YPRESP_MAP_PARMS;
8729573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.domain =
8739573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.domain;
8749573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.map =
8759573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.map;
8769573c1f1SBill Paul 	/*
8779573c1f1SBill Paul 	 * Hmm... there is no 'status' value in the
8789573c1f1SBill Paul 	 * yp_resp_map_parmstype structure, so I have to
8799573c1f1SBill Paul 	 * guess at what to do to indicate a failure.
8809573c1f1SBill Paul 	 * I hope this is right.
8819573c1f1SBill Paul 	 */
8829573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0;
8839573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer = "";
8849573c1f1SBill Paul 
8859573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_MAP_PARMS) {
8869573c1f1SBill Paul 		return(&result);
8879573c1f1SBill Paul 	}
8889573c1f1SBill Paul 
8899573c1f1SBill Paul 	v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8909573c1f1SBill Paul 									rqstp);
8919573c1f1SBill Paul 	if (v2_result1 == NULL)
8929573c1f1SBill Paul 		return(NULL);
8939573c1f1SBill Paul 
8949573c1f1SBill Paul 	if (v2_result1->stat != YP_TRUE) {
8959573c1f1SBill Paul 		return(&result);
8969573c1f1SBill Paul 	}
8979573c1f1SBill Paul 
8989573c1f1SBill Paul 	v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8999573c1f1SBill Paul 									rqstp);
9009573c1f1SBill Paul 	if (v2_result2 == NULL)
9019573c1f1SBill Paul 		return(NULL);
9029573c1f1SBill Paul 
9039573c1f1SBill Paul 	if (v2_result2->stat != YP_TRUE) {
9049573c1f1SBill Paul 		return(&result);
9059573c1f1SBill Paul 	}
9069573c1f1SBill Paul 
9079573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer =
9089573c1f1SBill Paul 		v2_result1->peer;
9099573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum =
9109573c1f1SBill Paul 		v2_result2->ordernum;
9119573c1f1SBill Paul 
9129573c1f1SBill Paul 	return (&result);
9139573c1f1SBill Paul }
9149573c1f1SBill Paul 
9159573c1f1SBill Paul ypresponse *
9169573c1f1SBill Paul ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp)
9179573c1f1SBill Paul {
9189573c1f1SBill Paul 	static ypresponse  result;
9199573c1f1SBill Paul 
9209573c1f1SBill Paul 	/*
9219573c1f1SBill Paul 	 * Not implemented.
9229573c1f1SBill Paul 	 */
9239573c1f1SBill Paul 
9249573c1f1SBill Paul 	return (&result);
9259573c1f1SBill Paul }
9269573c1f1SBill Paul 
9279573c1f1SBill Paul ypresponse *
9289573c1f1SBill Paul ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp)
9299573c1f1SBill Paul {
9309573c1f1SBill Paul 	static ypresponse  result;
9319573c1f1SBill Paul 
9329573c1f1SBill Paul 	/*
9339573c1f1SBill Paul 	 * Not implemented.
9349573c1f1SBill Paul 	 */
9359573c1f1SBill Paul 
9369573c1f1SBill Paul 	return (&result);
9379573c1f1SBill Paul }
9389573c1f1SBill Paul 
9399573c1f1SBill Paul ypresponse *
9409573c1f1SBill Paul ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp)
9419573c1f1SBill Paul {
9429573c1f1SBill Paul 	static ypresponse  result;
9439573c1f1SBill Paul 
9449573c1f1SBill Paul 	/*
9459573c1f1SBill Paul 	 * Not implemented.
9469573c1f1SBill Paul 	 */
9479573c1f1SBill Paul 
9489573c1f1SBill Paul 	return (&result);
9499573c1f1SBill Paul }
950