activate.c revision 1.4 1 /* $NetBSD: activate.c,v 1.4 1995/03/18 14:57:51 cgd Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 * All rights reserved.
7 *
8 * This code is derived from software donated to Berkeley by
9 * Jan-Simon Pendry.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * from: Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp
40 * @(#)activate.c 8.2 (Berkeley) 3/27/94
41 */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <signal.h>
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/socket.h>
52 #include <sys/un.h>
53 #include <sys/syslog.h>
54 #include <sys/uio.h>
55
56 #include "portald.h"
57
58 /*
59 * Scan the providers list and call the
60 * appropriate function.
61 */
62 static int activate_argv(pcr, key, v, so, fdp)
63 struct portal_cred *pcr;
64 char *key;
65 char **v;
66 int so;
67 int *fdp;
68 {
69 provider *pr;
70
71 for (pr = providers; pr->pr_match; pr++)
72 if (strcmp(v[0], pr->pr_match) == 0)
73 return ((*pr->pr_func)(pcr, key, v, so, fdp));
74
75 return (ENOENT);
76 }
77
78 static int get_request(so, pcr, key, klen)
79 int so;
80 struct portal_cred *pcr;
81 char *key;
82 int klen;
83 {
84 struct iovec iov[2];
85 struct msghdr msg;
86 int n;
87
88 iov[0].iov_base = (caddr_t) pcr;
89 iov[0].iov_len = sizeof(*pcr);
90 iov[1].iov_base = key;
91 iov[1].iov_len = klen;
92
93 memset(&msg, 0, sizeof(msg));
94 msg.msg_iov = iov;
95 msg.msg_iovlen = 2;
96
97 n = recvmsg(so, &msg, 0);
98 if (n < 0)
99 return (errno);
100
101 if (n <= sizeof(*pcr))
102 return (EINVAL);
103
104 n -= sizeof(*pcr);
105 key[n] = '\0';
106
107 return (0);
108 }
109
110 static void send_reply(so, fd, error)
111 int so;
112 int fd;
113 int error;
114 {
115 int n;
116 struct iovec iov;
117 struct msghdr msg;
118 struct {
119 struct cmsghdr cmsg;
120 int fd;
121 } ctl;
122
123 /*
124 * Line up error code. Don't worry about byte ordering
125 * because we must be sending to the local machine.
126 */
127 iov.iov_base = (caddr_t) &error;
128 iov.iov_len = sizeof(error);
129
130 /*
131 * Build a msghdr
132 */
133 memset(&msg, 0, sizeof(msg));
134 msg.msg_iov = &iov;
135 msg.msg_iovlen = 1;
136
137 /*
138 * If there is a file descriptor to send then
139 * construct a suitable rights control message.
140 */
141 if (fd >= 0) {
142 ctl.fd = fd;
143 ctl.cmsg.cmsg_len = sizeof(ctl);
144 ctl.cmsg.cmsg_level = SOL_SOCKET;
145 ctl.cmsg.cmsg_type = SCM_RIGHTS;
146 msg.msg_control = (caddr_t) &ctl;
147 msg.msg_controllen = ctl.cmsg.cmsg_len;
148 }
149
150 /*
151 * Send to kernel...
152 */
153 if ((n = sendmsg(so, &msg, MSG_EOR)) < 0)
154 syslog(LOG_ERR, "send: %s", strerror(errno));
155 #ifdef DEBUG
156 fprintf(stderr, "sent %d bytes\n", n);
157 #endif
158 sleep(1); /*XXX*/
159 #ifdef notdef
160 if (shutdown(so, 2) < 0)
161 syslog(LOG_ERR, "shutdown: %s", strerror(errno));
162 #endif
163 /*
164 * Throw away the open file descriptor
165 */
166 (void) close(fd);
167 }
168
169 void activate(q, so)
170 qelem *q;
171 int so;
172 {
173 struct portal_cred pcred;
174 char key[MAXPATHLEN+1];
175 int error;
176 char **v;
177 int fd = -1;
178
179 /*
180 * Read the key from the socket
181 */
182 error = get_request(so, &pcred, key, sizeof(key));
183 if (error) {
184 syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
185 goto drop;
186 }
187
188 #ifdef DEBUG
189 fprintf(stderr, "lookup key %s\n", key);
190 #endif
191
192 /*
193 * Find a match in the configuration file
194 */
195 v = conf_match(q, key);
196
197 /*
198 * If a match existed, then find an appropriate portal
199 * otherwise simply return ENOENT.
200 */
201 if (v) {
202 error = activate_argv(&pcred, key, v, so, &fd);
203 if (error)
204 fd = -1;
205 else if (fd < 0)
206 error = -1;
207 } else {
208 error = ENOENT;
209 }
210
211 if (error >= 0)
212 send_reply(so, fd, error);
213
214 drop:;
215 close(so);
216 }
217