138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1990 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/amd/amq_svc.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien#ifdef HAVE_CONFIG_H 4538494Sobrien# include <config.h> 4638494Sobrien#endif /* HAVE_CONFIG_H */ 4738494Sobrien#include <am_defs.h> 4838494Sobrien#include <amd.h> 4938494Sobrien 5038494Sobrien/* typedefs */ 5138494Sobrientypedef char *(*amqsvcproc_t)(voidp, struct svc_req *); 5238494Sobrien 53174294Sobrien#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) 54174294Sobrien# ifdef NEED_LIBWRAP_SEVERITY_VARIABLES 55174294Sobrien/* 56174294Sobrien * Some systems that define libwrap already define these two variables 57174294Sobrien * in libwrap, while others don't: so I need to know precisely iff 58174294Sobrien * to define these two severity variables. 59174294Sobrien */ 60174294Sobrienint allow_severity=0, deny_severity=0; 61174294Sobrien# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */ 6238494Sobrien 63174294Sobrien/* 64174294Sobrien * check if remote amq is authorized to access this amd. 65174294Sobrien * Returns: 1=allowed, 0=denied. 66174294Sobrien */ 67174294Sobrienstatic int 68174294Sobrienamqsvc_is_client_allowed(const struct sockaddr_in *addr, char *remote) 69174294Sobrien{ 70174294Sobrien struct hostent *h; 71174294Sobrien char *name = NULL, **ad; 72174294Sobrien int ret = 0; /* default is 0==denied */ 73174294Sobrien 74174294Sobrien /* Check IP address */ 75174294Sobrien if (hosts_ctl(AMD_SERVICE_NAME, "", remote, "")) { 76174294Sobrien ret = 1; 77174294Sobrien goto out; 78174294Sobrien } 79174294Sobrien /* Get address */ 80174294Sobrien if (!(h = gethostbyaddr((const char *)&(addr->sin_addr), 81174294Sobrien sizeof(addr->sin_addr), 82174294Sobrien AF_INET))) 83174294Sobrien goto out; 84174294Sobrien if (!(name = strdup(h->h_name))) 85174294Sobrien goto out; 86174294Sobrien /* Paranoia check */ 87174294Sobrien if (!(h = gethostbyname(name))) 88174294Sobrien goto out; 89174294Sobrien for (ad = h->h_addr_list; *ad; ad++) 90174294Sobrien if (!memcmp(*ad, &(addr->sin_addr), h->h_length)) 91174294Sobrien break; 92174294Sobrien if (!*ad) 93174294Sobrien goto out; 94174294Sobrien if (hosts_ctl(AMD_SERVICE_NAME, "", h->h_name, "")) { 95174294Sobrien return 1; 96174294Sobrien goto out; 97174294Sobrien } 98174294Sobrien /* Check aliases */ 99174294Sobrien for (ad = h->h_aliases; *ad; ad++) 100174294Sobrien if (hosts_ctl(AMD_SERVICE_NAME, "", *ad, "")) { 101174294Sobrien return 1; 102174294Sobrien goto out; 103174294Sobrien } 104174294Sobrien 105174294Sobrien out: 106174294Sobrien if (name) 107174294Sobrien XFREE(name); 108174294Sobrien return ret; 109174294Sobrien} 110174294Sobrien#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */ 111174294Sobrien 112174294Sobrien 11338494Sobrienvoid 11438494Sobrienamq_program_1(struct svc_req *rqstp, SVCXPRT *transp) 11538494Sobrien{ 11638494Sobrien union { 11738494Sobrien amq_string amqproc_mnttree_1_arg; 11838494Sobrien amq_string amqproc_umnt_1_arg; 11938494Sobrien amq_setopt amqproc_setopt_1_arg; 12038494Sobrien } argument; 12138494Sobrien char *result; 12238494Sobrien xdrproc_t xdr_argument, xdr_result; 12338494Sobrien amqsvcproc_t local; 12438494Sobrien 125174294Sobrien#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) 126174294Sobrien if (gopt.flags & CFM_USE_TCPWRAPPERS) { 127174294Sobrien struct sockaddr_in *remote_addr = svc_getcaller(rqstp->rq_xprt); 128174294Sobrien char *remote_hostname = inet_ntoa(remote_addr->sin_addr); 129174294Sobrien 130174294Sobrien if (!amqsvc_is_client_allowed(remote_addr, remote_hostname)) { 131174294Sobrien plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname); 132174294Sobrien svcerr_auth(transp, AUTH_FAILED); 133174294Sobrien return; 134174294Sobrien } else { 135174294Sobrien dlog("Amd allowed remote amq service to %s", remote_hostname); 136174294Sobrien } 137174294Sobrien } 138174294Sobrien#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */ 139174294Sobrien 14038494Sobrien switch (rqstp->rq_proc) { 14138494Sobrien 14238494Sobrien case AMQPROC_NULL: 14338494Sobrien xdr_argument = (xdrproc_t) xdr_void; 14438494Sobrien xdr_result = (xdrproc_t) xdr_void; 14538494Sobrien local = (amqsvcproc_t) amqproc_null_1_svc; 14638494Sobrien break; 14738494Sobrien 14838494Sobrien case AMQPROC_MNTTREE: 14938494Sobrien xdr_argument = (xdrproc_t) xdr_amq_string; 15038494Sobrien xdr_result = (xdrproc_t) xdr_amq_mount_tree_p; 15138494Sobrien local = (amqsvcproc_t) amqproc_mnttree_1_svc; 15238494Sobrien break; 15338494Sobrien 15438494Sobrien case AMQPROC_UMNT: 15538494Sobrien xdr_argument = (xdrproc_t) xdr_amq_string; 15638494Sobrien xdr_result = (xdrproc_t) xdr_void; 15738494Sobrien local = (amqsvcproc_t) amqproc_umnt_1_svc; 15838494Sobrien break; 15938494Sobrien 16038494Sobrien case AMQPROC_STATS: 16138494Sobrien xdr_argument = (xdrproc_t) xdr_void; 16238494Sobrien xdr_result = (xdrproc_t) xdr_amq_mount_stats; 16338494Sobrien local = (amqsvcproc_t) amqproc_stats_1_svc; 16438494Sobrien break; 16538494Sobrien 16638494Sobrien case AMQPROC_EXPORT: 16738494Sobrien xdr_argument = (xdrproc_t) xdr_void; 16838494Sobrien xdr_result = (xdrproc_t) xdr_amq_mount_tree_list; 16938494Sobrien local = (amqsvcproc_t) amqproc_export_1_svc; 17038494Sobrien break; 17138494Sobrien 17238494Sobrien case AMQPROC_SETOPT: 17338494Sobrien xdr_argument = (xdrproc_t) xdr_amq_setopt; 17438494Sobrien xdr_result = (xdrproc_t) xdr_int; 17538494Sobrien local = (amqsvcproc_t) amqproc_setopt_1_svc; 17638494Sobrien break; 17738494Sobrien 17838494Sobrien case AMQPROC_GETMNTFS: 17938494Sobrien xdr_argument = (xdrproc_t) xdr_void; 18038494Sobrien xdr_result = (xdrproc_t) xdr_amq_mount_info_qelem; 18138494Sobrien local = (amqsvcproc_t) amqproc_getmntfs_1_svc; 18238494Sobrien break; 18338494Sobrien 18438494Sobrien case AMQPROC_GETVERS: 18538494Sobrien xdr_argument = (xdrproc_t) xdr_void; 18638494Sobrien xdr_result = (xdrproc_t) xdr_amq_string; 18738494Sobrien local = (amqsvcproc_t) amqproc_getvers_1_svc; 18838494Sobrien break; 18938494Sobrien 19038494Sobrien case AMQPROC_GETPID: 19138494Sobrien xdr_argument = (xdrproc_t) xdr_void; 19238494Sobrien xdr_result = (xdrproc_t) xdr_int; 19338494Sobrien local = (amqsvcproc_t) amqproc_getpid_1_svc; 19438494Sobrien break; 19538494Sobrien 196174294Sobrien case AMQPROC_PAWD: 197174294Sobrien xdr_argument = (xdrproc_t) xdr_amq_string; 198174294Sobrien xdr_result = (xdrproc_t) xdr_amq_string; 199174294Sobrien local = (amqsvcproc_t) amqproc_pawd_1_svc; 200174294Sobrien break; 201174294Sobrien 20238494Sobrien default: 20338494Sobrien svcerr_noproc(transp); 20438494Sobrien return; 20538494Sobrien } 20638494Sobrien 20738494Sobrien memset((char *) &argument, 0, sizeof(argument)); 20838494Sobrien if (!svc_getargs(transp, 20938494Sobrien (XDRPROC_T_TYPE) xdr_argument, 21038494Sobrien (SVC_IN_ARG_TYPE) & argument)) { 21138494Sobrien svcerr_decode(transp); 21238494Sobrien return; 21338494Sobrien } 21438494Sobrien 21538494Sobrien result = (*local) (&argument, rqstp); 21638494Sobrien 21738494Sobrien if (result != NULL && !svc_sendreply(transp, 21838494Sobrien (XDRPROC_T_TYPE) xdr_result, 21938494Sobrien result)) { 22038494Sobrien svcerr_systemerr(transp); 22138494Sobrien } 22238494Sobrien 22338494Sobrien if (!svc_freeargs(transp, 22438494Sobrien (XDRPROC_T_TYPE) xdr_argument, 22538494Sobrien (SVC_IN_ARG_TYPE) & argument)) { 22638494Sobrien plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1"); 22738494Sobrien going_down(1); 22838494Sobrien } 22938494Sobrien} 230