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