1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 30*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 31*7c478bd9Sstevel@tonic-gate * All Rights Reserved 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 34*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 35*7c478bd9Sstevel@tonic-gate * contributors. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * pmap_svc.c 42*7c478bd9Sstevel@tonic-gate * The server procedure for the version 2 portmaper. 43*7c478bd9Sstevel@tonic-gate * All the portmapper related interface from the portmap side. 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 47*7c478bd9Sstevel@tonic-gate #include <stdio.h> 48*7c478bd9Sstevel@tonic-gate #include <alloca.h> 49*7c478bd9Sstevel@tonic-gate #include <ucred.h> 50*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 51*7c478bd9Sstevel@tonic-gate #include <rpc/pmap_prot.h> 52*7c478bd9Sstevel@tonic-gate #include <rpc/rpcb_prot.h> 53*7c478bd9Sstevel@tonic-gate #include "rpcbind.h" 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 56*7c478bd9Sstevel@tonic-gate #include <netdir.h> 57*7c478bd9Sstevel@tonic-gate #endif 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate static PMAPLIST *find_service_pmap(); 60*7c478bd9Sstevel@tonic-gate static bool_t pmapproc_change(); 61*7c478bd9Sstevel@tonic-gate static bool_t pmapproc_getport(); 62*7c478bd9Sstevel@tonic-gate static bool_t pmapproc_dump(); 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* 65*7c478bd9Sstevel@tonic-gate * Called for all the version 2 inquiries. 66*7c478bd9Sstevel@tonic-gate */ 67*7c478bd9Sstevel@tonic-gate void 68*7c478bd9Sstevel@tonic-gate pmap_service(rqstp, xprt) 69*7c478bd9Sstevel@tonic-gate register struct svc_req *rqstp; 70*7c478bd9Sstevel@tonic-gate register SVCXPRT *xprt; 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate rpcbs_procinfo(RPCBVERS_2_STAT, rqstp->rq_proc); 73*7c478bd9Sstevel@tonic-gate switch (rqstp->rq_proc) { 74*7c478bd9Sstevel@tonic-gate case PMAPPROC_NULL: 75*7c478bd9Sstevel@tonic-gate /* 76*7c478bd9Sstevel@tonic-gate * Null proc call 77*7c478bd9Sstevel@tonic-gate */ 78*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 79*7c478bd9Sstevel@tonic-gate fprintf(stderr, "PMAPPROC_NULL\n"); 80*7c478bd9Sstevel@tonic-gate #endif 81*7c478bd9Sstevel@tonic-gate PMAP_CHECK(xprt, rqstp->rq_proc); 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate if ((!svc_sendreply(xprt, (xdrproc_t)xdr_void, NULL)) && 84*7c478bd9Sstevel@tonic-gate debugging) { 85*7c478bd9Sstevel@tonic-gate if (doabort) { 86*7c478bd9Sstevel@tonic-gate rpcbind_abort(); 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate break; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate case PMAPPROC_SET: 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * Set a program, version to port mapping 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate pmapproc_change(rqstp, xprt, rqstp->rq_proc); 96*7c478bd9Sstevel@tonic-gate break; 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate case PMAPPROC_UNSET: 99*7c478bd9Sstevel@tonic-gate /* 100*7c478bd9Sstevel@tonic-gate * Remove a program, version to port mapping. 101*7c478bd9Sstevel@tonic-gate */ 102*7c478bd9Sstevel@tonic-gate pmapproc_change(rqstp, xprt, rqstp->rq_proc); 103*7c478bd9Sstevel@tonic-gate break; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate case PMAPPROC_GETPORT: 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * Lookup the mapping for a program, version and return its 108*7c478bd9Sstevel@tonic-gate * port number. 109*7c478bd9Sstevel@tonic-gate */ 110*7c478bd9Sstevel@tonic-gate pmapproc_getport(rqstp, xprt); 111*7c478bd9Sstevel@tonic-gate break; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate case PMAPPROC_DUMP: 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * Return the current set of mapped program, version 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 118*7c478bd9Sstevel@tonic-gate fprintf(stderr, "PMAPPROC_DUMP\n"); 119*7c478bd9Sstevel@tonic-gate #endif 120*7c478bd9Sstevel@tonic-gate PMAP_CHECK(xprt, rqstp->rq_proc); 121*7c478bd9Sstevel@tonic-gate pmapproc_dump(rqstp, xprt); 122*7c478bd9Sstevel@tonic-gate break; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate case PMAPPROC_CALLIT: 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * Calls a procedure on the local machine. If the requested 127*7c478bd9Sstevel@tonic-gate * procedure is not registered this procedure does not return 128*7c478bd9Sstevel@tonic-gate * error information!! 129*7c478bd9Sstevel@tonic-gate * This procedure is only supported on rpc/udp and calls via 130*7c478bd9Sstevel@tonic-gate * rpc/udp. It passes null authentication parameters. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate rpcbproc_callit_com(rqstp, xprt, PMAPPROC_CALLIT, PMAPVERS); 133*7c478bd9Sstevel@tonic-gate break; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate default: 136*7c478bd9Sstevel@tonic-gate PMAP_CHECK(xprt, rqstp->rq_proc); 137*7c478bd9Sstevel@tonic-gate svcerr_noproc(xprt); 138*7c478bd9Sstevel@tonic-gate break; 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /* 143*7c478bd9Sstevel@tonic-gate * returns the item with the given program, version number. If that version 144*7c478bd9Sstevel@tonic-gate * number is not found, it returns the item with that program number, so that 145*7c478bd9Sstevel@tonic-gate * the port number is now returned to the caller. The caller when makes a 146*7c478bd9Sstevel@tonic-gate * call to this program, version number, the call will fail and it will 147*7c478bd9Sstevel@tonic-gate * return with PROGVERS_MISMATCH. The user can then determine the highest 148*7c478bd9Sstevel@tonic-gate * and the lowest version number for this program using clnt_geterr() and 149*7c478bd9Sstevel@tonic-gate * use those program version numbers. 150*7c478bd9Sstevel@tonic-gate */ 151*7c478bd9Sstevel@tonic-gate static PMAPLIST * 152*7c478bd9Sstevel@tonic-gate find_service_pmap(prog, vers, prot) 153*7c478bd9Sstevel@tonic-gate ulong_t prog; 154*7c478bd9Sstevel@tonic-gate ulong_t vers; 155*7c478bd9Sstevel@tonic-gate ulong_t prot; 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate register PMAPLIST *hit = NULL; 158*7c478bd9Sstevel@tonic-gate register PMAPLIST *pml; 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate for (pml = list_pml; pml != NULL; pml = pml->pml_next) { 161*7c478bd9Sstevel@tonic-gate if ((pml->pml_map.pm_prog != prog) || 162*7c478bd9Sstevel@tonic-gate (pml->pml_map.pm_prot != prot)) 163*7c478bd9Sstevel@tonic-gate continue; 164*7c478bd9Sstevel@tonic-gate hit = pml; 165*7c478bd9Sstevel@tonic-gate if (pml->pml_map.pm_vers == vers) 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate return (hit); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate extern char *getowner(SVCXPRT *xprt, char *); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 174*7c478bd9Sstevel@tonic-gate static bool_t 175*7c478bd9Sstevel@tonic-gate pmapproc_change(rqstp, xprt, op) 176*7c478bd9Sstevel@tonic-gate struct svc_req *rqstp; 177*7c478bd9Sstevel@tonic-gate register SVCXPRT *xprt; 178*7c478bd9Sstevel@tonic-gate unsigned long op; 179*7c478bd9Sstevel@tonic-gate { 180*7c478bd9Sstevel@tonic-gate PMAP reg; 181*7c478bd9Sstevel@tonic-gate RPCB rpcbreg; 182*7c478bd9Sstevel@tonic-gate int ans; 183*7c478bd9Sstevel@tonic-gate struct sockaddr_in *who; 184*7c478bd9Sstevel@tonic-gate extern bool_t map_set(), map_unset(); 185*7c478bd9Sstevel@tonic-gate char owner[64]; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (char *)®)) { 188*7c478bd9Sstevel@tonic-gate svcerr_decode(xprt); 189*7c478bd9Sstevel@tonic-gate return (FALSE); 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate who = svc_getcaller(xprt); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 194*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s request for (%lu, %lu) : ", 195*7c478bd9Sstevel@tonic-gate op == PMAPPROC_SET ? "PMAP_SET" : "PMAP_UNSET", 196*7c478bd9Sstevel@tonic-gate reg.pm_prog, reg.pm_vers); 197*7c478bd9Sstevel@tonic-gate #endif 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* Don't allow unset/set from remote. */ 200*7c478bd9Sstevel@tonic-gate if (!localxprt(xprt, B_TRUE)) { 201*7c478bd9Sstevel@tonic-gate ans = FALSE; 202*7c478bd9Sstevel@tonic-gate goto done_change; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate rpcbreg.r_owner = getowner(xprt, owner); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if ((op == PMAPPROC_SET) && (reg.pm_port < IPPORT_RESERVED) && 208*7c478bd9Sstevel@tonic-gate (ntohs(who->sin_port) >= IPPORT_RESERVED)) { 209*7c478bd9Sstevel@tonic-gate ans = FALSE; 210*7c478bd9Sstevel@tonic-gate goto done_change; 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate rpcbreg.r_prog = reg.pm_prog; 213*7c478bd9Sstevel@tonic-gate rpcbreg.r_vers = reg.pm_vers; 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if (op == PMAPPROC_SET) { 216*7c478bd9Sstevel@tonic-gate char buf[32]; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate sprintf(buf, "0.0.0.0.%d.%d", (reg.pm_port >> 8) & 0xff, 219*7c478bd9Sstevel@tonic-gate reg.pm_port & 0xff); 220*7c478bd9Sstevel@tonic-gate rpcbreg.r_addr = buf; 221*7c478bd9Sstevel@tonic-gate if (reg.pm_prot == IPPROTO_UDP) { 222*7c478bd9Sstevel@tonic-gate rpcbreg.r_netid = udptrans; 223*7c478bd9Sstevel@tonic-gate } else if (reg.pm_prot == IPPROTO_TCP) { 224*7c478bd9Sstevel@tonic-gate rpcbreg.r_netid = tcptrans; 225*7c478bd9Sstevel@tonic-gate } else { 226*7c478bd9Sstevel@tonic-gate ans = FALSE; 227*7c478bd9Sstevel@tonic-gate goto done_change; 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate ans = map_set(&rpcbreg, rpcbreg.r_owner); 230*7c478bd9Sstevel@tonic-gate } else if (op == PMAPPROC_UNSET) { 231*7c478bd9Sstevel@tonic-gate bool_t ans1, ans2; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate rpcbreg.r_addr = NULL; 234*7c478bd9Sstevel@tonic-gate rpcbreg.r_netid = tcptrans; 235*7c478bd9Sstevel@tonic-gate ans1 = map_unset(&rpcbreg, rpcbreg.r_owner); 236*7c478bd9Sstevel@tonic-gate rpcbreg.r_netid = udptrans; 237*7c478bd9Sstevel@tonic-gate ans2 = map_unset(&rpcbreg, rpcbreg.r_owner); 238*7c478bd9Sstevel@tonic-gate ans = ans1 || ans2; 239*7c478bd9Sstevel@tonic-gate } else { 240*7c478bd9Sstevel@tonic-gate ans = FALSE; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate done_change: 243*7c478bd9Sstevel@tonic-gate PMAP_LOG(ans, xprt, op, reg.pm_prog); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate if ((!svc_sendreply(xprt, (xdrproc_t)xdr_long, (caddr_t)&ans)) && 246*7c478bd9Sstevel@tonic-gate debugging) { 247*7c478bd9Sstevel@tonic-gate fprintf(stderr, "portmap: svc_sendreply\n"); 248*7c478bd9Sstevel@tonic-gate if (doabort) { 249*7c478bd9Sstevel@tonic-gate rpcbind_abort(); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 253*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed"); 254*7c478bd9Sstevel@tonic-gate #endif 255*7c478bd9Sstevel@tonic-gate if (op == PMAPPROC_SET) 256*7c478bd9Sstevel@tonic-gate rpcbs_set(RPCBVERS_2_STAT, ans); 257*7c478bd9Sstevel@tonic-gate else 258*7c478bd9Sstevel@tonic-gate rpcbs_unset(RPCBVERS_2_STAT, ans); 259*7c478bd9Sstevel@tonic-gate return (TRUE); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 263*7c478bd9Sstevel@tonic-gate static bool_t 264*7c478bd9Sstevel@tonic-gate pmapproc_getport(rqstp, xprt) 265*7c478bd9Sstevel@tonic-gate struct svc_req *rqstp; 266*7c478bd9Sstevel@tonic-gate register SVCXPRT *xprt; 267*7c478bd9Sstevel@tonic-gate { 268*7c478bd9Sstevel@tonic-gate PMAP reg; 269*7c478bd9Sstevel@tonic-gate int port = 0; 270*7c478bd9Sstevel@tonic-gate PMAPLIST *fnd; 271*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 272*7c478bd9Sstevel@tonic-gate char *uaddr; 273*7c478bd9Sstevel@tonic-gate #endif 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (char *)®)) { 276*7c478bd9Sstevel@tonic-gate svcerr_decode(xprt); 277*7c478bd9Sstevel@tonic-gate return (FALSE); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate PMAP_CHECK_RET(xprt, rqstp->rq_proc, FALSE); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 282*7c478bd9Sstevel@tonic-gate uaddr = taddr2uaddr(rpcbind_get_conf(xprt->xp_netid), 283*7c478bd9Sstevel@tonic-gate svc_getrpccaller(xprt)); 284*7c478bd9Sstevel@tonic-gate fprintf(stderr, "PMAP_GETPORT request for (%lu, %lu, %s) from %s :", 285*7c478bd9Sstevel@tonic-gate reg.pm_prog, reg.pm_vers, 286*7c478bd9Sstevel@tonic-gate reg.pm_prot == IPPROTO_UDP ? "udp" : "tcp", uaddr); 287*7c478bd9Sstevel@tonic-gate free(uaddr); 288*7c478bd9Sstevel@tonic-gate #endif 289*7c478bd9Sstevel@tonic-gate fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot); 290*7c478bd9Sstevel@tonic-gate if (fnd) { 291*7c478bd9Sstevel@tonic-gate char serveuaddr[32], *ua; 292*7c478bd9Sstevel@tonic-gate int h1, h2, h3, h4, p1, p2; 293*7c478bd9Sstevel@tonic-gate char *netid; 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate if (reg.pm_prot == IPPROTO_UDP) { 296*7c478bd9Sstevel@tonic-gate ua = udp_uaddr; 297*7c478bd9Sstevel@tonic-gate netid = udptrans; 298*7c478bd9Sstevel@tonic-gate } else { 299*7c478bd9Sstevel@tonic-gate ua = tcp_uaddr; /* To get the len */ 300*7c478bd9Sstevel@tonic-gate netid = tcptrans; 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate if (ua == NULL) { 303*7c478bd9Sstevel@tonic-gate goto sendreply; 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate if (sscanf(ua, "%d.%d.%d.%d.%d.%d", &h1, &h2, &h3, 306*7c478bd9Sstevel@tonic-gate &h4, &p1, &p2) == 6) { 307*7c478bd9Sstevel@tonic-gate p1 = (fnd->pml_map.pm_port >> 8) & 0xff; 308*7c478bd9Sstevel@tonic-gate p2 = (fnd->pml_map.pm_port) & 0xff; 309*7c478bd9Sstevel@tonic-gate sprintf(serveuaddr, "%d.%d.%d.%d.%d.%d", 310*7c478bd9Sstevel@tonic-gate h1, h2, h3, h4, p1, p2); 311*7c478bd9Sstevel@tonic-gate if (is_bound(netid, serveuaddr)) { 312*7c478bd9Sstevel@tonic-gate port = fnd->pml_map.pm_port; 313*7c478bd9Sstevel@tonic-gate } else { /* this service is dead; delete it */ 314*7c478bd9Sstevel@tonic-gate delete_prog(reg.pm_prog); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate sendreply: 319*7c478bd9Sstevel@tonic-gate if ((!svc_sendreply(xprt, (xdrproc_t)xdr_long, (caddr_t)&port)) && 320*7c478bd9Sstevel@tonic-gate debugging) { 321*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "portmap: svc_sendreply\n"); 322*7c478bd9Sstevel@tonic-gate if (doabort) { 323*7c478bd9Sstevel@tonic-gate rpcbind_abort(); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate #ifdef RPCBIND_DEBUG 327*7c478bd9Sstevel@tonic-gate fprintf(stderr, "port = %d\n", port); 328*7c478bd9Sstevel@tonic-gate #endif 329*7c478bd9Sstevel@tonic-gate rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers, 330*7c478bd9Sstevel@tonic-gate reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans, 331*7c478bd9Sstevel@tonic-gate port ? udptrans : ""); 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate return (TRUE); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 337*7c478bd9Sstevel@tonic-gate static bool_t 338*7c478bd9Sstevel@tonic-gate pmapproc_dump(rqstp, xprt) 339*7c478bd9Sstevel@tonic-gate struct svc_req *rqstp; 340*7c478bd9Sstevel@tonic-gate register SVCXPRT *xprt; 341*7c478bd9Sstevel@tonic-gate { 342*7c478bd9Sstevel@tonic-gate if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) { 343*7c478bd9Sstevel@tonic-gate svcerr_decode(xprt); 344*7c478bd9Sstevel@tonic-gate return (FALSE); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate if ((!svc_sendreply(xprt, (xdrproc_t)xdr_pmaplist_ptr, 347*7c478bd9Sstevel@tonic-gate (caddr_t)&list_pml)) && debugging) { 348*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "portmap: svc_sendreply\n"); 349*7c478bd9Sstevel@tonic-gate if (doabort) { 350*7c478bd9Sstevel@tonic-gate rpcbind_abort(); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate return (TRUE); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * Is the transport local? The original rpcbind code tried to 358*7c478bd9Sstevel@tonic-gate * figure out all the network interfaces but there can be a nearly 359*7c478bd9Sstevel@tonic-gate * infinite number of network interfaces. And the number of interfaces can 360*7c478bd9Sstevel@tonic-gate * vary over time. 361*7c478bd9Sstevel@tonic-gate * 362*7c478bd9Sstevel@tonic-gate * Note that when we get here, we've already establised that we're 363*7c478bd9Sstevel@tonic-gate * dealing with a TCP/IP endpoint. 364*7c478bd9Sstevel@tonic-gate */ 365*7c478bd9Sstevel@tonic-gate boolean_t 366*7c478bd9Sstevel@tonic-gate localxprt(SVCXPRT *transp, boolean_t forceipv4) 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate struct sockaddr_gen *sgen = svc_getgencaller(transp); 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate switch (SGFAM(sgen)) { 371*7c478bd9Sstevel@tonic-gate case AF_INET: 372*7c478bd9Sstevel@tonic-gate break; 373*7c478bd9Sstevel@tonic-gate case AF_INET6: 374*7c478bd9Sstevel@tonic-gate if (forceipv4) 375*7c478bd9Sstevel@tonic-gate return (B_FALSE); 376*7c478bd9Sstevel@tonic-gate break; 377*7c478bd9Sstevel@tonic-gate default: 378*7c478bd9Sstevel@tonic-gate return (B_FALSE); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /* 382*7c478bd9Sstevel@tonic-gate * Get the peer's uid; if it is known it is sufficiently 383*7c478bd9Sstevel@tonic-gate * authenticated and considered local. The magic behind this 384*7c478bd9Sstevel@tonic-gate * call is all in libnsl. 385*7c478bd9Sstevel@tonic-gate */ 386*7c478bd9Sstevel@tonic-gate return (rpcb_caller_uid(transp) != -1); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate #endif /* PORTMAP */ 389