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