xref: /freebsd/usr.sbin/rpcbind/rpcb_svc_4.c (revision 8a7b61203704d362cfbc66c00619f51b24106b55)
18360efbdSAlfred Perlstein /*
28360efbdSAlfred Perlstein  * $NetBSD: rpcb_svc_4.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $
38360efbdSAlfred Perlstein  */
48360efbdSAlfred Perlstein 
5a7c51fa1SHiroki Sato /*-
6*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
7*8a16b7a1SPedro F. Giffuni  *
8a7c51fa1SHiroki Sato  * Copyright (c) 2009, Sun Microsystems, Inc.
9a7c51fa1SHiroki Sato  * All rights reserved.
108360efbdSAlfred Perlstein  *
11a7c51fa1SHiroki Sato  * Redistribution and use in source and binary forms, with or without
12a7c51fa1SHiroki Sato  * modification, are permitted provided that the following conditions are met:
13a7c51fa1SHiroki Sato  * - Redistributions of source code must retain the above copyright notice,
14a7c51fa1SHiroki Sato  *   this list of conditions and the following disclaimer.
15a7c51fa1SHiroki Sato  * - Redistributions in binary form must reproduce the above copyright notice,
16a7c51fa1SHiroki Sato  *   this list of conditions and the following disclaimer in the documentation
17a7c51fa1SHiroki Sato  *   and/or other materials provided with the distribution.
18a7c51fa1SHiroki Sato  * - Neither the name of Sun Microsystems, Inc. nor the names of its
19a7c51fa1SHiroki Sato  *   contributors may be used to endorse or promote products derived
20a7c51fa1SHiroki Sato  *   from this software without specific prior written permission.
218360efbdSAlfred Perlstein  *
22a7c51fa1SHiroki Sato  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23a7c51fa1SHiroki Sato  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24a7c51fa1SHiroki Sato  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25a7c51fa1SHiroki Sato  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26a7c51fa1SHiroki Sato  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27a7c51fa1SHiroki Sato  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28a7c51fa1SHiroki Sato  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29a7c51fa1SHiroki Sato  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30a7c51fa1SHiroki Sato  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31a7c51fa1SHiroki Sato  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32a7c51fa1SHiroki Sato  * POSSIBILITY OF SUCH DAMAGE.
338360efbdSAlfred Perlstein  */
348360efbdSAlfred Perlstein /*
358360efbdSAlfred Perlstein  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
368360efbdSAlfred Perlstein  */
378360efbdSAlfred Perlstein 
388360efbdSAlfred Perlstein /*
398360efbdSAlfred Perlstein  * rpcb_svc_4.c
408360efbdSAlfred Perlstein  * The server procedure for the version 4 rpcbind.
418360efbdSAlfred Perlstein  *
428360efbdSAlfred Perlstein  */
438360efbdSAlfred Perlstein 
448360efbdSAlfred Perlstein #include <sys/types.h>
458360efbdSAlfred Perlstein #include <sys/stat.h>
468360efbdSAlfred Perlstein #include <rpc/rpc.h>
478360efbdSAlfred Perlstein #include <stdio.h>
488360efbdSAlfred Perlstein #include <netconfig.h>
498360efbdSAlfred Perlstein #include <string.h>
508360efbdSAlfred Perlstein #include <stdlib.h>
518360efbdSAlfred Perlstein #include "rpcbind.h"
528360efbdSAlfred Perlstein 
53784bddbcSKevin Lo static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
54784bddbcSKevin Lo 				      rpcvers_t);
55784bddbcSKevin Lo static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
568360efbdSAlfred Perlstein static void *rpcbproc_getaddrlist_4_local
57784bddbcSKevin Lo 	(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
58784bddbcSKevin Lo static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
59784bddbcSKevin Lo static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
608360efbdSAlfred Perlstein 
618360efbdSAlfred Perlstein /*
628360efbdSAlfred Perlstein  * Called by svc_getreqset. There is a separate server handle for
638360efbdSAlfred Perlstein  * every transport that it waits on.
648360efbdSAlfred Perlstein  */
658360efbdSAlfred Perlstein void
rpcb_service_4(struct svc_req * rqstp,SVCXPRT * transp)668360efbdSAlfred Perlstein rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
678360efbdSAlfred Perlstein {
688360efbdSAlfred Perlstein 	union {
698360efbdSAlfred Perlstein 		rpcb rpcbproc_set_4_arg;
708360efbdSAlfred Perlstein 		rpcb rpcbproc_unset_4_arg;
718360efbdSAlfred Perlstein 		rpcb rpcbproc_getaddr_4_local_arg;
728360efbdSAlfred Perlstein 		char *rpcbproc_uaddr2taddr_4_arg;
738360efbdSAlfred Perlstein 		struct netbuf rpcbproc_taddr2uaddr_4_arg;
748360efbdSAlfred Perlstein 	} argument;
758360efbdSAlfred Perlstein 	char *result;
768360efbdSAlfred Perlstein 	xdrproc_t xdr_argument, xdr_result;
77784bddbcSKevin Lo 	void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
788360efbdSAlfred Perlstein 
798360efbdSAlfred Perlstein 	rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
808360efbdSAlfred Perlstein 
818360efbdSAlfred Perlstein 	switch (rqstp->rq_proc) {
828360efbdSAlfred Perlstein 	case NULLPROC:
838360efbdSAlfred Perlstein 		/*
848360efbdSAlfred Perlstein 		 * Null proc call
858360efbdSAlfred Perlstein 		 */
868360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
878360efbdSAlfred Perlstein 		if (debugging)
888360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_NULL\n");
898360efbdSAlfred Perlstein #endif
908360efbdSAlfred Perlstein 		check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
918360efbdSAlfred Perlstein 		(void) svc_sendreply(transp, (xdrproc_t) xdr_void,
928360efbdSAlfred Perlstein 					(char *)NULL);
938360efbdSAlfred Perlstein 		return;
948360efbdSAlfred Perlstein 
958360efbdSAlfred Perlstein 	case RPCBPROC_SET:
968360efbdSAlfred Perlstein 		/*
978360efbdSAlfred Perlstein 		 * Check to see whether the message came from
988360efbdSAlfred Perlstein 		 * loopback transports (for security reasons)
998360efbdSAlfred Perlstein 		 */
1008360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1018360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_bool;
1028360efbdSAlfred Perlstein 		local = rpcbproc_set_com;
1038360efbdSAlfred Perlstein 		break;
1048360efbdSAlfred Perlstein 
1058360efbdSAlfred Perlstein 	case RPCBPROC_UNSET:
1068360efbdSAlfred Perlstein 		/*
1078360efbdSAlfred Perlstein 		 * Check to see whether the message came from
1088360efbdSAlfred Perlstein 		 * loopback transports (for security reasons)
1098360efbdSAlfred Perlstein 		 */
1108360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1118360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_bool;
1128360efbdSAlfred Perlstein 		local = rpcbproc_unset_com;
1138360efbdSAlfred Perlstein 		break;
1148360efbdSAlfred Perlstein 
1158360efbdSAlfred Perlstein 	case RPCBPROC_GETADDR:
1168360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1178360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_wrapstring;
1188360efbdSAlfred Perlstein 		local = rpcbproc_getaddr_4_local;
1198360efbdSAlfred Perlstein 		break;
1208360efbdSAlfred Perlstein 
1218360efbdSAlfred Perlstein 	case RPCBPROC_GETVERSADDR:
1228360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1238360efbdSAlfred Perlstein 		if (debugging)
1248360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
1258360efbdSAlfred Perlstein #endif
1268360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1278360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_wrapstring;
1288360efbdSAlfred Perlstein 		local = rpcbproc_getversaddr_4_local;
1298360efbdSAlfred Perlstein 		break;
1308360efbdSAlfred Perlstein 
1318360efbdSAlfred Perlstein 	case RPCBPROC_DUMP:
1328360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1338360efbdSAlfred Perlstein 		if (debugging)
1348360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_DUMP\n");
1358360efbdSAlfred Perlstein #endif
1368360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_void;
1378360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
1388360efbdSAlfred Perlstein 		local = rpcbproc_dump_4_local;
1398360efbdSAlfred Perlstein 		break;
1408360efbdSAlfred Perlstein 
1418360efbdSAlfred Perlstein 	case RPCBPROC_INDIRECT:
1428360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1438360efbdSAlfred Perlstein 		if (debugging)
1448360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_INDIRECT\n");
1458360efbdSAlfred Perlstein #endif
1468360efbdSAlfred Perlstein 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
1478360efbdSAlfred Perlstein 		return;
1488360efbdSAlfred Perlstein 
1498360efbdSAlfred Perlstein /*	case RPCBPROC_CALLIT: */
1508360efbdSAlfred Perlstein 	case RPCBPROC_BCAST:
1518360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1528360efbdSAlfred Perlstein 		if (debugging)
1538360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_BCAST\n");
1548360efbdSAlfred Perlstein #endif
1558360efbdSAlfred Perlstein 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
1568360efbdSAlfred Perlstein 		return;
1578360efbdSAlfred Perlstein 
1588360efbdSAlfred Perlstein 	case RPCBPROC_GETTIME:
1598360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1608360efbdSAlfred Perlstein 		if (debugging)
1618360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_GETTIME\n");
1628360efbdSAlfred Perlstein #endif
1638360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_void;
1648360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_u_long;
1658360efbdSAlfred Perlstein 		local = rpcbproc_gettime_com;
1668360efbdSAlfred Perlstein 		break;
1678360efbdSAlfred Perlstein 
1688360efbdSAlfred Perlstein 	case RPCBPROC_UADDR2TADDR:
1698360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1708360efbdSAlfred Perlstein 		if (debugging)
1718360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
1728360efbdSAlfred Perlstein #endif
1738360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_wrapstring;
1748360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_netbuf;
1758360efbdSAlfred Perlstein 		local = rpcbproc_uaddr2taddr_com;
1768360efbdSAlfred Perlstein 		break;
1778360efbdSAlfred Perlstein 
1788360efbdSAlfred Perlstein 	case RPCBPROC_TADDR2UADDR:
1798360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1808360efbdSAlfred Perlstein 		if (debugging)
1818360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
1828360efbdSAlfred Perlstein #endif
1838360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_netbuf;
1848360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_wrapstring;
1858360efbdSAlfred Perlstein 		local = rpcbproc_taddr2uaddr_com;
1868360efbdSAlfred Perlstein 		break;
1878360efbdSAlfred Perlstein 
1888360efbdSAlfred Perlstein 	case RPCBPROC_GETADDRLIST:
1898360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1908360efbdSAlfred Perlstein 		if (debugging)
1918360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
1928360efbdSAlfred Perlstein #endif
1938360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1948360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
1958360efbdSAlfred Perlstein 		local = rpcbproc_getaddrlist_4_local;
1968360efbdSAlfred Perlstein 		break;
1978360efbdSAlfred Perlstein 
1988360efbdSAlfred Perlstein 	case RPCBPROC_GETSTAT:
1998360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
2008360efbdSAlfred Perlstein 		if (debugging)
2018360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_GETSTAT\n");
2028360efbdSAlfred Perlstein #endif
2038360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_void;
2048360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
2058360efbdSAlfred Perlstein 		local = rpcbproc_getstat;
2068360efbdSAlfred Perlstein 		break;
2078360efbdSAlfred Perlstein 
2088360efbdSAlfred Perlstein 	default:
2098360efbdSAlfred Perlstein 		svcerr_noproc(transp);
2108360efbdSAlfred Perlstein 		return;
2118360efbdSAlfred Perlstein 	}
2128360efbdSAlfred Perlstein 	memset((char *)&argument, 0, sizeof (argument));
2138360efbdSAlfred Perlstein 	if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
2148360efbdSAlfred Perlstein 		(char *)&argument)) {
2158360efbdSAlfred Perlstein 		svcerr_decode(transp);
2168360efbdSAlfred Perlstein 		if (debugging)
2178360efbdSAlfred Perlstein 			(void) fprintf(stderr, "rpcbind: could not decode\n");
2188360efbdSAlfred Perlstein 		return;
2198360efbdSAlfred Perlstein 	}
2208360efbdSAlfred Perlstein 	if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
2218360efbdSAlfred Perlstein 		svcerr_weakauth(transp);
2228360efbdSAlfred Perlstein 		goto done;
2238360efbdSAlfred Perlstein 	}
2248360efbdSAlfred Perlstein 	result = (*local)(&argument, rqstp, transp, RPCBVERS4);
2258360efbdSAlfred Perlstein 	if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
2268360efbdSAlfred Perlstein 						result)) {
2278360efbdSAlfred Perlstein 		svcerr_systemerr(transp);
2288360efbdSAlfred Perlstein 		if (debugging) {
2298360efbdSAlfred Perlstein 			(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
2308360efbdSAlfred Perlstein 			if (doabort) {
2318360efbdSAlfred Perlstein 				rpcbind_abort();
2328360efbdSAlfred Perlstein 			}
2338360efbdSAlfred Perlstein 		}
2348360efbdSAlfred Perlstein 	}
2358360efbdSAlfred Perlstein done:
2368360efbdSAlfred Perlstein 	if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
2378360efbdSAlfred Perlstein 				(char *)&argument)) {
2388360efbdSAlfred Perlstein 		if (debugging) {
2398360efbdSAlfred Perlstein 			(void) fprintf(stderr, "unable to free arguments\n");
2408360efbdSAlfred Perlstein 			if (doabort) {
2418360efbdSAlfred Perlstein 				rpcbind_abort();
2428360efbdSAlfred Perlstein 			}
2438360efbdSAlfred Perlstein 		}
2448360efbdSAlfred Perlstein 	}
2458360efbdSAlfred Perlstein }
2468360efbdSAlfred Perlstein 
2478360efbdSAlfred Perlstein /*
2488360efbdSAlfred Perlstein  * Lookup the mapping for a program, version and return its
2498360efbdSAlfred Perlstein  * address. Assuming that the caller wants the address of the
2508360efbdSAlfred Perlstein  * server running on the transport on which the request came.
2518360efbdSAlfred Perlstein  * Even if a service with a different version number is available,
2528360efbdSAlfred Perlstein  * it will return that address.  The client should check with an
2538360efbdSAlfred Perlstein  * clnt_call to verify whether the service is the one that is desired.
2548360efbdSAlfred Perlstein  * We also try to resolve the universal address in terms of
2558360efbdSAlfred Perlstein  * address of the caller.
2568360efbdSAlfred Perlstein  */
2578360efbdSAlfred Perlstein /* ARGSUSED */
2588360efbdSAlfred Perlstein static void *
rpcbproc_getaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t rpcbversnum __unused)2598360efbdSAlfred Perlstein rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
2604180788fSAlfred Perlstein 			 rpcvers_t rpcbversnum __unused)
2618360efbdSAlfred Perlstein {
2628360efbdSAlfred Perlstein 	RPCB *regp = (RPCB *)arg;
2638360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
2648360efbdSAlfred Perlstein 	if (debugging) {
2658360efbdSAlfred Perlstein 		char *uaddr;
2668360efbdSAlfred Perlstein 
2678360efbdSAlfred Perlstein 		uaddr =	taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
2688360efbdSAlfred Perlstein 			    svc_getrpccaller(transp));
2698360efbdSAlfred Perlstein 		fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
2708360efbdSAlfred Perlstein 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
2718360efbdSAlfred Perlstein 		    regp->r_netid, uaddr);
2728360efbdSAlfred Perlstein 		free(uaddr);
2738360efbdSAlfred Perlstein 	}
2748360efbdSAlfred Perlstein #endif
2758360efbdSAlfred Perlstein 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
2768360efbdSAlfred Perlstein 					RPCB_ALLVERS));
2778360efbdSAlfred Perlstein }
2788360efbdSAlfred Perlstein 
2798360efbdSAlfred Perlstein /*
2808360efbdSAlfred Perlstein  * Lookup the mapping for a program, version and return its
2818360efbdSAlfred Perlstein  * address. Assuming that the caller wants the address of the
2828360efbdSAlfred Perlstein  * server running on the transport on which the request came.
2838360efbdSAlfred Perlstein  *
2848360efbdSAlfred Perlstein  * We also try to resolve the universal address in terms of
2858360efbdSAlfred Perlstein  * address of the caller.
2868360efbdSAlfred Perlstein  */
2878360efbdSAlfred Perlstein /* ARGSUSED */
2888360efbdSAlfred Perlstein static void *
rpcbproc_getversaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t versnum __unused)2898360efbdSAlfred Perlstein rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
2904180788fSAlfred Perlstein 			     rpcvers_t versnum __unused)
2918360efbdSAlfred Perlstein {
2928360efbdSAlfred Perlstein 	RPCB *regp = (RPCB *)arg;
2938360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
2948360efbdSAlfred Perlstein 	if (debugging) {
2958360efbdSAlfred Perlstein 		char *uaddr;
2968360efbdSAlfred Perlstein 
2978360efbdSAlfred Perlstein 		uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
2988360efbdSAlfred Perlstein 			    svc_getrpccaller(transp));
2998360efbdSAlfred Perlstein 		fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
3008360efbdSAlfred Perlstein 				" from %s : ",
3018360efbdSAlfred Perlstein 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
3028360efbdSAlfred Perlstein 		    regp->r_netid, uaddr);
3038360efbdSAlfred Perlstein 		free(uaddr);
3048360efbdSAlfred Perlstein 	}
3058360efbdSAlfred Perlstein #endif
3068360efbdSAlfred Perlstein 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
3078360efbdSAlfred Perlstein 					RPCB_ONEVERS));
3088360efbdSAlfred Perlstein }
3098360efbdSAlfred Perlstein 
3108360efbdSAlfred Perlstein /*
3118360efbdSAlfred Perlstein  * Lookup the mapping for a program, version and return the
3128360efbdSAlfred Perlstein  * addresses for all transports in the current transport family.
3138360efbdSAlfred Perlstein  * We return a merged address.
3148360efbdSAlfred Perlstein  */
3158360efbdSAlfred Perlstein /* ARGSUSED */
3168360efbdSAlfred Perlstein static void *
rpcbproc_getaddrlist_4_local(void * arg,struct svc_req * rqstp __unused,SVCXPRT * transp,rpcvers_t versnum __unused)3174180788fSAlfred Perlstein rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused,
3184180788fSAlfred Perlstein 			     SVCXPRT *transp, rpcvers_t versnum __unused)
3198360efbdSAlfred Perlstein {
3208360efbdSAlfred Perlstein 	RPCB *regp = (RPCB *)arg;
3218360efbdSAlfred Perlstein 	static rpcb_entry_list_ptr rlist;
3228360efbdSAlfred Perlstein 	register rpcblist_ptr rbl;
3238360efbdSAlfred Perlstein 	rpcb_entry_list_ptr rp, tail;
3248360efbdSAlfred Perlstein 	rpcprog_t prog;
3258360efbdSAlfred Perlstein 	rpcvers_t vers;
3268360efbdSAlfred Perlstein 	rpcb_entry *a;
3278360efbdSAlfred Perlstein 	struct netconfig *nconf;
3288360efbdSAlfred Perlstein 	struct netconfig *reg_nconf;
3298360efbdSAlfred Perlstein 	char *saddr, *maddr = NULL;
3308360efbdSAlfred Perlstein 
3318360efbdSAlfred Perlstein 	free_rpcb_entry_list(&rlist);
3325732749cSIan Dowse 	tail = NULL;
3338360efbdSAlfred Perlstein 	prog = regp->r_prog;
3348360efbdSAlfred Perlstein 	vers = regp->r_vers;
3358360efbdSAlfred Perlstein 	reg_nconf = rpcbind_get_conf(transp->xp_netid);
3368360efbdSAlfred Perlstein 	if (reg_nconf == NULL)
3378360efbdSAlfred Perlstein 		return (NULL);
3388360efbdSAlfred Perlstein 	if (*(regp->r_addr) != '\0') {
3398360efbdSAlfred Perlstein 		saddr = regp->r_addr;
3408360efbdSAlfred Perlstein 	} else {
3418360efbdSAlfred Perlstein 		saddr = NULL;
3428360efbdSAlfred Perlstein 	}
3438360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
3448360efbdSAlfred Perlstein 	if (debugging) {
3458360efbdSAlfred Perlstein 		fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
3468360efbdSAlfred Perlstein 		    regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
3478360efbdSAlfred Perlstein 	}
3488360efbdSAlfred Perlstein #endif
3498360efbdSAlfred Perlstein 	for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
3508360efbdSAlfred Perlstein 	    if ((rbl->rpcb_map.r_prog == prog) &&
3518360efbdSAlfred Perlstein 		(rbl->rpcb_map.r_vers == vers)) {
3528360efbdSAlfred Perlstein 		nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
3538360efbdSAlfred Perlstein 		if (nconf == NULL)
3548360efbdSAlfred Perlstein 			goto fail;
3558360efbdSAlfred Perlstein 		if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
3568360efbdSAlfred Perlstein 				!= 0) {
3578360efbdSAlfred Perlstein 			continue;	/* not same proto family */
3588360efbdSAlfred Perlstein 		}
3598360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
3608360efbdSAlfred Perlstein 		if (debugging)
3615732749cSIan Dowse 			fprintf(stderr, "\tmerge with: %s\n",
3625732749cSIan Dowse 			    rbl->rpcb_map.r_addr);
3638360efbdSAlfred Perlstein #endif
3648360efbdSAlfred Perlstein 		if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
3658360efbdSAlfred Perlstein 				rbl->rpcb_map.r_addr, saddr)) == NULL) {
3668360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
3678360efbdSAlfred Perlstein 		if (debugging)
3688360efbdSAlfred Perlstein 			fprintf(stderr, " FAILED\n");
3698360efbdSAlfred Perlstein #endif
3708360efbdSAlfred Perlstein 			continue;
3718360efbdSAlfred Perlstein 		} else if (!maddr[0]) {
3728360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
3738360efbdSAlfred Perlstein 	if (debugging)
3748360efbdSAlfred Perlstein 		fprintf(stderr, " SUCCEEDED, but port died -  maddr: nullstring\n");
3758360efbdSAlfred Perlstein #endif
3768360efbdSAlfred Perlstein 			/* The server died. Unset this combination */
3778360efbdSAlfred Perlstein 			delete_prog(regp->r_prog);
3788360efbdSAlfred Perlstein 			continue;
3798360efbdSAlfred Perlstein 		}
3808360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
3818360efbdSAlfred Perlstein 		if (debugging)
3828360efbdSAlfred Perlstein 			fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
3838360efbdSAlfred Perlstein #endif
3848360efbdSAlfred Perlstein 		/*
3858360efbdSAlfred Perlstein 		 * Add it to rlist.
3868360efbdSAlfred Perlstein 		 */
3872244ec01SJuli Mallett 		rp = malloc(sizeof (rpcb_entry_list));
3888360efbdSAlfred Perlstein 		if (rp == NULL)
3898360efbdSAlfred Perlstein 			goto fail;
3908360efbdSAlfred Perlstein 		a = &rp->rpcb_entry_map;
3918360efbdSAlfred Perlstein 		a->r_maddr = maddr;
3928360efbdSAlfred Perlstein 		a->r_nc_netid = nconf->nc_netid;
3938360efbdSAlfred Perlstein 		a->r_nc_semantics = nconf->nc_semantics;
3948360efbdSAlfred Perlstein 		a->r_nc_protofmly = nconf->nc_protofmly;
3958360efbdSAlfred Perlstein 		a->r_nc_proto = nconf->nc_proto;
3968360efbdSAlfred Perlstein 		rp->rpcb_entry_next = NULL;
3978360efbdSAlfred Perlstein 		if (rlist == NULL) {
3988360efbdSAlfred Perlstein 			rlist = rp;
3998360efbdSAlfred Perlstein 			tail = rp;
4008360efbdSAlfred Perlstein 		} else {
4018360efbdSAlfred Perlstein 			tail->rpcb_entry_next = rp;
4028360efbdSAlfred Perlstein 			tail = rp;
4038360efbdSAlfred Perlstein 		}
4048360efbdSAlfred Perlstein 		rp = NULL;
4058360efbdSAlfred Perlstein 	    }
4068360efbdSAlfred Perlstein 	}
4078360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
4088360efbdSAlfred Perlstein 	if (debugging) {
4098360efbdSAlfred Perlstein 		for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
4108360efbdSAlfred Perlstein 			fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
4118360efbdSAlfred Perlstein 				rp->rpcb_entry_map.r_nc_proto);
4128360efbdSAlfred Perlstein 		}
4138360efbdSAlfred Perlstein 	}
4148360efbdSAlfred Perlstein #endif
4158360efbdSAlfred Perlstein 	/*
4168360efbdSAlfred Perlstein 	 * XXX: getaddrlist info is also being stuffed into getaddr.
4178360efbdSAlfred Perlstein 	 * Perhaps wrong, but better than it not getting counted at all.
4188360efbdSAlfred Perlstein 	 */
4198360efbdSAlfred Perlstein 	rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
4208360efbdSAlfred Perlstein 	return (void *)&rlist;
4218360efbdSAlfred Perlstein 
4228360efbdSAlfred Perlstein fail:	free_rpcb_entry_list(&rlist);
4238360efbdSAlfred Perlstein 	return (NULL);
4248360efbdSAlfred Perlstein }
4258360efbdSAlfred Perlstein 
4268360efbdSAlfred Perlstein /*
4278360efbdSAlfred Perlstein  * Free only the allocated structure, rest is all a pointer to some
4288360efbdSAlfred Perlstein  * other data somewhere else.
4298360efbdSAlfred Perlstein  */
4308360efbdSAlfred Perlstein static void
free_rpcb_entry_list(rpcb_entry_list_ptr * rlistp)4318360efbdSAlfred Perlstein free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
4328360efbdSAlfred Perlstein {
4338360efbdSAlfred Perlstein 	register rpcb_entry_list_ptr rbl, tmp;
4348360efbdSAlfred Perlstein 
4358360efbdSAlfred Perlstein 	for (rbl = *rlistp; rbl != NULL; ) {
4368360efbdSAlfred Perlstein 		tmp = rbl;
4378360efbdSAlfred Perlstein 		rbl = rbl->rpcb_entry_next;
4388360efbdSAlfred Perlstein 		free((char *)tmp->rpcb_entry_map.r_maddr);
4398360efbdSAlfred Perlstein 		free((char *)tmp);
4408360efbdSAlfred Perlstein 	}
4418360efbdSAlfred Perlstein 	*rlistp = NULL;
4428360efbdSAlfred Perlstein }
4438360efbdSAlfred Perlstein 
4448360efbdSAlfred Perlstein /* ARGSUSED */
4458360efbdSAlfred Perlstein static void *
rpcbproc_dump_4_local(void * arg __unused,struct svc_req * req __unused,SVCXPRT * xprt __unused,rpcvers_t versnum __unused)4464180788fSAlfred Perlstein rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused,
4474180788fSAlfred Perlstein     		      SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
4488360efbdSAlfred Perlstein {
4498360efbdSAlfred Perlstein 	return ((void *)&list_rbl);
4508360efbdSAlfred Perlstein }
451