154851Spendry /*
261515Sbostic * Copyright (c) 1992, 1993
361515Sbostic * The Regents of the University of California. All rights reserved.
454851Spendry * All rights reserved.
554851Spendry *
654851Spendry * This code is derived from software donated to Berkeley by
754851Spendry * Jan-Simon Pendry.
854851Spendry *
954851Spendry * %sccs.include.redist.c%
1054851Spendry *
11*68995Sbostic * @(#)activate.c 8.3 (Berkeley) 04/28/95
1254851Spendry *
1354851Spendry * $Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $
1454851Spendry */
1554851Spendry
1654851Spendry #include <stdio.h>
1754851Spendry #include <stdlib.h>
1854851Spendry #include <unistd.h>
1954851Spendry #include <string.h>
2054851Spendry #include <errno.h>
2154851Spendry #include <signal.h>
2254851Spendry #include <sys/types.h>
2354851Spendry #include <sys/param.h>
2454851Spendry #include <sys/socket.h>
2554851Spendry #include <sys/un.h>
2654851Spendry #include <sys/syslog.h>
2754851Spendry #include <sys/uio.h>
2854851Spendry
2954851Spendry #include "portald.h"
3054851Spendry
3154851Spendry /*
3254851Spendry * Scan the providers list and call the
3354851Spendry * appropriate function.
3454851Spendry */
activate_argv(pcr,key,v,so,fdp)3554851Spendry static int activate_argv(pcr, key, v, so, fdp)
3654851Spendry struct portal_cred *pcr;
3754851Spendry char *key;
3854851Spendry char **v;
3954851Spendry int so;
4054851Spendry int *fdp;
4154851Spendry {
4254851Spendry provider *pr;
4354851Spendry
4454851Spendry for (pr = providers; pr->pr_match; pr++)
4554851Spendry if (strcmp(v[0], pr->pr_match) == 0)
4654851Spendry return ((*pr->pr_func)(pcr, key, v, so, fdp));
4754851Spendry
4854851Spendry return (ENOENT);
4954851Spendry }
5054851Spendry
get_request(so,pcr,key,klen)5154851Spendry static int get_request(so, pcr, key, klen)
5254851Spendry int so;
5354851Spendry struct portal_cred *pcr;
5454851Spendry char *key;
5554851Spendry int klen;
5654851Spendry {
5754851Spendry struct iovec iov[2];
5854851Spendry struct msghdr msg;
5954851Spendry int n;
6054851Spendry
6154851Spendry iov[0].iov_base = (caddr_t) pcr;
6254851Spendry iov[0].iov_len = sizeof(*pcr);
6354851Spendry iov[1].iov_base = key;
6454851Spendry iov[1].iov_len = klen;
6554851Spendry
66*68995Sbostic memset(&msg, 0, sizeof(msg));
6754851Spendry msg.msg_iov = iov;
6854851Spendry msg.msg_iovlen = 2;
6954851Spendry
7054851Spendry n = recvmsg(so, &msg, 0);
7154851Spendry if (n < 0)
7254851Spendry return (errno);
7354851Spendry
7454851Spendry if (n <= sizeof(*pcr))
7554851Spendry return (EINVAL);
7654851Spendry
7754851Spendry n -= sizeof(*pcr);
7854851Spendry key[n] = '\0';
7954851Spendry
8054851Spendry return (0);
8154851Spendry }
8254851Spendry
send_reply(so,fd,error)8354851Spendry static void send_reply(so, fd, error)
8454851Spendry int so;
8554851Spendry int fd;
8654851Spendry int error;
8754851Spendry {
8854851Spendry int n;
8954851Spendry struct iovec iov;
9054851Spendry struct msghdr msg;
9154851Spendry struct {
9254851Spendry struct cmsghdr cmsg;
9354851Spendry int fd;
9454851Spendry } ctl;
9554851Spendry
9654851Spendry /*
9754851Spendry * Line up error code. Don't worry about byte ordering
9854851Spendry * because we must be sending to the local machine.
9954851Spendry */
10054851Spendry iov.iov_base = (caddr_t) &error;
10154851Spendry iov.iov_len = sizeof(error);
10254851Spendry
10354851Spendry /*
10454851Spendry * Build a msghdr
10554851Spendry */
106*68995Sbostic memset(&msg, 0, sizeof(msg));
10754851Spendry msg.msg_iov = &iov;
10854851Spendry msg.msg_iovlen = 1;
10954851Spendry
11054851Spendry /*
11154851Spendry * If there is a file descriptor to send then
11254851Spendry * construct a suitable rights control message.
11354851Spendry */
11454851Spendry if (fd >= 0) {
11554851Spendry ctl.fd = fd;
11654851Spendry ctl.cmsg.cmsg_len = sizeof(ctl);
11754851Spendry ctl.cmsg.cmsg_level = SOL_SOCKET;
11854851Spendry ctl.cmsg.cmsg_type = SCM_RIGHTS;
11954851Spendry msg.msg_control = (caddr_t) &ctl;
12054851Spendry msg.msg_controllen = ctl.cmsg.cmsg_len;
12154851Spendry }
12254851Spendry
12354851Spendry /*
12454851Spendry * Send to kernel...
12554851Spendry */
12654851Spendry if ((n = sendmsg(so, &msg, MSG_EOR)) < 0)
12754851Spendry syslog(LOG_ERR, "send: %s", strerror(errno));
12854851Spendry #ifdef DEBUG
12954851Spendry fprintf(stderr, "sent %d bytes\n", n);
13054851Spendry #endif
13154851Spendry sleep(1); /*XXX*/
13254851Spendry #ifdef notdef
13354851Spendry if (shutdown(so, 2) < 0)
13454851Spendry syslog(LOG_ERR, "shutdown: %s", strerror(errno));
13554851Spendry #endif
13654851Spendry /*
13754851Spendry * Throw away the open file descriptor
13854851Spendry */
13954851Spendry (void) close(fd);
14054851Spendry }
14154851Spendry
activate(q,so)14254851Spendry void activate(q, so)
14354851Spendry qelem *q;
14454851Spendry int so;
14554851Spendry {
14654851Spendry struct portal_cred pcred;
14754851Spendry char key[MAXPATHLEN+1];
14854851Spendry int error;
14954851Spendry char **v;
15054851Spendry int fd = -1;
15154851Spendry
15254851Spendry /*
15354851Spendry * Read the key from the socket
15454851Spendry */
15554851Spendry error = get_request(so, &pcred, key, sizeof(key));
15654851Spendry if (error) {
15754851Spendry syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
15854851Spendry goto drop;
15954851Spendry }
16054851Spendry
16154979Spendry #ifdef DEBUG
16254851Spendry fprintf(stderr, "lookup key %s\n", key);
16354979Spendry #endif
16454851Spendry
16554851Spendry /*
16654851Spendry * Find a match in the configuration file
16754851Spendry */
16854851Spendry v = conf_match(q, key);
16954851Spendry
17054851Spendry /*
17154851Spendry * If a match existed, then find an appropriate portal
17254851Spendry * otherwise simply return ENOENT.
17354851Spendry */
17454851Spendry if (v) {
17554851Spendry error = activate_argv(&pcred, key, v, so, &fd);
17654851Spendry if (error)
17754851Spendry fd = -1;
17854851Spendry else if (fd < 0)
17954851Spendry error = -1;
18054851Spendry } else {
18154851Spendry error = ENOENT;
18254851Spendry }
18354851Spendry
18454851Spendry if (error >= 0)
18554851Spendry send_reply(so, fd, error);
18654851Spendry
18754851Spendry drop:;
18854851Spendry close(so);
18954851Spendry }
190