174462Salfred/* 274462Salfred * $NetBSD: rpcb_svc_4.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $ 374462Salfred * $FreeBSD$ 474462Salfred */ 574462Salfred 674462Salfred/* 774462Salfred * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 874462Salfred * unrestricted use provided that this legend is included on all tape 974462Salfred * media and as a part of the software program in whole or part. Users 1074462Salfred * may copy or modify Sun RPC without charge, but are not authorized 1174462Salfred * to license or distribute it to anyone else except as part of a product or 1274462Salfred * program developed by the user. 1374462Salfred * 1474462Salfred * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1574462Salfred * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1674462Salfred * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1774462Salfred * 1874462Salfred * Sun RPC is provided with no support and without any obligation on the 1974462Salfred * part of Sun Microsystems, Inc. to assist in its use, correction, 2074462Salfred * modification or enhancement. 2174462Salfred * 2274462Salfred * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2374462Salfred * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2474462Salfred * OR ANY PART THEREOF. 2574462Salfred * 2674462Salfred * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2774462Salfred * or profits or other special, indirect and consequential damages, even if 2874462Salfred * Sun has been advised of the possibility of such damages. 2974462Salfred * 3074462Salfred * Sun Microsystems, Inc. 3174462Salfred * 2550 Garcia Avenue 3274462Salfred * Mountain View, California 94043 3374462Salfred */ 3474462Salfred/* 3574462Salfred * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 3674462Salfred */ 3774462Salfred 3874462Salfred/* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */ 3974462Salfred 4074462Salfred/* 4174462Salfred * rpcb_svc_4.c 4274462Salfred * The server procedure for the version 4 rpcbind. 4374462Salfred * 4474462Salfred */ 4574462Salfred 4674462Salfred#include <sys/types.h> 4774462Salfred#include <sys/stat.h> 4874462Salfred#include <rpc/rpc.h> 4974462Salfred#include <stdio.h> 5074462Salfred#include <unistd.h> 5174462Salfred#include <netconfig.h> 5274462Salfred#include <syslog.h> 5374462Salfred#include <string.h> 5474462Salfred#include <stdlib.h> 5574462Salfred#include "rpcbind.h" 5674462Salfred 57173412Skevlostatic void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *, 58173412Skevlo rpcvers_t); 59173412Skevlostatic void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *, rpcvers_t); 6074462Salfredstatic void *rpcbproc_getaddrlist_4_local 61173412Skevlo (void *, struct svc_req *, SVCXPRT *, rpcvers_t); 62173412Skevlostatic void free_rpcb_entry_list(rpcb_entry_list_ptr *); 63173412Skevlostatic void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *, rpcvers_t); 6474462Salfred 6574462Salfred/* 6674462Salfred * Called by svc_getreqset. There is a separate server handle for 6774462Salfred * every transport that it waits on. 6874462Salfred */ 6974462Salfredvoid 7074462Salfredrpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp) 7174462Salfred{ 7274462Salfred union { 7374462Salfred rpcb rpcbproc_set_4_arg; 7474462Salfred rpcb rpcbproc_unset_4_arg; 7574462Salfred rpcb rpcbproc_getaddr_4_local_arg; 7674462Salfred char *rpcbproc_uaddr2taddr_4_arg; 7774462Salfred struct netbuf rpcbproc_taddr2uaddr_4_arg; 7874462Salfred } argument; 7974462Salfred char *result; 8074462Salfred xdrproc_t xdr_argument, xdr_result; 81173412Skevlo void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t); 8274462Salfred 8374462Salfred rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc); 8474462Salfred 8574462Salfred switch (rqstp->rq_proc) { 8674462Salfred case NULLPROC: 8774462Salfred /* 8874462Salfred * Null proc call 8974462Salfred */ 9074462Salfred#ifdef RPCBIND_DEBUG 9174462Salfred if (debugging) 9274462Salfred fprintf(stderr, "RPCBPROC_NULL\n"); 9374462Salfred#endif 9474462Salfred check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4); 9574462Salfred (void) svc_sendreply(transp, (xdrproc_t) xdr_void, 9674462Salfred (char *)NULL); 9774462Salfred return; 9874462Salfred 9974462Salfred case RPCBPROC_SET: 10074462Salfred /* 10174462Salfred * Check to see whether the message came from 10274462Salfred * loopback transports (for security reasons) 10374462Salfred */ 10474462Salfred xdr_argument = (xdrproc_t)xdr_rpcb; 10574462Salfred xdr_result = (xdrproc_t)xdr_bool; 10674462Salfred local = rpcbproc_set_com; 10774462Salfred break; 10874462Salfred 10974462Salfred case RPCBPROC_UNSET: 11074462Salfred /* 11174462Salfred * Check to see whether the message came from 11274462Salfred * loopback transports (for security reasons) 11374462Salfred */ 11474462Salfred xdr_argument = (xdrproc_t)xdr_rpcb; 11574462Salfred xdr_result = (xdrproc_t)xdr_bool; 11674462Salfred local = rpcbproc_unset_com; 11774462Salfred break; 11874462Salfred 11974462Salfred case RPCBPROC_GETADDR: 12074462Salfred xdr_argument = (xdrproc_t)xdr_rpcb; 12174462Salfred xdr_result = (xdrproc_t)xdr_wrapstring; 12274462Salfred local = rpcbproc_getaddr_4_local; 12374462Salfred break; 12474462Salfred 12574462Salfred case RPCBPROC_GETVERSADDR: 12674462Salfred#ifdef RPCBIND_DEBUG 12774462Salfred if (debugging) 12874462Salfred fprintf(stderr, "RPCBPROC_GETVERSADDR\n"); 12974462Salfred#endif 13074462Salfred xdr_argument = (xdrproc_t)xdr_rpcb; 13174462Salfred xdr_result = (xdrproc_t)xdr_wrapstring; 13274462Salfred local = rpcbproc_getversaddr_4_local; 13374462Salfred break; 13474462Salfred 13574462Salfred case RPCBPROC_DUMP: 13674462Salfred#ifdef RPCBIND_DEBUG 13774462Salfred if (debugging) 13874462Salfred fprintf(stderr, "RPCBPROC_DUMP\n"); 13974462Salfred#endif 14074462Salfred xdr_argument = (xdrproc_t)xdr_void; 14174462Salfred xdr_result = (xdrproc_t)xdr_rpcblist_ptr; 14274462Salfred local = rpcbproc_dump_4_local; 14374462Salfred break; 14474462Salfred 14574462Salfred case RPCBPROC_INDIRECT: 14674462Salfred#ifdef RPCBIND_DEBUG 14774462Salfred if (debugging) 14874462Salfred fprintf(stderr, "RPCBPROC_INDIRECT\n"); 14974462Salfred#endif 15074462Salfred rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4); 15174462Salfred return; 15274462Salfred 15374462Salfred/* case RPCBPROC_CALLIT: */ 15474462Salfred case RPCBPROC_BCAST: 15574462Salfred#ifdef RPCBIND_DEBUG 15674462Salfred if (debugging) 15774462Salfred fprintf(stderr, "RPCBPROC_BCAST\n"); 15874462Salfred#endif 15974462Salfred rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4); 16074462Salfred return; 16174462Salfred 16274462Salfred case RPCBPROC_GETTIME: 16374462Salfred#ifdef RPCBIND_DEBUG 16474462Salfred if (debugging) 16574462Salfred fprintf(stderr, "RPCBPROC_GETTIME\n"); 16674462Salfred#endif 16774462Salfred xdr_argument = (xdrproc_t)xdr_void; 16874462Salfred xdr_result = (xdrproc_t)xdr_u_long; 16974462Salfred local = rpcbproc_gettime_com; 17074462Salfred break; 17174462Salfred 17274462Salfred case RPCBPROC_UADDR2TADDR: 17374462Salfred#ifdef RPCBIND_DEBUG 17474462Salfred if (debugging) 17574462Salfred fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); 17674462Salfred#endif 17774462Salfred xdr_argument = (xdrproc_t)xdr_wrapstring; 17874462Salfred xdr_result = (xdrproc_t)xdr_netbuf; 17974462Salfred local = rpcbproc_uaddr2taddr_com; 18074462Salfred break; 18174462Salfred 18274462Salfred case RPCBPROC_TADDR2UADDR: 18374462Salfred#ifdef RPCBIND_DEBUG 18474462Salfred if (debugging) 18574462Salfred fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); 18674462Salfred#endif 18774462Salfred xdr_argument = (xdrproc_t)xdr_netbuf; 18874462Salfred xdr_result = (xdrproc_t)xdr_wrapstring; 18974462Salfred local = rpcbproc_taddr2uaddr_com; 19074462Salfred break; 19174462Salfred 19274462Salfred case RPCBPROC_GETADDRLIST: 19374462Salfred#ifdef RPCBIND_DEBUG 19474462Salfred if (debugging) 19574462Salfred fprintf(stderr, "RPCBPROC_GETADDRLIST\n"); 19674462Salfred#endif 19774462Salfred xdr_argument = (xdrproc_t)xdr_rpcb; 19874462Salfred xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr; 19974462Salfred local = rpcbproc_getaddrlist_4_local; 20074462Salfred break; 20174462Salfred 20274462Salfred case RPCBPROC_GETSTAT: 20374462Salfred#ifdef RPCBIND_DEBUG 20474462Salfred if (debugging) 20574462Salfred fprintf(stderr, "RPCBPROC_GETSTAT\n"); 20674462Salfred#endif 20774462Salfred xdr_argument = (xdrproc_t)xdr_void; 20874462Salfred xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers; 20974462Salfred local = rpcbproc_getstat; 21074462Salfred break; 21174462Salfred 21274462Salfred default: 21374462Salfred svcerr_noproc(transp); 21474462Salfred return; 21574462Salfred } 21674462Salfred memset((char *)&argument, 0, sizeof (argument)); 21774462Salfred if (!svc_getargs(transp, (xdrproc_t) xdr_argument, 21874462Salfred (char *)&argument)) { 21974462Salfred svcerr_decode(transp); 22074462Salfred if (debugging) 22174462Salfred (void) fprintf(stderr, "rpcbind: could not decode\n"); 22274462Salfred return; 22374462Salfred } 22474462Salfred if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) { 22574462Salfred svcerr_weakauth(transp); 22674462Salfred goto done; 22774462Salfred } 22874462Salfred result = (*local)(&argument, rqstp, transp, RPCBVERS4); 22974462Salfred if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result, 23074462Salfred result)) { 23174462Salfred svcerr_systemerr(transp); 23274462Salfred if (debugging) { 23374462Salfred (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); 23474462Salfred if (doabort) { 23574462Salfred rpcbind_abort(); 23674462Salfred } 23774462Salfred } 23874462Salfred } 23974462Salfreddone: 24074462Salfred if (!svc_freeargs(transp, (xdrproc_t) xdr_argument, 24174462Salfred (char *)&argument)) { 24274462Salfred if (debugging) { 24374462Salfred (void) fprintf(stderr, "unable to free arguments\n"); 24474462Salfred if (doabort) { 24574462Salfred rpcbind_abort(); 24674462Salfred } 24774462Salfred } 24874462Salfred } 24974462Salfred return; 25074462Salfred} 25174462Salfred 25274462Salfred/* 25374462Salfred * Lookup the mapping for a program, version and return its 25474462Salfred * address. Assuming that the caller wants the address of the 25574462Salfred * server running on the transport on which the request came. 25674462Salfred * Even if a service with a different version number is available, 25774462Salfred * it will return that address. The client should check with an 25874462Salfred * clnt_call to verify whether the service is the one that is desired. 25974462Salfred * We also try to resolve the universal address in terms of 26074462Salfred * address of the caller. 26174462Salfred */ 26274462Salfred/* ARGSUSED */ 26374462Salfredstatic void * 26474462Salfredrpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, 265104592Salfred rpcvers_t rpcbversnum __unused) 26674462Salfred{ 26774462Salfred RPCB *regp = (RPCB *)arg; 26874462Salfred#ifdef RPCBIND_DEBUG 26974462Salfred if (debugging) { 27074462Salfred char *uaddr; 27174462Salfred 27274462Salfred uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 27374462Salfred svc_getrpccaller(transp)); 27474462Salfred fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ", 27574462Salfred (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, 27674462Salfred regp->r_netid, uaddr); 27774462Salfred free(uaddr); 27874462Salfred } 27974462Salfred#endif 28074462Salfred return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4, 28174462Salfred RPCB_ALLVERS)); 28274462Salfred} 28374462Salfred 28474462Salfred/* 28574462Salfred * Lookup the mapping for a program, version and return its 28674462Salfred * address. Assuming that the caller wants the address of the 28774462Salfred * server running on the transport on which the request came. 28874462Salfred * 28974462Salfred * We also try to resolve the universal address in terms of 29074462Salfred * address of the caller. 29174462Salfred */ 29274462Salfred/* ARGSUSED */ 29374462Salfredstatic void * 29474462Salfredrpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, 295104592Salfred rpcvers_t versnum __unused) 29674462Salfred{ 29774462Salfred RPCB *regp = (RPCB *)arg; 29874462Salfred#ifdef RPCBIND_DEBUG 29974462Salfred if (debugging) { 30074462Salfred char *uaddr; 30174462Salfred 30274462Salfred uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 30374462Salfred svc_getrpccaller(transp)); 30474462Salfred fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)" 30574462Salfred " from %s : ", 30674462Salfred (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, 30774462Salfred regp->r_netid, uaddr); 30874462Salfred free(uaddr); 30974462Salfred } 31074462Salfred#endif 31174462Salfred return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4, 31274462Salfred RPCB_ONEVERS)); 31374462Salfred} 31474462Salfred 31574462Salfred/* 31674462Salfred * Lookup the mapping for a program, version and return the 31774462Salfred * addresses for all transports in the current transport family. 31874462Salfred * We return a merged address. 31974462Salfred */ 32074462Salfred/* ARGSUSED */ 32174462Salfredstatic void * 322104592Salfredrpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused, 323104592Salfred SVCXPRT *transp, rpcvers_t versnum __unused) 32474462Salfred{ 32574462Salfred RPCB *regp = (RPCB *)arg; 32674462Salfred static rpcb_entry_list_ptr rlist; 32774462Salfred register rpcblist_ptr rbl; 32874462Salfred rpcb_entry_list_ptr rp, tail; 32974462Salfred rpcprog_t prog; 33074462Salfred rpcvers_t vers; 33174462Salfred rpcb_entry *a; 33274462Salfred struct netconfig *nconf; 33374462Salfred struct netconfig *reg_nconf; 33474462Salfred char *saddr, *maddr = NULL; 33574462Salfred 33674462Salfred free_rpcb_entry_list(&rlist); 33779718Siedowse tail = NULL; 33874462Salfred prog = regp->r_prog; 33974462Salfred vers = regp->r_vers; 34074462Salfred reg_nconf = rpcbind_get_conf(transp->xp_netid); 34174462Salfred if (reg_nconf == NULL) 34274462Salfred return (NULL); 34374462Salfred if (*(regp->r_addr) != '\0') { 34474462Salfred saddr = regp->r_addr; 34574462Salfred } else { 34674462Salfred saddr = NULL; 34774462Salfred } 34874462Salfred#ifdef RPCBIND_DEBUG 34974462Salfred if (debugging) { 35074462Salfred fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n", 35174462Salfred regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly); 35274462Salfred } 35374462Salfred#endif 35474462Salfred for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { 35574462Salfred if ((rbl->rpcb_map.r_prog == prog) && 35674462Salfred (rbl->rpcb_map.r_vers == vers)) { 35774462Salfred nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid); 35874462Salfred if (nconf == NULL) 35974462Salfred goto fail; 36074462Salfred if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly) 36174462Salfred != 0) { 36274462Salfred continue; /* not same proto family */ 36374462Salfred } 36474462Salfred#ifdef RPCBIND_DEBUG 36574462Salfred if (debugging) 36679718Siedowse fprintf(stderr, "\tmerge with: %s\n", 36779718Siedowse rbl->rpcb_map.r_addr); 36874462Salfred#endif 36974462Salfred if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid, 37074462Salfred rbl->rpcb_map.r_addr, saddr)) == NULL) { 37174462Salfred#ifdef RPCBIND_DEBUG 37274462Salfred if (debugging) 37374462Salfred fprintf(stderr, " FAILED\n"); 37474462Salfred#endif 37574462Salfred continue; 37674462Salfred } else if (!maddr[0]) { 37774462Salfred#ifdef RPCBIND_DEBUG 37874462Salfred if (debugging) 37974462Salfred fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n"); 38074462Salfred#endif 38174462Salfred /* The server died. Unset this combination */ 38274462Salfred delete_prog(regp->r_prog); 38374462Salfred continue; 38474462Salfred } 38574462Salfred#ifdef RPCBIND_DEBUG 38674462Salfred if (debugging) 38774462Salfred fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr); 38874462Salfred#endif 38974462Salfred /* 39074462Salfred * Add it to rlist. 39174462Salfred */ 39296788Sjmallett rp = malloc(sizeof (rpcb_entry_list)); 39374462Salfred if (rp == NULL) 39474462Salfred goto fail; 39574462Salfred a = &rp->rpcb_entry_map; 39674462Salfred a->r_maddr = maddr; 39774462Salfred a->r_nc_netid = nconf->nc_netid; 39874462Salfred a->r_nc_semantics = nconf->nc_semantics; 39974462Salfred a->r_nc_protofmly = nconf->nc_protofmly; 40074462Salfred a->r_nc_proto = nconf->nc_proto; 40174462Salfred rp->rpcb_entry_next = NULL; 40274462Salfred if (rlist == NULL) { 40374462Salfred rlist = rp; 40474462Salfred tail = rp; 40574462Salfred } else { 40674462Salfred tail->rpcb_entry_next = rp; 40774462Salfred tail = rp; 40874462Salfred } 40974462Salfred rp = NULL; 41074462Salfred } 41174462Salfred } 41274462Salfred#ifdef RPCBIND_DEBUG 41374462Salfred if (debugging) { 41474462Salfred for (rp = rlist; rp; rp = rp->rpcb_entry_next) { 41574462Salfred fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr, 41674462Salfred rp->rpcb_entry_map.r_nc_proto); 41774462Salfred } 41874462Salfred } 41974462Salfred#endif 42074462Salfred /* 42174462Salfred * XXX: getaddrlist info is also being stuffed into getaddr. 42274462Salfred * Perhaps wrong, but better than it not getting counted at all. 42374462Salfred */ 42474462Salfred rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr); 42574462Salfred return (void *)&rlist; 42674462Salfred 42774462Salfredfail: free_rpcb_entry_list(&rlist); 42874462Salfred return (NULL); 42974462Salfred} 43074462Salfred 43174462Salfred/* 43274462Salfred * Free only the allocated structure, rest is all a pointer to some 43374462Salfred * other data somewhere else. 43474462Salfred */ 43574462Salfredstatic void 43674462Salfredfree_rpcb_entry_list(rpcb_entry_list_ptr *rlistp) 43774462Salfred{ 43874462Salfred register rpcb_entry_list_ptr rbl, tmp; 43974462Salfred 44074462Salfred for (rbl = *rlistp; rbl != NULL; ) { 44174462Salfred tmp = rbl; 44274462Salfred rbl = rbl->rpcb_entry_next; 44374462Salfred free((char *)tmp->rpcb_entry_map.r_maddr); 44474462Salfred free((char *)tmp); 44574462Salfred } 44674462Salfred *rlistp = NULL; 44774462Salfred} 44874462Salfred 44974462Salfred/* ARGSUSED */ 45074462Salfredstatic void * 451104592Salfredrpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused, 452104592Salfred SVCXPRT *xprt __unused, rpcvers_t versnum __unused) 45374462Salfred{ 45474462Salfred return ((void *)&list_rbl); 45574462Salfred} 456