11558Srgrimes/* 21558Srgrimes * Copyright (c) 1992, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * All rights reserved. 51558Srgrimes * 61558Srgrimes * This code is derived from software donated to Berkeley by 71558Srgrimes * Jan-Simon Pendry. 81558Srgrimes * 91558Srgrimes * Redistribution and use in source and binary forms, with or without 101558Srgrimes * modification, are permitted provided that the following conditions 111558Srgrimes * are met: 121558Srgrimes * 1. Redistributions of source code must retain the above copyright 131558Srgrimes * notice, this list of conditions and the following disclaimer. 141558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151558Srgrimes * notice, this list of conditions and the following disclaimer in the 161558Srgrimes * documentation and/or other materials provided with the distribution. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes * 3323680Speter * @(#)activate.c 8.3 (Berkeley) 4/28/95 341558Srgrimes */ 351558Srgrimes 36129862Sstefanf#include <sys/cdefs.h> 37129862Sstefanf__FBSDID("$FreeBSD$"); 3837429Scharnier 3937429Scharnier#include <errno.h> 4037429Scharnier#include <string.h> 411558Srgrimes#include <unistd.h> 421558Srgrimes#include <sys/types.h> 431558Srgrimes#include <sys/param.h> 441558Srgrimes#include <sys/socket.h> 451558Srgrimes#include <sys/syslog.h> 461558Srgrimes#include <sys/uio.h> 471558Srgrimes 481558Srgrimes#include "portald.h" 491558Srgrimes 501558Srgrimes/* 511558Srgrimes * Scan the providers list and call the 521558Srgrimes * appropriate function. 531558Srgrimes */ 54166157Srodrigcstatic int activate_argv(struct portal_cred *pcr, char *key, char **v, int so, 55166157Srodrigc int *fdp) 561558Srgrimes{ 571558Srgrimes provider *pr; 581558Srgrimes 591558Srgrimes for (pr = providers; pr->pr_match; pr++) 601558Srgrimes if (strcmp(v[0], pr->pr_match) == 0) 611558Srgrimes return ((*pr->pr_func)(pcr, key, v, so, fdp)); 621558Srgrimes 631558Srgrimes return (ENOENT); 641558Srgrimes} 651558Srgrimes 66166157Srodrigcstatic int get_request(int so, struct portal_cred *pcr, char *key, int klen) 671558Srgrimes{ 681558Srgrimes struct iovec iov[2]; 691558Srgrimes struct msghdr msg; 701558Srgrimes int n; 711558Srgrimes 721558Srgrimes iov[0].iov_base = (caddr_t) pcr; 731558Srgrimes iov[0].iov_len = sizeof(*pcr); 741558Srgrimes iov[1].iov_base = key; 751558Srgrimes iov[1].iov_len = klen; 761558Srgrimes 7723680Speter memset(&msg, 0, sizeof(msg)); 781558Srgrimes msg.msg_iov = iov; 791558Srgrimes msg.msg_iovlen = 2; 801558Srgrimes 811558Srgrimes n = recvmsg(so, &msg, 0); 821558Srgrimes if (n < 0) 831558Srgrimes return (errno); 841558Srgrimes 85166157Srodrigc if (n <= (int)sizeof(*pcr)) 861558Srgrimes return (EINVAL); 871558Srgrimes 881558Srgrimes n -= sizeof(*pcr); 891558Srgrimes key[n] = '\0'; 901558Srgrimes 911558Srgrimes return (0); 921558Srgrimes} 931558Srgrimes 94166157Srodrigcstatic void send_reply(int so, int fd, int error) 951558Srgrimes{ 961558Srgrimes int n; 971558Srgrimes struct iovec iov; 981558Srgrimes struct msghdr msg; 9984472Sdwmalone union { 1001558Srgrimes struct cmsghdr cmsg; 10184472Sdwmalone char control[CMSG_SPACE(sizeof(int))]; 1021558Srgrimes } ctl; 1031558Srgrimes 1041558Srgrimes /* 1051558Srgrimes * Line up error code. Don't worry about byte ordering 1061558Srgrimes * because we must be sending to the local machine. 1071558Srgrimes */ 1081558Srgrimes iov.iov_base = (caddr_t) &error; 1091558Srgrimes iov.iov_len = sizeof(error); 1101558Srgrimes 1111558Srgrimes /* 1121558Srgrimes * Build a msghdr 1131558Srgrimes */ 11423680Speter memset(&msg, 0, sizeof(msg)); 1151558Srgrimes msg.msg_iov = &iov; 1161558Srgrimes msg.msg_iovlen = 1; 1171558Srgrimes 1181558Srgrimes /* 1191558Srgrimes * If there is a file descriptor to send then 1201558Srgrimes * construct a suitable rights control message. 1211558Srgrimes */ 1221558Srgrimes if (fd >= 0) { 12384472Sdwmalone ctl.cmsg.cmsg_len = CMSG_LEN(sizeof(int)); 1241558Srgrimes ctl.cmsg.cmsg_level = SOL_SOCKET; 1251558Srgrimes ctl.cmsg.cmsg_type = SCM_RIGHTS; 12684472Sdwmalone *((int *)CMSG_DATA(&ctl.cmsg)) = fd; 1271558Srgrimes msg.msg_control = (caddr_t) &ctl; 1281558Srgrimes msg.msg_controllen = ctl.cmsg.cmsg_len; 1291558Srgrimes } 1301558Srgrimes 1311558Srgrimes /* 1321558Srgrimes * Send to kernel... 1331558Srgrimes */ 13441701Sdillon if ((n = sendmsg(so, &msg, 0)) < 0) 1351558Srgrimes syslog(LOG_ERR, "send: %s", strerror(errno)); 1361558Srgrimes#ifdef DEBUG 1371558Srgrimes fprintf(stderr, "sent %d bytes\n", n); 1381558Srgrimes#endif 1391558Srgrimes sleep(1); /*XXX*/ 1401558Srgrimes#ifdef notdef 141146077Sjmallett if (shutdown(so, SHUT_RDWR) < 0) 1421558Srgrimes syslog(LOG_ERR, "shutdown: %s", strerror(errno)); 1431558Srgrimes#endif 1441558Srgrimes /* 1451558Srgrimes * Throw away the open file descriptor 1461558Srgrimes */ 1471558Srgrimes (void) close(fd); 1481558Srgrimes} 1491558Srgrimes 150166157Srodrigcvoid activate(qelem *q, int so) 1511558Srgrimes{ 1521558Srgrimes struct portal_cred pcred; 1531558Srgrimes char key[MAXPATHLEN+1]; 1541558Srgrimes int error; 1551558Srgrimes char **v; 1561558Srgrimes int fd = -1; 1571558Srgrimes 1581558Srgrimes /* 1591558Srgrimes * Read the key from the socket 1601558Srgrimes */ 1611558Srgrimes error = get_request(so, &pcred, key, sizeof(key)); 1621558Srgrimes if (error) { 1631558Srgrimes syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error)); 1641558Srgrimes goto drop; 1651558Srgrimes } 1661558Srgrimes 1671558Srgrimes#ifdef DEBUG 1681558Srgrimes fprintf(stderr, "lookup key %s\n", key); 1691558Srgrimes#endif 1701558Srgrimes 1711558Srgrimes /* 1721558Srgrimes * Find a match in the configuration file 1731558Srgrimes */ 1741558Srgrimes v = conf_match(q, key); 1751558Srgrimes 1761558Srgrimes /* 1771558Srgrimes * If a match existed, then find an appropriate portal 1781558Srgrimes * otherwise simply return ENOENT. 1791558Srgrimes */ 1801558Srgrimes if (v) { 1811558Srgrimes error = activate_argv(&pcred, key, v, so, &fd); 1821558Srgrimes if (error) 1831558Srgrimes fd = -1; 1841558Srgrimes else if (fd < 0) 1851558Srgrimes error = -1; 1861558Srgrimes } else { 1871558Srgrimes error = ENOENT; 1881558Srgrimes } 1891558Srgrimes 1901558Srgrimes if (error >= 0) 1911558Srgrimes send_reply(so, fd, error); 1921558Srgrimes 1931558Srgrimesdrop:; 1941558Srgrimes close(so); 1951558Srgrimes} 196