xref: /freebsd/usr.sbin/ypserv/yp_server.c (revision 746c49fb53fa3098aa868f2ea491d115eb22f705)
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_extern.h"
35778c7b1cSBill Paul #include "yp.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
48746c49fbSBill Paul static const char rcsid[] = "$Id: yp_server.c,v 1.10 1996/05/31 16:01:51 wpaul Exp $";
49778c7b1cSBill Paul #endif /* not lint */
50778c7b1cSBill Paul 
51778c7b1cSBill Paul int forked = 0;
52778c7b1cSBill Paul int children = 0;
53778c7b1cSBill Paul DB *spec_dbp = NULL;	/* Special global DB handle for ypproc_all. */
54b2264be8SBill Paul char *master_string = "YP_MASTER_NAME";
55b2264be8SBill Paul char *order_string = "YP_LAST_MODIFIED";
56b2264be8SBill Paul 
579573c1f1SBill Paul /*
589573c1f1SBill Paul  * NIS v2 support. This is where most of the action happens.
599573c1f1SBill Paul  */
609573c1f1SBill Paul 
61778c7b1cSBill Paul void *
62778c7b1cSBill Paul ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
63778c7b1cSBill Paul {
64778c7b1cSBill Paul 	static char * result;
65778c7b1cSBill Paul 	static char rval = 0;
66778c7b1cSBill Paul 
67778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
68778c7b1cSBill Paul 		return(NULL);
69778c7b1cSBill Paul 
70778c7b1cSBill Paul 	result = &rval;
71778c7b1cSBill Paul 
72778c7b1cSBill Paul 	return((void *) &result);
73778c7b1cSBill Paul }
74778c7b1cSBill Paul 
75778c7b1cSBill Paul bool_t *
76778c7b1cSBill Paul ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
77778c7b1cSBill Paul {
78778c7b1cSBill Paul 	static bool_t  result;
79778c7b1cSBill Paul 
80778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
81778c7b1cSBill Paul 		result = FALSE;
82778c7b1cSBill Paul 		return (&result);
83778c7b1cSBill Paul 	}
84778c7b1cSBill Paul 
85778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
86778c7b1cSBill Paul 		result = FALSE;
87778c7b1cSBill Paul 	else
88778c7b1cSBill Paul 		result = TRUE;
89778c7b1cSBill Paul 
90778c7b1cSBill Paul 	return (&result);
91778c7b1cSBill Paul }
92778c7b1cSBill Paul 
93778c7b1cSBill Paul bool_t *
94778c7b1cSBill Paul ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
95778c7b1cSBill Paul {
96778c7b1cSBill Paul 	static bool_t  result;
97778c7b1cSBill Paul 
98778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
99778c7b1cSBill Paul 		return (NULL);
100778c7b1cSBill Paul 
101778c7b1cSBill Paul 	if (argp == NULL || yp_validdomain(*argp))
102778c7b1cSBill Paul 		return (NULL);
103778c7b1cSBill Paul 	else
104778c7b1cSBill Paul 		result = TRUE;
105778c7b1cSBill Paul 
106778c7b1cSBill Paul 	return (&result);
107778c7b1cSBill Paul }
108778c7b1cSBill Paul 
109778c7b1cSBill Paul ypresp_val *
110778c7b1cSBill Paul ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
111778c7b1cSBill Paul {
112778c7b1cSBill Paul 	static ypresp_val  result;
113778c7b1cSBill Paul 	DBT key, data;
114778c7b1cSBill Paul 
11511504a40SBill Paul 	result.val.valdat_val = "";
11611504a40SBill Paul 	result.val.valdat_len = 0;
11711504a40SBill Paul 
118778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
119778c7b1cSBill Paul 		result.stat = YP_YPERR;
120778c7b1cSBill Paul 		return (&result);
121778c7b1cSBill Paul 	}
122778c7b1cSBill Paul 
123778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
124778c7b1cSBill Paul 		result.stat = YP_BADARGS;
125778c7b1cSBill Paul 		return (&result);
126778c7b1cSBill Paul 	}
127778c7b1cSBill Paul 
128778c7b1cSBill Paul 	key.size = argp->key.keydat_len;
129778c7b1cSBill Paul 	key.data = argp->key.keydat_val;
130778c7b1cSBill Paul 
131b2264be8SBill Paul 	if ((result.stat = yp_get_record(argp->domain, argp->map,
132b2264be8SBill Paul 						&key, &data, 1)) == YP_TRUE) {
133778c7b1cSBill Paul 		result.val.valdat_len = data.size;
134778c7b1cSBill Paul 		result.val.valdat_val = data.data;
135778c7b1cSBill Paul 	}
136778c7b1cSBill Paul 
137778c7b1cSBill Paul 	/*
138778c7b1cSBill Paul 	 * Do DNS lookups for hosts maps if database lookup failed.
139778c7b1cSBill Paul 	 */
140778c7b1cSBill Paul 
141778c7b1cSBill Paul 	if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) {
14277732bc5SBill Paul 		char *rval = NULL;
143778c7b1cSBill Paul 
144778c7b1cSBill Paul 	/* DNS lookups can take time -- do them in a subprocess */
145778c7b1cSBill Paul 
146778c7b1cSBill Paul 		if (!debug && children < MAX_CHILDREN && fork()) {
147778c7b1cSBill Paul 			children++;
148778c7b1cSBill Paul 			forked = 0;
149778c7b1cSBill Paul 			/*
150778c7b1cSBill Paul 			 * Returning NULL here prevents svc_sendreply()
151778c7b1cSBill Paul 			 * from being called by the parent. This is vital
152778c7b1cSBill Paul 			 * since having both the parent and the child process
153778c7b1cSBill Paul 			 * call it would confuse the client.
154778c7b1cSBill Paul 			 */
155778c7b1cSBill Paul 			return (NULL);
156778c7b1cSBill Paul 		} else {
157778c7b1cSBill Paul 			forked++;
158778c7b1cSBill Paul 		}
159778c7b1cSBill Paul 
160778c7b1cSBill Paul 		if (debug)
161778c7b1cSBill Paul 			yp_error("Doing DNS lookup of %.*s",
162778c7b1cSBill Paul 			 	  argp->key.keydat_len,
163778c7b1cSBill Paul 				  argp->key.keydat_val);
164778c7b1cSBill Paul 
165778c7b1cSBill Paul 		/* NUL terminate! NUL terminate!! NUL TERMINATE!!! */
166778c7b1cSBill Paul 		argp->key.keydat_val[argp->key.keydat_len] = '\0';
167778c7b1cSBill Paul 
168778c7b1cSBill Paul 		if (!strcmp(argp->map, "hosts.byname"))
169778c7b1cSBill Paul 			rval = yp_dnsname((char *)argp->key.keydat_val);
170778c7b1cSBill Paul 		else if (!strcmp(argp->map, "hosts.byaddr"))
171778c7b1cSBill Paul 			rval = yp_dnsaddr((const char *)argp->key.keydat_val);
172778c7b1cSBill Paul 
173778c7b1cSBill Paul 
174778c7b1cSBill Paul 		if (rval) {
175778c7b1cSBill Paul 			if (debug)
17611504a40SBill Paul 				yp_error("DNS lookup successful. Result: %s",
17711504a40SBill Paul 									rval);
178778c7b1cSBill Paul 			result.val.valdat_len = strlen(rval);
179778c7b1cSBill Paul 			result.val.valdat_val = rval;
180778c7b1cSBill Paul 			result.stat = YP_TRUE;
181778c7b1cSBill Paul 		} else {
182778c7b1cSBill Paul 			if (debug)
183778c7b1cSBill Paul 				yp_error("DNS lookup failed.");
184778c7b1cSBill Paul 			result.stat = YP_NOKEY;
185778c7b1cSBill Paul 		}
186778c7b1cSBill Paul 	}
187778c7b1cSBill Paul 
188778c7b1cSBill Paul 	return (&result);
189778c7b1cSBill Paul }
190778c7b1cSBill Paul 
191778c7b1cSBill Paul ypresp_key_val *
192778c7b1cSBill Paul ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
193778c7b1cSBill Paul {
194778c7b1cSBill Paul 	static ypresp_key_val  result;
195778c7b1cSBill Paul 	DBT key, data;
196778c7b1cSBill Paul 	DB *dbp;
197778c7b1cSBill Paul 
19811504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
19911504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
20011504a40SBill Paul 
201778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
202778c7b1cSBill Paul 		result.stat = YP_YPERR;
203778c7b1cSBill Paul 		return (&result);
204778c7b1cSBill Paul 	}
205778c7b1cSBill Paul 
206778c7b1cSBill Paul 	if (argp->domain == NULL) {
207778c7b1cSBill Paul 		result.stat = YP_BADARGS;
208778c7b1cSBill Paul 		return (&result);
209778c7b1cSBill Paul 	}
210778c7b1cSBill Paul 
211b2264be8SBill Paul #ifdef DB_CACHE
212b2264be8SBill Paul 	if ((dbp = yp_open_db_cache(argp->domain, argp->map, NULL, 0)) == NULL) {
213b2264be8SBill Paul #else
214778c7b1cSBill Paul 	if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
215b2264be8SBill Paul #endif
216778c7b1cSBill Paul 		result.stat = yp_errno;
217778c7b1cSBill Paul 		return(&result);
218778c7b1cSBill Paul 	}
219778c7b1cSBill Paul 
220778c7b1cSBill Paul 	key.data = NULL;
221778c7b1cSBill Paul 	key.size = 0;
222778c7b1cSBill Paul 
223b2264be8SBill Paul 	if ((result.stat = yp_first_record(dbp, &key, &data, 0)) == YP_TRUE) {
224778c7b1cSBill Paul 		result.key.keydat_len = key.size;
225778c7b1cSBill Paul 		result.key.keydat_val = key.data;
226778c7b1cSBill Paul 		result.val.valdat_len = data.size;
227778c7b1cSBill Paul 		result.val.valdat_val = data.data;
228778c7b1cSBill Paul 	}
229b2264be8SBill Paul #ifndef DB_CACHE
230b2264be8SBill Paul 	(void)(dbp->close)(dbp);
231b2264be8SBill Paul #endif
232778c7b1cSBill Paul 	return (&result);
233778c7b1cSBill Paul }
234778c7b1cSBill Paul 
235778c7b1cSBill Paul ypresp_key_val *
236778c7b1cSBill Paul ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
237778c7b1cSBill Paul {
238778c7b1cSBill Paul 	static ypresp_key_val  result;
239778c7b1cSBill Paul 	DBT key, data;
240778c7b1cSBill Paul 	DB *dbp;
241778c7b1cSBill Paul 
24211504a40SBill Paul 	result.val.valdat_val = result.key.keydat_val = "";
24311504a40SBill Paul 	result.val.valdat_len = result.key.keydat_len = 0;
24411504a40SBill Paul 
245778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
246778c7b1cSBill Paul 		result.stat = YP_YPERR;
247778c7b1cSBill Paul 		return (&result);
248778c7b1cSBill Paul 	}
249778c7b1cSBill Paul 
250778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
251778c7b1cSBill Paul 		result.stat = YP_BADARGS;
252778c7b1cSBill Paul 		return (&result);
253778c7b1cSBill Paul 	}
254778c7b1cSBill Paul 
255b2264be8SBill Paul #ifdef DB_CACHE
256b2264be8SBill Paul 	if ((dbp = yp_open_db_cache(argp->domain, argp->map,
257b2264be8SBill Paul 					argp->key.keydat_val,
258b2264be8SBill Paul 					argp->key.keydat_len)) == NULL) {
259b2264be8SBill Paul #else
260778c7b1cSBill Paul 	if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
261b2264be8SBill Paul #endif
262778c7b1cSBill Paul 		result.stat = yp_errno;
263778c7b1cSBill Paul 		return(&result);
264778c7b1cSBill Paul 	}
265778c7b1cSBill Paul 
266778c7b1cSBill Paul 	key.size = argp->key.keydat_len;
267778c7b1cSBill Paul 	key.data = argp->key.keydat_val;
268778c7b1cSBill Paul 
269b2264be8SBill Paul 	if ((result.stat = yp_next_record(dbp, &key, &data,0,0)) == YP_TRUE) {
270778c7b1cSBill Paul 		result.key.keydat_len = key.size;
271778c7b1cSBill Paul 		result.key.keydat_val = key.data;
272778c7b1cSBill Paul 		result.val.valdat_len = data.size;
273778c7b1cSBill Paul 		result.val.valdat_val = data.data;
274778c7b1cSBill Paul 	}
275b2264be8SBill Paul #ifndef DB_CACHE
276b2264be8SBill Paul 	(void)(dbp->close)(dbp);
277b2264be8SBill Paul #endif
278778c7b1cSBill Paul 	return (&result);
279778c7b1cSBill Paul }
280778c7b1cSBill Paul 
28177732bc5SBill Paul static void ypxfr_callback(rval,addr,transid,prognum,port)
28277732bc5SBill Paul 	ypxfrstat rval;
28377732bc5SBill Paul 	struct sockaddr_in *addr;
28477732bc5SBill Paul 	unsigned int transid;
28577732bc5SBill Paul 	unsigned int prognum;
28677732bc5SBill Paul 	unsigned long port;
28777732bc5SBill Paul {
28877732bc5SBill Paul 	CLIENT *clnt;
28977732bc5SBill Paul 	int sock = RPC_ANYSOCK;
29077732bc5SBill Paul 	struct timeval timeout;
29177732bc5SBill Paul 	yppushresp_xfr ypxfr_resp;
292009790d1SBill Paul 	struct rpc_err err;
29377732bc5SBill Paul 
294009790d1SBill Paul 	timeout.tv_sec = 5;
29577732bc5SBill Paul 	timeout.tv_usec = 0;
29677732bc5SBill Paul 	addr->sin_port = htons(port);
29777732bc5SBill Paul 
298746c49fbSBill Paul 	if ((clnt = clntudp_create(addr,prognum,1,timeout,&sock)) == NULL) {
299746c49fbSBill Paul 		yp_error("%s: %s", inet_ntoa(addr->sin_addr),
300746c49fbSBill Paul 		    clnt_spcreateerror("failed to establish callback handle"));
301746c49fbSBill Paul 		return;
302746c49fbSBill Paul 	}
30377732bc5SBill Paul 
30477732bc5SBill Paul 	ypxfr_resp.status = rval;
30577732bc5SBill Paul 	ypxfr_resp.transid = transid;
30677732bc5SBill Paul 
307009790d1SBill Paul 	/* Turn the timeout off -- we don't want to block. */
308009790d1SBill Paul 	timeout.tv_sec = 0;
309009790d1SBill Paul 	if (clnt_control(clnt, CLSET_TIMEOUT, (char *)&timeout) == FALSE)
310009790d1SBill Paul 		yp_error("failed to set timeout on ypproc_xfr callback");
311009790d1SBill Paul 
312009790d1SBill Paul 	if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
313009790d1SBill Paul 		clnt_geterr(clnt, &err);
314009790d1SBill Paul 		if (err.re_status != RPC_SUCCESS &&
315009790d1SBill Paul 		    err.re_status != RPC_TIMEDOUT)
316009790d1SBill Paul 			yp_error("%s", clnt_sperror(clnt,
317009790d1SBill Paul 				"ypxfr callback failed"));
318009790d1SBill Paul 	}
31977732bc5SBill Paul 
32077732bc5SBill Paul 	clnt_destroy(clnt);
32177732bc5SBill Paul 	return;
32277732bc5SBill Paul }
32377732bc5SBill Paul 
324b2264be8SBill Paul #define YPXFR_RETURN(CODE) 						\
325b2264be8SBill Paul 	/* Order is important: send regular RPC reply, then callback */	\
326b2264be8SBill Paul 	result.xfrstat = CODE; 						\
327b2264be8SBill Paul 	svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result); \
328b2264be8SBill Paul 	ypxfr_callback(CODE,rqhost,argp->transid, 			\
329b2264be8SBill Paul 					argp->prog,argp->port); 	\
330b2264be8SBill Paul 	return(NULL);
331b2264be8SBill Paul 
332778c7b1cSBill Paul ypresp_xfr *
333778c7b1cSBill Paul ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
334778c7b1cSBill Paul {
335778c7b1cSBill Paul 	static ypresp_xfr  result;
33677732bc5SBill Paul 	struct sockaddr_in *rqhost;
337778c7b1cSBill Paul 
338009790d1SBill Paul 	result.transid = argp->transid;
339009790d1SBill Paul 	rqhost = svc_getcaller(rqstp->rq_xprt);
340009790d1SBill Paul 
341778c7b1cSBill Paul 	if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
342b2264be8SBill Paul 		YPXFR_RETURN(YPXFR_REFUSED);
343778c7b1cSBill Paul 	}
344778c7b1cSBill Paul 
345778c7b1cSBill Paul 	if (argp->map_parms.domain == NULL) {
346b2264be8SBill Paul 		YPXFR_RETURN(YPXFR_BADARGS);
347778c7b1cSBill Paul 	}
348778c7b1cSBill Paul 
349778c7b1cSBill Paul 	if (yp_validdomain(argp->map_parms.domain)) {
350b2264be8SBill Paul 		YPXFR_RETURN(YPXFR_NODOM);
351778c7b1cSBill Paul 	}
352778c7b1cSBill Paul 
353778c7b1cSBill Paul 	switch(fork()) {
354778c7b1cSBill Paul 	case 0:
355778c7b1cSBill Paul 	{
356778c7b1cSBill Paul 		char g[11], t[11], p[11];
357778c7b1cSBill Paul 		char ypxfr_command[MAXPATHLEN + 2];
358778c7b1cSBill Paul 
359778c7b1cSBill Paul 		sprintf (ypxfr_command, "%sypxfr", _PATH_LIBEXEC);
360778c7b1cSBill Paul 		sprintf (t, "%u", argp->transid);
361778c7b1cSBill Paul 		sprintf (g, "%u", argp->prog);
362778c7b1cSBill Paul 		sprintf (p, "%u", argp->port);
36377732bc5SBill Paul 		if (debug)
36477732bc5SBill Paul 			close(0); close(1); close(2);
36577732bc5SBill Paul 		if (strcmp(yp_dir, _PATH_YP)) {
36611504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
36711504a40SBill Paul 			"-d", argp->map_parms.domain,
36811504a40SBill Paul 		      	"-h", argp->map_parms.peer,
36911504a40SBill Paul 			"-p", yp_dir, "-C", t,
37011504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
37111504a40SBill Paul 			p, argp->map_parms.map,
37277732bc5SBill Paul 		      	NULL);
37377732bc5SBill Paul 		} else {
37411504a40SBill Paul 			execl(ypxfr_command, "ypxfr",
37511504a40SBill Paul 			"-d", argp->map_parms.domain,
37611504a40SBill Paul 		      	"-h", argp->map_parms.peer,
37711504a40SBill Paul 			"-C", t,
37811504a40SBill Paul 		      	g, inet_ntoa(rqhost->sin_addr),
37911504a40SBill Paul 			p, argp->map_parms.map,
380778c7b1cSBill Paul 		      	NULL);
38177732bc5SBill Paul 		}
38277732bc5SBill Paul 		forked++;
383b2264be8SBill Paul 		yp_error("ypxfr execl(%s): %s", ypxfr_command, strerror(errno));
384b2264be8SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR);
38577732bc5SBill Paul 		break;
386778c7b1cSBill Paul 	}
387778c7b1cSBill Paul 	case -1:
388778c7b1cSBill Paul 		yp_error("ypxfr fork(): %s", strerror(errno));
389b2264be8SBill Paul 		YPXFR_RETURN(YPXFR_XFRERR);
390778c7b1cSBill Paul 		break;
391778c7b1cSBill Paul 	default:
392009790d1SBill Paul 		result.xfrstat = YPXFR_SUCC;
39377732bc5SBill Paul 		children++;
39477732bc5SBill Paul 		forked = 0;
395778c7b1cSBill Paul 		break;
396778c7b1cSBill Paul 	}
397009790d1SBill Paul 
398009790d1SBill Paul 	return (&result);
399778c7b1cSBill Paul }
400b2264be8SBill Paul #undef YPXFR_RETURN
401778c7b1cSBill Paul 
402778c7b1cSBill Paul void *
403778c7b1cSBill Paul ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
404778c7b1cSBill Paul {
405778c7b1cSBill Paul 	static char * result;
406778c7b1cSBill Paul 	static char rval = 0;
407778c7b1cSBill Paul 
408778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp))
409778c7b1cSBill Paul 		return (NULL);
410b2264be8SBill Paul #ifdef DB_CACHE
411b2264be8SBill Paul 	/* clear out the database cache */
412b2264be8SBill Paul 	yp_flush_all();
413b2264be8SBill Paul #endif
414f7f470a8SBill Paul 	/* Re-read the securenets database for the hell of it. */
415f7f470a8SBill Paul 	load_securenets();
416f7f470a8SBill Paul 
417778c7b1cSBill Paul 	result = &rval;
418778c7b1cSBill Paul 	return((void *) &result);
419778c7b1cSBill Paul }
420778c7b1cSBill Paul 
421778c7b1cSBill Paul /*
422778c7b1cSBill Paul  * For ypproc_all, we have to send a stream of ypresp_all structures
423778c7b1cSBill Paul  * via TCP, but the XDR filter generated from the yp.x protocol
424778c7b1cSBill Paul  * definition file only serializes one such structure. This means that
425778c7b1cSBill Paul  * to send the whole stream, you need a wrapper which feeds all the
426778c7b1cSBill Paul  * records into the underlying XDR routine until it hits an 'EOF.'
427778c7b1cSBill Paul  * But to use the wrapper, you have to violate the boundaries between
428778c7b1cSBill Paul  * RPC layers by calling svc_sendreply() directly from the ypproc_all
429778c7b1cSBill Paul  * service routine instead of letting the RPC dispatcher do it.
430778c7b1cSBill Paul  *
431778c7b1cSBill Paul  * Bleah.
432778c7b1cSBill Paul  */
433778c7b1cSBill Paul 
434778c7b1cSBill Paul /*
435778c7b1cSBill Paul  * Custom XDR routine for serialzing results of ypproc_all: keep
436778c7b1cSBill Paul  * reading from the database and spew until we run out of records
437778c7b1cSBill Paul  * or encounter an error.
438778c7b1cSBill Paul  */
439778c7b1cSBill Paul static bool_t
440778c7b1cSBill Paul xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp)
441778c7b1cSBill Paul {
442b2264be8SBill Paul 	DBT key = { NULL, 0 } , data = { NULL, 0 };
443778c7b1cSBill Paul 
444778c7b1cSBill Paul 	while (1) {
445778c7b1cSBill Paul 		/* Get a record. */
446778c7b1cSBill Paul 		if ((objp->ypresp_all_u.val.stat =
447b2264be8SBill Paul 	    		yp_next_record(spec_dbp,&key,&data,1,0)) == YP_TRUE) {
448778c7b1cSBill Paul 			objp->ypresp_all_u.val.val.valdat_len = data.size;
449778c7b1cSBill Paul 			objp->ypresp_all_u.val.val.valdat_val = data.data;
450778c7b1cSBill Paul 			objp->ypresp_all_u.val.key.keydat_len = key.size;
451778c7b1cSBill Paul 			objp->ypresp_all_u.val.key.keydat_val = key.data;
452778c7b1cSBill Paul 			objp->more = TRUE;
453778c7b1cSBill Paul 		} else {
454778c7b1cSBill Paul 			objp->more = FALSE;
455778c7b1cSBill Paul 		}
456778c7b1cSBill Paul 
457778c7b1cSBill Paul 		/* Serialize. */
458778c7b1cSBill Paul 		if (!xdr_ypresp_all(xdrs, objp))
459778c7b1cSBill Paul 			return(FALSE);
460778c7b1cSBill Paul 		if (objp->more == FALSE)
461778c7b1cSBill Paul 			return(TRUE);
462778c7b1cSBill Paul 	}
463778c7b1cSBill Paul }
464778c7b1cSBill Paul 
465778c7b1cSBill Paul ypresp_all *
466778c7b1cSBill Paul ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
467778c7b1cSBill Paul {
468778c7b1cSBill Paul 	static ypresp_all  result;
469778c7b1cSBill Paul 
470778c7b1cSBill Paul 	/*
471778c7b1cSBill Paul 	 * Set this here so that the client will be forced to make
472778c7b1cSBill Paul 	 * at least one attempt to read from us even if all we're
473778c7b1cSBill Paul 	 * doing is returning an error.
474778c7b1cSBill Paul 	 */
475778c7b1cSBill Paul 	result.more = TRUE;
47611504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_len = 0;
47711504a40SBill Paul 	result.ypresp_all_u.val.key.keydat_val = "";
478778c7b1cSBill Paul 
479778c7b1cSBill Paul 	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
480778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_YPERR;
481778c7b1cSBill Paul 		return (&result);
482778c7b1cSBill Paul 	}
483778c7b1cSBill Paul 
484778c7b1cSBill Paul 	if (argp->domain == NULL || argp->map == NULL) {
485778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = YP_BADARGS;
486778c7b1cSBill Paul 		return (&result);
487778c7b1cSBill Paul 	}
488778c7b1cSBill Paul 
489778c7b1cSBill Paul 	/*
490778c7b1cSBill Paul 	 * The ypproc_all procedure can take a while to complete.
491778c7b1cSBill Paul 	 * Best to handle it in a subprocess so the parent doesn't
492b2264be8SBill Paul 	 * block. (Is there a better way to do this? Maybe with
493b2264be8SBill Paul 	 * async socket I/O?)
494778c7b1cSBill Paul 	 */
495778c7b1cSBill Paul 	if (!debug && children < MAX_CHILDREN && fork()) {
496778c7b1cSBill Paul 		children++;
497778c7b1cSBill Paul 		forked = 0;
498778c7b1cSBill Paul 		return (NULL);
499778c7b1cSBill Paul 	} else {
500778c7b1cSBill Paul 		forked++;
501778c7b1cSBill Paul 	}
502778c7b1cSBill Paul 
503b2264be8SBill Paul #ifndef DB_CACHE
504778c7b1cSBill Paul 	if ((spec_dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
505778c7b1cSBill Paul 		result.ypresp_all_u.val.stat = yp_errno;
506778c7b1cSBill Paul 		return(&result);
507778c7b1cSBill Paul 	}
508b2264be8SBill Paul #else
509b2264be8SBill Paul 	if ((spec_dbp = yp_open_db_cache(argp->domain, argp->map, NULL, 0)) == NULL) {
510b2264be8SBill Paul 		result.ypresp_all_u.val.stat = yp_errno;
511b2264be8SBill Paul 		return(&result);
512b2264be8SBill Paul 	}
513b2264be8SBill Paul #endif
514778c7b1cSBill Paul 
515778c7b1cSBill Paul 	/* Kick off the actual data transfer. */
516778c7b1cSBill Paul 	svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result);
517778c7b1cSBill Paul 
518b2264be8SBill Paul #ifndef DB_CACHE
519778c7b1cSBill Paul 	(void)(spec_dbp->close)(spec_dbp);
520b2264be8SBill Paul #endif
521778c7b1cSBill Paul 	/*
522778c7b1cSBill Paul 	 * Returning NULL prevents the dispatcher from calling
523778c7b1cSBill Paul 	 * svc_sendreply() since we already did it.
524778c7b1cSBill Paul 	 */
525778c7b1cSBill Paul 	return (NULL);
526778c7b1cSBill Paul }
527778c7b1cSBill Paul 
528778c7b1cSBill Paul ypresp_master *
529778c7b1cSBill Paul ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
530778c7b1cSBill Paul {
531778c7b1cSBill Paul 	static ypresp_master  result;
532b2264be8SBill Paul 	static char ypvalbuf[YPMAXRECORD];
533778c7b1cSBill Paul 	DBT key, data;
534778c7b1cSBill Paul 
53545da6d16SBill Paul 	result.peer = "";
53645da6d16SBill Paul 
537778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
538778c7b1cSBill Paul 		result.stat = YP_YPERR;
539778c7b1cSBill Paul 		return(&result);
540778c7b1cSBill Paul 	}
541778c7b1cSBill Paul 
542778c7b1cSBill Paul 	if (argp->domain == NULL) {
543778c7b1cSBill Paul 		result.stat = YP_BADARGS;
544778c7b1cSBill Paul 		return (&result);
545778c7b1cSBill Paul 	}
546778c7b1cSBill Paul 
547b2264be8SBill Paul 	key.data = master_string;
548b2264be8SBill Paul 	key.size = strlen(master_string);
549778c7b1cSBill Paul 
550b2264be8SBill Paul 	/*
551b2264be8SBill Paul 	 * Note that we copy the data retrieved from the database to
552b2264be8SBill Paul 	 * a private buffer and NUL terminate the buffer rather than
553b2264be8SBill Paul 	 * terminating the data in place. We do this because by stuffing
554b2264be8SBill Paul 	 * a '\0' into data.data, we will actually be corrupting memory
555b2264be8SBill Paul 	 * allocated by the DB package. This is a bad thing now that we
556b2264be8SBill Paul 	 * cache DB handles rather than closing the database immediately.
557b2264be8SBill Paul 	 */
558b2264be8SBill Paul 	if ((result.stat = yp_get_record(argp->domain, argp->map,
559b2264be8SBill Paul 						&key, &data, 1)) == YP_TRUE) {
560b2264be8SBill Paul 		bcopy((char *)data.data, (char *)&ypvalbuf, data.size);
561b2264be8SBill Paul 		ypvalbuf[data.size] = '\0';
562b2264be8SBill Paul 		result.peer = (char *)&ypvalbuf;
563778c7b1cSBill Paul 	} else
564778c7b1cSBill Paul 		result.peer = "";
565778c7b1cSBill Paul 
566778c7b1cSBill Paul 	return (&result);
567778c7b1cSBill Paul }
568778c7b1cSBill Paul 
569778c7b1cSBill Paul ypresp_order *
570778c7b1cSBill Paul ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
571778c7b1cSBill Paul {
572778c7b1cSBill Paul 	static ypresp_order  result;
573778c7b1cSBill Paul 	DBT key,data;
574778c7b1cSBill Paul 
57511504a40SBill Paul 	result.ordernum = 0;
57611504a40SBill Paul 
577778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
578778c7b1cSBill Paul 		result.stat = YP_YPERR;
579778c7b1cSBill Paul 		return(&result);
580778c7b1cSBill Paul 	}
581778c7b1cSBill Paul 
582778c7b1cSBill Paul 	if (argp->domain == NULL) {
583778c7b1cSBill Paul 		result.stat = YP_BADARGS;
584778c7b1cSBill Paul 		return (&result);
585778c7b1cSBill Paul 	}
586778c7b1cSBill Paul 
587778c7b1cSBill Paul 	/*
588778c7b1cSBill Paul 	 * We could just check the timestamp on the map file,
589778c7b1cSBill Paul 	 * but that's a hack: we'll only know the last time the file
590778c7b1cSBill Paul 	 * was touched, not the last time the database contents were
591778c7b1cSBill Paul 	 * updated.
592778c7b1cSBill Paul 	 */
593778c7b1cSBill Paul 
594b2264be8SBill Paul 	key.data = order_string;
595b2264be8SBill Paul 	key.size = strlen(order_string);
596778c7b1cSBill Paul 
597b2264be8SBill Paul 	if ((result.stat = yp_get_record(argp->domain, argp->map,
598b2264be8SBill Paul 						&key, &data, 1)) == YP_TRUE)
599778c7b1cSBill Paul 		result.ordernum = atoi((char *)data.data);
600778c7b1cSBill Paul 	else
601778c7b1cSBill Paul 		result.ordernum = 0;
602778c7b1cSBill Paul 
603b2264be8SBill Paul 
604778c7b1cSBill Paul 	return (&result);
605778c7b1cSBill Paul }
606778c7b1cSBill Paul 
607778c7b1cSBill Paul static void yp_maplist_free(yp_maplist)
608778c7b1cSBill Paul 	struct ypmaplist *yp_maplist;
609778c7b1cSBill Paul {
610778c7b1cSBill Paul 	register struct ypmaplist *next;
611778c7b1cSBill Paul 
612778c7b1cSBill Paul 	while(yp_maplist) {
613778c7b1cSBill Paul 		next = yp_maplist->next;
614778c7b1cSBill Paul 		free(yp_maplist->map);
615778c7b1cSBill Paul 		free(yp_maplist);
616778c7b1cSBill Paul 		yp_maplist = next;
617778c7b1cSBill Paul 	}
618778c7b1cSBill Paul 	return;
619778c7b1cSBill Paul }
620778c7b1cSBill Paul 
621778c7b1cSBill Paul static struct ypmaplist *yp_maplist_create(domain)
622778c7b1cSBill Paul 	const char *domain;
623778c7b1cSBill Paul {
624778c7b1cSBill Paul 	char yp_mapdir[MAXPATHLEN + 2];
625778c7b1cSBill Paul 	char yp_mapname[MAXPATHLEN + 2];
626778c7b1cSBill Paul 	struct ypmaplist *cur = NULL;
627778c7b1cSBill Paul 	struct ypmaplist *yp_maplist = NULL;
628778c7b1cSBill Paul 	DIR *dird;
629778c7b1cSBill Paul 	struct dirent *dirp;
630778c7b1cSBill Paul 	struct stat statbuf;
631778c7b1cSBill Paul 
632778c7b1cSBill Paul 	snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain);
633778c7b1cSBill Paul 
634778c7b1cSBill Paul 	if ((dird = opendir(yp_mapdir)) == NULL) {
635c0b36ac2SBill Paul 		yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno));
636778c7b1cSBill Paul 		return(NULL);
637778c7b1cSBill Paul 	}
638778c7b1cSBill Paul 
639778c7b1cSBill Paul 	while ((dirp = readdir(dird)) != NULL) {
640778c7b1cSBill Paul 		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) {
64111504a40SBill Paul 			snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",
64211504a40SBill Paul 							yp_mapdir,dirp->d_name);
64311504a40SBill Paul 			if (stat(yp_mapname, &statbuf) < 0 ||
64411504a40SBill Paul 						!S_ISREG(statbuf.st_mode))
645778c7b1cSBill Paul 				continue;
64611504a40SBill Paul 			if ((cur = (struct ypmaplist *)
6471fbdac93SBill Paul 				malloc(sizeof(struct ypmaplist))) == NULL) {
648778c7b1cSBill Paul 				yp_error("malloc() failed: %s",strerror(errno));
649778c7b1cSBill Paul 				closedir(dird);
650778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
651778c7b1cSBill Paul 				return(NULL);
652778c7b1cSBill Paul 			}
653778c7b1cSBill Paul 			if ((cur->map = (char *)strdup(dirp->d_name)) == NULL) {
654778c7b1cSBill Paul 				yp_error("strdup() failed: %s",strerror(errno));
655778c7b1cSBill Paul 				closedir(dird);
656778c7b1cSBill Paul 				yp_maplist_free(yp_maplist);
657778c7b1cSBill Paul 				return(NULL);
658778c7b1cSBill Paul 			}
659778c7b1cSBill Paul 			cur->next = yp_maplist;
660778c7b1cSBill Paul 			yp_maplist = cur;
661778c7b1cSBill Paul 			if (debug)
662778c7b1cSBill Paul 				yp_error("map: %s", yp_maplist->map);
663778c7b1cSBill Paul 		}
664778c7b1cSBill Paul 
665778c7b1cSBill Paul 	}
666778c7b1cSBill Paul 	closedir(dird);
667778c7b1cSBill Paul 	return(yp_maplist);
668778c7b1cSBill Paul }
669778c7b1cSBill Paul 
670778c7b1cSBill Paul ypresp_maplist *
671778c7b1cSBill Paul ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
672778c7b1cSBill Paul {
673b2264be8SBill Paul 	static ypresp_maplist  result = { 0, NULL };
67411504a40SBill Paul 
675778c7b1cSBill Paul 	if (yp_access(NULL, (struct svc_req *)rqstp)) {
676778c7b1cSBill Paul 		result.stat = YP_YPERR;
677778c7b1cSBill Paul 		return(&result);
678778c7b1cSBill Paul 	}
679778c7b1cSBill Paul 
680778c7b1cSBill Paul 	if (argp == NULL) {
681778c7b1cSBill Paul 		result.stat = YP_BADARGS;
682778c7b1cSBill Paul 		return (&result);
683778c7b1cSBill Paul 	}
684778c7b1cSBill Paul 
685778c7b1cSBill Paul 	if (yp_validdomain(*argp)) {
686778c7b1cSBill Paul 		result.stat = YP_NODOM;
687778c7b1cSBill Paul 		return (&result);
688778c7b1cSBill Paul 	}
689778c7b1cSBill Paul 
690778c7b1cSBill Paul 	/*
691778c7b1cSBill Paul 	 * We have to construct a linked list for the ypproc_maplist
692778c7b1cSBill Paul 	 * procedure using dynamically allocated memory. Since the XDR
693778c7b1cSBill Paul 	 * layer won't free this list for us, we have to deal with it
694778c7b1cSBill Paul 	 * ourselves. We call yp_maplist_free() first to free any
695778c7b1cSBill Paul 	 * previously allocated data we may have accumulated to insure
696778c7b1cSBill Paul 	 * that we have only one linked list in memory at any given
697778c7b1cSBill Paul 	 * time.
698778c7b1cSBill Paul 	 */
699778c7b1cSBill Paul 
700778c7b1cSBill Paul 	yp_maplist_free(result.maps);
701778c7b1cSBill Paul 
702778c7b1cSBill Paul 	if ((result.maps = yp_maplist_create(*argp)) == NULL) {
703778c7b1cSBill Paul 		yp_error("yp_maplist_create failed");
704778c7b1cSBill Paul 		result.stat = YP_YPERR;
705778c7b1cSBill Paul 		return(&result);
706778c7b1cSBill Paul 	} else
707778c7b1cSBill Paul 		result.stat = YP_TRUE;
708778c7b1cSBill Paul 
709778c7b1cSBill Paul 	return (&result);
710778c7b1cSBill Paul }
7119573c1f1SBill Paul 
7129573c1f1SBill Paul /*
7139573c1f1SBill Paul  * NIS v1 support. The nullproc, domain and domain_nonack
7149573c1f1SBill Paul  * functions from v1 are identical to those in v2, so all
7159573c1f1SBill Paul  * we have to do is hand off to them.
7169573c1f1SBill Paul  *
7179573c1f1SBill Paul  * The other functions are mostly just wrappers around their v2
7189573c1f1SBill Paul  * counterparts. For example, for the v1 'match' procedure, we
7199573c1f1SBill Paul  * crack open the argument structure, make a request to the v2
7209573c1f1SBill Paul  * 'match' function, repackage the data into a v1 response and
7219573c1f1SBill Paul  * then send it on its way.
7229573c1f1SBill Paul  *
7239573c1f1SBill Paul  * Note that we don't support the pull, push and get procedures.
7249573c1f1SBill Paul  * There's little documentation available to show what they
7259573c1f1SBill Paul  * do, and I suspect they're meant largely for map transfers
7269573c1f1SBill Paul  * between master and slave servers.
7279573c1f1SBill Paul  */
7289573c1f1SBill Paul 
7299573c1f1SBill Paul void *
7309573c1f1SBill Paul ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp)
7319573c1f1SBill Paul {
7329573c1f1SBill Paul 	return(ypproc_null_2_svc(argp, rqstp));
7339573c1f1SBill Paul }
7349573c1f1SBill Paul 
7359573c1f1SBill Paul bool_t *
7369573c1f1SBill Paul ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp)
7379573c1f1SBill Paul {
7389573c1f1SBill Paul 	return(ypproc_domain_2_svc(argp, rqstp));
7399573c1f1SBill Paul }
7409573c1f1SBill Paul 
7419573c1f1SBill Paul bool_t *
7429573c1f1SBill Paul ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp)
7439573c1f1SBill Paul {
7449573c1f1SBill Paul 	return (ypproc_domain_nonack_2_svc(argp, rqstp));
7459573c1f1SBill Paul }
7469573c1f1SBill Paul 
74711504a40SBill Paul /*
74811504a40SBill Paul  * the 'match' procedure sends a response of type YPRESP_VAL
74911504a40SBill Paul  */
7509573c1f1SBill Paul ypresponse *
7519573c1f1SBill Paul ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp)
7529573c1f1SBill Paul {
7539573c1f1SBill Paul 	static ypresponse  result;
7549573c1f1SBill Paul 	ypresp_val *v2_result;
7559573c1f1SBill Paul 
7569573c1f1SBill Paul 	result.yp_resptype = YPRESP_VAL;
75711504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_val = "";
75811504a40SBill Paul 	result.ypresponse_u.yp_resp_valtype.val.valdat_len = 0;
7599573c1f1SBill Paul 
7609573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
7619573c1f1SBill Paul 		result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS;
7629573c1f1SBill Paul 		return(&result);
7639573c1f1SBill Paul 	}
7649573c1f1SBill Paul 
7659573c1f1SBill Paul 	v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
7669573c1f1SBill Paul 	if (v2_result == NULL)
7679573c1f1SBill Paul 		return(NULL);
7689573c1f1SBill Paul 
7699573c1f1SBill Paul 	bcopy((char *)v2_result,
7709573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_valtype,
7719573c1f1SBill Paul 	      sizeof(ypresp_val));
7729573c1f1SBill Paul 
7739573c1f1SBill Paul 	return (&result);
7749573c1f1SBill Paul }
7759573c1f1SBill Paul 
77611504a40SBill Paul /*
77711504a40SBill Paul  * the 'first' procedure sends a response of type YPRESP_KEY_VAL
77811504a40SBill Paul  */
7799573c1f1SBill Paul ypresponse *
7809573c1f1SBill Paul ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp)
7819573c1f1SBill Paul {
7829573c1f1SBill Paul 	static ypresponse  result;
7839573c1f1SBill Paul 	ypresp_key_val *v2_result;
7849573c1f1SBill Paul 
7859573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
78611504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
78711504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
78811504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
78911504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
7909573c1f1SBill Paul 
7919573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_NOKEY) {
7929573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
7939573c1f1SBill Paul 		return(&result);
7949573c1f1SBill Paul 	}
7959573c1f1SBill Paul 
7969573c1f1SBill Paul 	v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype,
7979573c1f1SBill Paul 									rqstp);
7989573c1f1SBill Paul 	if (v2_result == NULL)
7999573c1f1SBill Paul 		return(NULL);
8009573c1f1SBill Paul 
8019573c1f1SBill Paul 	bcopy((char *)v2_result,
8029573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
8039573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8049573c1f1SBill Paul 
8059573c1f1SBill Paul 	return (&result);
8069573c1f1SBill Paul }
8079573c1f1SBill Paul 
80811504a40SBill Paul /*
80911504a40SBill Paul  * the 'next' procedure sends a response of type YPRESP_KEY_VAL
81011504a40SBill Paul  */
8119573c1f1SBill Paul ypresponse *
8129573c1f1SBill Paul ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp)
8139573c1f1SBill Paul {
8149573c1f1SBill Paul 	static ypresponse  result;
8159573c1f1SBill Paul 	ypresp_key_val *v2_result;
8169573c1f1SBill Paul 
8179573c1f1SBill Paul 	result.yp_resptype = YPRESP_KEY_VAL;
81811504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_val =
81911504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = "";
82011504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.val.valdat_len =
82111504a40SBill Paul 	result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0;
8229573c1f1SBill Paul 
8239573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_KEY) {
8249573c1f1SBill Paul 		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
8259573c1f1SBill Paul 		return(&result);
8269573c1f1SBill Paul 	}
8279573c1f1SBill Paul 
8289573c1f1SBill Paul 	v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
8299573c1f1SBill Paul 	if (v2_result == NULL)
8309573c1f1SBill Paul 		return(NULL);
8319573c1f1SBill Paul 
8329573c1f1SBill Paul 	bcopy((char *)v2_result,
8339573c1f1SBill Paul 	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
8349573c1f1SBill Paul 	      sizeof(ypresp_key_val));
8359573c1f1SBill Paul 
8369573c1f1SBill Paul 	return (&result);
8379573c1f1SBill Paul }
8389573c1f1SBill Paul 
83911504a40SBill Paul /*
84011504a40SBill Paul  * the 'poll' procedure sends a response of type YPRESP_MAP_PARMS
84111504a40SBill Paul  */
8429573c1f1SBill Paul ypresponse *
8439573c1f1SBill Paul ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp)
8449573c1f1SBill Paul {
8459573c1f1SBill Paul 	static ypresponse  result;
8469573c1f1SBill Paul 	ypresp_master *v2_result1;
8479573c1f1SBill Paul 	ypresp_order *v2_result2;
8489573c1f1SBill Paul 
8499573c1f1SBill Paul 	result.yp_resptype = YPRESP_MAP_PARMS;
8509573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.domain =
8519573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.domain;
8529573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.map =
8539573c1f1SBill Paul 		argp->yprequest_u.yp_req_nokeytype.map;
8549573c1f1SBill Paul 	/*
8559573c1f1SBill Paul 	 * Hmm... there is no 'status' value in the
8569573c1f1SBill Paul 	 * yp_resp_map_parmstype structure, so I have to
8579573c1f1SBill Paul 	 * guess at what to do to indicate a failure.
8589573c1f1SBill Paul 	 * I hope this is right.
8599573c1f1SBill Paul 	 */
8609573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0;
8619573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer = "";
8629573c1f1SBill Paul 
8639573c1f1SBill Paul 	if (argp->yp_reqtype != YPREQ_MAP_PARMS) {
8649573c1f1SBill Paul 		return(&result);
8659573c1f1SBill Paul 	}
8669573c1f1SBill Paul 
8679573c1f1SBill Paul 	v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8689573c1f1SBill Paul 									rqstp);
8699573c1f1SBill Paul 	if (v2_result1 == NULL)
8709573c1f1SBill Paul 		return(NULL);
8719573c1f1SBill Paul 
8729573c1f1SBill Paul 	if (v2_result1->stat != YP_TRUE) {
8739573c1f1SBill Paul 		return(&result);
8749573c1f1SBill Paul 	}
8759573c1f1SBill Paul 
8769573c1f1SBill Paul 	v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype,
8779573c1f1SBill Paul 									rqstp);
8789573c1f1SBill Paul 	if (v2_result2 == NULL)
8799573c1f1SBill Paul 		return(NULL);
8809573c1f1SBill Paul 
8819573c1f1SBill Paul 	if (v2_result2->stat != YP_TRUE) {
8829573c1f1SBill Paul 		return(&result);
8839573c1f1SBill Paul 	}
8849573c1f1SBill Paul 
8859573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.peer =
8869573c1f1SBill Paul 		v2_result1->peer;
8879573c1f1SBill Paul 	result.ypresponse_u.yp_resp_map_parmstype.ordernum =
8889573c1f1SBill Paul 		v2_result2->ordernum;
8899573c1f1SBill Paul 
8909573c1f1SBill Paul 	return (&result);
8919573c1f1SBill Paul }
8929573c1f1SBill Paul 
8939573c1f1SBill Paul ypresponse *
8949573c1f1SBill Paul ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp)
8959573c1f1SBill Paul {
8969573c1f1SBill Paul 	static ypresponse  result;
8979573c1f1SBill Paul 
8989573c1f1SBill Paul 	/*
8999573c1f1SBill Paul 	 * Not implemented.
9009573c1f1SBill Paul 	 */
9019573c1f1SBill Paul 
9029573c1f1SBill Paul 	return (&result);
9039573c1f1SBill Paul }
9049573c1f1SBill Paul 
9059573c1f1SBill Paul ypresponse *
9069573c1f1SBill Paul ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp)
9079573c1f1SBill Paul {
9089573c1f1SBill Paul 	static ypresponse  result;
9099573c1f1SBill Paul 
9109573c1f1SBill Paul 	/*
9119573c1f1SBill Paul 	 * Not implemented.
9129573c1f1SBill Paul 	 */
9139573c1f1SBill Paul 
9149573c1f1SBill Paul 	return (&result);
9159573c1f1SBill Paul }
9169573c1f1SBill Paul 
9179573c1f1SBill Paul ypresponse *
9189573c1f1SBill Paul ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp)
9199573c1f1SBill Paul {
9209573c1f1SBill Paul 	static ypresponse  result;
9219573c1f1SBill Paul 
9229573c1f1SBill Paul 	/*
9239573c1f1SBill Paul 	 * Not implemented.
9249573c1f1SBill Paul 	 */
9259573c1f1SBill Paul 
9269573c1f1SBill Paul 	return (&result);
9279573c1f1SBill Paul }
928