1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 /* 29 * University Copyright- Copyright (c) 1982, 1986, 1988 30 * The Regents of the University of California 31 * All Rights Reserved 32 * 33 * University Acknowledgment- Portions of this document are derived from 34 * software developed by the University of California, Berkeley, and its 35 * contributors. 36 */ 37 38 #pragma ident "%Z%%M% %I% %E% SMI" 39 40 /* 41 * rpcb_svc.c 42 * The server procedure for the version 3 rpcbind (TLI). 43 * 44 * It maintains a separate list of all the registered services with the 45 * version 3 of rpcbind. 46 */ 47 #include <stdio.h> 48 #include <strings.h> 49 #include <sys/types.h> 50 #include <rpc/rpc.h> 51 #include <rpc/rpcb_prot.h> 52 #include <netconfig.h> 53 #include <syslog.h> 54 #include <netdir.h> 55 #include <stdlib.h> 56 #include "rpcbind.h" 57 58 /* 59 * Called by svc_getreqset. There is a separate server handle for 60 * every transport that it waits on. 61 */ 62 void 63 rpcb_service_3(rqstp, transp) 64 register struct svc_req *rqstp; 65 register SVCXPRT *transp; 66 { 67 union { 68 RPCB rpcbproc_set_3_arg; 69 RPCB rpcbproc_unset_3_arg; 70 RPCB rpcbproc_getaddr_3_arg; 71 struct rpcb_rmtcallargs rpcbproc_callit_3_arg; 72 char *rpcbproc_uaddr2taddr_3_arg; 73 struct netbuf rpcbproc_taddr2uaddr_3_arg; 74 } argument; 75 char *result; 76 bool_t (*xdr_argument)(), (*xdr_result)(); 77 char *(*local)(); 78 79 rpcbs_procinfo((ulong_t)RPCBVERS_3_STAT, rqstp->rq_proc); 80 81 RPCB_CHECK(transp, rqstp->rq_proc); 82 83 switch (rqstp->rq_proc) { 84 case NULLPROC: 85 /* 86 * Null proc call 87 */ 88 #ifdef RPCBIND_DEBUG 89 fprintf(stderr, "RPCBPROC_NULL\n"); 90 #endif 91 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL); 92 return; 93 94 case RPCBPROC_SET: 95 /* 96 * Check to see whether the message came from 97 * loopback transports (for security reasons) 98 */ 99 if (strcasecmp(transp->xp_netid, loopback_dg) && 100 strcasecmp(transp->xp_netid, loopback_vc) && 101 strcasecmp(transp->xp_netid, loopback_vc_ord)) { 102 char *uaddr; 103 104 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 105 svc_getrpccaller(transp)); 106 syslog(LOG_ERR, "non-local attempt to set from %s", 107 uaddr); 108 free(uaddr); 109 svcerr_weakauth(transp); 110 return; 111 } 112 xdr_argument = xdr_rpcb; 113 xdr_result = xdr_bool; 114 local = (char *(*)()) rpcbproc_set_com; 115 break; 116 117 case RPCBPROC_UNSET: 118 /* 119 * Check to see whether the message came from 120 * loopback transports (for security reasons) 121 */ 122 if (strcasecmp(transp->xp_netid, loopback_dg) && 123 strcasecmp(transp->xp_netid, loopback_vc) && 124 strcasecmp(transp->xp_netid, loopback_vc_ord)) { 125 char *uaddr; 126 127 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 128 svc_getrpccaller(transp)); 129 syslog(LOG_ERR, "non-local attempt to unset from %s", 130 uaddr); 131 free(uaddr); 132 svcerr_weakauth(transp); 133 return; 134 } 135 xdr_argument = xdr_rpcb; 136 xdr_result = xdr_bool; 137 local = (char *(*)()) rpcbproc_unset_com; 138 break; 139 140 case RPCBPROC_GETADDR: 141 xdr_argument = xdr_rpcb; 142 xdr_result = xdr_wrapstring; 143 local = (char *(*)()) rpcbproc_getaddr_3; 144 break; 145 146 case RPCBPROC_DUMP: 147 #ifdef RPCBIND_DEBUG 148 fprintf(stderr, "RPCBPROC_DUMP\n"); 149 #endif 150 xdr_argument = xdr_void; 151 xdr_result = xdr_rpcblist_ptr; 152 local = (char *(*)()) rpcbproc_dump_3; 153 break; 154 155 case RPCBPROC_CALLIT: 156 rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS); 157 return; 158 159 case RPCBPROC_GETTIME: 160 #ifdef RPCBIND_DEBUG 161 fprintf(stderr, "RPCBPROC_GETTIME\n"); 162 #endif 163 xdr_argument = xdr_void; 164 xdr_result = xdr_u_long; 165 local = (char *(*)()) rpcbproc_gettime_com; 166 break; 167 168 case RPCBPROC_UADDR2TADDR: 169 #ifdef RPCBIND_DEBUG 170 fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); 171 #endif 172 xdr_argument = xdr_wrapstring; 173 xdr_result = xdr_netbuf; 174 local = (char *(*)()) rpcbproc_uaddr2taddr_com; 175 break; 176 177 case RPCBPROC_TADDR2UADDR: 178 #ifdef RPCBIND_DEBUG 179 fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); 180 #endif 181 xdr_argument = xdr_netbuf; 182 xdr_result = xdr_wrapstring; 183 local = (char *(*)()) rpcbproc_taddr2uaddr_com; 184 break; 185 186 default: 187 svcerr_noproc(transp); 188 return; 189 } 190 (void) memset((char *)&argument, 0, sizeof (argument)); 191 if (!svc_getargs(transp, (xdrproc_t)xdr_argument, 192 (char *)&argument)) { 193 svcerr_decode(transp); 194 if (debugging) 195 (void) fprintf(stderr, "rpcbind: could not decode\n"); 196 return; 197 } 198 result = (*local)(&argument, rqstp, transp, RPCBVERS); 199 if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, 200 result)) { 201 svcerr_systemerr(transp); 202 if (debugging) { 203 (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); 204 if (doabort) { 205 rpcbind_abort(); 206 } 207 } 208 } 209 if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *) 210 &argument)) { 211 if (debugging) { 212 (void) fprintf(stderr, "unable to free arguments\n"); 213 if (doabort) { 214 rpcbind_abort(); 215 } 216 } 217 } 218 } 219 220 /* 221 * Lookup the mapping for a program, version and return its 222 * address. Assuming that the caller wants the address of the 223 * server running on the transport on which the request came. 224 * 225 * We also try to resolve the universal address in terms of 226 * address of the caller. 227 */ 228 /* ARGSUSED */ 229 static char ** 230 rpcbproc_getaddr_3(regp, rqstp, transp) 231 RPCB *regp; 232 struct svc_req *rqstp; /* Not used here */ 233 SVCXPRT *transp; 234 { 235 #ifdef RPCBIND_DEBUG 236 char *uaddr; 237 238 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), 239 svc_getrpccaller(transp)); 240 fprintf(stderr, "RPCB_GETADDR request for (%lu, %lu, %s) from %s : ", 241 regp->r_prog, regp->r_vers, transp->xp_netid, uaddr); 242 free(uaddr); 243 #endif 244 return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS, 245 (ulong_t)RPCB_ALLVERS)); 246 } 247 248 /* ARGSUSED */ 249 static rpcblist_ptr * 250 rpcbproc_dump_3() 251 { 252 return ((rpcblist_ptr *)&list_rbl); 253 } 254