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 <syslog.h> 51 #include <stdlib.h> 52 #include <stdio.h> 53 #include <string.h> 54 55 #include "rpcbind.h" 56 57 static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *, 58 rpcvers_t); 59 static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *, 60 rpcvers_t); 61 62 /* 63 * Called by svc_getreqset. There is a separate server handle for 64 * every transport that it waits on. 65 */ 66 void 67 rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp) 68 { 69 union { 70 RPCB rpcbproc_set_3_arg; 71 RPCB rpcbproc_unset_3_arg; 72 RPCB rpcbproc_getaddr_3_local_arg; 73 struct rpcb_rmtcallargs rpcbproc_callit_3_arg; 74 char *rpcbproc_uaddr2taddr_3_arg; 75 struct netbuf rpcbproc_taddr2uaddr_3_arg; 76 } argument; 77 char *result; 78 xdrproc_t xdr_argument, xdr_result; 79 void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t); 80 81 rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc); 82 83 switch (rqstp->rq_proc) { 84 case NULLPROC: 85 /* 86 * Null proc call 87 */ 88 #ifdef RPCBIND_DEBUG 89 if (debugging) 90 fprintf(stderr, "RPCBPROC_NULL\n"); 91 #endif 92 /* This call just logs, no actual checks */ 93 check_access(transp, rqstp->rq_proc, NULL, RPCBVERS); 94 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL); 95 return; 96 97 case RPCBPROC_SET: 98 xdr_argument = (xdrproc_t )xdr_rpcb; 99 xdr_result = (xdrproc_t )xdr_bool; 100 local = rpcbproc_set_com; 101 break; 102 103 case RPCBPROC_UNSET: 104 xdr_argument = (xdrproc_t)xdr_rpcb; 105 xdr_result = (xdrproc_t)xdr_bool; 106 local = rpcbproc_unset_com; 107 break; 108 109 case RPCBPROC_GETADDR: 110 xdr_argument = (xdrproc_t)xdr_rpcb; 111 xdr_result = (xdrproc_t)xdr_wrapstring; 112 local = rpcbproc_getaddr_3_local; 113 break; 114 115 case RPCBPROC_DUMP: 116 #ifdef RPCBIND_DEBUG 117 if (debugging) 118 fprintf(stderr, "RPCBPROC_DUMP\n"); 119 #endif 120 xdr_argument = (xdrproc_t)xdr_void; 121 xdr_result = (xdrproc_t)xdr_rpcblist_ptr; 122 local = rpcbproc_dump_3_local; 123 break; 124 125 case RPCBPROC_CALLIT: 126 rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS); 127 return; 128 129 case RPCBPROC_GETTIME: 130 #ifdef RPCBIND_DEBUG 131 if (debugging) 132 fprintf(stderr, "RPCBPROC_GETTIME\n"); 133 #endif 134 xdr_argument = (xdrproc_t)xdr_void; 135 xdr_result = (xdrproc_t)xdr_u_long; 136 local = rpcbproc_gettime_com; 137 break; 138 139 case RPCBPROC_UADDR2TADDR: 140 #ifdef RPCBIND_DEBUG 141 if (debugging) 142 fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); 143 #endif 144 xdr_argument = (xdrproc_t)xdr_wrapstring; 145 xdr_result = (xdrproc_t)xdr_netbuf; 146 local = rpcbproc_uaddr2taddr_com; 147 break; 148 149 case RPCBPROC_TADDR2UADDR: 150 #ifdef RPCBIND_DEBUG 151 if (debugging) 152 fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); 153 #endif 154 xdr_argument = (xdrproc_t)xdr_netbuf; 155 xdr_result = (xdrproc_t)xdr_wrapstring; 156 local = rpcbproc_taddr2uaddr_com; 157 break; 158 159 default: 160 svcerr_noproc(transp); 161 return; 162 } 163 (void) memset((char *)&argument, 0, sizeof (argument)); 164 if (!svc_getargs(transp, (xdrproc_t) xdr_argument, 165 (char *) &argument)) { 166 svcerr_decode(transp); 167 if (debugging) 168 (void) fprintf(stderr, "rpcbind: could not decode\n"); 169 return; 170 } 171 if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) { 172 svcerr_weakauth(transp); 173 goto done; 174 } 175 result = (*local)(&argument, rqstp, transp, RPCBVERS); 176 if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, 177 result)) { 178 svcerr_systemerr(transp); 179 if (debugging) { 180 (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); 181 if (doabort) { 182 rpcbind_abort(); 183 } 184 } 185 } 186 done: 187 if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *) 188 &argument)) { 189 if (debugging) { 190 (void) fprintf(stderr, "unable to free arguments\n"); 191 if (doabort) { 192 rpcbind_abort(); 193 } 194 } 195 } 196 } 197 198 /* 199 * Lookup the mapping for a program, version and return its 200 * address. Assuming that the caller wants the address of the 201 * server running on the transport on which the request came. 202 * 203 * We also try to resolve the universal address in terms of 204 * address of the caller. 205 */ 206 /* ARGSUSED */ 207 static void * 208 rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused, 209 SVCXPRT *transp __unused, rpcvers_t versnum __unused) 210 { 211 RPCB *regp = (RPCB *)arg; 212 #ifdef RPCBIND_DEBUG 213 if (debugging) { 214 char *uaddr; 215 216 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 217 svc_getrpccaller(transp)); 218 fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ", 219 (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, 220 regp->r_netid, uaddr); 221 free(uaddr); 222 } 223 #endif 224 return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS, 225 RPCB_ALLVERS)); 226 } 227 228 /* ARGSUSED */ 229 static void * 230 rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused, 231 SVCXPRT *transp __unused, rpcvers_t versnum __unused) 232 { 233 return ((void *)&list_rbl); 234 } 235