xref: /dflybsd-src/usr.sbin/rpcbind/rpcb_svc_4.c (revision ce0e08e21d42c06c0014fae6b9d27144aa5109b0)
1*ce0e08e2SPeter Avalos /*
2*ce0e08e2SPeter Avalos  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3*ce0e08e2SPeter Avalos  * unrestricted use provided that this legend is included on all tape
4*ce0e08e2SPeter Avalos  * media and as a part of the software program in whole or part.  Users
5*ce0e08e2SPeter Avalos  * may copy or modify Sun RPC without charge, but are not authorized
6*ce0e08e2SPeter Avalos  * to license or distribute it to anyone else except as part of a product or
7*ce0e08e2SPeter Avalos  * program developed by the user.
8*ce0e08e2SPeter Avalos  *
9*ce0e08e2SPeter Avalos  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10*ce0e08e2SPeter Avalos  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11*ce0e08e2SPeter Avalos  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12*ce0e08e2SPeter Avalos  *
13*ce0e08e2SPeter Avalos  * Sun RPC is provided with no support and without any obligation on the
14*ce0e08e2SPeter Avalos  * part of Sun Microsystems, Inc. to assist in its use, correction,
15*ce0e08e2SPeter Avalos  * modification or enhancement.
16*ce0e08e2SPeter Avalos  *
17*ce0e08e2SPeter Avalos  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18*ce0e08e2SPeter Avalos  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19*ce0e08e2SPeter Avalos  * OR ANY PART THEREOF.
20*ce0e08e2SPeter Avalos  *
21*ce0e08e2SPeter Avalos  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22*ce0e08e2SPeter Avalos  * or profits or other special, indirect and consequential damages, even if
23*ce0e08e2SPeter Avalos  * Sun has been advised of the possibility of such damages.
24*ce0e08e2SPeter Avalos  *
25*ce0e08e2SPeter Avalos  * Sun Microsystems, Inc.
26*ce0e08e2SPeter Avalos  * 2550 Garcia Avenue
27*ce0e08e2SPeter Avalos  * Mountain View, California  94043
28*ce0e08e2SPeter Avalos  *
29*ce0e08e2SPeter Avalos  * @(#)rpcb_svc_4.c	1.8	93/07/05 SMI
30*ce0e08e2SPeter Avalos  * $NetBSD: rpcb_svc_4.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $
31*ce0e08e2SPeter Avalos  * $FreeBSD: src/usr.sbin/rpcbind/rpcb_svc_4.c,v 1.5 2007/11/07 10:53:39 kevlo Exp $
32*ce0e08e2SPeter Avalos  * $DragonFly$
33*ce0e08e2SPeter Avalos  */
34*ce0e08e2SPeter Avalos /*
35*ce0e08e2SPeter Avalos  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
36*ce0e08e2SPeter Avalos  */
37*ce0e08e2SPeter Avalos 
38*ce0e08e2SPeter Avalos /*
39*ce0e08e2SPeter Avalos  * rpcb_svc_4.c
40*ce0e08e2SPeter Avalos  * The server procedure for the version 4 rpcbind.
41*ce0e08e2SPeter Avalos  *
42*ce0e08e2SPeter Avalos  */
43*ce0e08e2SPeter Avalos 
44*ce0e08e2SPeter Avalos #include <sys/types.h>
45*ce0e08e2SPeter Avalos #include <sys/stat.h>
46*ce0e08e2SPeter Avalos #include <rpc/rpc.h>
47*ce0e08e2SPeter Avalos #include <stdio.h>
48*ce0e08e2SPeter Avalos #include <unistd.h>
49*ce0e08e2SPeter Avalos #include <netconfig.h>
50*ce0e08e2SPeter Avalos #include <syslog.h>
51*ce0e08e2SPeter Avalos #include <string.h>
52*ce0e08e2SPeter Avalos #include <stdlib.h>
53*ce0e08e2SPeter Avalos #include "rpcbind.h"
54*ce0e08e2SPeter Avalos 
55*ce0e08e2SPeter Avalos static void	*rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
56*ce0e08e2SPeter Avalos 					  rpcvers_t);
57*ce0e08e2SPeter Avalos static void	*rpcbproc_getversaddr_4_local(void *, struct svc_req *,
58*ce0e08e2SPeter Avalos 					      SVCXPRT *, rpcvers_t);
59*ce0e08e2SPeter Avalos static void	*rpcbproc_getaddrlist_4_local(void *, struct svc_req *,
60*ce0e08e2SPeter Avalos 					      SVCXPRT *, rpcvers_t);
61*ce0e08e2SPeter Avalos static void	free_rpcb_entry_list(rpcb_entry_list_ptr *);
62*ce0e08e2SPeter Avalos static void	*rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
63*ce0e08e2SPeter Avalos 				       rpcvers_t);
64*ce0e08e2SPeter Avalos 
65*ce0e08e2SPeter Avalos /*
66*ce0e08e2SPeter Avalos  * Called by svc_getreqset. There is a separate server handle for
67*ce0e08e2SPeter Avalos  * every transport that it waits on.
68*ce0e08e2SPeter Avalos  */
69*ce0e08e2SPeter Avalos void
70*ce0e08e2SPeter Avalos rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
71*ce0e08e2SPeter Avalos {
72*ce0e08e2SPeter Avalos 	union {
73*ce0e08e2SPeter Avalos 		rpcb rpcbproc_set_4_arg;
74*ce0e08e2SPeter Avalos 		rpcb rpcbproc_unset_4_arg;
75*ce0e08e2SPeter Avalos 		rpcb rpcbproc_getaddr_4_local_arg;
76*ce0e08e2SPeter Avalos 		char *rpcbproc_uaddr2taddr_4_arg;
77*ce0e08e2SPeter Avalos 		struct netbuf rpcbproc_taddr2uaddr_4_arg;
78*ce0e08e2SPeter Avalos 	} argument;
79*ce0e08e2SPeter Avalos 	char *result;
80*ce0e08e2SPeter Avalos 	xdrproc_t xdr_argument, xdr_result;
81*ce0e08e2SPeter Avalos 	void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
82*ce0e08e2SPeter Avalos 
83*ce0e08e2SPeter Avalos 	rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
84*ce0e08e2SPeter Avalos 
85*ce0e08e2SPeter Avalos 	switch (rqstp->rq_proc) {
86*ce0e08e2SPeter Avalos 	case NULLPROC:
87*ce0e08e2SPeter Avalos 		/*
88*ce0e08e2SPeter Avalos 		 * Null proc call
89*ce0e08e2SPeter Avalos 		 */
90*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
91*ce0e08e2SPeter Avalos 		if (debugging)
92*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_NULL\n");
93*ce0e08e2SPeter Avalos #endif
94*ce0e08e2SPeter Avalos 		check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
95*ce0e08e2SPeter Avalos 		svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
96*ce0e08e2SPeter Avalos 		return;
97*ce0e08e2SPeter Avalos 
98*ce0e08e2SPeter Avalos 	case RPCBPROC_SET:
99*ce0e08e2SPeter Avalos 		/*
100*ce0e08e2SPeter Avalos 		 * Check to see whether the message came from
101*ce0e08e2SPeter Avalos 		 * loopback transports (for security reasons)
102*ce0e08e2SPeter Avalos 		 */
103*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_rpcb;
104*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_bool;
105*ce0e08e2SPeter Avalos 		local = rpcbproc_set_com;
106*ce0e08e2SPeter Avalos 		break;
107*ce0e08e2SPeter Avalos 
108*ce0e08e2SPeter Avalos 	case RPCBPROC_UNSET:
109*ce0e08e2SPeter Avalos 		/*
110*ce0e08e2SPeter Avalos 		 * Check to see whether the message came from
111*ce0e08e2SPeter Avalos 		 * loopback transports (for security reasons)
112*ce0e08e2SPeter Avalos 		 */
113*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_rpcb;
114*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_bool;
115*ce0e08e2SPeter Avalos 		local = rpcbproc_unset_com;
116*ce0e08e2SPeter Avalos 		break;
117*ce0e08e2SPeter Avalos 
118*ce0e08e2SPeter Avalos 	case RPCBPROC_GETADDR:
119*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_rpcb;
120*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_wrapstring;
121*ce0e08e2SPeter Avalos 		local = rpcbproc_getaddr_4_local;
122*ce0e08e2SPeter Avalos 		break;
123*ce0e08e2SPeter Avalos 
124*ce0e08e2SPeter Avalos 	case RPCBPROC_GETVERSADDR:
125*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
126*ce0e08e2SPeter Avalos 		if (debugging)
127*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
128*ce0e08e2SPeter Avalos #endif
129*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_rpcb;
130*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_wrapstring;
131*ce0e08e2SPeter Avalos 		local = rpcbproc_getversaddr_4_local;
132*ce0e08e2SPeter Avalos 		break;
133*ce0e08e2SPeter Avalos 
134*ce0e08e2SPeter Avalos 	case RPCBPROC_DUMP:
135*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
136*ce0e08e2SPeter Avalos 		if (debugging)
137*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_DUMP\n");
138*ce0e08e2SPeter Avalos #endif
139*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_void;
140*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
141*ce0e08e2SPeter Avalos 		local = rpcbproc_dump_4_local;
142*ce0e08e2SPeter Avalos 		break;
143*ce0e08e2SPeter Avalos 
144*ce0e08e2SPeter Avalos 	case RPCBPROC_INDIRECT:
145*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
146*ce0e08e2SPeter Avalos 		if (debugging)
147*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_INDIRECT\n");
148*ce0e08e2SPeter Avalos #endif
149*ce0e08e2SPeter Avalos 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
150*ce0e08e2SPeter Avalos 		return;
151*ce0e08e2SPeter Avalos 
152*ce0e08e2SPeter Avalos /*	case RPCBPROC_CALLIT: */
153*ce0e08e2SPeter Avalos 	case RPCBPROC_BCAST:
154*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
155*ce0e08e2SPeter Avalos 		if (debugging)
156*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_BCAST\n");
157*ce0e08e2SPeter Avalos #endif
158*ce0e08e2SPeter Avalos 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
159*ce0e08e2SPeter Avalos 		return;
160*ce0e08e2SPeter Avalos 
161*ce0e08e2SPeter Avalos 	case RPCBPROC_GETTIME:
162*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
163*ce0e08e2SPeter Avalos 		if (debugging)
164*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_GETTIME\n");
165*ce0e08e2SPeter Avalos #endif
166*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_void;
167*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_u_long;
168*ce0e08e2SPeter Avalos 		local = rpcbproc_gettime_com;
169*ce0e08e2SPeter Avalos 		break;
170*ce0e08e2SPeter Avalos 
171*ce0e08e2SPeter Avalos 	case RPCBPROC_UADDR2TADDR:
172*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
173*ce0e08e2SPeter Avalos 		if (debugging)
174*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
175*ce0e08e2SPeter Avalos #endif
176*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_wrapstring;
177*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_netbuf;
178*ce0e08e2SPeter Avalos 		local = rpcbproc_uaddr2taddr_com;
179*ce0e08e2SPeter Avalos 		break;
180*ce0e08e2SPeter Avalos 
181*ce0e08e2SPeter Avalos 	case RPCBPROC_TADDR2UADDR:
182*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
183*ce0e08e2SPeter Avalos 		if (debugging)
184*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
185*ce0e08e2SPeter Avalos #endif
186*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_netbuf;
187*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_wrapstring;
188*ce0e08e2SPeter Avalos 		local = rpcbproc_taddr2uaddr_com;
189*ce0e08e2SPeter Avalos 		break;
190*ce0e08e2SPeter Avalos 
191*ce0e08e2SPeter Avalos 	case RPCBPROC_GETADDRLIST:
192*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
193*ce0e08e2SPeter Avalos 		if (debugging)
194*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
195*ce0e08e2SPeter Avalos #endif
196*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_rpcb;
197*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
198*ce0e08e2SPeter Avalos 		local = rpcbproc_getaddrlist_4_local;
199*ce0e08e2SPeter Avalos 		break;
200*ce0e08e2SPeter Avalos 
201*ce0e08e2SPeter Avalos 	case RPCBPROC_GETSTAT:
202*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
203*ce0e08e2SPeter Avalos 		if (debugging)
204*ce0e08e2SPeter Avalos 			fprintf(stderr, "RPCBPROC_GETSTAT\n");
205*ce0e08e2SPeter Avalos #endif
206*ce0e08e2SPeter Avalos 		xdr_argument = (xdrproc_t)xdr_void;
207*ce0e08e2SPeter Avalos 		xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
208*ce0e08e2SPeter Avalos 		local = rpcbproc_getstat;
209*ce0e08e2SPeter Avalos 		break;
210*ce0e08e2SPeter Avalos 
211*ce0e08e2SPeter Avalos 	default:
212*ce0e08e2SPeter Avalos 		svcerr_noproc(transp);
213*ce0e08e2SPeter Avalos 		return;
214*ce0e08e2SPeter Avalos 	}
215*ce0e08e2SPeter Avalos 	memset((char *)&argument, 0, sizeof (argument));
216*ce0e08e2SPeter Avalos 	if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
217*ce0e08e2SPeter Avalos 		(char *)&argument)) {
218*ce0e08e2SPeter Avalos 		svcerr_decode(transp);
219*ce0e08e2SPeter Avalos 		if (debugging)
220*ce0e08e2SPeter Avalos 			fprintf(stderr, "rpcbind: could not decode\n");
221*ce0e08e2SPeter Avalos 		return;
222*ce0e08e2SPeter Avalos 	}
223*ce0e08e2SPeter Avalos 	if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
224*ce0e08e2SPeter Avalos 		svcerr_weakauth(transp);
225*ce0e08e2SPeter Avalos 		goto done;
226*ce0e08e2SPeter Avalos 	}
227*ce0e08e2SPeter Avalos 	result = (*local)(&argument, rqstp, transp, RPCBVERS4);
228*ce0e08e2SPeter Avalos 	if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
229*ce0e08e2SPeter Avalos 						result)) {
230*ce0e08e2SPeter Avalos 		svcerr_systemerr(transp);
231*ce0e08e2SPeter Avalos 		if (debugging) {
232*ce0e08e2SPeter Avalos 			fprintf(stderr, "rpcbind: svc_sendreply\n");
233*ce0e08e2SPeter Avalos 			if (doabort) {
234*ce0e08e2SPeter Avalos 				rpcbind_abort();
235*ce0e08e2SPeter Avalos 			}
236*ce0e08e2SPeter Avalos 		}
237*ce0e08e2SPeter Avalos 	}
238*ce0e08e2SPeter Avalos done:
239*ce0e08e2SPeter Avalos 	if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
240*ce0e08e2SPeter Avalos 				(char *)&argument)) {
241*ce0e08e2SPeter Avalos 		if (debugging) {
242*ce0e08e2SPeter Avalos 			fprintf(stderr, "unable to free arguments\n");
243*ce0e08e2SPeter Avalos 			if (doabort) {
244*ce0e08e2SPeter Avalos 				rpcbind_abort();
245*ce0e08e2SPeter Avalos 			}
246*ce0e08e2SPeter Avalos 		}
247*ce0e08e2SPeter Avalos 	}
248*ce0e08e2SPeter Avalos 	return;
249*ce0e08e2SPeter Avalos }
250*ce0e08e2SPeter Avalos 
251*ce0e08e2SPeter Avalos /*
252*ce0e08e2SPeter Avalos  * Lookup the mapping for a program, version and return its
253*ce0e08e2SPeter Avalos  * address. Assuming that the caller wants the address of the
254*ce0e08e2SPeter Avalos  * server running on the transport on which the request came.
255*ce0e08e2SPeter Avalos  * Even if a service with a different version number is available,
256*ce0e08e2SPeter Avalos  * it will return that address.  The client should check with an
257*ce0e08e2SPeter Avalos  * clnt_call to verify whether the service is the one that is desired.
258*ce0e08e2SPeter Avalos  * We also try to resolve the universal address in terms of
259*ce0e08e2SPeter Avalos  * address of the caller.
260*ce0e08e2SPeter Avalos  */
261*ce0e08e2SPeter Avalos /* ARGSUSED */
262*ce0e08e2SPeter Avalos static void *
263*ce0e08e2SPeter Avalos rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
264*ce0e08e2SPeter Avalos 			 rpcvers_t rpcbversnum __unused)
265*ce0e08e2SPeter Avalos {
266*ce0e08e2SPeter Avalos 	RPCB *regp = (RPCB *)arg;
267*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
268*ce0e08e2SPeter Avalos 	if (debugging) {
269*ce0e08e2SPeter Avalos 		char *uaddr;
270*ce0e08e2SPeter Avalos 
271*ce0e08e2SPeter Avalos 		uaddr =	taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
272*ce0e08e2SPeter Avalos 			    svc_getrpccaller(transp));
273*ce0e08e2SPeter Avalos 		fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
274*ce0e08e2SPeter Avalos 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
275*ce0e08e2SPeter Avalos 		    regp->r_netid, uaddr);
276*ce0e08e2SPeter Avalos 		free(uaddr);
277*ce0e08e2SPeter Avalos 	}
278*ce0e08e2SPeter Avalos #endif
279*ce0e08e2SPeter Avalos 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
280*ce0e08e2SPeter Avalos 					RPCB_ALLVERS));
281*ce0e08e2SPeter Avalos }
282*ce0e08e2SPeter Avalos 
283*ce0e08e2SPeter Avalos /*
284*ce0e08e2SPeter Avalos  * Lookup the mapping for a program, version and return its
285*ce0e08e2SPeter Avalos  * address. Assuming that the caller wants the address of the
286*ce0e08e2SPeter Avalos  * server running on the transport on which the request came.
287*ce0e08e2SPeter Avalos  *
288*ce0e08e2SPeter Avalos  * We also try to resolve the universal address in terms of
289*ce0e08e2SPeter Avalos  * address of the caller.
290*ce0e08e2SPeter Avalos  */
291*ce0e08e2SPeter Avalos /* ARGSUSED */
292*ce0e08e2SPeter Avalos static void *
293*ce0e08e2SPeter Avalos rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
294*ce0e08e2SPeter Avalos 			     rpcvers_t versnum __unused)
295*ce0e08e2SPeter Avalos {
296*ce0e08e2SPeter Avalos 	RPCB *regp = (RPCB *)arg;
297*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
298*ce0e08e2SPeter Avalos 	if (debugging) {
299*ce0e08e2SPeter Avalos 		char *uaddr;
300*ce0e08e2SPeter Avalos 
301*ce0e08e2SPeter Avalos 		uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
302*ce0e08e2SPeter Avalos 			    svc_getrpccaller(transp));
303*ce0e08e2SPeter Avalos 		fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
304*ce0e08e2SPeter Avalos 				" from %s : ",
305*ce0e08e2SPeter Avalos 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
306*ce0e08e2SPeter Avalos 		    regp->r_netid, uaddr);
307*ce0e08e2SPeter Avalos 		free(uaddr);
308*ce0e08e2SPeter Avalos 	}
309*ce0e08e2SPeter Avalos #endif
310*ce0e08e2SPeter Avalos 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
311*ce0e08e2SPeter Avalos 					RPCB_ONEVERS));
312*ce0e08e2SPeter Avalos }
313*ce0e08e2SPeter Avalos 
314*ce0e08e2SPeter Avalos /*
315*ce0e08e2SPeter Avalos  * Lookup the mapping for a program, version and return the
316*ce0e08e2SPeter Avalos  * addresses for all transports in the current transport family.
317*ce0e08e2SPeter Avalos  * We return a merged address.
318*ce0e08e2SPeter Avalos  */
319*ce0e08e2SPeter Avalos /* ARGSUSED */
320*ce0e08e2SPeter Avalos static void *
321*ce0e08e2SPeter Avalos rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused,
322*ce0e08e2SPeter Avalos 			     SVCXPRT *transp, rpcvers_t versnum __unused)
323*ce0e08e2SPeter Avalos {
324*ce0e08e2SPeter Avalos 	RPCB *regp = (RPCB *)arg;
325*ce0e08e2SPeter Avalos 	static rpcb_entry_list_ptr rlist;
326*ce0e08e2SPeter Avalos 	rpcblist_ptr rbl;
327*ce0e08e2SPeter Avalos 	rpcb_entry_list_ptr rp, tail;
328*ce0e08e2SPeter Avalos 	rpcprog_t prog;
329*ce0e08e2SPeter Avalos 	rpcvers_t vers;
330*ce0e08e2SPeter Avalos 	rpcb_entry *a;
331*ce0e08e2SPeter Avalos 	struct netconfig *nconf;
332*ce0e08e2SPeter Avalos 	struct netconfig *reg_nconf;
333*ce0e08e2SPeter Avalos 	char *saddr, *maddr = NULL;
334*ce0e08e2SPeter Avalos 
335*ce0e08e2SPeter Avalos 	free_rpcb_entry_list(&rlist);
336*ce0e08e2SPeter Avalos 	tail = NULL;
337*ce0e08e2SPeter Avalos 	prog = regp->r_prog;
338*ce0e08e2SPeter Avalos 	vers = regp->r_vers;
339*ce0e08e2SPeter Avalos 	reg_nconf = rpcbind_get_conf(transp->xp_netid);
340*ce0e08e2SPeter Avalos 	if (reg_nconf == NULL)
341*ce0e08e2SPeter Avalos 		return (NULL);
342*ce0e08e2SPeter Avalos 	if (*(regp->r_addr) != '\0') {
343*ce0e08e2SPeter Avalos 		saddr = regp->r_addr;
344*ce0e08e2SPeter Avalos 	} else {
345*ce0e08e2SPeter Avalos 		saddr = NULL;
346*ce0e08e2SPeter Avalos 	}
347*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
348*ce0e08e2SPeter Avalos 	if (debugging) {
349*ce0e08e2SPeter Avalos 		fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
350*ce0e08e2SPeter Avalos 		    regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
351*ce0e08e2SPeter Avalos 	}
352*ce0e08e2SPeter Avalos #endif
353*ce0e08e2SPeter Avalos 	for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
354*ce0e08e2SPeter Avalos 	    if ((rbl->rpcb_map.r_prog == prog) &&
355*ce0e08e2SPeter Avalos 		(rbl->rpcb_map.r_vers == vers)) {
356*ce0e08e2SPeter Avalos 		nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
357*ce0e08e2SPeter Avalos 		if (nconf == NULL)
358*ce0e08e2SPeter Avalos 			goto fail;
359*ce0e08e2SPeter Avalos 		if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
360*ce0e08e2SPeter Avalos 				!= 0) {
361*ce0e08e2SPeter Avalos 			continue;	/* not same proto family */
362*ce0e08e2SPeter Avalos 		}
363*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
364*ce0e08e2SPeter Avalos 		if (debugging)
365*ce0e08e2SPeter Avalos 			fprintf(stderr, "\tmerge with: %s\n",
366*ce0e08e2SPeter Avalos 			    rbl->rpcb_map.r_addr);
367*ce0e08e2SPeter Avalos #endif
368*ce0e08e2SPeter Avalos 		if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
369*ce0e08e2SPeter Avalos 				rbl->rpcb_map.r_addr, saddr)) == NULL) {
370*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
371*ce0e08e2SPeter Avalos 		if (debugging)
372*ce0e08e2SPeter Avalos 			fprintf(stderr, " FAILED\n");
373*ce0e08e2SPeter Avalos #endif
374*ce0e08e2SPeter Avalos 			continue;
375*ce0e08e2SPeter Avalos 		} else if (!maddr[0]) {
376*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
377*ce0e08e2SPeter Avalos 	if (debugging)
378*ce0e08e2SPeter Avalos 		fprintf(stderr, " SUCCEEDED, but port died -  maddr: nullstring\n");
379*ce0e08e2SPeter Avalos #endif
380*ce0e08e2SPeter Avalos 			/* The server died. Unset this combination */
381*ce0e08e2SPeter Avalos 			delete_prog(regp->r_prog);
382*ce0e08e2SPeter Avalos 			continue;
383*ce0e08e2SPeter Avalos 		}
384*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
385*ce0e08e2SPeter Avalos 		if (debugging)
386*ce0e08e2SPeter Avalos 			fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
387*ce0e08e2SPeter Avalos #endif
388*ce0e08e2SPeter Avalos 		/*
389*ce0e08e2SPeter Avalos 		 * Add it to rlist.
390*ce0e08e2SPeter Avalos 		 */
391*ce0e08e2SPeter Avalos 		rp = malloc(sizeof (rpcb_entry_list));
392*ce0e08e2SPeter Avalos 		if (rp == NULL)
393*ce0e08e2SPeter Avalos 			goto fail;
394*ce0e08e2SPeter Avalos 		a = &rp->rpcb_entry_map;
395*ce0e08e2SPeter Avalos 		a->r_maddr = maddr;
396*ce0e08e2SPeter Avalos 		a->r_nc_netid = nconf->nc_netid;
397*ce0e08e2SPeter Avalos 		a->r_nc_semantics = nconf->nc_semantics;
398*ce0e08e2SPeter Avalos 		a->r_nc_protofmly = nconf->nc_protofmly;
399*ce0e08e2SPeter Avalos 		a->r_nc_proto = nconf->nc_proto;
400*ce0e08e2SPeter Avalos 		rp->rpcb_entry_next = NULL;
401*ce0e08e2SPeter Avalos 		if (rlist == NULL) {
402*ce0e08e2SPeter Avalos 			rlist = rp;
403*ce0e08e2SPeter Avalos 			tail = rp;
404*ce0e08e2SPeter Avalos 		} else {
405*ce0e08e2SPeter Avalos 			tail->rpcb_entry_next = rp;
406*ce0e08e2SPeter Avalos 			tail = rp;
407*ce0e08e2SPeter Avalos 		}
408*ce0e08e2SPeter Avalos 		rp = NULL;
409*ce0e08e2SPeter Avalos 	    }
410*ce0e08e2SPeter Avalos 	}
411*ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
412*ce0e08e2SPeter Avalos 	if (debugging) {
413*ce0e08e2SPeter Avalos 		for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
414*ce0e08e2SPeter Avalos 			fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
415*ce0e08e2SPeter Avalos 				rp->rpcb_entry_map.r_nc_proto);
416*ce0e08e2SPeter Avalos 		}
417*ce0e08e2SPeter Avalos 	}
418*ce0e08e2SPeter Avalos #endif
419*ce0e08e2SPeter Avalos 	/*
420*ce0e08e2SPeter Avalos 	 * XXX: getaddrlist info is also being stuffed into getaddr.
421*ce0e08e2SPeter Avalos 	 * Perhaps wrong, but better than it not getting counted at all.
422*ce0e08e2SPeter Avalos 	 */
423*ce0e08e2SPeter Avalos 	rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
424*ce0e08e2SPeter Avalos 	return (void *)&rlist;
425*ce0e08e2SPeter Avalos 
426*ce0e08e2SPeter Avalos fail:	free_rpcb_entry_list(&rlist);
427*ce0e08e2SPeter Avalos 	return (NULL);
428*ce0e08e2SPeter Avalos }
429*ce0e08e2SPeter Avalos 
430*ce0e08e2SPeter Avalos /*
431*ce0e08e2SPeter Avalos  * Free only the allocated structure, rest is all a pointer to some
432*ce0e08e2SPeter Avalos  * other data somewhere else.
433*ce0e08e2SPeter Avalos  */
434*ce0e08e2SPeter Avalos static void
435*ce0e08e2SPeter Avalos free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
436*ce0e08e2SPeter Avalos {
437*ce0e08e2SPeter Avalos 	rpcb_entry_list_ptr rbl, tmp;
438*ce0e08e2SPeter Avalos 
439*ce0e08e2SPeter Avalos 	for (rbl = *rlistp; rbl != NULL; ) {
440*ce0e08e2SPeter Avalos 		tmp = rbl;
441*ce0e08e2SPeter Avalos 		rbl = rbl->rpcb_entry_next;
442*ce0e08e2SPeter Avalos 		free((char *)tmp->rpcb_entry_map.r_maddr);
443*ce0e08e2SPeter Avalos 		free((char *)tmp);
444*ce0e08e2SPeter Avalos 	}
445*ce0e08e2SPeter Avalos 	*rlistp = NULL;
446*ce0e08e2SPeter Avalos }
447*ce0e08e2SPeter Avalos 
448*ce0e08e2SPeter Avalos /* ARGSUSED */
449*ce0e08e2SPeter Avalos static void *
450*ce0e08e2SPeter Avalos rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused,
451*ce0e08e2SPeter Avalos 		      SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
452*ce0e08e2SPeter Avalos {
453*ce0e08e2SPeter Avalos 	return ((void *)&list_rbl);
454*ce0e08e2SPeter Avalos }
455