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