Blame


1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: control.c,v 1.65 2026/03/02 19:28:01 rsadowski Exp $ */
2 41042ecc 2006-12-16 reyk
3 41042ecc 2006-12-16 reyk /*
4 41042ecc 2006-12-16 reyk * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5 41042ecc 2006-12-16 reyk *
6 41042ecc 2006-12-16 reyk * Permission to use, copy, modify, and distribute this software for any
7 41042ecc 2006-12-16 reyk * purpose with or without fee is hereby granted, provided that the above
8 41042ecc 2006-12-16 reyk * copyright notice and this permission notice appear in all copies.
9 41042ecc 2006-12-16 reyk *
10 41042ecc 2006-12-16 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 41042ecc 2006-12-16 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 41042ecc 2006-12-16 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 41042ecc 2006-12-16 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 41042ecc 2006-12-16 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 41042ecc 2006-12-16 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 41042ecc 2006-12-16 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 41042ecc 2006-12-16 reyk */
18 41042ecc 2006-12-16 reyk
19 41042ecc 2006-12-16 reyk #include <sys/queue.h>
20 41042ecc 2006-12-16 reyk #include <sys/stat.h>
21 41042ecc 2006-12-16 reyk #include <sys/socket.h>
22 d93c36af 2015-01-22 reyk #include <sys/time.h>
23 41042ecc 2006-12-16 reyk #include <sys/un.h>
24 e1f9d231 2007-11-24 reyk
25 41042ecc 2006-12-16 reyk #include <errno.h>
26 41042ecc 2006-12-16 reyk #include <event.h>
27 41042ecc 2006-12-16 reyk #include <fcntl.h>
28 41042ecc 2006-12-16 reyk #include <stdlib.h>
29 41042ecc 2006-12-16 reyk #include <string.h>
30 41042ecc 2006-12-16 reyk #include <unistd.h>
31 d93c36af 2015-01-22 reyk #include <imsg.h>
32 41042ecc 2006-12-16 reyk
33 6d0767ae 2007-12-07 reyk #include "relayd.h"
34 6b5c4000 2026-03-02 rsadowski #include "log.h"
35 41042ecc 2006-12-16 reyk
36 41042ecc 2006-12-16 reyk #define CONTROL_BACKLOG 5
37 41042ecc 2006-12-16 reyk
38 b9228e18 2021-04-20 dv struct ctl_connlist ctl_conns = TAILQ_HEAD_INITIALIZER(ctl_conns);
39 41042ecc 2006-12-16 reyk
40 dbef7d4f 2011-05-09 reyk void control_accept(int, short, void *);
41 1ca19f87 2012-04-11 deraadt void control_close(int, struct control_sock *);
42 41042ecc 2006-12-16 reyk
43 41042ecc 2006-12-16 reyk int
44 dbef7d4f 2011-05-09 reyk control_init(struct privsep *ps, struct control_sock *cs)
45 41042ecc 2006-12-16 reyk {
46 dbef7d4f 2011-05-09 reyk struct relayd *env = ps->ps_env;
47 41042ecc 2006-12-16 reyk struct sockaddr_un sun;
48 41042ecc 2006-12-16 reyk int fd;
49 dbef7d4f 2011-05-09 reyk mode_t old_umask, mode;
50 41042ecc 2006-12-16 reyk
51 dbef7d4f 2011-05-09 reyk if (cs->cs_name == NULL)
52 dbef7d4f 2011-05-09 reyk return (0);
53 dbef7d4f 2011-05-09 reyk
54 24dcf092 2015-11-28 reyk if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) {
55 666bd316 2011-05-05 reyk log_warn("%s: socket", __func__);
56 41042ecc 2006-12-16 reyk return (-1);
57 41042ecc 2006-12-16 reyk }
58 41042ecc 2006-12-16 reyk
59 41042ecc 2006-12-16 reyk sun.sun_family = AF_UNIX;
60 dbef7d4f 2011-05-09 reyk if (strlcpy(sun.sun_path, cs->cs_name,
61 1ad64381 2007-02-08 reyk sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
62 dbef7d4f 2011-05-09 reyk log_warn("%s: %s name too long", __func__, cs->cs_name);
63 1ad64381 2007-02-08 reyk close(fd);
64 1ad64381 2007-02-08 reyk return (-1);
65 1ad64381 2007-02-08 reyk }
66 41042ecc 2006-12-16 reyk
67 dbef7d4f 2011-05-09 reyk if (unlink(cs->cs_name) == -1)
68 41042ecc 2006-12-16 reyk if (errno != ENOENT) {
69 dbef7d4f 2011-05-09 reyk log_warn("%s: unlink %s", __func__, cs->cs_name);
70 41042ecc 2006-12-16 reyk close(fd);
71 41042ecc 2006-12-16 reyk return (-1);
72 41042ecc 2006-12-16 reyk }
73 41042ecc 2006-12-16 reyk
74 dbef7d4f 2011-05-09 reyk if (cs->cs_restricted) {
75 dbef7d4f 2011-05-09 reyk old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
76 dbef7d4f 2011-05-09 reyk mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
77 dbef7d4f 2011-05-09 reyk } else {
78 dbef7d4f 2011-05-09 reyk old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
79 dbef7d4f 2011-05-09 reyk mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
80 dbef7d4f 2011-05-09 reyk }
81 dbef7d4f 2011-05-09 reyk
82 41042ecc 2006-12-16 reyk if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
83 dbef7d4f 2011-05-09 reyk log_warn("%s: bind: %s", __func__, cs->cs_name);
84 41042ecc 2006-12-16 reyk close(fd);
85 1ad64381 2007-02-08 reyk (void)umask(old_umask);
86 41042ecc 2006-12-16 reyk return (-1);
87 41042ecc 2006-12-16 reyk }
88 1ad64381 2007-02-08 reyk (void)umask(old_umask);
89 41042ecc 2006-12-16 reyk
90 dbef7d4f 2011-05-09 reyk if (chmod(cs->cs_name, mode) == -1) {
91 666bd316 2011-05-05 reyk log_warn("%s: chmod", __func__);
92 41042ecc 2006-12-16 reyk close(fd);
93 dbef7d4f 2011-05-09 reyk (void)unlink(cs->cs_name);
94 41042ecc 2006-12-16 reyk return (-1);
95 41042ecc 2006-12-16 reyk }
96 41042ecc 2006-12-16 reyk
97 dbef7d4f 2011-05-09 reyk cs->cs_fd = fd;
98 dbef7d4f 2011-05-09 reyk cs->cs_env = env;
99 41042ecc 2006-12-16 reyk
100 41042ecc 2006-12-16 reyk return (0);
101 41042ecc 2006-12-16 reyk }
102 41042ecc 2006-12-16 reyk
103 41042ecc 2006-12-16 reyk int
104 dbef7d4f 2011-05-09 reyk control_listen(struct control_sock *cs)
105 41042ecc 2006-12-16 reyk {
106 dbef7d4f 2011-05-09 reyk if (cs->cs_name == NULL)
107 dbef7d4f 2011-05-09 reyk return (0);
108 41042ecc 2006-12-16 reyk
109 dbef7d4f 2011-05-09 reyk if (listen(cs->cs_fd, CONTROL_BACKLOG) == -1) {
110 666bd316 2011-05-05 reyk log_warn("%s: listen", __func__);
111 41042ecc 2006-12-16 reyk return (-1);
112 41042ecc 2006-12-16 reyk }
113 41042ecc 2006-12-16 reyk
114 1ca19f87 2012-04-11 deraadt event_set(&cs->cs_ev, cs->cs_fd, EV_READ,
115 1ca19f87 2012-04-11 deraadt control_accept, cs);
116 dbef7d4f 2011-05-09 reyk event_add(&cs->cs_ev, NULL);
117 1ca19f87 2012-04-11 deraadt evtimer_set(&cs->cs_evt, control_accept, cs);
118 41042ecc 2006-12-16 reyk
119 41042ecc 2006-12-16 reyk return (0);
120 41042ecc 2006-12-16 reyk }
121 41042ecc 2006-12-16 reyk
122 41042ecc 2006-12-16 reyk void
123 dbef7d4f 2011-05-09 reyk control_cleanup(struct control_sock *cs)
124 41042ecc 2006-12-16 reyk {
125 dbef7d4f 2011-05-09 reyk if (cs->cs_name == NULL)
126 dbef7d4f 2011-05-09 reyk return;
127 1ca19f87 2012-04-11 deraadt event_del(&cs->cs_ev);
128 e2545807 2012-04-11 deraadt event_del(&cs->cs_evt);
129 41042ecc 2006-12-16 reyk }
130 41042ecc 2006-12-16 reyk
131 41042ecc 2006-12-16 reyk void
132 41042ecc 2006-12-16 reyk control_accept(int listenfd, short event, void *arg)
133 41042ecc 2006-12-16 reyk {
134 41042ecc 2006-12-16 reyk int connfd;
135 41042ecc 2006-12-16 reyk socklen_t len;
136 41042ecc 2006-12-16 reyk struct sockaddr_un sun;
137 41042ecc 2006-12-16 reyk struct ctl_conn *c;
138 1ca19f87 2012-04-11 deraadt struct control_sock *cs = arg;
139 41042ecc 2006-12-16 reyk
140 1ca19f87 2012-04-11 deraadt event_add(&cs->cs_ev, NULL);
141 1ca19f87 2012-04-11 deraadt if ((event & EV_TIMEOUT))
142 1ca19f87 2012-04-11 deraadt return;
143 1ca19f87 2012-04-11 deraadt
144 41042ecc 2006-12-16 reyk len = sizeof(sun);
145 24dcf092 2015-11-28 reyk if ((connfd = accept4(listenfd,
146 24dcf092 2015-11-28 reyk (struct sockaddr *)&sun, &len, SOCK_NONBLOCK)) == -1) {
147 1ca19f87 2012-04-11 deraadt /*
148 1ca19f87 2012-04-11 deraadt * Pause accept if we are out of file descriptors, or
149 1ca19f87 2012-04-11 deraadt * libevent will haunt us here too.
150 1ca19f87 2012-04-11 deraadt */
151 1ca19f87 2012-04-11 deraadt if (errno == ENFILE || errno == EMFILE) {
152 1ca19f87 2012-04-11 deraadt struct timeval evtpause = { 1, 0 };
153 1ca19f87 2012-04-11 deraadt
154 1ca19f87 2012-04-11 deraadt event_del(&cs->cs_ev);
155 1ca19f87 2012-04-11 deraadt evtimer_add(&cs->cs_evt, &evtpause);
156 8041276c 2013-03-11 deraadt } else if (errno != EWOULDBLOCK && errno != EINTR &&
157 8041276c 2013-03-11 deraadt errno != ECONNABORTED)
158 666bd316 2011-05-05 reyk log_warn("%s: accept", __func__);
159 41042ecc 2006-12-16 reyk return;
160 41042ecc 2006-12-16 reyk }
161 41042ecc 2006-12-16 reyk
162 d9beb635 2010-05-14 reyk if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
163 666bd316 2011-05-05 reyk log_warn("%s: calloc", __func__);
164 418ab141 2024-11-21 claudio close(connfd);
165 41042ecc 2006-12-16 reyk return;
166 41042ecc 2006-12-16 reyk }
167 41042ecc 2006-12-16 reyk
168 418ab141 2024-11-21 claudio if (imsgbuf_init(&c->iev.ibuf, connfd) == -1) {
169 418ab141 2024-11-21 claudio log_warn("%s: imsgbuf_init", __func__);
170 418ab141 2024-11-21 claudio close(connfd);
171 418ab141 2024-11-21 claudio free(c);
172 418ab141 2024-11-21 claudio return;
173 418ab141 2024-11-21 claudio }
174 418ab141 2024-11-21 claudio
175 eabfa908 2009-06-05 pyr c->iev.handler = control_dispatch_imsg;
176 eabfa908 2009-06-05 pyr c->iev.events = EV_READ;
177 89e136f0 2012-04-19 deraadt c->iev.data = cs; /* proc.c cheats (reuses the handler) */
178 eabfa908 2009-06-05 pyr event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
179 1ca19f87 2012-04-11 deraadt c->iev.handler, cs);
180 eabfa908 2009-06-05 pyr event_add(&c->iev.ev, NULL);
181 41042ecc 2006-12-16 reyk
182 41042ecc 2006-12-16 reyk TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
183 41042ecc 2006-12-16 reyk }
184 41042ecc 2006-12-16 reyk
185 41042ecc 2006-12-16 reyk struct ctl_conn *
186 41042ecc 2006-12-16 reyk control_connbyfd(int fd)
187 41042ecc 2006-12-16 reyk {
188 41042ecc 2006-12-16 reyk struct ctl_conn *c;
189 41042ecc 2006-12-16 reyk
190 602b9b65 2017-01-09 krw TAILQ_FOREACH(c, &ctl_conns, entry) {
191 602b9b65 2017-01-09 krw if (c->iev.ibuf.fd == fd)
192 602b9b65 2017-01-09 krw break;
193 602b9b65 2017-01-09 krw }
194 41042ecc 2006-12-16 reyk
195 41042ecc 2006-12-16 reyk return (c);
196 41042ecc 2006-12-16 reyk }
197 41042ecc 2006-12-16 reyk
198 41042ecc 2006-12-16 reyk void
199 1ca19f87 2012-04-11 deraadt control_close(int fd, struct control_sock *cs)
200 41042ecc 2006-12-16 reyk {
201 41042ecc 2006-12-16 reyk struct ctl_conn *c;
202 41042ecc 2006-12-16 reyk
203 280196b4 2009-02-25 claudio if ((c = control_connbyfd(fd)) == NULL) {
204 666bd316 2011-05-05 reyk log_warn("%s: fd %d not found", __func__, fd);
205 280196b4 2009-02-25 claudio return;
206 280196b4 2009-02-25 claudio }
207 41042ecc 2006-12-16 reyk
208 4e3b971d 2024-11-21 claudio imsgbuf_clear(&c->iev.ibuf);
209 41042ecc 2006-12-16 reyk TAILQ_REMOVE(&ctl_conns, c, entry);
210 41042ecc 2006-12-16 reyk
211 eabfa908 2009-06-05 pyr event_del(&c->iev.ev);
212 eabfa908 2009-06-05 pyr close(c->iev.ibuf.fd);
213 1ca19f87 2012-04-11 deraadt
214 1ca19f87 2012-04-11 deraadt /* Some file descriptors are available again. */
215 1ca19f87 2012-04-11 deraadt if (evtimer_pending(&cs->cs_evt, NULL)) {
216 1ca19f87 2012-04-11 deraadt evtimer_del(&cs->cs_evt);
217 1ca19f87 2012-04-11 deraadt event_add(&cs->cs_ev, NULL);
218 1ca19f87 2012-04-11 deraadt }
219 1ca19f87 2012-04-11 deraadt
220 41042ecc 2006-12-16 reyk free(c);
221 41042ecc 2006-12-16 reyk }
222 41042ecc 2006-12-16 reyk
223 41042ecc 2006-12-16 reyk void
224 41042ecc 2006-12-16 reyk control_dispatch_imsg(int fd, short event, void *arg)
225 41042ecc 2006-12-16 reyk {
226 89e136f0 2012-04-19 deraadt struct control_sock *cs = arg;
227 41042ecc 2006-12-16 reyk struct ctl_conn *c;
228 4ab45c57 2006-12-16 reyk struct imsg imsg;
229 d2170f6d 2006-12-16 reyk struct ctl_id id;
230 4ab45c57 2006-12-16 reyk int n;
231 67bc535b 2010-01-11 jsg int verbose;
232 1ca19f87 2012-04-11 deraadt struct relayd *env = cs->cs_env;
233 3b28f64e 2016-09-02 reyk struct privsep *ps = env->sc_ps;
234 41042ecc 2006-12-16 reyk
235 41042ecc 2006-12-16 reyk if ((c = control_connbyfd(fd)) == NULL) {
236 666bd316 2011-05-05 reyk log_warn("%s: fd %d not found", __func__, fd);
237 41042ecc 2006-12-16 reyk return;
238 41042ecc 2006-12-16 reyk }
239 41042ecc 2006-12-16 reyk
240 650b98e6 2009-06-02 reyk if (event & EV_READ) {
241 a523d270 2024-11-21 claudio if (imsgbuf_read(&c->iev.ibuf) != 1) {
242 1ca19f87 2012-04-11 deraadt control_close(fd, cs);
243 41042ecc 2006-12-16 reyk return;
244 41042ecc 2006-12-16 reyk }
245 650b98e6 2009-06-02 reyk }
246 650b98e6 2009-06-02 reyk
247 650b98e6 2009-06-02 reyk if (event & EV_WRITE) {
248 585eb325 2024-11-21 claudio if (imsgbuf_write(&c->iev.ibuf) == -1) {
249 1ca19f87 2012-04-11 deraadt control_close(fd, cs);
250 41042ecc 2006-12-16 reyk return;
251 41042ecc 2006-12-16 reyk }
252 41042ecc 2006-12-16 reyk }
253 41042ecc 2006-12-16 reyk
254 41042ecc 2006-12-16 reyk for (;;) {
255 eabfa908 2009-06-05 pyr if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
256 1ca19f87 2012-04-11 deraadt control_close(fd, cs);
257 41042ecc 2006-12-16 reyk return;
258 41042ecc 2006-12-16 reyk }
259 41042ecc 2006-12-16 reyk
260 41042ecc 2006-12-16 reyk if (n == 0)
261 41042ecc 2006-12-16 reyk break;
262 41042ecc 2006-12-16 reyk
263 f55b0941 2011-05-20 reyk if (c->waiting) {
264 f55b0941 2011-05-20 reyk log_debug("%s: unexpected imsg %d",
265 f55b0941 2011-05-20 reyk __func__, imsg.hdr.type);
266 f55b0941 2011-05-20 reyk imsg_free(&imsg);
267 1ca19f87 2012-04-11 deraadt control_close(fd, cs);
268 f55b0941 2011-05-20 reyk return;
269 f55b0941 2011-05-20 reyk }
270 f55b0941 2011-05-20 reyk
271 41042ecc 2006-12-16 reyk switch (imsg.hdr.type) {
272 41042ecc 2006-12-16 reyk case IMSG_CTL_SHOW_SUM:
273 41042ecc 2006-12-16 reyk show(c);
274 41042ecc 2006-12-16 reyk break;
275 41b83bb1 2007-09-07 reyk case IMSG_CTL_SESSION:
276 41b83bb1 2007-09-07 reyk show_sessions(c);
277 41b83bb1 2007-09-07 reyk break;
278 c8f9d8e3 2007-12-08 pyr case IMSG_CTL_RDR_DISABLE:
279 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
280 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
281 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
282 c8f9d8e3 2007-12-08 pyr if (disable_rdr(c, &id))
283 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
284 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
285 f16408f4 2007-02-01 pyr else {
286 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
287 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
288 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
289 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
290 f16408f4 2007-02-01 pyr }
291 41042ecc 2006-12-16 reyk break;
292 c8f9d8e3 2007-12-08 pyr case IMSG_CTL_RDR_ENABLE:
293 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
294 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
295 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
296 c8f9d8e3 2007-12-08 pyr if (enable_rdr(c, &id))
297 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
298 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
299 f16408f4 2007-02-01 pyr else {
300 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
301 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
302 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
303 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
304 f16408f4 2007-02-01 pyr }
305 41042ecc 2006-12-16 reyk break;
306 41042ecc 2006-12-16 reyk case IMSG_CTL_TABLE_DISABLE:
307 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
308 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
309 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
310 d2170f6d 2006-12-16 reyk if (disable_table(c, &id))
311 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
312 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
313 f16408f4 2007-02-01 pyr else {
314 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
315 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
316 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
317 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
318 f16408f4 2007-02-01 pyr }
319 41042ecc 2006-12-16 reyk break;
320 41042ecc 2006-12-16 reyk case IMSG_CTL_TABLE_ENABLE:
321 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
322 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
323 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
324 d2170f6d 2006-12-16 reyk if (enable_table(c, &id))
325 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
326 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
327 f16408f4 2007-02-01 pyr else {
328 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
329 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
330 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
331 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
332 f16408f4 2007-02-01 pyr }
333 41042ecc 2006-12-16 reyk break;
334 41042ecc 2006-12-16 reyk case IMSG_CTL_HOST_DISABLE:
335 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
336 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
337 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
338 17acabee 2008-07-19 reyk if (disable_host(c, &id, NULL))
339 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
340 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
341 f16408f4 2007-02-01 pyr else {
342 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
343 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
344 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
345 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
346 f16408f4 2007-02-01 pyr }
347 41042ecc 2006-12-16 reyk break;
348 41042ecc 2006-12-16 reyk case IMSG_CTL_HOST_ENABLE:
349 41042ecc 2006-12-16 reyk if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
350 41042ecc 2006-12-16 reyk fatalx("invalid imsg header len");
351 41042ecc 2006-12-16 reyk memcpy(&id, imsg.data, sizeof(id));
352 17acabee 2008-07-19 reyk if (enable_host(c, &id, NULL))
353 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
354 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
355 f16408f4 2007-02-01 pyr else {
356 f16408f4 2007-02-01 pyr memcpy(imsg.data, &id, sizeof(id));
357 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
358 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
359 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
360 f16408f4 2007-02-01 pyr }
361 41042ecc 2006-12-16 reyk break;
362 41042ecc 2006-12-16 reyk case IMSG_CTL_SHUTDOWN:
363 591e6ab5 2011-05-19 reyk case IMSG_CTL_RELOAD:
364 591e6ab5 2011-05-19 reyk proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
365 05b9f328 2007-05-29 pyr break;
366 5d05c593 2007-10-19 pyr case IMSG_CTL_POLL:
367 04adeb63 2016-09-26 reyk proc_compose(env->sc_ps, PROC_HCE,
368 04adeb63 2016-09-26 reyk IMSG_CTL_POLL, NULL, 0);
369 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_OK,
370 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
371 5d05c593 2007-10-19 pyr break;
372 f16408f4 2007-02-01 pyr case IMSG_CTL_NOTIFY:
373 f16408f4 2007-02-01 pyr if (c->flags & CTL_CONN_NOTIFY) {
374 666bd316 2011-05-05 reyk log_debug("%s: "
375 666bd316 2011-05-05 reyk "client requested notify more than once",
376 666bd316 2011-05-05 reyk __func__);
377 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
378 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, NULL, 0);
379 f16408f4 2007-02-01 pyr break;
380 f16408f4 2007-02-01 pyr }
381 f16408f4 2007-02-01 pyr c->flags |= CTL_CONN_NOTIFY;
382 f16408f4 2007-02-01 pyr break;
383 dbef7d4f 2011-05-09 reyk case IMSG_CTL_VERBOSE:
384 dbef7d4f 2011-05-09 reyk IMSG_SIZE_CHECK(&imsg, &verbose);
385 67bc535b 2010-01-11 jsg
386 67bc535b 2010-01-11 jsg memcpy(&verbose, imsg.data, sizeof(verbose));
387 67bc535b 2010-01-11 jsg
388 591e6ab5 2011-05-19 reyk proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
389 591e6ab5 2011-05-19 reyk proc_forward_imsg(env->sc_ps, &imsg, PROC_HCE, -1);
390 dbef7d4f 2011-05-09 reyk proc_forward_imsg(env->sc_ps, &imsg, PROC_RELAY, -1);
391 dbef7d4f 2011-05-09 reyk
392 67bc535b 2010-01-11 jsg memcpy(imsg.data, &verbose, sizeof(verbose));
393 3b28f64e 2016-09-02 reyk control_imsg_forward(ps, &imsg);
394 afbe8d84 2017-01-09 reyk log_setverbose(verbose);
395 67bc535b 2010-01-11 jsg break;
396 41042ecc 2006-12-16 reyk default:
397 666bd316 2011-05-05 reyk log_debug("%s: error handling imsg %d",
398 666bd316 2011-05-05 reyk __func__, imsg.hdr.type);
399 41042ecc 2006-12-16 reyk break;
400 41042ecc 2006-12-16 reyk }
401 41042ecc 2006-12-16 reyk imsg_free(&imsg);
402 41042ecc 2006-12-16 reyk }
403 41042ecc 2006-12-16 reyk
404 eabfa908 2009-06-05 pyr imsg_event_add(&c->iev);
405 41042ecc 2006-12-16 reyk }
406 41042ecc 2006-12-16 reyk
407 41042ecc 2006-12-16 reyk void
408 3b28f64e 2016-09-02 reyk control_imsg_forward(struct privsep *ps, struct imsg *imsg)
409 f16408f4 2007-02-01 pyr {
410 f16408f4 2007-02-01 pyr struct ctl_conn *c;
411 f16408f4 2007-02-01 pyr
412 f16408f4 2007-02-01 pyr TAILQ_FOREACH(c, &ctl_conns, entry)
413 f16408f4 2007-02-01 pyr if (c->flags & CTL_CONN_NOTIFY)
414 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, imsg->hdr.type,
415 3b28f64e 2016-09-02 reyk 0, ps->ps_instance + 1, -1, imsg->data,
416 6f81a163 2009-06-05 pyr imsg->hdr.len - IMSG_HEADER_SIZE);
417 f16408f4 2007-02-01 pyr }