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