1*54851Spendry /* 2*54851Spendry * Copyright (c) 1992 The Regents of the University of California 3*54851Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 4*54851Spendry * All rights reserved. 5*54851Spendry * 6*54851Spendry * This code is derived from software donated to Berkeley by 7*54851Spendry * Jan-Simon Pendry. 8*54851Spendry * 9*54851Spendry * %sccs.include.redist.c% 10*54851Spendry * 11*54851Spendry * @(#)activate.c 1.1 (Berkeley) 07/09/92 12*54851Spendry * 13*54851Spendry * $Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $ 14*54851Spendry */ 15*54851Spendry 16*54851Spendry #include <stdio.h> 17*54851Spendry #include <stdlib.h> 18*54851Spendry #include <unistd.h> 19*54851Spendry #include <string.h> 20*54851Spendry #include <errno.h> 21*54851Spendry #include <signal.h> 22*54851Spendry #include <sys/types.h> 23*54851Spendry #include <sys/param.h> 24*54851Spendry #include <sys/socket.h> 25*54851Spendry #include <sys/un.h> 26*54851Spendry #include <sys/syslog.h> 27*54851Spendry #include <sys/uio.h> 28*54851Spendry 29*54851Spendry #include "portald.h" 30*54851Spendry 31*54851Spendry /* 32*54851Spendry * Scan the providers list and call the 33*54851Spendry * appropriate function. 34*54851Spendry */ 35*54851Spendry static int activate_argv(pcr, key, v, so, fdp) 36*54851Spendry struct portal_cred *pcr; 37*54851Spendry char *key; 38*54851Spendry char **v; 39*54851Spendry int so; 40*54851Spendry int *fdp; 41*54851Spendry { 42*54851Spendry provider *pr; 43*54851Spendry 44*54851Spendry for (pr = providers; pr->pr_match; pr++) 45*54851Spendry if (strcmp(v[0], pr->pr_match) == 0) 46*54851Spendry return ((*pr->pr_func)(pcr, key, v, so, fdp)); 47*54851Spendry 48*54851Spendry return (ENOENT); 49*54851Spendry } 50*54851Spendry 51*54851Spendry static int get_request(so, pcr, key, klen) 52*54851Spendry int so; 53*54851Spendry struct portal_cred *pcr; 54*54851Spendry char *key; 55*54851Spendry int klen; 56*54851Spendry { 57*54851Spendry struct iovec iov[2]; 58*54851Spendry struct msghdr msg; 59*54851Spendry int n; 60*54851Spendry 61*54851Spendry iov[0].iov_base = (caddr_t) pcr; 62*54851Spendry iov[0].iov_len = sizeof(*pcr); 63*54851Spendry iov[1].iov_base = key; 64*54851Spendry iov[1].iov_len = klen; 65*54851Spendry 66*54851Spendry bzero((char *) &msg, sizeof(msg)); 67*54851Spendry msg.msg_iov = iov; 68*54851Spendry msg.msg_iovlen = 2; 69*54851Spendry 70*54851Spendry n = recvmsg(so, &msg, 0); 71*54851Spendry if (n < 0) 72*54851Spendry return (errno); 73*54851Spendry 74*54851Spendry if (n <= sizeof(*pcr)) 75*54851Spendry return (EINVAL); 76*54851Spendry 77*54851Spendry n -= sizeof(*pcr); 78*54851Spendry key[n] = '\0'; 79*54851Spendry 80*54851Spendry return (0); 81*54851Spendry } 82*54851Spendry 83*54851Spendry static void send_reply(so, fd, error) 84*54851Spendry int so; 85*54851Spendry int fd; 86*54851Spendry int error; 87*54851Spendry { 88*54851Spendry int n; 89*54851Spendry struct iovec iov; 90*54851Spendry struct msghdr msg; 91*54851Spendry struct { 92*54851Spendry struct cmsghdr cmsg; 93*54851Spendry int fd; 94*54851Spendry } ctl; 95*54851Spendry 96*54851Spendry /* 97*54851Spendry * Line up error code. Don't worry about byte ordering 98*54851Spendry * because we must be sending to the local machine. 99*54851Spendry */ 100*54851Spendry iov.iov_base = (caddr_t) &error; 101*54851Spendry iov.iov_len = sizeof(error); 102*54851Spendry 103*54851Spendry /* 104*54851Spendry * Build a msghdr 105*54851Spendry */ 106*54851Spendry bzero((char *) &msg, sizeof(msg)); 107*54851Spendry msg.msg_iov = &iov; 108*54851Spendry msg.msg_iovlen = 1; 109*54851Spendry 110*54851Spendry /* 111*54851Spendry * If there is a file descriptor to send then 112*54851Spendry * construct a suitable rights control message. 113*54851Spendry */ 114*54851Spendry if (fd >= 0) { 115*54851Spendry ctl.fd = fd; 116*54851Spendry ctl.cmsg.cmsg_len = sizeof(ctl); 117*54851Spendry ctl.cmsg.cmsg_level = SOL_SOCKET; 118*54851Spendry ctl.cmsg.cmsg_type = SCM_RIGHTS; 119*54851Spendry msg.msg_control = (caddr_t) &ctl; 120*54851Spendry msg.msg_controllen = ctl.cmsg.cmsg_len; 121*54851Spendry } 122*54851Spendry 123*54851Spendry /* 124*54851Spendry * Send to kernel... 125*54851Spendry */ 126*54851Spendry if ((n = sendmsg(so, &msg, MSG_EOR)) < 0) 127*54851Spendry syslog(LOG_ERR, "send: %s", strerror(errno)); 128*54851Spendry #ifdef DEBUG 129*54851Spendry fprintf(stderr, "sent %d bytes\n", n); 130*54851Spendry #endif 131*54851Spendry sleep(1); /*XXX*/ 132*54851Spendry #ifdef notdef 133*54851Spendry if (shutdown(so, 2) < 0) 134*54851Spendry syslog(LOG_ERR, "shutdown: %s", strerror(errno)); 135*54851Spendry #endif 136*54851Spendry /* 137*54851Spendry * Throw away the open file descriptor 138*54851Spendry */ 139*54851Spendry (void) close(fd); 140*54851Spendry } 141*54851Spendry 142*54851Spendry void activate(q, so) 143*54851Spendry qelem *q; 144*54851Spendry int so; 145*54851Spendry { 146*54851Spendry struct portal_cred pcred; 147*54851Spendry char key[MAXPATHLEN+1]; 148*54851Spendry int n; 149*54851Spendry int error; 150*54851Spendry char **v; 151*54851Spendry int fd = -1; 152*54851Spendry 153*54851Spendry /* 154*54851Spendry * Read the key from the socket 155*54851Spendry */ 156*54851Spendry error = get_request(so, &pcred, key, sizeof(key)); 157*54851Spendry if (error) { 158*54851Spendry syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error)); 159*54851Spendry goto drop; 160*54851Spendry } 161*54851Spendry 162*54851Spendry fprintf(stderr, "lookup key %s\n", key); 163*54851Spendry 164*54851Spendry /* 165*54851Spendry * Find a match in the configuration file 166*54851Spendry */ 167*54851Spendry v = conf_match(q, key); 168*54851Spendry 169*54851Spendry /* 170*54851Spendry * If a match existed, then find an appropriate portal 171*54851Spendry * otherwise simply return ENOENT. 172*54851Spendry */ 173*54851Spendry if (v) { 174*54851Spendry error = activate_argv(&pcred, key, v, so, &fd); 175*54851Spendry if (error) 176*54851Spendry fd = -1; 177*54851Spendry else if (fd < 0) 178*54851Spendry error = -1; 179*54851Spendry } else { 180*54851Spendry error = ENOENT; 181*54851Spendry } 182*54851Spendry 183*54851Spendry if (error >= 0) 184*54851Spendry send_reply(so, fd, error); 185*54851Spendry 186*54851Spendry drop:; 187*54851Spendry close(so); 188*54851Spendry } 189