1 1.4 christos /* $NetBSD: rpcb_svc.c,v 1.4 2017/08/16 08:44:40 christos Exp $ */ 2 1.4 christos /* $FreeBSD: head/usr.sbin/rpcbind/rpcb_svc.c 258564 2013-11-25 16:44:02Z hrs $ */ 3 1.1 fvdl 4 1.4 christos /*- 5 1.4 christos * Copyright (c) 2009, Sun Microsystems, Inc. 6 1.4 christos * All rights reserved. 7 1.4 christos * 8 1.4 christos * Redistribution and use in source and binary forms, with or without 9 1.4 christos * modification, are permitted provided that the following conditions are met: 10 1.4 christos * - Redistributions of source code must retain the above copyright notice, 11 1.4 christos * this list of conditions and the following disclaimer. 12 1.4 christos * - Redistributions in binary form must reproduce the above copyright notice, 13 1.4 christos * this list of conditions and the following disclaimer in the documentation 14 1.4 christos * and/or other materials provided with the distribution. 15 1.4 christos * - Neither the name of Sun Microsystems, Inc. nor the names of its 16 1.4 christos * contributors may be used to endorse or promote products derived 17 1.4 christos * from this software without specific prior written permission. 18 1.4 christos * 19 1.4 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 1.4 christos * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.4 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.4 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 1.4 christos * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.4 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.4 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.4 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.4 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.4 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.4 christos * POSSIBILITY OF SUCH DAMAGE. 30 1.1 fvdl */ 31 1.1 fvdl /* 32 1.1 fvdl * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 33 1.1 fvdl */ 34 1.1 fvdl 35 1.1 fvdl /* #ident "@(#)rpcb_svc.c 1.16 93/07/05 SMI" */ 36 1.1 fvdl 37 1.1 fvdl /* 38 1.1 fvdl * rpcb_svc.c 39 1.1 fvdl * The server procedure for the version 3 rpcbind (TLI). 40 1.1 fvdl * 41 1.1 fvdl * It maintains a separate list of all the registered services with the 42 1.1 fvdl * version 3 of rpcbind. 43 1.1 fvdl */ 44 1.1 fvdl #include <sys/types.h> 45 1.1 fvdl #include <rpc/rpc.h> 46 1.1 fvdl #include <rpc/rpcb_prot.h> 47 1.1 fvdl #include <netconfig.h> 48 1.1 fvdl #include <syslog.h> 49 1.1 fvdl #include <stdlib.h> 50 1.1 fvdl #include <stdio.h> 51 1.1 fvdl #include <string.h> 52 1.1 fvdl 53 1.1 fvdl #include "rpcbind.h" 54 1.1 fvdl 55 1.2 christos static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *, 56 1.2 christos rpcvers_t); 57 1.2 christos static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *, 58 1.2 christos rpcvers_t); 59 1.1 fvdl 60 1.1 fvdl /* 61 1.1 fvdl * Called by svc_getreqset. There is a separate server handle for 62 1.1 fvdl * every transport that it waits on. 63 1.1 fvdl */ 64 1.1 fvdl void 65 1.1 fvdl rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp) 66 1.1 fvdl { 67 1.1 fvdl union { 68 1.1 fvdl RPCB rpcbproc_set_3_arg; 69 1.1 fvdl RPCB rpcbproc_unset_3_arg; 70 1.1 fvdl RPCB rpcbproc_getaddr_3_local_arg; 71 1.1 fvdl struct rpcb_rmtcallargs rpcbproc_callit_3_arg; 72 1.1 fvdl char *rpcbproc_uaddr2taddr_3_arg; 73 1.1 fvdl struct netbuf rpcbproc_taddr2uaddr_3_arg; 74 1.1 fvdl } argument; 75 1.1 fvdl char *result; 76 1.1 fvdl xdrproc_t xdr_argument, xdr_result; 77 1.2 christos void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t); 78 1.1 fvdl 79 1.1 fvdl rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc); 80 1.1 fvdl 81 1.1 fvdl switch (rqstp->rq_proc) { 82 1.1 fvdl case NULLPROC: 83 1.1 fvdl /* 84 1.1 fvdl * Null proc call 85 1.1 fvdl */ 86 1.1 fvdl #ifdef RPCBIND_DEBUG 87 1.1 fvdl if (debugging) 88 1.1 fvdl fprintf(stderr, "RPCBPROC_NULL\n"); 89 1.1 fvdl #endif 90 1.1 fvdl /* This call just logs, no actual checks */ 91 1.1 fvdl check_access(transp, rqstp->rq_proc, NULL, RPCBVERS); 92 1.3 plunky (void) svc_sendreply(transp, (xdrproc_t)xdr_void, NULL); 93 1.1 fvdl return; 94 1.1 fvdl 95 1.1 fvdl case RPCBPROC_SET: 96 1.1 fvdl xdr_argument = (xdrproc_t )xdr_rpcb; 97 1.1 fvdl xdr_result = (xdrproc_t )xdr_bool; 98 1.1 fvdl local = rpcbproc_set_com; 99 1.1 fvdl break; 100 1.1 fvdl 101 1.1 fvdl case RPCBPROC_UNSET: 102 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb; 103 1.1 fvdl xdr_result = (xdrproc_t)xdr_bool; 104 1.1 fvdl local = rpcbproc_unset_com; 105 1.1 fvdl break; 106 1.1 fvdl 107 1.1 fvdl case RPCBPROC_GETADDR: 108 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb; 109 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring; 110 1.1 fvdl local = rpcbproc_getaddr_3_local; 111 1.1 fvdl break; 112 1.1 fvdl 113 1.1 fvdl case RPCBPROC_DUMP: 114 1.1 fvdl #ifdef RPCBIND_DEBUG 115 1.1 fvdl if (debugging) 116 1.1 fvdl fprintf(stderr, "RPCBPROC_DUMP\n"); 117 1.1 fvdl #endif 118 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void; 119 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcblist_ptr; 120 1.1 fvdl local = rpcbproc_dump_3_local; 121 1.1 fvdl break; 122 1.1 fvdl 123 1.1 fvdl case RPCBPROC_CALLIT: 124 1.1 fvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS); 125 1.1 fvdl return; 126 1.1 fvdl 127 1.1 fvdl case RPCBPROC_GETTIME: 128 1.1 fvdl #ifdef RPCBIND_DEBUG 129 1.1 fvdl if (debugging) 130 1.1 fvdl fprintf(stderr, "RPCBPROC_GETTIME\n"); 131 1.1 fvdl #endif 132 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void; 133 1.1 fvdl xdr_result = (xdrproc_t)xdr_u_long; 134 1.1 fvdl local = rpcbproc_gettime_com; 135 1.1 fvdl break; 136 1.1 fvdl 137 1.1 fvdl case RPCBPROC_UADDR2TADDR: 138 1.1 fvdl #ifdef RPCBIND_DEBUG 139 1.1 fvdl if (debugging) 140 1.1 fvdl fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); 141 1.1 fvdl #endif 142 1.1 fvdl xdr_argument = (xdrproc_t)xdr_wrapstring; 143 1.1 fvdl xdr_result = (xdrproc_t)xdr_netbuf; 144 1.1 fvdl local = rpcbproc_uaddr2taddr_com; 145 1.1 fvdl break; 146 1.1 fvdl 147 1.1 fvdl case RPCBPROC_TADDR2UADDR: 148 1.1 fvdl #ifdef RPCBIND_DEBUG 149 1.1 fvdl if (debugging) 150 1.1 fvdl fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); 151 1.1 fvdl #endif 152 1.1 fvdl xdr_argument = (xdrproc_t)xdr_netbuf; 153 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring; 154 1.1 fvdl local = rpcbproc_taddr2uaddr_com; 155 1.1 fvdl break; 156 1.1 fvdl 157 1.1 fvdl default: 158 1.1 fvdl svcerr_noproc(transp); 159 1.1 fvdl return; 160 1.1 fvdl } 161 1.1 fvdl (void) memset((char *)&argument, 0, sizeof (argument)); 162 1.1 fvdl if (!svc_getargs(transp, (xdrproc_t) xdr_argument, 163 1.1 fvdl (char *) &argument)) { 164 1.1 fvdl svcerr_decode(transp); 165 1.1 fvdl if (debugging) 166 1.1 fvdl (void) fprintf(stderr, "rpcbind: could not decode\n"); 167 1.1 fvdl return; 168 1.1 fvdl } 169 1.1 fvdl if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) { 170 1.1 fvdl svcerr_weakauth(transp); 171 1.1 fvdl goto done; 172 1.1 fvdl } 173 1.1 fvdl result = (*local)(&argument, rqstp, transp, RPCBVERS); 174 1.1 fvdl if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, 175 1.1 fvdl result)) { 176 1.1 fvdl svcerr_systemerr(transp); 177 1.1 fvdl if (debugging) { 178 1.1 fvdl (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); 179 1.1 fvdl if (doabort) { 180 1.1 fvdl rpcbind_abort(); 181 1.1 fvdl } 182 1.1 fvdl } 183 1.1 fvdl } 184 1.1 fvdl done: 185 1.1 fvdl if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *) 186 1.1 fvdl &argument)) { 187 1.1 fvdl if (debugging) { 188 1.1 fvdl (void) fprintf(stderr, "unable to free arguments\n"); 189 1.1 fvdl if (doabort) { 190 1.1 fvdl rpcbind_abort(); 191 1.1 fvdl } 192 1.1 fvdl } 193 1.1 fvdl } 194 1.1 fvdl } 195 1.1 fvdl 196 1.1 fvdl /* 197 1.1 fvdl * Lookup the mapping for a program, version and return its 198 1.1 fvdl * address. Assuming that the caller wants the address of the 199 1.1 fvdl * server running on the transport on which the request came. 200 1.1 fvdl * 201 1.1 fvdl * We also try to resolve the universal address in terms of 202 1.1 fvdl * address of the caller. 203 1.1 fvdl */ 204 1.1 fvdl /* ARGSUSED */ 205 1.1 fvdl static void * 206 1.4 christos rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused, 207 1.4 christos SVCXPRT *transp __unused, rpcvers_t versnum __unused) 208 1.1 fvdl { 209 1.1 fvdl RPCB *regp = (RPCB *)arg; 210 1.1 fvdl #ifdef RPCBIND_DEBUG 211 1.1 fvdl if (debugging) { 212 1.1 fvdl char *uaddr; 213 1.1 fvdl 214 1.1 fvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 215 1.1 fvdl svc_getrpccaller(transp)); 216 1.1 fvdl fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ", 217 1.1 fvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, 218 1.1 fvdl regp->r_netid, uaddr); 219 1.1 fvdl free(uaddr); 220 1.1 fvdl } 221 1.1 fvdl #endif 222 1.1 fvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS, 223 1.1 fvdl RPCB_ALLVERS)); 224 1.1 fvdl } 225 1.1 fvdl 226 1.1 fvdl /* ARGSUSED */ 227 1.1 fvdl static void * 228 1.4 christos rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused, 229 1.4 christos SVCXPRT *transp __unused, rpcvers_t versnum __unused) 230 1.1 fvdl { 231 1.1 fvdl return ((void *)&list_rbl); 232 1.1 fvdl } 233