yp_server.c revision 14303
1/*
2 * Copyright (c) 1995
3 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34#include "yp_extern.h"
35#include "yp.h"
36#include <stdlib.h>
37#include <dirent.h>
38#include <sys/stat.h>
39#include <sys/param.h>
40#include <errno.h>
41#include <sys/types.h>
42#include <sys/socket.h>
43#include <netinet/in.h>
44#include <arpa/inet.h>
45#include <rpc/rpc.h>
46
47#ifndef lint
48static char rcsid[] = "$Id: yp_server.c,v 1.6 1996/02/26 02:34:26 wpaul Exp $";
49#endif /* not lint */
50
51int forked = 0;
52int children = 0;
53DB *spec_dbp = NULL;	/* Special global DB handle for ypproc_all. */
54
55/*
56 * NIS v2 support. This is where most of the action happens.
57 */
58
59void *
60ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
61{
62	static char * result;
63	static char rval = 0;
64
65	if (yp_access(NULL, (struct svc_req *)rqstp))
66		return(NULL);
67
68	result = &rval;
69
70	return((void *) &result);
71}
72
73bool_t *
74ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
75{
76	static bool_t  result;
77
78	if (yp_access(NULL, (struct svc_req *)rqstp)) {
79		result = FALSE;
80		return (&result);
81	}
82
83	if (argp == NULL || yp_validdomain(*argp))
84		result = FALSE;
85	else
86		result = TRUE;
87
88	return (&result);
89}
90
91bool_t *
92ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
93{
94	static bool_t  result;
95
96	if (yp_access(NULL, (struct svc_req *)rqstp))
97		return (NULL);
98
99	if (argp == NULL || yp_validdomain(*argp))
100		return (NULL);
101	else
102		result = TRUE;
103
104	return (&result);
105}
106
107ypresp_val *
108ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
109{
110	static ypresp_val  result;
111	DBT key, data;
112
113	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
114		result.stat = YP_YPERR;
115		return (&result);
116	}
117
118	if (argp->domain == NULL || argp->map == NULL) {
119		result.stat = YP_BADARGS;
120		return (&result);
121	}
122
123	if (yp_validdomain(argp->domain)) {
124		result.stat = YP_NODOM;
125		return(&result);
126	}
127
128	key.size = argp->key.keydat_len;
129	key.data = argp->key.keydat_val;
130
131	result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 0);
132
133	if (result.stat == YP_TRUE) {
134		result.val.valdat_len = data.size;
135		result.val.valdat_val = data.data;
136	}
137
138	/*
139	 * Do DNS lookups for hosts maps if database lookup failed.
140	 */
141
142	if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) {
143		char *rval = NULL;
144
145	/* DNS lookups can take time -- do them in a subprocess */
146
147		if (!debug && children < MAX_CHILDREN && fork()) {
148			children++;
149			forked = 0;
150			/*
151			 * Returning NULL here prevents svc_sendreply()
152			 * from being called by the parent. This is vital
153			 * since having both the parent and the child process
154			 * call it would confuse the client.
155			 */
156			return (NULL);
157		} else {
158			forked++;
159		}
160
161		if (debug)
162			yp_error("Doing DNS lookup of %.*s",
163			 	  argp->key.keydat_len,
164				  argp->key.keydat_val);
165
166		/* NUL terminate! NUL terminate!! NUL TERMINATE!!! */
167		argp->key.keydat_val[argp->key.keydat_len] = '\0';
168
169		if (!strcmp(argp->map, "hosts.byname"))
170			rval = yp_dnsname((char *)argp->key.keydat_val);
171		else if (!strcmp(argp->map, "hosts.byaddr"))
172			rval = yp_dnsaddr((const char *)argp->key.keydat_val);
173
174
175		if (rval) {
176			if (debug)
177				yp_error("DNS lookup successful. Result: %s", rval);
178			result.val.valdat_len = strlen(rval);
179			result.val.valdat_val = rval;
180			result.stat = YP_TRUE;
181		} else {
182			if (debug)
183				yp_error("DNS lookup failed.");
184			result.stat = YP_NOKEY;
185		}
186	}
187
188	return (&result);
189}
190
191ypresp_key_val *
192ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
193{
194	static ypresp_key_val  result;
195	DBT key, data;
196	DB *dbp;
197
198	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
199		result.stat = YP_YPERR;
200		return (&result);
201	}
202
203	if (argp->domain == NULL) {
204		result.stat = YP_BADARGS;
205		return (&result);
206	}
207
208	if (yp_validdomain(argp->domain)) {
209		result.stat = YP_NODOM;
210		return(&result);
211	}
212
213	if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
214		result.stat = yp_errno;
215		return(&result);
216	}
217
218	key.data = NULL;
219	key.size = 0;
220	result.stat = yp_first_record(dbp, &key, &data);
221	(void)(dbp->close)(dbp);
222
223	if (result.stat == YP_TRUE) {
224		result.key.keydat_len = key.size;
225		result.key.keydat_val = key.data;
226		result.val.valdat_len = data.size;
227		result.val.valdat_val = data.data;
228	}
229
230	return (&result);
231}
232
233ypresp_key_val *
234ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
235{
236	static ypresp_key_val  result;
237	DBT key, data;
238	DB *dbp;
239
240	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
241		result.stat = YP_YPERR;
242		return (&result);
243	}
244
245	if (argp->domain == NULL || argp->map == NULL) {
246		result.stat = YP_BADARGS;
247		return (&result);
248	}
249
250	if (yp_validdomain(argp->domain)) {
251		result.stat = YP_NODOM;
252		return(&result);
253	}
254
255	if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
256		result.stat = yp_errno;
257		return(&result);
258	}
259
260	key.size = argp->key.keydat_len;
261	key.data = argp->key.keydat_val;
262
263	result.stat = yp_next_record(dbp, &key, &data, 0);
264	(void)(dbp->close)(dbp);
265
266	if (result.stat == YP_TRUE) {
267		result.key.keydat_len = key.size;
268		result.key.keydat_val = key.data;
269		result.val.valdat_len = data.size;
270		result.val.valdat_val = data.data;
271	}
272
273	return (&result);
274}
275
276static void ypxfr_callback(rval,addr,transid,prognum,port)
277	ypxfrstat rval;
278	struct sockaddr_in *addr;
279	unsigned int transid;
280	unsigned int prognum;
281	unsigned long port;
282{
283	CLIENT *clnt;
284	int sock = RPC_ANYSOCK;
285	struct timeval timeout;
286	yppushresp_xfr ypxfr_resp;
287	struct rpc_err err;
288
289	timeout.tv_sec = 5;
290	timeout.tv_usec = 0;
291	addr->sin_port = htons(port);
292
293	if ((clnt = clntudp_create(addr, prognum, 1, timeout, &sock)) == NULL)
294		yp_error("%s", clnt_spcreateerror("failed to establish \
295callback handle"));
296
297	ypxfr_resp.status = rval;
298	ypxfr_resp.transid = transid;
299
300	/* Turn the timeout off -- we don't want to block. */
301	timeout.tv_sec = 0;
302	if (clnt_control(clnt, CLSET_TIMEOUT, (char *)&timeout) == FALSE)
303		yp_error("failed to set timeout on ypproc_xfr callback");
304
305	if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
306		clnt_geterr(clnt, &err);
307		if (err.re_status != RPC_SUCCESS &&
308		    err.re_status != RPC_TIMEDOUT)
309			yp_error("%s", clnt_sperror(clnt,
310				"ypxfr callback failed"));
311	}
312
313	clnt_destroy(clnt);
314	return;
315}
316
317ypresp_xfr *
318ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
319{
320	static ypresp_xfr  result;
321	struct sockaddr_in *rqhost;
322
323	result.transid = argp->transid;
324	rqhost = svc_getcaller(rqstp->rq_xprt);
325
326	if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
327		/* Order is important: send regular RPC reply, then callback */
328		result.xfrstat = YPXFR_REFUSED;
329		svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result);
330		ypxfr_callback(YPXFR_REFUSED,rqhost,argp->transid,
331			       argp->prog,argp->port);
332		return(NULL);
333	}
334
335	if (argp->map_parms.domain == NULL) {
336		result.xfrstat = YPXFR_BADARGS;
337		svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result);
338		ypxfr_callback(YPXFR_BADARGS,rqhost,argp->transid,
339			       argp->prog,argp->port);
340		return(NULL);
341	}
342
343	if (yp_validdomain(argp->map_parms.domain)) {
344		result.xfrstat = YPXFR_NODOM;
345		svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result);
346		ypxfr_callback(YPXFR_NODOM,rqhost,argp->transid,
347			       argp->prog,argp->port);
348		return(NULL);
349	}
350
351	switch(fork()) {
352	case 0:
353	{
354		char g[11], t[11], p[11];
355		char ypxfr_command[MAXPATHLEN + 2];
356
357		sprintf (ypxfr_command, "%sypxfr", _PATH_LIBEXEC);
358		sprintf (t, "%u", argp->transid);
359		sprintf (g, "%u", argp->prog);
360		sprintf (p, "%u", argp->port);
361		if (debug)
362			close(0); close(1); close(2);
363		if (strcmp(yp_dir, _PATH_YP)) {
364			execl(ypxfr_command, "ypxfr", "-d", argp->map_parms.domain,
365		      	"-h", argp->map_parms.peer, "-p", yp_dir, "-C", t,
366		      	g, inet_ntoa(rqhost->sin_addr), p, argp->map_parms.map,
367		      	NULL);
368		} else {
369			execl(ypxfr_command, "ypxfr", "-d", argp->map_parms.domain,
370		      	"-h", argp->map_parms.peer, "-C", t, g,
371		      	inet_ntoa(rqhost->sin_addr), p, argp->map_parms.map,
372		      	NULL);
373		}
374		forked++;
375		result.xfrstat = YPXFR_XFRERR;
376		yp_error("ypxfr execl(): %s", strerror(errno));
377		svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result);
378		ypxfr_callback(YPXFR_XFRERR,rqhost,argp->transid,
379			       argp->prog,argp->port);
380		return(NULL);
381		break;
382	}
383	case -1:
384		yp_error("ypxfr fork(): %s", strerror(errno));
385		result.xfrstat = YPXFR_XFRERR;
386		svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result);
387		ypxfr_callback(YPXFR_XFRERR,rqhost,argp->transid,
388			       argp->prog,argp->port);
389		return(NULL);
390		break;
391	default:
392		result.xfrstat = YPXFR_SUCC;
393		children++;
394		forked = 0;
395		break;
396	}
397
398	return (&result);
399}
400
401void *
402ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
403{
404	static char * result;
405	static char rval = 0;
406
407	/*
408	 * We don't have to do anything for ypproc_clear. Unlike
409	 * the SunOS ypserv, we don't hold out database descriptors
410	 * open forever.
411	 */
412	if (yp_access(NULL, (struct svc_req *)rqstp))
413		return (NULL);
414
415	/* Re-read the securenets database for the hell of it. */
416	load_securenets();
417
418	result = &rval;
419	return((void *) &result);
420}
421
422/*
423 * For ypproc_all, we have to send a stream of ypresp_all structures
424 * via TCP, but the XDR filter generated from the yp.x protocol
425 * definition file only serializes one such structure. This means that
426 * to send the whole stream, you need a wrapper which feeds all the
427 * records into the underlying XDR routine until it hits an 'EOF.'
428 * But to use the wrapper, you have to violate the boundaries between
429 * RPC layers by calling svc_sendreply() directly from the ypproc_all
430 * service routine instead of letting the RPC dispatcher do it.
431 *
432 * Bleah.
433 */
434
435/*
436 * Custom XDR routine for serialzing results of ypproc_all: keep
437 * reading from the database and spew until we run out of records
438 * or encounter an error.
439 */
440static bool_t
441xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp)
442{
443	DBT key, data;
444
445	while (1) {
446		/* Get a record. */
447		key.size = objp->ypresp_all_u.val.key.keydat_len;
448		key.data = objp->ypresp_all_u.val.key.keydat_val;
449
450		if ((objp->ypresp_all_u.val.stat =
451		    yp_next_record(spec_dbp,&key,&data,1)) == YP_TRUE) {
452			objp->ypresp_all_u.val.val.valdat_len = data.size;
453			objp->ypresp_all_u.val.val.valdat_val = data.data;
454			objp->ypresp_all_u.val.key.keydat_len = key.size;
455			objp->ypresp_all_u.val.key.keydat_val = key.data;
456			objp->more = TRUE;
457		} else {
458			objp->more = FALSE;
459		}
460
461		/* Serialize. */
462		if (!xdr_ypresp_all(xdrs, objp))
463			return(FALSE);
464		if (objp->more == FALSE)
465			return(TRUE);
466	}
467}
468
469ypresp_all *
470ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
471{
472	static ypresp_all  result;
473
474	/*
475	 * Set this here so that the client will be forced to make
476	 * at least one attempt to read from us even if all we're
477	 * doing is returning an error.
478	 */
479	result.more = TRUE;
480
481	if (yp_access(argp->map, (struct svc_req *)rqstp)) {
482		result.ypresp_all_u.val.stat = YP_YPERR;
483		return (&result);
484	}
485
486	if (argp->domain == NULL || argp->map == NULL) {
487		result.ypresp_all_u.val.stat = YP_BADARGS;
488		return (&result);
489	}
490
491	if (yp_validdomain(argp->domain)) {
492		result.ypresp_all_u.val.stat = YP_NODOM;
493		return(&result);
494	}
495
496	/*
497	 * The ypproc_all procedure can take a while to complete.
498	 * Best to handle it in a subprocess so the parent doesn't
499	 * block. We fork() here so we don't end up sharing a
500	 * DB file handle with the parent.
501	 */
502
503	if (!debug && children < MAX_CHILDREN && fork()) {
504		children++;
505		forked = 0;
506		return (NULL);
507	} else {
508		forked++;
509	}
510
511	if ((spec_dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
512		result.ypresp_all_u.val.stat = yp_errno;
513		return(&result);
514	}
515
516	/* Kick off the actual data transfer. */
517	svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result);
518
519	/* Close database when done. */
520	(void)(spec_dbp->close)(spec_dbp);
521
522	/*
523	 * Returning NULL prevents the dispatcher from calling
524	 * svc_sendreply() since we already did it.
525	 */
526	return (NULL);
527}
528
529ypresp_master *
530ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
531{
532	static ypresp_master  result;
533	DBT key,data;
534
535	result.peer = "";
536
537	if (yp_access(NULL, (struct svc_req *)rqstp)) {
538		result.stat = YP_YPERR;
539		return(&result);
540	}
541
542	if (argp->domain == NULL) {
543		result.stat = YP_BADARGS;
544		return (&result);
545	}
546
547	if (yp_validdomain(argp->domain)) {
548		result.stat = YP_NODOM;
549		return (&result);
550	}
551
552	key.data = "YP_MASTER_NAME";
553	key.size = sizeof("YP_MASTER_NAME") - 1;
554
555	result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1);
556
557	if (result.stat == YP_TRUE) {
558		result.peer = (char *)data.data;
559		result.peer[data.size] = '\0';
560	} else
561		result.peer = "";
562
563	return (&result);
564}
565
566ypresp_order *
567ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
568{
569	static ypresp_order  result;
570	DBT key,data;
571
572	if (yp_access(NULL, (struct svc_req *)rqstp)) {
573		result.stat = YP_YPERR;
574		return(&result);
575	}
576
577	if (argp->domain == NULL) {
578		result.stat = YP_BADARGS;
579		return (&result);
580	}
581
582	if (yp_validdomain(argp->domain)) {
583		result.stat = YP_NODOM;
584		return (&result);
585	}
586
587	/*
588	 * We could just check the timestamp on the map file,
589	 * but that's a hack: we'll only know the last time the file
590	 * was touched, not the last time the database contents were
591	 * updated.
592	 */
593	key.data = "YP_LAST_MODIFIED";
594	key.size = sizeof("YP_LAST_MODIFIED") - 1;
595
596	result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1);
597
598	if (result.stat == YP_TRUE)
599		result.ordernum = atoi((char *)data.data);
600	else
601		result.ordernum = 0;
602
603	return (&result);
604}
605
606static void yp_maplist_free(yp_maplist)
607	struct ypmaplist *yp_maplist;
608{
609	register struct ypmaplist *next;
610
611	while(yp_maplist) {
612		next = yp_maplist->next;
613		free(yp_maplist->map);
614		free(yp_maplist);
615		yp_maplist = next;
616	}
617	return;
618}
619
620static struct ypmaplist *yp_maplist_create(domain)
621	const char *domain;
622{
623	char yp_mapdir[MAXPATHLEN + 2];
624	char yp_mapname[MAXPATHLEN + 2];
625	struct ypmaplist *cur = NULL;
626	struct ypmaplist *yp_maplist = NULL;
627	DIR *dird;
628	struct dirent *dirp;
629	struct stat statbuf;
630
631	snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain);
632
633	if ((dird = opendir(yp_mapdir)) == NULL) {
634		yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno));
635		return(NULL);
636	}
637
638	while ((dirp = readdir(dird)) != NULL) {
639		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) {
640			snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",yp_mapdir,dirp->d_name);
641			if (stat(yp_mapname, &statbuf) < 0 || !S_ISREG(statbuf.st_mode))
642				continue;
643			if ((cur = (struct ypmaplist *)malloc(sizeof(struct ypmaplist))) < 0) {
644				yp_error("malloc() failed: %s", strerror(errno));
645				closedir(dird);
646				yp_maplist_free(yp_maplist);
647				return(NULL);
648			}
649			if ((cur->map = (char *)strdup(dirp->d_name)) == NULL) {
650				yp_error("strdup() failed: %s", strerror(errno));
651				closedir(dird);
652				yp_maplist_free(yp_maplist);
653				return(NULL);
654			}
655			cur->next = yp_maplist;
656			yp_maplist = cur;
657			if (debug)
658				yp_error("map: %s", yp_maplist->map);
659		}
660
661	}
662	closedir(dird);
663	return(yp_maplist);
664}
665
666ypresp_maplist *
667ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
668{
669	static ypresp_maplist  result;
670
671	if (yp_access(NULL, (struct svc_req *)rqstp)) {
672		result.stat = YP_YPERR;
673		return(&result);
674	}
675
676	if (argp == NULL) {
677		result.stat = YP_BADARGS;
678		return (&result);
679	}
680
681	if (yp_validdomain(*argp)) {
682		result.stat = YP_NODOM;
683		return (&result);
684	}
685
686	/*
687	 * We have to construct a linked list for the ypproc_maplist
688	 * procedure using dynamically allocated memory. Since the XDR
689	 * layer won't free this list for us, we have to deal with it
690	 * ourselves. We call yp_maplist_free() first to free any
691	 * previously allocated data we may have accumulated to insure
692	 * that we have only one linked list in memory at any given
693	 * time.
694	 */
695
696	yp_maplist_free(result.maps);
697
698	if ((result.maps = yp_maplist_create(*argp)) == NULL) {
699		yp_error("yp_maplist_create failed");
700		result.stat = YP_YPERR;
701		return(&result);
702	} else
703		result.stat = YP_TRUE;
704
705	return (&result);
706}
707
708/*
709 * NIS v1 support. The nullproc, domain and domain_nonack
710 * functions from v1 are identical to those in v2, so all
711 * we have to do is hand off to them.
712 *
713 * The other functions are mostly just wrappers around their v2
714 * counterparts. For example, for the v1 'match' procedure, we
715 * crack open the argument structure, make a request to the v2
716 * 'match' function, repackage the data into a v1 response and
717 * then send it on its way.
718 *
719 * Note that we don't support the pull, push and get procedures.
720 * There's little documentation available to show what they
721 * do, and I suspect they're meant largely for map transfers
722 * between master and slave servers.
723 */
724
725void *
726ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp)
727{
728	return(ypproc_null_2_svc(argp, rqstp));
729}
730
731bool_t *
732ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp)
733{
734	return(ypproc_domain_2_svc(argp, rqstp));
735}
736
737bool_t *
738ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp)
739{
740	return (ypproc_domain_nonack_2_svc(argp, rqstp));
741}
742
743ypresponse *
744ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp)
745{
746	static ypresponse  result;
747	ypresp_val *v2_result;
748
749	result.yp_resptype = YPRESP_VAL;
750
751	if (argp->yp_reqtype != YPREQ_KEY) {
752		result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS;
753		return(&result);
754	}
755
756	v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
757	if (v2_result == NULL)
758		return(NULL);
759
760	bcopy((char *)v2_result,
761	      (char *)&result.ypresponse_u.yp_resp_valtype,
762	      sizeof(ypresp_val));
763
764	return (&result);
765}
766
767ypresponse *
768ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp)
769{
770	static ypresponse  result;
771	ypresp_key_val *v2_result;
772
773	result.yp_resptype = YPRESP_KEY_VAL;
774
775	if (argp->yp_reqtype != YPREQ_NOKEY) {
776		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
777		return(&result);
778	}
779
780	v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype,
781									rqstp);
782	if (v2_result == NULL)
783		return(NULL);
784
785	bcopy((char *)v2_result,
786	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
787	      sizeof(ypresp_key_val));
788
789	return (&result);
790}
791
792ypresponse *
793ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp)
794{
795	static ypresponse  result;
796	ypresp_key_val *v2_result;
797
798	result.yp_resptype = YPRESP_KEY_VAL;
799
800	if (argp->yp_reqtype != YPREQ_KEY) {
801		result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS;
802		return(&result);
803	}
804
805	v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp);
806	if (v2_result == NULL)
807		return(NULL);
808
809	bcopy((char *)v2_result,
810	      (char *)&result.ypresponse_u.yp_resp_key_valtype,
811	      sizeof(ypresp_key_val));
812
813	return (&result);
814}
815
816ypresponse *
817ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp)
818{
819	static ypresponse  result;
820	ypresp_master *v2_result1;
821	ypresp_order *v2_result2;
822
823	result.yp_resptype = YPRESP_MAP_PARMS;
824	result.ypresponse_u.yp_resp_map_parmstype.domain =
825		argp->yprequest_u.yp_req_nokeytype.domain;
826	result.ypresponse_u.yp_resp_map_parmstype.map =
827		argp->yprequest_u.yp_req_nokeytype.map;
828	/*
829	 * Hmm... there is no 'status' value in the
830	 * yp_resp_map_parmstype structure, so I have to
831	 * guess at what to do to indicate a failure.
832	 * I hope this is right.
833	 */
834	result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0;
835	result.ypresponse_u.yp_resp_map_parmstype.peer = "";
836
837	if (argp->yp_reqtype != YPREQ_MAP_PARMS) {
838		return(&result);
839	}
840
841	v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype,
842									rqstp);
843	if (v2_result1 == NULL)
844		return(NULL);
845
846	if (v2_result1->stat != YP_TRUE) {
847		return(&result);
848	}
849
850	v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype,
851									rqstp);
852	if (v2_result2 == NULL)
853		return(NULL);
854
855	if (v2_result2->stat != YP_TRUE) {
856		return(&result);
857	}
858
859	result.ypresponse_u.yp_resp_map_parmstype.peer =
860		v2_result1->peer;
861	result.ypresponse_u.yp_resp_map_parmstype.ordernum =
862		v2_result2->ordernum;
863
864	return (&result);
865}
866
867ypresponse *
868ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp)
869{
870	static ypresponse  result;
871
872	/*
873	 * Not implemented.
874	 */
875
876	return (&result);
877}
878
879ypresponse *
880ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp)
881{
882	static ypresponse  result;
883
884	/*
885	 * Not implemented.
886	 */
887
888	return (&result);
889}
890
891ypresponse *
892ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp)
893{
894	static ypresponse  result;
895
896	/*
897	 * Not implemented.
898	 */
899
900	return (&result);
901}
902