amq_svc.c revision 302408
1/* 2 * Copyright (c) 1997-2006 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * 40 * File: am-utils/amd/amq_svc.c 41 * 42 */ 43 44#ifdef HAVE_CONFIG_H 45# include <config.h> 46#endif /* HAVE_CONFIG_H */ 47#include <am_defs.h> 48#include <amd.h> 49 50/* typedefs */ 51typedef char *(*amqsvcproc_t)(voidp, struct svc_req *); 52 53#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) 54# ifdef NEED_LIBWRAP_SEVERITY_VARIABLES 55/* 56 * Some systems that define libwrap already define these two variables 57 * in libwrap, while others don't: so I need to know precisely iff 58 * to define these two severity variables. 59 */ 60int allow_severity=0, deny_severity=0; 61# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */ 62 63/* 64 * check if remote amq is authorized to access this amd. 65 * Returns: 1=allowed, 0=denied. 66 */ 67static int 68amqsvc_is_client_allowed(const struct sockaddr_in *addr, char *remote) 69{ 70 struct hostent *h; 71 char *name = NULL, **ad; 72 int ret = 0; /* default is 0==denied */ 73 74 /* Check IP address */ 75 if (hosts_ctl(AMD_SERVICE_NAME, "", remote, "")) { 76 ret = 1; 77 goto out; 78 } 79 /* Get address */ 80 if (!(h = gethostbyaddr((const char *)&(addr->sin_addr), 81 sizeof(addr->sin_addr), 82 AF_INET))) 83 goto out; 84 if (!(name = strdup(h->h_name))) 85 goto out; 86 /* Paranoia check */ 87 if (!(h = gethostbyname(name))) 88 goto out; 89 for (ad = h->h_addr_list; *ad; ad++) 90 if (!memcmp(*ad, &(addr->sin_addr), h->h_length)) 91 break; 92 if (!*ad) 93 goto out; 94 if (hosts_ctl(AMD_SERVICE_NAME, "", h->h_name, "")) { 95 return 1; 96 goto out; 97 } 98 /* Check aliases */ 99 for (ad = h->h_aliases; *ad; ad++) 100 if (hosts_ctl(AMD_SERVICE_NAME, "", *ad, "")) { 101 return 1; 102 goto out; 103 } 104 105 out: 106 if (name) 107 XFREE(name); 108 return ret; 109} 110#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */ 111 112 113void 114amq_program_1(struct svc_req *rqstp, SVCXPRT *transp) 115{ 116 union { 117 amq_string amqproc_mnttree_1_arg; 118 amq_string amqproc_umnt_1_arg; 119 amq_setopt amqproc_setopt_1_arg; 120 } argument; 121 char *result; 122 xdrproc_t xdr_argument, xdr_result; 123 amqsvcproc_t local; 124 125#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) 126 if (gopt.flags & CFM_USE_TCPWRAPPERS) { 127 struct sockaddr_in *remote_addr = svc_getcaller(rqstp->rq_xprt); 128 char *remote_hostname = inet_ntoa(remote_addr->sin_addr); 129 130 if (!amqsvc_is_client_allowed(remote_addr, remote_hostname)) { 131 plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname); 132 svcerr_auth(transp, AUTH_FAILED); 133 return; 134 } else { 135 dlog("Amd allowed remote amq service to %s", remote_hostname); 136 } 137 } 138#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */ 139 140 switch (rqstp->rq_proc) { 141 142 case AMQPROC_NULL: 143 xdr_argument = (xdrproc_t) xdr_void; 144 xdr_result = (xdrproc_t) xdr_void; 145 local = (amqsvcproc_t) amqproc_null_1_svc; 146 break; 147 148 case AMQPROC_MNTTREE: 149 xdr_argument = (xdrproc_t) xdr_amq_string; 150 xdr_result = (xdrproc_t) xdr_amq_mount_tree_p; 151 local = (amqsvcproc_t) amqproc_mnttree_1_svc; 152 break; 153 154 case AMQPROC_UMNT: 155 xdr_argument = (xdrproc_t) xdr_amq_string; 156 xdr_result = (xdrproc_t) xdr_void; 157 local = (amqsvcproc_t) amqproc_umnt_1_svc; 158 break; 159 160 case AMQPROC_STATS: 161 xdr_argument = (xdrproc_t) xdr_void; 162 xdr_result = (xdrproc_t) xdr_amq_mount_stats; 163 local = (amqsvcproc_t) amqproc_stats_1_svc; 164 break; 165 166 case AMQPROC_EXPORT: 167 xdr_argument = (xdrproc_t) xdr_void; 168 xdr_result = (xdrproc_t) xdr_amq_mount_tree_list; 169 local = (amqsvcproc_t) amqproc_export_1_svc; 170 break; 171 172 case AMQPROC_SETOPT: 173 xdr_argument = (xdrproc_t) xdr_amq_setopt; 174 xdr_result = (xdrproc_t) xdr_int; 175 local = (amqsvcproc_t) amqproc_setopt_1_svc; 176 break; 177 178 case AMQPROC_GETMNTFS: 179 xdr_argument = (xdrproc_t) xdr_void; 180 xdr_result = (xdrproc_t) xdr_amq_mount_info_qelem; 181 local = (amqsvcproc_t) amqproc_getmntfs_1_svc; 182 break; 183 184 case AMQPROC_GETVERS: 185 xdr_argument = (xdrproc_t) xdr_void; 186 xdr_result = (xdrproc_t) xdr_amq_string; 187 local = (amqsvcproc_t) amqproc_getvers_1_svc; 188 break; 189 190 case AMQPROC_GETPID: 191 xdr_argument = (xdrproc_t) xdr_void; 192 xdr_result = (xdrproc_t) xdr_int; 193 local = (amqsvcproc_t) amqproc_getpid_1_svc; 194 break; 195 196 case AMQPROC_PAWD: 197 xdr_argument = (xdrproc_t) xdr_amq_string; 198 xdr_result = (xdrproc_t) xdr_amq_string; 199 local = (amqsvcproc_t) amqproc_pawd_1_svc; 200 break; 201 202 default: 203 svcerr_noproc(transp); 204 return; 205 } 206 207 memset((char *) &argument, 0, sizeof(argument)); 208 if (!svc_getargs(transp, 209 (XDRPROC_T_TYPE) xdr_argument, 210 (SVC_IN_ARG_TYPE) & argument)) { 211 svcerr_decode(transp); 212 return; 213 } 214 215 result = (*local) (&argument, rqstp); 216 217 if (result != NULL && !svc_sendreply(transp, 218 (XDRPROC_T_TYPE) xdr_result, 219 result)) { 220 svcerr_systemerr(transp); 221 } 222 223 if (!svc_freeargs(transp, 224 (XDRPROC_T_TYPE) xdr_argument, 225 (SVC_IN_ARG_TYPE) & argument)) { 226 plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1"); 227 going_down(1); 228 } 229} 230