xref: /illumos-gate/usr/src/cmd/rpcbind/pmap_svc.c (revision 8f6d9dae)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
26*8f6d9daeSMarcel Telka /*
27*8f6d9daeSMarcel Telka  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
28*8f6d9daeSMarcel Telka  */
297c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
307c478bd9Sstevel@tonic-gate /* All Rights Reserved */
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
337c478bd9Sstevel@tonic-gate  * The Regents of the University of California
347c478bd9Sstevel@tonic-gate  * All Rights Reserved
357c478bd9Sstevel@tonic-gate  *
367c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
377c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
387c478bd9Sstevel@tonic-gate  * contributors.
397c478bd9Sstevel@tonic-gate  */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * pmap_svc.c
437c478bd9Sstevel@tonic-gate  * The server procedure for the version 2 portmaper.
447c478bd9Sstevel@tonic-gate  * All the portmapper related interface from the portmap side.
457c478bd9Sstevel@tonic-gate  */
467c478bd9Sstevel@tonic-gate 
47*8f6d9daeSMarcel Telka #include <rpc/rpc.h>
48*8f6d9daeSMarcel Telka #include <tcpd.h>
49*8f6d9daeSMarcel Telka 
50*8f6d9daeSMarcel Telka #include "rpcbind.h"
51*8f6d9daeSMarcel Telka 
527c478bd9Sstevel@tonic-gate #ifdef PORTMAP
537c478bd9Sstevel@tonic-gate #include <stdio.h>
547c478bd9Sstevel@tonic-gate #include <alloca.h>
557c478bd9Sstevel@tonic-gate #include <ucred.h>
567c478bd9Sstevel@tonic-gate #include <rpc/pmap_prot.h>
577c478bd9Sstevel@tonic-gate #include <rpc/rpcb_prot.h>
58*8f6d9daeSMarcel Telka #include <assert.h>
597c478bd9Sstevel@tonic-gate 
60*8f6d9daeSMarcel Telka static bool_t pmapproc_change(struct svc_req *, SVCXPRT *, unsigned long);
61*8f6d9daeSMarcel Telka static bool_t pmapproc_getport(struct svc_req *, SVCXPRT *);
62*8f6d9daeSMarcel Telka static bool_t pmapproc_dump(struct svc_req *, SVCXPRT *);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate /*
657c478bd9Sstevel@tonic-gate  * Called for all the version 2 inquiries.
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate void
pmap_service(struct svc_req * rqstp,SVCXPRT * xprt)68*8f6d9daeSMarcel Telka pmap_service(struct svc_req *rqstp, SVCXPRT *xprt)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate 	rpcbs_procinfo(RPCBVERS_2_STAT, rqstp->rq_proc);
71*8f6d9daeSMarcel Telka 
727c478bd9Sstevel@tonic-gate 	switch (rqstp->rq_proc) {
737c478bd9Sstevel@tonic-gate 	case PMAPPROC_NULL:
747c478bd9Sstevel@tonic-gate 		/*
757c478bd9Sstevel@tonic-gate 		 * Null proc call
767c478bd9Sstevel@tonic-gate 		 */
777c478bd9Sstevel@tonic-gate 		PMAP_CHECK(xprt, rqstp->rq_proc);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 		if ((!svc_sendreply(xprt, (xdrproc_t)xdr_void, NULL)) &&
80*8f6d9daeSMarcel Telka 		    debugging) {
817c478bd9Sstevel@tonic-gate 			if (doabort) {
827c478bd9Sstevel@tonic-gate 				rpcbind_abort();
837c478bd9Sstevel@tonic-gate 			}
847c478bd9Sstevel@tonic-gate 		}
857c478bd9Sstevel@tonic-gate 		break;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	case PMAPPROC_SET:
887c478bd9Sstevel@tonic-gate 		/*
897c478bd9Sstevel@tonic-gate 		 * Set a program, version to port mapping
907c478bd9Sstevel@tonic-gate 		 */
917c478bd9Sstevel@tonic-gate 		pmapproc_change(rqstp, xprt, rqstp->rq_proc);
927c478bd9Sstevel@tonic-gate 		break;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	case PMAPPROC_UNSET:
957c478bd9Sstevel@tonic-gate 		/*
967c478bd9Sstevel@tonic-gate 		 * Remove a program, version to port mapping.
977c478bd9Sstevel@tonic-gate 		 */
987c478bd9Sstevel@tonic-gate 		pmapproc_change(rqstp, xprt, rqstp->rq_proc);
997c478bd9Sstevel@tonic-gate 		break;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	case PMAPPROC_GETPORT:
1027c478bd9Sstevel@tonic-gate 		/*
1037c478bd9Sstevel@tonic-gate 		 * Lookup the mapping for a program, version and return its
1047c478bd9Sstevel@tonic-gate 		 * port number.
1057c478bd9Sstevel@tonic-gate 		 */
1067c478bd9Sstevel@tonic-gate 		pmapproc_getport(rqstp, xprt);
1077c478bd9Sstevel@tonic-gate 		break;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	case PMAPPROC_DUMP:
1107c478bd9Sstevel@tonic-gate 		/*
1117c478bd9Sstevel@tonic-gate 		 * Return the current set of mapped program, version
1127c478bd9Sstevel@tonic-gate 		 */
1137c478bd9Sstevel@tonic-gate 		PMAP_CHECK(xprt, rqstp->rq_proc);
1147c478bd9Sstevel@tonic-gate 		pmapproc_dump(rqstp, xprt);
1157c478bd9Sstevel@tonic-gate 		break;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	case PMAPPROC_CALLIT:
1187c478bd9Sstevel@tonic-gate 		/*
1197c478bd9Sstevel@tonic-gate 		 * Calls a procedure on the local machine. If the requested
1207c478bd9Sstevel@tonic-gate 		 * procedure is not registered this procedure does not return
1217c478bd9Sstevel@tonic-gate 		 * error information!!
1227c478bd9Sstevel@tonic-gate 		 * This procedure is only supported on rpc/udp and calls via
1237c478bd9Sstevel@tonic-gate 		 * rpc/udp. It passes null authentication parameters.
1247c478bd9Sstevel@tonic-gate 		 */
1257c478bd9Sstevel@tonic-gate 		rpcbproc_callit_com(rqstp, xprt, PMAPPROC_CALLIT, PMAPVERS);
1267c478bd9Sstevel@tonic-gate 		break;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	default:
1297c478bd9Sstevel@tonic-gate 		PMAP_CHECK(xprt, rqstp->rq_proc);
1307c478bd9Sstevel@tonic-gate 		svcerr_noproc(xprt);
1317c478bd9Sstevel@tonic-gate 		break;
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate  * returns the item with the given program, version number. If that version
1377c478bd9Sstevel@tonic-gate  * number is not found, it returns the item with that program number, so that
1387c478bd9Sstevel@tonic-gate  * the port number is now returned to the caller. The caller when makes a
1397c478bd9Sstevel@tonic-gate  * call to this program, version number, the call will fail and it will
1407c478bd9Sstevel@tonic-gate  * return with PROGVERS_MISMATCH. The user can then determine the highest
1417c478bd9Sstevel@tonic-gate  * and the lowest version number for this program using clnt_geterr() and
1427c478bd9Sstevel@tonic-gate  * use those program version numbers.
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate static PMAPLIST *
find_service_pmap(rpcprog_t prog,rpcvers_t vers,rpcprot_t prot)145*8f6d9daeSMarcel Telka find_service_pmap(rpcprog_t prog, rpcvers_t vers, rpcprot_t prot)
1467c478bd9Sstevel@tonic-gate {
147*8f6d9daeSMarcel Telka 	PMAPLIST *hit = NULL;
148*8f6d9daeSMarcel Telka 	PMAPLIST *pml;
149*8f6d9daeSMarcel Telka 
150*8f6d9daeSMarcel Telka 	assert(RW_LOCK_HELD(&list_pml_lock));
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	for (pml = list_pml; pml != NULL; pml = pml->pml_next) {
1537c478bd9Sstevel@tonic-gate 		if ((pml->pml_map.pm_prog != prog) ||
154*8f6d9daeSMarcel Telka 		    (pml->pml_map.pm_prot != prot))
1557c478bd9Sstevel@tonic-gate 			continue;
1567c478bd9Sstevel@tonic-gate 		hit = pml;
1577c478bd9Sstevel@tonic-gate 		if (pml->pml_map.pm_vers == vers)
1587c478bd9Sstevel@tonic-gate 			break;
1597c478bd9Sstevel@tonic-gate 	}
160*8f6d9daeSMarcel Telka 
1617c478bd9Sstevel@tonic-gate 	return (hit);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
164*8f6d9daeSMarcel Telka /* ARGSUSED */
1657c478bd9Sstevel@tonic-gate static bool_t
pmapproc_change(struct svc_req * rqstp,SVCXPRT * xprt,unsigned long op)166*8f6d9daeSMarcel Telka pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate 	PMAP reg;
1697c478bd9Sstevel@tonic-gate 	RPCB rpcbreg;
1707c478bd9Sstevel@tonic-gate 	int ans;
1717c478bd9Sstevel@tonic-gate 	struct sockaddr_in *who;
1727c478bd9Sstevel@tonic-gate 	char owner[64];
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (char *)&reg)) {
1757c478bd9Sstevel@tonic-gate 		svcerr_decode(xprt);
1767c478bd9Sstevel@tonic-gate 		return (FALSE);
1777c478bd9Sstevel@tonic-gate 	}
178*8f6d9daeSMarcel Telka 	who = (struct sockaddr_in *)svc_getrpccaller(xprt)->buf;
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	/* Don't allow unset/set from remote. */
1817c478bd9Sstevel@tonic-gate 	if (!localxprt(xprt, B_TRUE)) {
1827c478bd9Sstevel@tonic-gate 		ans = FALSE;
1837c478bd9Sstevel@tonic-gate 		goto done_change;
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	rpcbreg.r_owner = getowner(xprt, owner);
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	if ((op == PMAPPROC_SET) && (reg.pm_port < IPPORT_RESERVED) &&
1897c478bd9Sstevel@tonic-gate 	    (ntohs(who->sin_port) >= IPPORT_RESERVED)) {
1907c478bd9Sstevel@tonic-gate 		ans = FALSE;
1917c478bd9Sstevel@tonic-gate 		goto done_change;
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 	rpcbreg.r_prog = reg.pm_prog;
1947c478bd9Sstevel@tonic-gate 	rpcbreg.r_vers = reg.pm_vers;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	if (op == PMAPPROC_SET) {
1977c478bd9Sstevel@tonic-gate 		char buf[32];
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 		sprintf(buf, "0.0.0.0.%d.%d", (reg.pm_port >> 8) & 0xff,
200*8f6d9daeSMarcel Telka 		    reg.pm_port & 0xff);
2017c478bd9Sstevel@tonic-gate 		rpcbreg.r_addr = buf;
2027c478bd9Sstevel@tonic-gate 		if (reg.pm_prot == IPPROTO_UDP) {
2037c478bd9Sstevel@tonic-gate 			rpcbreg.r_netid = udptrans;
2047c478bd9Sstevel@tonic-gate 		} else if (reg.pm_prot == IPPROTO_TCP) {
2057c478bd9Sstevel@tonic-gate 			rpcbreg.r_netid = tcptrans;
2067c478bd9Sstevel@tonic-gate 		} else {
2077c478bd9Sstevel@tonic-gate 			ans = FALSE;
2087c478bd9Sstevel@tonic-gate 			goto done_change;
2097c478bd9Sstevel@tonic-gate 		}
2107c478bd9Sstevel@tonic-gate 		ans = map_set(&rpcbreg, rpcbreg.r_owner);
2117c478bd9Sstevel@tonic-gate 	} else if (op == PMAPPROC_UNSET) {
2127c478bd9Sstevel@tonic-gate 		bool_t ans1, ans2;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 		rpcbreg.r_addr = NULL;
2157c478bd9Sstevel@tonic-gate 		rpcbreg.r_netid = tcptrans;
2167c478bd9Sstevel@tonic-gate 		ans1 = map_unset(&rpcbreg, rpcbreg.r_owner);
2177c478bd9Sstevel@tonic-gate 		rpcbreg.r_netid = udptrans;
2187c478bd9Sstevel@tonic-gate 		ans2 = map_unset(&rpcbreg, rpcbreg.r_owner);
2197c478bd9Sstevel@tonic-gate 		ans = ans1 || ans2;
2207c478bd9Sstevel@tonic-gate 	} else {
2217c478bd9Sstevel@tonic-gate 		ans = FALSE;
2227c478bd9Sstevel@tonic-gate 	}
2237c478bd9Sstevel@tonic-gate done_change:
2247c478bd9Sstevel@tonic-gate 	PMAP_LOG(ans, xprt, op, reg.pm_prog);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	if ((!svc_sendreply(xprt, (xdrproc_t)xdr_long, (caddr_t)&ans)) &&
2277c478bd9Sstevel@tonic-gate 	    debugging) {
2287c478bd9Sstevel@tonic-gate 		fprintf(stderr, "portmap: svc_sendreply\n");
2297c478bd9Sstevel@tonic-gate 		if (doabort) {
2307c478bd9Sstevel@tonic-gate 			rpcbind_abort();
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 	if (op == PMAPPROC_SET)
2347c478bd9Sstevel@tonic-gate 		rpcbs_set(RPCBVERS_2_STAT, ans);
2357c478bd9Sstevel@tonic-gate 	else
2367c478bd9Sstevel@tonic-gate 		rpcbs_unset(RPCBVERS_2_STAT, ans);
2377c478bd9Sstevel@tonic-gate 	return (TRUE);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate /* ARGSUSED */
2417c478bd9Sstevel@tonic-gate static bool_t
pmapproc_getport(struct svc_req * rqstp,SVCXPRT * xprt)242*8f6d9daeSMarcel Telka pmapproc_getport(struct svc_req *rqstp, SVCXPRT *xprt)
2437c478bd9Sstevel@tonic-gate {
2447c478bd9Sstevel@tonic-gate 	PMAP reg;
2457c478bd9Sstevel@tonic-gate 	int port = 0;
2467c478bd9Sstevel@tonic-gate 	PMAPLIST *fnd;
247*8f6d9daeSMarcel Telka 	bool_t rbl_locked = FALSE;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (char *)&reg)) {
2507c478bd9Sstevel@tonic-gate 		svcerr_decode(xprt);
2517c478bd9Sstevel@tonic-gate 		return (FALSE);
2527c478bd9Sstevel@tonic-gate 	}
2537c478bd9Sstevel@tonic-gate 	PMAP_CHECK_RET(xprt, rqstp->rq_proc, FALSE);
2547c478bd9Sstevel@tonic-gate 
255*8f6d9daeSMarcel Telka 	(void) rw_rdlock(&list_pml_lock);
256*8f6d9daeSMarcel Telka retry:
2577c478bd9Sstevel@tonic-gate 	fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot);
2587c478bd9Sstevel@tonic-gate 	if (fnd) {
2597c478bd9Sstevel@tonic-gate 		char serveuaddr[32], *ua;
2607c478bd9Sstevel@tonic-gate 		int h1, h2, h3, h4, p1, p2;
2617c478bd9Sstevel@tonic-gate 		char *netid;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 		if (reg.pm_prot == IPPROTO_UDP) {
2647c478bd9Sstevel@tonic-gate 			ua = udp_uaddr;
2657c478bd9Sstevel@tonic-gate 			netid = udptrans;
2667c478bd9Sstevel@tonic-gate 		} else {
2677c478bd9Sstevel@tonic-gate 			ua = tcp_uaddr; /* To get the len */
2687c478bd9Sstevel@tonic-gate 			netid = tcptrans;
2697c478bd9Sstevel@tonic-gate 		}
2707c478bd9Sstevel@tonic-gate 		if (ua == NULL) {
271*8f6d9daeSMarcel Telka 			(void) rw_unlock(&list_pml_lock);
272*8f6d9daeSMarcel Telka 			if (rbl_locked)
273*8f6d9daeSMarcel Telka 				(void) rw_unlock(&list_rbl_lock);
2747c478bd9Sstevel@tonic-gate 			goto sendreply;
2757c478bd9Sstevel@tonic-gate 		}
2767c478bd9Sstevel@tonic-gate 		if (sscanf(ua, "%d.%d.%d.%d.%d.%d", &h1, &h2, &h3,
277*8f6d9daeSMarcel Telka 		    &h4, &p1, &p2) == 6) {
2787c478bd9Sstevel@tonic-gate 			p1 = (fnd->pml_map.pm_port >> 8) & 0xff;
2797c478bd9Sstevel@tonic-gate 			p2 = (fnd->pml_map.pm_port) & 0xff;
2807c478bd9Sstevel@tonic-gate 			sprintf(serveuaddr, "%d.%d.%d.%d.%d.%d",
281*8f6d9daeSMarcel Telka 			    h1, h2, h3, h4, p1, p2);
2827c478bd9Sstevel@tonic-gate 			if (is_bound(netid, serveuaddr)) {
2837c478bd9Sstevel@tonic-gate 				port = fnd->pml_map.pm_port;
2847c478bd9Sstevel@tonic-gate 			} else { /* this service is dead; delete it */
285*8f6d9daeSMarcel Telka 				if (!rbl_locked) {
286*8f6d9daeSMarcel Telka 					(void) rw_unlock(&list_pml_lock);
287*8f6d9daeSMarcel Telka 					(void) rw_wrlock(&list_rbl_lock);
288*8f6d9daeSMarcel Telka 					(void) rw_wrlock(&list_pml_lock);
289*8f6d9daeSMarcel Telka 					rbl_locked = TRUE;
290*8f6d9daeSMarcel Telka 					goto retry;
291*8f6d9daeSMarcel Telka 				}
2927c478bd9Sstevel@tonic-gate 				delete_prog(reg.pm_prog);
2937c478bd9Sstevel@tonic-gate 			}
2947c478bd9Sstevel@tonic-gate 		}
2957c478bd9Sstevel@tonic-gate 	}
296*8f6d9daeSMarcel Telka 	(void) rw_unlock(&list_pml_lock);
297*8f6d9daeSMarcel Telka 	if (rbl_locked)
298*8f6d9daeSMarcel Telka 		(void) rw_unlock(&list_rbl_lock);
299*8f6d9daeSMarcel Telka 
3007c478bd9Sstevel@tonic-gate sendreply:
3017c478bd9Sstevel@tonic-gate 	if ((!svc_sendreply(xprt, (xdrproc_t)xdr_long, (caddr_t)&port)) &&
302*8f6d9daeSMarcel Telka 	    debugging) {
3037c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "portmap: svc_sendreply\n");
3047c478bd9Sstevel@tonic-gate 		if (doabort) {
3057c478bd9Sstevel@tonic-gate 			rpcbind_abort();
3067c478bd9Sstevel@tonic-gate 		}
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 	rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers,
309*8f6d9daeSMarcel Telka 	    reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans,
310*8f6d9daeSMarcel Telka 	    port ? udptrans : "");
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	return (TRUE);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate /* ARGSUSED */
3167c478bd9Sstevel@tonic-gate static bool_t
pmapproc_dump(struct svc_req * rqstp,SVCXPRT * xprt)317*8f6d9daeSMarcel Telka pmapproc_dump(struct svc_req *rqstp, SVCXPRT *xprt)
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate 	if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) {
3207c478bd9Sstevel@tonic-gate 		svcerr_decode(xprt);
3217c478bd9Sstevel@tonic-gate 		return (FALSE);
3227c478bd9Sstevel@tonic-gate 	}
323*8f6d9daeSMarcel Telka 
324*8f6d9daeSMarcel Telka 	(void) rw_rdlock(&list_pml_lock);
3257c478bd9Sstevel@tonic-gate 	if ((!svc_sendreply(xprt, (xdrproc_t)xdr_pmaplist_ptr,
326*8f6d9daeSMarcel Telka 	    (caddr_t)&list_pml)) && debugging) {
327*8f6d9daeSMarcel Telka 		(void) rw_unlock(&list_pml_lock);
3287c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "portmap: svc_sendreply\n");
3297c478bd9Sstevel@tonic-gate 		if (doabort) {
3307c478bd9Sstevel@tonic-gate 			rpcbind_abort();
3317c478bd9Sstevel@tonic-gate 		}
332*8f6d9daeSMarcel Telka 	} else {
333*8f6d9daeSMarcel Telka 		(void) rw_unlock(&list_pml_lock);
3347c478bd9Sstevel@tonic-gate 	}
335*8f6d9daeSMarcel Telka 
3367c478bd9Sstevel@tonic-gate 	return (TRUE);
3377c478bd9Sstevel@tonic-gate }
338*8f6d9daeSMarcel Telka #endif /* PORTMAP */
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate /*
3417c478bd9Sstevel@tonic-gate  * Is the transport local?  The original rpcbind code tried to
3427c478bd9Sstevel@tonic-gate  * figure out all the network interfaces but there can be a nearly
3437c478bd9Sstevel@tonic-gate  * infinite number of network interfaces.  And the number of interfaces can
3447c478bd9Sstevel@tonic-gate  * vary over time.
3457c478bd9Sstevel@tonic-gate  *
3467c478bd9Sstevel@tonic-gate  * Note that when we get here, we've already establised that we're
3477c478bd9Sstevel@tonic-gate  * dealing with a TCP/IP endpoint.
3487c478bd9Sstevel@tonic-gate  */
3497c478bd9Sstevel@tonic-gate boolean_t
localxprt(SVCXPRT * transp,boolean_t forceipv4)3507c478bd9Sstevel@tonic-gate localxprt(SVCXPRT *transp, boolean_t forceipv4)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate 	struct sockaddr_gen *sgen = svc_getgencaller(transp);
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	switch (SGFAM(sgen)) {
3557c478bd9Sstevel@tonic-gate 	case AF_INET:
3567c478bd9Sstevel@tonic-gate 		break;
3577c478bd9Sstevel@tonic-gate 	case AF_INET6:
3587c478bd9Sstevel@tonic-gate 		if (forceipv4)
3597c478bd9Sstevel@tonic-gate 			return (B_FALSE);
3607c478bd9Sstevel@tonic-gate 		break;
3617c478bd9Sstevel@tonic-gate 	default:
3627c478bd9Sstevel@tonic-gate 		return (B_FALSE);
3637c478bd9Sstevel@tonic-gate 	}
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	/*
3667c478bd9Sstevel@tonic-gate 	 * Get the peer's uid; if it is known it is sufficiently
3677c478bd9Sstevel@tonic-gate 	 * authenticated and considered local.  The magic behind this
3687c478bd9Sstevel@tonic-gate 	 * call is all in libnsl.
3697c478bd9Sstevel@tonic-gate 	 */
3707c478bd9Sstevel@tonic-gate 	return (rpcb_caller_uid(transp) != -1);
3717c478bd9Sstevel@tonic-gate }
372