xref: /netbsd/usr.sbin/rpcbind/rpcb_svc_4.c (revision 3e9c5584)
1*3e9c5584Schristos /*	$NetBSD: rpcb_svc_4.c,v 1.9 2019/01/03 19:04:21 christos Exp $	*/
2df898ddbSchristos /* $FreeBSD: head/usr.sbin/rpcbind/rpcb_svc_4.c 258564 2013-11-25 16:44:02Z hrs $ */
3d687de29Sfvdl 
4df898ddbSchristos /*-
5df898ddbSchristos  * Copyright (c) 2009, Sun Microsystems, Inc.
6df898ddbSchristos  * All rights reserved.
7d687de29Sfvdl  *
8df898ddbSchristos  * Redistribution and use in source and binary forms, with or without
9df898ddbSchristos  * modification, are permitted provided that the following conditions are met:
10df898ddbSchristos  * - Redistributions of source code must retain the above copyright notice,
11df898ddbSchristos  *   this list of conditions and the following disclaimer.
12df898ddbSchristos  * - Redistributions in binary form must reproduce the above copyright notice,
13df898ddbSchristos  *   this list of conditions and the following disclaimer in the documentation
14df898ddbSchristos  *   and/or other materials provided with the distribution.
15df898ddbSchristos  * - Neither the name of Sun Microsystems, Inc. nor the names of its
16df898ddbSchristos  *   contributors may be used to endorse or promote products derived
17df898ddbSchristos  *   from this software without specific prior written permission.
18d687de29Sfvdl  *
19df898ddbSchristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20df898ddbSchristos  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21df898ddbSchristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22df898ddbSchristos  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23df898ddbSchristos  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24df898ddbSchristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25df898ddbSchristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26df898ddbSchristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27df898ddbSchristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28df898ddbSchristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29df898ddbSchristos  * POSSIBILITY OF SUCH DAMAGE.
30d687de29Sfvdl  */
31d687de29Sfvdl /*
32d687de29Sfvdl  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
33d687de29Sfvdl  */
34d687de29Sfvdl 
35d687de29Sfvdl /* #ident	"@(#)rpcb_svc_4.c	1.8	93/07/05 SMI" */
36d687de29Sfvdl 
37d687de29Sfvdl /*
38d687de29Sfvdl  * rpcb_svc_4.c
39d687de29Sfvdl  * The server procedure for the version 4 rpcbind.
40d687de29Sfvdl  *
41d687de29Sfvdl  */
42d687de29Sfvdl 
43d687de29Sfvdl #include <sys/types.h>
44d687de29Sfvdl #include <sys/stat.h>
45d687de29Sfvdl #include <rpc/rpc.h>
46d687de29Sfvdl #include <stdio.h>
47d687de29Sfvdl #include <unistd.h>
48d687de29Sfvdl #include <netconfig.h>
49d687de29Sfvdl #include <syslog.h>
50d687de29Sfvdl #include <string.h>
51d687de29Sfvdl #include <stdlib.h>
52d687de29Sfvdl #include "rpcbind.h"
53d687de29Sfvdl 
54de327a01Schristos static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
55de327a01Schristos     rpcvers_t);
56de327a01Schristos static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *,
57de327a01Schristos     rpcvers_t);
58de327a01Schristos static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *,
59de327a01Schristos     rpcvers_t);
60de327a01Schristos static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
61de327a01Schristos static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
62de327a01Schristos     rpcvers_t);
63d687de29Sfvdl 
64d687de29Sfvdl /*
65d687de29Sfvdl  * Called by svc_getreqset. There is a separate server handle for
66d687de29Sfvdl  * every transport that it waits on.
67d687de29Sfvdl  */
68d687de29Sfvdl void
rpcb_service_4(struct svc_req * rqstp,SVCXPRT * transp)69d687de29Sfvdl rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
70d687de29Sfvdl {
71d687de29Sfvdl 	union {
72d687de29Sfvdl 		rpcb rpcbproc_set_4_arg;
73d687de29Sfvdl 		rpcb rpcbproc_unset_4_arg;
74d687de29Sfvdl 		rpcb rpcbproc_getaddr_4_local_arg;
75d687de29Sfvdl 		char *rpcbproc_uaddr2taddr_4_arg;
76d687de29Sfvdl 		struct netbuf rpcbproc_taddr2uaddr_4_arg;
77d687de29Sfvdl 	} argument;
78d687de29Sfvdl 	char *result;
79d687de29Sfvdl 	xdrproc_t xdr_argument, xdr_result;
80de327a01Schristos 	void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
81d687de29Sfvdl 
82d687de29Sfvdl 	rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
83d687de29Sfvdl 
84d687de29Sfvdl 	switch (rqstp->rq_proc) {
85d687de29Sfvdl 	case NULLPROC:
86d687de29Sfvdl 		/*
87d687de29Sfvdl 		 * Null proc call
88d687de29Sfvdl 		 */
89d687de29Sfvdl #ifdef RPCBIND_DEBUG
90d687de29Sfvdl 		if (debugging)
91d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_NULL\n");
92d687de29Sfvdl #endif
93d687de29Sfvdl 		check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
944a1b3429Splunky 		(void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
95d687de29Sfvdl 		return;
96d687de29Sfvdl 
97d687de29Sfvdl 	case RPCBPROC_SET:
98d687de29Sfvdl 		/*
99d687de29Sfvdl 		 * Check to see whether the message came from
100d687de29Sfvdl 		 * loopback transports (for security reasons)
101d687de29Sfvdl 		 */
102d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_rpcb;
103d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_bool;
104d687de29Sfvdl 		local = rpcbproc_set_com;
105d687de29Sfvdl 		break;
106d687de29Sfvdl 
107d687de29Sfvdl 	case RPCBPROC_UNSET:
108d687de29Sfvdl 		/*
109d687de29Sfvdl 		 * Check to see whether the message came from
110d687de29Sfvdl 		 * loopback transports (for security reasons)
111d687de29Sfvdl 		 */
112d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_rpcb;
113d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_bool;
114d687de29Sfvdl 		local = rpcbproc_unset_com;
115d687de29Sfvdl 		break;
116d687de29Sfvdl 
117d687de29Sfvdl 	case RPCBPROC_GETADDR:
118d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_rpcb;
119d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_wrapstring;
120d687de29Sfvdl 		local = rpcbproc_getaddr_4_local;
121d687de29Sfvdl 		break;
122d687de29Sfvdl 
123d687de29Sfvdl 	case RPCBPROC_GETVERSADDR:
124d687de29Sfvdl #ifdef RPCBIND_DEBUG
125d687de29Sfvdl 		if (debugging)
126d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
127d687de29Sfvdl #endif
128d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_rpcb;
129d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_wrapstring;
130d687de29Sfvdl 		local = rpcbproc_getversaddr_4_local;
131d687de29Sfvdl 		break;
132d687de29Sfvdl 
133d687de29Sfvdl 	case RPCBPROC_DUMP:
134d687de29Sfvdl #ifdef RPCBIND_DEBUG
135d687de29Sfvdl 		if (debugging)
136d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_DUMP\n");
137d687de29Sfvdl #endif
138d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_void;
139d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
140d687de29Sfvdl 		local = rpcbproc_dump_4_local;
141d687de29Sfvdl 		break;
142d687de29Sfvdl 
143d687de29Sfvdl 	case RPCBPROC_INDIRECT:
144d687de29Sfvdl #ifdef RPCBIND_DEBUG
145d687de29Sfvdl 		if (debugging)
146d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_INDIRECT\n");
147d687de29Sfvdl #endif
148d687de29Sfvdl 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
149d687de29Sfvdl 		return;
150d687de29Sfvdl 
151d687de29Sfvdl /*	case RPCBPROC_CALLIT: */
152d687de29Sfvdl 	case RPCBPROC_BCAST:
153d687de29Sfvdl #ifdef RPCBIND_DEBUG
154d687de29Sfvdl 		if (debugging)
155d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_BCAST\n");
156d687de29Sfvdl #endif
157d687de29Sfvdl 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
158d687de29Sfvdl 		return;
159d687de29Sfvdl 
160d687de29Sfvdl 	case RPCBPROC_GETTIME:
161d687de29Sfvdl #ifdef RPCBIND_DEBUG
162d687de29Sfvdl 		if (debugging)
163d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_GETTIME\n");
164d687de29Sfvdl #endif
165d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_void;
166d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_u_long;
167d687de29Sfvdl 		local = rpcbproc_gettime_com;
168d687de29Sfvdl 		break;
169d687de29Sfvdl 
170d687de29Sfvdl 	case RPCBPROC_UADDR2TADDR:
171d687de29Sfvdl #ifdef RPCBIND_DEBUG
172d687de29Sfvdl 		if (debugging)
173d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
174d687de29Sfvdl #endif
175d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_wrapstring;
176d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_netbuf;
177d687de29Sfvdl 		local = rpcbproc_uaddr2taddr_com;
178d687de29Sfvdl 		break;
179d687de29Sfvdl 
180d687de29Sfvdl 	case RPCBPROC_TADDR2UADDR:
181d687de29Sfvdl #ifdef RPCBIND_DEBUG
182d687de29Sfvdl 		if (debugging)
183d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
184d687de29Sfvdl #endif
185d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_netbuf;
186d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_wrapstring;
187d687de29Sfvdl 		local = rpcbproc_taddr2uaddr_com;
188d687de29Sfvdl 		break;
189d687de29Sfvdl 
190d687de29Sfvdl 	case RPCBPROC_GETADDRLIST:
191d687de29Sfvdl #ifdef RPCBIND_DEBUG
192d687de29Sfvdl 		if (debugging)
193d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
194d687de29Sfvdl #endif
195d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_rpcb;
196d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
197d687de29Sfvdl 		local = rpcbproc_getaddrlist_4_local;
198d687de29Sfvdl 		break;
199d687de29Sfvdl 
200d687de29Sfvdl 	case RPCBPROC_GETSTAT:
201d687de29Sfvdl #ifdef RPCBIND_DEBUG
202d687de29Sfvdl 		if (debugging)
203d687de29Sfvdl 			fprintf(stderr, "RPCBPROC_GETSTAT\n");
204d687de29Sfvdl #endif
205d687de29Sfvdl 		xdr_argument = (xdrproc_t)xdr_void;
206d687de29Sfvdl 		xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
207d687de29Sfvdl 		local = rpcbproc_getstat;
208d687de29Sfvdl 		break;
209d687de29Sfvdl 
210d687de29Sfvdl 	default:
211d687de29Sfvdl 		svcerr_noproc(transp);
212d687de29Sfvdl 		return;
213d687de29Sfvdl 	}
214d687de29Sfvdl 	memset((char *)&argument, 0, sizeof (argument));
215d687de29Sfvdl 	if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
216d687de29Sfvdl 		(char *)&argument)) {
217d687de29Sfvdl 		svcerr_decode(transp);
218d687de29Sfvdl 		if (debugging)
219d687de29Sfvdl 			(void) fprintf(stderr, "rpcbind: could not decode\n");
220d687de29Sfvdl 		return;
221d687de29Sfvdl 	}
222d687de29Sfvdl 	if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
223d687de29Sfvdl 		svcerr_weakauth(transp);
224d687de29Sfvdl 		goto done;
225d687de29Sfvdl 	}
226d687de29Sfvdl 	result = (*local)(&argument, rqstp, transp, RPCBVERS4);
227d687de29Sfvdl 	if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
228d687de29Sfvdl 						result)) {
229d687de29Sfvdl 		svcerr_systemerr(transp);
230d687de29Sfvdl 		if (debugging) {
231d687de29Sfvdl 			(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
232d687de29Sfvdl 			if (doabort) {
233d687de29Sfvdl 				rpcbind_abort();
234d687de29Sfvdl 			}
235d687de29Sfvdl 		}
236d687de29Sfvdl 	}
237d687de29Sfvdl done:
238d687de29Sfvdl 	if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
239d687de29Sfvdl 				(char *)&argument)) {
240d687de29Sfvdl 		if (debugging) {
241d687de29Sfvdl 			(void) fprintf(stderr, "unable to free arguments\n");
242d687de29Sfvdl 			if (doabort) {
243d687de29Sfvdl 				rpcbind_abort();
244d687de29Sfvdl 			}
245d687de29Sfvdl 		}
246d687de29Sfvdl 	}
247d687de29Sfvdl 	return;
248d687de29Sfvdl }
249d687de29Sfvdl 
250d687de29Sfvdl /*
251d687de29Sfvdl  * Lookup the mapping for a program, version and return its
252d687de29Sfvdl  * address. Assuming that the caller wants the address of the
253d687de29Sfvdl  * server running on the transport on which the request came.
254d687de29Sfvdl  * Even if a service with a different version number is available,
255d687de29Sfvdl  * it will return that address.  The client should check with an
256d687de29Sfvdl  * clnt_call to verify whether the service is the one that is desired.
257d687de29Sfvdl  * We also try to resolve the universal address in terms of
258d687de29Sfvdl  * address of the caller.
259d687de29Sfvdl  */
260d687de29Sfvdl /* ARGSUSED */
261d687de29Sfvdl static void *
rpcbproc_getaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t rpcbversnum __unused)262d687de29Sfvdl rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
263df898ddbSchristos 			 rpcvers_t rpcbversnum __unused)
264d687de29Sfvdl {
265d687de29Sfvdl 	RPCB *regp = (RPCB *)arg;
266d687de29Sfvdl #ifdef RPCBIND_DEBUG
267d687de29Sfvdl 	if (debugging) {
268d687de29Sfvdl 		char *uaddr;
269d687de29Sfvdl 
270d687de29Sfvdl 		uaddr =	taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
271d687de29Sfvdl 			    svc_getrpccaller(transp));
272d687de29Sfvdl 		fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
273d687de29Sfvdl 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
274d687de29Sfvdl 		    regp->r_netid, uaddr);
275d687de29Sfvdl 		free(uaddr);
276d687de29Sfvdl 	}
277d687de29Sfvdl #endif
278d687de29Sfvdl 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
279d687de29Sfvdl 					RPCB_ALLVERS));
280d687de29Sfvdl }
281d687de29Sfvdl 
282d687de29Sfvdl /*
283d687de29Sfvdl  * Lookup the mapping for a program, version and return its
284d687de29Sfvdl  * address. Assuming that the caller wants the address of the
285d687de29Sfvdl  * server running on the transport on which the request came.
286d687de29Sfvdl  *
287d687de29Sfvdl  * We also try to resolve the universal address in terms of
288d687de29Sfvdl  * address of the caller.
289d687de29Sfvdl  */
290d687de29Sfvdl /* ARGSUSED */
291d687de29Sfvdl static void *
rpcbproc_getversaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t versnum __unused)292d687de29Sfvdl rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
293df898ddbSchristos 			     rpcvers_t versnum __unused)
294d687de29Sfvdl {
295d687de29Sfvdl 	RPCB *regp = (RPCB *)arg;
296d687de29Sfvdl #ifdef RPCBIND_DEBUG
297d687de29Sfvdl 	if (debugging) {
298d687de29Sfvdl 		char *uaddr;
299d687de29Sfvdl 
300d687de29Sfvdl 		uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
301d687de29Sfvdl 			    svc_getrpccaller(transp));
302d687de29Sfvdl 		fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
303d687de29Sfvdl 				" from %s : ",
304d687de29Sfvdl 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
305d687de29Sfvdl 		    regp->r_netid, uaddr);
306d687de29Sfvdl 		free(uaddr);
307d687de29Sfvdl 	}
308d687de29Sfvdl #endif
309d687de29Sfvdl 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
310d687de29Sfvdl 					RPCB_ONEVERS));
311d687de29Sfvdl }
312d687de29Sfvdl 
313d687de29Sfvdl /*
314d687de29Sfvdl  * Lookup the mapping for a program, version and return the
315d687de29Sfvdl  * addresses for all transports in the current transport family.
316d687de29Sfvdl  * We return a merged address.
317d687de29Sfvdl  */
318d687de29Sfvdl /* ARGSUSED */
319d687de29Sfvdl static void *
rpcbproc_getaddrlist_4_local(void * arg,struct svc_req * rqstp __unused,SVCXPRT * transp,rpcvers_t versnum __unused)320df898ddbSchristos rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused,
321df898ddbSchristos     SVCXPRT *transp, rpcvers_t versnum __unused)
322d687de29Sfvdl {
323d687de29Sfvdl 	RPCB *regp = (RPCB *)arg;
324d687de29Sfvdl 	static rpcb_entry_list_ptr rlist;
325d687de29Sfvdl 	register rpcblist_ptr rbl;
326df898ddbSchristos 	rpcb_entry_list_ptr rp, tail;
327d687de29Sfvdl 	rpcprog_t prog;
328d687de29Sfvdl 	rpcvers_t vers;
329d687de29Sfvdl 	rpcb_entry *a;
330d687de29Sfvdl 	struct netconfig *nconf;
331d687de29Sfvdl 	struct netconfig *reg_nconf;
332d687de29Sfvdl 	char *saddr, *maddr = NULL;
333d687de29Sfvdl 
334d687de29Sfvdl 	free_rpcb_entry_list(&rlist);
335df898ddbSchristos 	tail = NULL;
336d687de29Sfvdl 	prog = regp->r_prog;
337d687de29Sfvdl 	vers = regp->r_vers;
338d687de29Sfvdl 	reg_nconf = rpcbind_get_conf(transp->xp_netid);
339d687de29Sfvdl 	if (reg_nconf == NULL)
340d687de29Sfvdl 		return (NULL);
341d687de29Sfvdl 	if (*(regp->r_addr) != '\0') {
342d687de29Sfvdl 		saddr = regp->r_addr;
343d687de29Sfvdl 	} else {
344d687de29Sfvdl 		saddr = NULL;
345d687de29Sfvdl 	}
346d687de29Sfvdl #ifdef RPCBIND_DEBUG
347d687de29Sfvdl 	if (debugging) {
348d687de29Sfvdl 		fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
349d687de29Sfvdl 		    regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
350d687de29Sfvdl 	}
351d687de29Sfvdl #endif
352d687de29Sfvdl 	for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
353d687de29Sfvdl 	    if ((rbl->rpcb_map.r_prog == prog) &&
354d687de29Sfvdl 		(rbl->rpcb_map.r_vers == vers)) {
355d687de29Sfvdl 		nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
356d687de29Sfvdl 		if (nconf == NULL)
357d687de29Sfvdl 			goto fail;
358d687de29Sfvdl 		if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
359d687de29Sfvdl 				!= 0) {
360d687de29Sfvdl 			continue;	/* not same proto family */
361d687de29Sfvdl 		}
362d687de29Sfvdl #ifdef RPCBIND_DEBUG
363d687de29Sfvdl 		if (debugging)
364df898ddbSchristos 			fprintf(stderr, "\tmerge with: %s\n",
365df898ddbSchristos 			    rbl->rpcb_map.r_addr);
366d687de29Sfvdl #endif
367d687de29Sfvdl 		if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
368d687de29Sfvdl 				rbl->rpcb_map.r_addr, saddr)) == NULL) {
369d687de29Sfvdl #ifdef RPCBIND_DEBUG
370d687de29Sfvdl 		if (debugging)
371d687de29Sfvdl 			fprintf(stderr, " FAILED\n");
372d687de29Sfvdl #endif
373d687de29Sfvdl 			continue;
374d687de29Sfvdl 		} else if (!maddr[0]) {
375d687de29Sfvdl #ifdef RPCBIND_DEBUG
376d687de29Sfvdl 	if (debugging)
377d687de29Sfvdl 		fprintf(stderr, " SUCCEEDED, but port died -  maddr: nullstring\n");
378d687de29Sfvdl #endif
379d687de29Sfvdl 			/* The server died. Unset this combination */
380d687de29Sfvdl 			delete_prog(regp->r_prog);
381d687de29Sfvdl 			continue;
382d687de29Sfvdl 		}
383d687de29Sfvdl #ifdef RPCBIND_DEBUG
384d687de29Sfvdl 		if (debugging)
385d687de29Sfvdl 			fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
386d687de29Sfvdl #endif
387d687de29Sfvdl 		/*
388d687de29Sfvdl 		 * Add it to rlist.
389d687de29Sfvdl 		 */
390*3e9c5584Schristos 		rp = malloc(sizeof(*rp));
391df898ddbSchristos 		if (rp == NULL)
392d687de29Sfvdl 			goto fail;
393d687de29Sfvdl 		a = &rp->rpcb_entry_map;
394d687de29Sfvdl 		a->r_maddr = maddr;
395d687de29Sfvdl 		a->r_nc_netid = nconf->nc_netid;
396d687de29Sfvdl 		a->r_nc_semantics = nconf->nc_semantics;
397d687de29Sfvdl 		a->r_nc_protofmly = nconf->nc_protofmly;
398d687de29Sfvdl 		a->r_nc_proto = nconf->nc_proto;
399d687de29Sfvdl 		rp->rpcb_entry_next = NULL;
400d687de29Sfvdl 		if (rlist == NULL) {
401d687de29Sfvdl 			rlist = rp;
402d687de29Sfvdl 			tail = rp;
4031716cd4eSchristos 		} else if (tail) {
404d687de29Sfvdl 			tail->rpcb_entry_next = rp;
405d687de29Sfvdl 			tail = rp;
406d687de29Sfvdl 		}
407d687de29Sfvdl 		rp = NULL;
408d687de29Sfvdl 	    }
409d687de29Sfvdl 	}
410d687de29Sfvdl #ifdef RPCBIND_DEBUG
411d687de29Sfvdl 	if (debugging) {
412d687de29Sfvdl 		for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
413d687de29Sfvdl 			fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
414d687de29Sfvdl 				rp->rpcb_entry_map.r_nc_proto);
415d687de29Sfvdl 		}
416d687de29Sfvdl 	}
417d687de29Sfvdl #endif
418d687de29Sfvdl 	/*
419d687de29Sfvdl 	 * XXX: getaddrlist info is also being stuffed into getaddr.
420d687de29Sfvdl 	 * Perhaps wrong, but better than it not getting counted at all.
421d687de29Sfvdl 	 */
422d687de29Sfvdl 	rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
423d687de29Sfvdl 	return (void *)&rlist;
424d687de29Sfvdl 
425d687de29Sfvdl fail:	free_rpcb_entry_list(&rlist);
426d687de29Sfvdl 	return (NULL);
427d687de29Sfvdl }
428d687de29Sfvdl 
429d687de29Sfvdl /*
430d687de29Sfvdl  * Free only the allocated structure, rest is all a pointer to some
431d687de29Sfvdl  * other data somewhere else.
432d687de29Sfvdl  */
433d687de29Sfvdl static void
free_rpcb_entry_list(rpcb_entry_list_ptr * rlistp)434d687de29Sfvdl free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
435d687de29Sfvdl {
436d687de29Sfvdl 	register rpcb_entry_list_ptr rbl, tmp;
437d687de29Sfvdl 
438d687de29Sfvdl 	for (rbl = *rlistp; rbl != NULL; ) {
439d687de29Sfvdl 		tmp = rbl;
440d687de29Sfvdl 		rbl = rbl->rpcb_entry_next;
441d687de29Sfvdl 		free((char *)tmp->rpcb_entry_map.r_maddr);
442d687de29Sfvdl 		free((char *)tmp);
443d687de29Sfvdl 	}
444d687de29Sfvdl 	*rlistp = NULL;
445d687de29Sfvdl }
446d687de29Sfvdl 
447d687de29Sfvdl /* ARGSUSED */
448d687de29Sfvdl static void *
rpcbproc_dump_4_local(void * arg __unused,struct svc_req * req __unused,SVCXPRT * xprt __unused,rpcvers_t versnum __unused)449df898ddbSchristos rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused,
450df898ddbSchristos     SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
451d687de29Sfvdl {
452d687de29Sfvdl 	return ((void *)&list_rbl);
453d687de29Sfvdl }
454