xref: /openbsd/usr.sbin/smtpd/queue.c (revision e5dd7070)
1 /*	$OpenBSD: queue.c,v 1.190 2020/04/22 11:35:34 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
5  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/tree.h>
24 #include <sys/socket.h>
25 #include <sys/stat.h>
26 
27 #include <err.h>
28 #include <event.h>
29 #include <imsg.h>
30 #include <inttypes.h>
31 #include <pwd.h>
32 #include <signal.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37 #include <unistd.h>
38 #include <limits.h>
39 
40 #include "smtpd.h"
41 #include "log.h"
42 
43 static void queue_imsg(struct mproc *, struct imsg *);
44 static void queue_timeout(int, short, void *);
45 static void queue_bounce(struct envelope *, struct delivery_bounce *);
46 static void queue_shutdown(void);
47 static void queue_log(const struct envelope *, const char *, const char *);
48 static void queue_msgid_walk(int, short, void *);
49 
50 
51 static void
52 queue_imsg(struct mproc *p, struct imsg *imsg)
53 {
54 	struct delivery_bounce	 bounce;
55 	struct msg_walkinfo	*wi;
56 	struct timeval		 tv;
57 	struct bounce_req_msg	*req_bounce;
58 	struct envelope		 evp;
59 	struct msg		 m;
60 	const char		*reason;
61 	uint64_t		 reqid, evpid, holdq;
62 	uint32_t		 msgid;
63 	time_t			 nexttry;
64 	size_t			 n_evp;
65 	int			 fd, mta_ext, ret, v, flags, code;
66 
67 	if (imsg == NULL)
68 		queue_shutdown();
69 
70 	memset(&bounce, 0, sizeof(struct delivery_bounce));
71 
72 	switch (imsg->hdr.type) {
73 	case IMSG_SMTP_MESSAGE_CREATE:
74 		m_msg(&m, imsg);
75 		m_get_id(&m, &reqid);
76 		m_end(&m);
77 
78 		ret = queue_message_create(&msgid);
79 
80 		m_create(p, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1);
81 		m_add_id(p, reqid);
82 		if (ret == 0)
83 			m_add_int(p, 0);
84 		else {
85 			m_add_int(p, 1);
86 			m_add_msgid(p, msgid);
87 		}
88 		m_close(p);
89 		return;
90 
91 	case IMSG_SMTP_MESSAGE_ROLLBACK:
92 		m_msg(&m, imsg);
93 		m_get_msgid(&m, &msgid);
94 		m_end(&m);
95 
96 		queue_message_delete(msgid);
97 
98 		m_create(p_scheduler, IMSG_QUEUE_MESSAGE_ROLLBACK,
99 		    0, 0, -1);
100 		m_add_msgid(p_scheduler, msgid);
101 		m_close(p_scheduler);
102 		return;
103 
104 	case IMSG_SMTP_MESSAGE_COMMIT:
105 		m_msg(&m, imsg);
106 		m_get_id(&m, &reqid);
107 		m_get_msgid(&m, &msgid);
108 		m_end(&m);
109 
110 		ret = queue_message_commit(msgid);
111 
112 		m_create(p, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
113 		m_add_id(p, reqid);
114 		m_add_int(p, (ret == 0) ? 0 : 1);
115 		m_close(p);
116 
117 		if (ret) {
118 			m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
119 			    0, 0, -1);
120 			m_add_msgid(p_scheduler, msgid);
121 			m_close(p_scheduler);
122 		}
123 		return;
124 
125 	case IMSG_SMTP_MESSAGE_OPEN:
126 		m_msg(&m, imsg);
127 		m_get_id(&m, &reqid);
128 		m_get_msgid(&m, &msgid);
129 		m_end(&m);
130 
131 		fd = queue_message_fd_rw(msgid);
132 
133 		m_create(p, IMSG_SMTP_MESSAGE_OPEN, 0, 0, fd);
134 		m_add_id(p, reqid);
135 		m_add_int(p, (fd == -1) ? 0 : 1);
136 		m_close(p);
137 		return;
138 
139 	case IMSG_QUEUE_SMTP_SESSION:
140 		bounce_fd(imsg->fd);
141 		return;
142 
143 	case IMSG_LKA_ENVELOPE_SUBMIT:
144 		m_msg(&m, imsg);
145 		m_get_id(&m, &reqid);
146 		m_get_envelope(&m, &evp);
147 		m_end(&m);
148 
149 		if (evp.id == 0)
150 			log_warnx("warn: imsg_queue_submit_envelope: evpid=0");
151 		if (evpid_to_msgid(evp.id) == 0)
152 			log_warnx("warn: imsg_queue_submit_envelope: msgid=0, "
153 			    "evpid=%016"PRIx64, evp.id);
154 		ret = queue_envelope_create(&evp);
155 		m_create(p_pony, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
156 		m_add_id(p_pony, reqid);
157 		if (ret == 0)
158 			m_add_int(p_pony, 0);
159 		else {
160 			m_add_int(p_pony, 1);
161 			m_add_evpid(p_pony, evp.id);
162 		}
163 		m_close(p_pony);
164 		if (ret) {
165 			m_create(p_scheduler,
166 			    IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
167 			m_add_envelope(p_scheduler, &evp);
168 			m_close(p_scheduler);
169 		}
170 		return;
171 
172 	case IMSG_LKA_ENVELOPE_COMMIT:
173 		m_msg(&m, imsg);
174 		m_get_id(&m, &reqid);
175 		m_end(&m);
176 		m_create(p_pony, IMSG_QUEUE_ENVELOPE_COMMIT, 0, 0, -1);
177 		m_add_id(p_pony, reqid);
178 		m_add_int(p_pony, 1);
179 		m_close(p_pony);
180 		return;
181 
182 	case IMSG_SCHED_ENVELOPE_REMOVE:
183 		m_msg(&m, imsg);
184 		m_get_evpid(&m, &evpid);
185 		m_end(&m);
186 
187 		m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_ACK, 0, 0, -1);
188 		m_add_evpid(p_scheduler, evpid);
189 		m_close(p_scheduler);
190 
191 		/* already removed by scheduler */
192 		if (queue_envelope_load(evpid, &evp) == 0)
193 			return;
194 
195 		queue_log(&evp, "Remove", "Removed by administrator");
196 		queue_envelope_delete(evpid);
197 		return;
198 
199 	case IMSG_SCHED_ENVELOPE_EXPIRE:
200 		m_msg(&m, imsg);
201 		m_get_evpid(&m, &evpid);
202 		m_end(&m);
203 
204 		m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_ACK, 0, 0, -1);
205 		m_add_evpid(p_scheduler, evpid);
206 		m_close(p_scheduler);
207 
208 		/* already removed by scheduler*/
209 		if (queue_envelope_load(evpid, &evp) == 0)
210 			return;
211 
212 		bounce.type = B_FAILED;
213 		envelope_set_errormsg(&evp, "Envelope expired");
214 		envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
215 		envelope_set_esc_code(&evp, ESC_DELIVERY_TIME_EXPIRED);
216 		queue_bounce(&evp, &bounce);
217 		queue_log(&evp, "Expire", "Envelope expired");
218 		queue_envelope_delete(evpid);
219 		return;
220 
221 	case IMSG_SCHED_ENVELOPE_BOUNCE:
222 		CHECK_IMSG_DATA_SIZE(imsg, sizeof *req_bounce);
223 		req_bounce = imsg->data;
224 		evpid = req_bounce->evpid;
225 
226 		if (queue_envelope_load(evpid, &evp) == 0) {
227 			log_warnx("queue: bounce: failed to load envelope");
228 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
229 			m_add_evpid(p_scheduler, evpid);
230 			m_add_u32(p_scheduler, 0); /* not in-flight */
231 			m_close(p_scheduler);
232 			return;
233 		}
234 		queue_bounce(&evp, &req_bounce->bounce);
235 		evp.lastbounce = req_bounce->timestamp;
236 		if (!queue_envelope_update(&evp))
237 			log_warnx("warn: could not update envelope %016"PRIx64, evpid);
238 		return;
239 
240 	case IMSG_SCHED_ENVELOPE_DELIVER:
241 		m_msg(&m, imsg);
242 		m_get_evpid(&m, &evpid);
243 		m_end(&m);
244 		if (queue_envelope_load(evpid, &evp) == 0) {
245 			log_warnx("queue: deliver: failed to load envelope");
246 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
247 			m_add_evpid(p_scheduler, evpid);
248 			m_add_u32(p_scheduler, 1); /* in-flight */
249 			m_close(p_scheduler);
250 			return;
251 		}
252 		evp.lasttry = time(NULL);
253 		m_create(p_pony, IMSG_QUEUE_DELIVER, 0, 0, -1);
254 		m_add_envelope(p_pony, &evp);
255 		m_close(p_pony);
256 		return;
257 
258 	case IMSG_SCHED_ENVELOPE_INJECT:
259 		m_msg(&m, imsg);
260 		m_get_evpid(&m, &evpid);
261 		m_end(&m);
262 		bounce_add(evpid);
263 		return;
264 
265 	case IMSG_SCHED_ENVELOPE_TRANSFER:
266 		m_msg(&m, imsg);
267 		m_get_evpid(&m, &evpid);
268 		m_end(&m);
269 		if (queue_envelope_load(evpid, &evp) == 0) {
270 			log_warnx("queue: failed to load envelope");
271 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
272 			m_add_evpid(p_scheduler, evpid);
273 			m_add_u32(p_scheduler, 1); /* in-flight */
274 			m_close(p_scheduler);
275 			return;
276 		}
277 		evp.lasttry = time(NULL);
278 		m_create(p_pony, IMSG_QUEUE_TRANSFER, 0, 0, -1);
279 		m_add_envelope(p_pony, &evp);
280 		m_close(p_pony);
281 		return;
282 
283 	case IMSG_CTL_LIST_ENVELOPES:
284 		if (imsg->hdr.len == sizeof imsg->hdr) {
285 			m_forward(p_control, imsg);
286 			return;
287 		}
288 
289 		m_msg(&m, imsg);
290 		m_get_evpid(&m, &evpid);
291 		m_get_int(&m, &flags);
292 		m_get_time(&m, &nexttry);
293 		m_end(&m);
294 
295 		if (queue_envelope_load(evpid, &evp) == 0)
296 			return; /* Envelope is gone, drop it */
297 
298 		/*
299 		 * XXX consistency: The envelope might already be on
300 		 * its way back to the scheduler.  We need to detect
301 		 * this properly and report that state.
302 		 */
303 		if (flags & EF_INFLIGHT) {
304 			/*
305 			 * Not exactly correct but pretty close: The
306 			 * value is not recorded on the envelope unless
307 			 * a tempfail occurs.
308 			 */
309 			evp.lasttry = nexttry;
310 		}
311 
312 		m_create(p_control, IMSG_CTL_LIST_ENVELOPES,
313 		    imsg->hdr.peerid, 0, -1);
314 		m_add_int(p_control, flags);
315 		m_add_time(p_control, nexttry);
316 		m_add_envelope(p_control, &evp);
317 		m_close(p_control);
318 		return;
319 
320 	case IMSG_MDA_OPEN_MESSAGE:
321 	case IMSG_MTA_OPEN_MESSAGE:
322 		m_msg(&m, imsg);
323 		m_get_id(&m, &reqid);
324 		m_get_msgid(&m, &msgid);
325 		m_end(&m);
326 		fd = queue_message_fd_r(msgid);
327 		m_create(p, imsg->hdr.type, 0, 0, fd);
328 		m_add_id(p, reqid);
329 		m_close(p);
330 		return;
331 
332 	case IMSG_MDA_DELIVERY_OK:
333 	case IMSG_MTA_DELIVERY_OK:
334 		m_msg(&m, imsg);
335 		m_get_evpid(&m, &evpid);
336 		if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK)
337 			m_get_int(&m, &mta_ext);
338 		m_end(&m);
339 		if (queue_envelope_load(evpid, &evp) == 0) {
340 			log_warn("queue: dsn: failed to load envelope");
341 			return;
342 		}
343 		if (evp.dsn_notify & DSN_SUCCESS) {
344 			bounce.type = B_DELIVERED;
345 			bounce.dsn_ret = evp.dsn_ret;
346 			envelope_set_esc_class(&evp, ESC_STATUS_OK);
347 			if (imsg->hdr.type == IMSG_MDA_DELIVERY_OK)
348 				queue_bounce(&evp, &bounce);
349 			else if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK &&
350 			    (mta_ext & MTA_EXT_DSN) == 0) {
351 				bounce.mta_without_dsn = 1;
352 				queue_bounce(&evp, &bounce);
353 			}
354 		}
355 		queue_envelope_delete(evpid);
356 		m_create(p_scheduler, IMSG_QUEUE_DELIVERY_OK, 0, 0, -1);
357 		m_add_evpid(p_scheduler, evpid);
358 		m_close(p_scheduler);
359 		return;
360 
361 	case IMSG_MDA_DELIVERY_TEMPFAIL:
362 	case IMSG_MTA_DELIVERY_TEMPFAIL:
363 		m_msg(&m, imsg);
364 		m_get_evpid(&m, &evpid);
365 		m_get_string(&m, &reason);
366 		m_get_int(&m, &code);
367 		m_end(&m);
368 		if (queue_envelope_load(evpid, &evp) == 0) {
369 			log_warnx("queue: tempfail: failed to load envelope");
370 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
371 			m_add_evpid(p_scheduler, evpid);
372 			m_add_u32(p_scheduler, 1); /* in-flight */
373 			m_close(p_scheduler);
374 			return;
375 		}
376 		envelope_set_errormsg(&evp, "%s", reason);
377 		envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
378 		envelope_set_esc_code(&evp, code);
379 		evp.retry++;
380 		if (!queue_envelope_update(&evp))
381 			log_warnx("warn: could not update envelope %016"PRIx64, evpid);
382 		m_create(p_scheduler, IMSG_QUEUE_DELIVERY_TEMPFAIL, 0, 0, -1);
383 		m_add_envelope(p_scheduler, &evp);
384 		m_close(p_scheduler);
385 		return;
386 
387 	case IMSG_MDA_DELIVERY_PERMFAIL:
388 	case IMSG_MTA_DELIVERY_PERMFAIL:
389 		m_msg(&m, imsg);
390 		m_get_evpid(&m, &evpid);
391 		m_get_string(&m, &reason);
392 		m_get_int(&m, &code);
393 		m_end(&m);
394 		if (queue_envelope_load(evpid, &evp) == 0) {
395 			log_warnx("queue: permfail: failed to load envelope");
396 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
397 			m_add_evpid(p_scheduler, evpid);
398 			m_add_u32(p_scheduler, 1); /* in-flight */
399 			m_close(p_scheduler);
400 			return;
401 		}
402 		bounce.type = B_FAILED;
403 		envelope_set_errormsg(&evp, "%s", reason);
404 		envelope_set_esc_class(&evp, ESC_STATUS_PERMFAIL);
405 		envelope_set_esc_code(&evp, code);
406 		queue_bounce(&evp, &bounce);
407 		queue_envelope_delete(evpid);
408 		m_create(p_scheduler, IMSG_QUEUE_DELIVERY_PERMFAIL, 0, 0, -1);
409 		m_add_evpid(p_scheduler, evpid);
410 		m_close(p_scheduler);
411 		return;
412 
413 	case IMSG_MDA_DELIVERY_LOOP:
414 	case IMSG_MTA_DELIVERY_LOOP:
415 		m_msg(&m, imsg);
416 		m_get_evpid(&m, &evpid);
417 		m_end(&m);
418 		if (queue_envelope_load(evpid, &evp) == 0) {
419 			log_warnx("queue: loop: failed to load envelope");
420 			m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
421 			m_add_evpid(p_scheduler, evpid);
422 			m_add_u32(p_scheduler, 1); /* in-flight */
423 			m_close(p_scheduler);
424 			return;
425 		}
426 		envelope_set_errormsg(&evp, "%s", "Loop detected");
427 		envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
428 		envelope_set_esc_code(&evp, ESC_ROUTING_LOOP_DETECTED);
429 		bounce.type = B_FAILED;
430 		queue_bounce(&evp, &bounce);
431 		queue_envelope_delete(evp.id);
432 		m_create(p_scheduler, IMSG_QUEUE_DELIVERY_LOOP, 0, 0, -1);
433 		m_add_evpid(p_scheduler, evp.id);
434 		m_close(p_scheduler);
435 		return;
436 
437 	case IMSG_MTA_DELIVERY_HOLD:
438 	case IMSG_MDA_DELIVERY_HOLD:
439 		imsg->hdr.type = IMSG_QUEUE_HOLDQ_HOLD;
440 		m_forward(p_scheduler, imsg);
441 		return;
442 
443 	case IMSG_MTA_SCHEDULE:
444 		imsg->hdr.type = IMSG_QUEUE_ENVELOPE_SCHEDULE;
445 		m_forward(p_scheduler, imsg);
446 		return;
447 
448 	case IMSG_MTA_HOLDQ_RELEASE:
449 	case IMSG_MDA_HOLDQ_RELEASE:
450 		m_msg(&m, imsg);
451 		m_get_id(&m, &holdq);
452 		m_get_int(&m, &v);
453 		m_end(&m);
454 		m_create(p_scheduler, IMSG_QUEUE_HOLDQ_RELEASE, 0, 0, -1);
455 		if (imsg->hdr.type == IMSG_MTA_HOLDQ_RELEASE)
456 			m_add_int(p_scheduler, D_MTA);
457 		else
458 			m_add_int(p_scheduler, D_MDA);
459 		m_add_id(p_scheduler, holdq);
460 		m_add_int(p_scheduler, v);
461 		m_close(p_scheduler);
462 		return;
463 
464 	case IMSG_CTL_PAUSE_MDA:
465 	case IMSG_CTL_PAUSE_MTA:
466 	case IMSG_CTL_RESUME_MDA:
467 	case IMSG_CTL_RESUME_MTA:
468 		m_forward(p_scheduler, imsg);
469 		return;
470 
471 	case IMSG_CTL_VERBOSE:
472 		m_msg(&m, imsg);
473 		m_get_int(&m, &v);
474 		m_end(&m);
475 		log_trace_verbose(v);
476 		return;
477 
478 	case IMSG_CTL_PROFILE:
479 		m_msg(&m, imsg);
480 		m_get_int(&m, &v);
481 		m_end(&m);
482 		profiling = v;
483 		return;
484 
485 	case IMSG_CTL_DISCOVER_EVPID:
486 		m_msg(&m, imsg);
487 		m_get_evpid(&m, &evpid);
488 		m_end(&m);
489 		if (queue_envelope_load(evpid, &evp) == 0) {
490 			log_warnx("queue: discover: failed to load "
491 			    "envelope %016" PRIx64, evpid);
492 			n_evp = 0;
493 			m_compose(p_control, imsg->hdr.type,
494 			    imsg->hdr.peerid, 0, -1,
495 			    &n_evp, sizeof n_evp);
496 			return;
497 		}
498 
499 		m_create(p_scheduler, IMSG_QUEUE_DISCOVER_EVPID,
500 		    0, 0, -1);
501 		m_add_envelope(p_scheduler, &evp);
502 		m_close(p_scheduler);
503 
504 		m_create(p_scheduler, IMSG_QUEUE_DISCOVER_MSGID,
505 		    0, 0, -1);
506 		m_add_msgid(p_scheduler, evpid_to_msgid(evpid));
507 		m_close(p_scheduler);
508 		n_evp = 1;
509 		m_compose(p_control, imsg->hdr.type, imsg->hdr.peerid,
510 		    0, -1, &n_evp, sizeof n_evp);
511 		return;
512 
513 	case IMSG_CTL_DISCOVER_MSGID:
514 		m_msg(&m, imsg);
515 		m_get_msgid(&m, &msgid);
516 		m_end(&m);
517 		/* handle concurrent walk requests */
518 		wi = xcalloc(1, sizeof *wi);
519 		wi->msgid = msgid;
520 		wi->peerid = imsg->hdr.peerid;
521 		evtimer_set(&wi->ev, queue_msgid_walk, wi);
522 		tv.tv_sec = 0;
523 		tv.tv_usec = 10;
524 		evtimer_add(&wi->ev, &tv);
525 		return;
526 	}
527 
528 	errx(1, "queue_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
529 }
530 
531 static void
532 queue_msgid_walk(int fd, short event, void *arg)
533 {
534 	struct envelope		 evp;
535 	struct timeval		 tv;
536 	struct msg_walkinfo	*wi = arg;
537 	int			 r;
538 
539 	r = queue_message_walk(&evp, wi->msgid, &wi->done, &wi->data);
540 	if (r == -1) {
541 		if (wi->n_evp) {
542 			m_create(p_scheduler, IMSG_QUEUE_DISCOVER_MSGID,
543 			    0, 0, -1);
544 			m_add_msgid(p_scheduler, wi->msgid);
545 			m_close(p_scheduler);
546 		}
547 
548 		m_compose(p_control, IMSG_CTL_DISCOVER_MSGID, wi->peerid, 0, -1,
549 		    &wi->n_evp, sizeof wi->n_evp);
550 		evtimer_del(&wi->ev);
551 		free(wi);
552 		return;
553 	}
554 
555 	if (r) {
556 		m_create(p_scheduler, IMSG_QUEUE_DISCOVER_EVPID, 0, 0, -1);
557 		m_add_envelope(p_scheduler, &evp);
558 		m_close(p_scheduler);
559 		wi->n_evp += 1;
560 	}
561 
562 	tv.tv_sec = 0;
563 	tv.tv_usec = 10;
564 	evtimer_set(&wi->ev, queue_msgid_walk, wi);
565 	evtimer_add(&wi->ev, &tv);
566 }
567 
568 static void
569 queue_bounce(struct envelope *e, struct delivery_bounce *d)
570 {
571 	struct envelope	b;
572 
573 	b = *e;
574 	b.type = D_BOUNCE;
575 	b.agent.bounce = *d;
576 	b.retry = 0;
577 	b.lasttry = 0;
578 	b.creation = time(NULL);
579 	b.ttl = 3600 * 24 * 7;
580 
581 	if (e->dsn_notify & DSN_NEVER)
582 		return;
583 
584 	if (b.id == 0)
585 		log_warnx("warn: queue_bounce: evpid=0");
586 	if (evpid_to_msgid(b.id) == 0)
587 		log_warnx("warn: queue_bounce: msgid=0, evpid=%016"PRIx64,
588 			b.id);
589 	if (e->type == D_BOUNCE) {
590 		log_warnx("warn: queue: double bounce!");
591 	} else if (e->sender.user[0] == '\0') {
592 		log_warnx("warn: queue: no return path!");
593 	} else if (!queue_envelope_create(&b)) {
594 		log_warnx("warn: queue: cannot bounce!");
595 	} else {
596 		log_debug("debug: queue: bouncing evp:%016" PRIx64
597 		    " as evp:%016" PRIx64, e->id, b.id);
598 
599 		m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
600 		m_add_envelope(p_scheduler, &b);
601 		m_close(p_scheduler);
602 
603 		m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT, 0, 0, -1);
604 		m_add_msgid(p_scheduler, evpid_to_msgid(b.id));
605 		m_close(p_scheduler);
606 
607 		stat_increment("queue.bounce", 1);
608 	}
609 }
610 
611 static void
612 queue_shutdown(void)
613 {
614 	log_debug("debug: queue agent exiting");
615 	queue_close();
616 	_exit(0);
617 }
618 
619 int
620 queue(void)
621 {
622 	struct passwd	*pw;
623 	struct timeval	 tv;
624 	struct event	 ev_qload;
625 
626 	purge_config(PURGE_EVERYTHING & ~PURGE_DISPATCHERS);
627 
628 	if ((pw = getpwnam(SMTPD_QUEUE_USER)) == NULL)
629 		if ((pw = getpwnam(SMTPD_USER)) == NULL)
630 			fatalx("unknown user " SMTPD_USER);
631 
632 	env->sc_queue_flags |= QUEUE_EVPCACHE;
633 	env->sc_queue_evpcache_size = 1024;
634 
635 	if (chroot(PATH_SPOOL) == -1)
636 		fatal("queue: chroot");
637 	if (chdir("/") == -1)
638 		fatal("queue: chdir(\"/\")");
639 
640 	config_process(PROC_QUEUE);
641 
642 	if (env->sc_queue_flags & QUEUE_COMPRESSION)
643 		log_info("queue: queue compression enabled");
644 
645 	if (env->sc_queue_key) {
646 		if (!crypto_setup(env->sc_queue_key, strlen(env->sc_queue_key)))
647 			fatalx("crypto_setup: invalid key for queue encryption");
648 		log_info("queue: queue encryption enabled");
649 	}
650 
651 	if (setgroups(1, &pw->pw_gid) ||
652 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
653 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
654 		fatal("queue: cannot drop privileges");
655 
656 	imsg_callback = queue_imsg;
657 	event_init();
658 
659 	signal(SIGINT, SIG_IGN);
660 	signal(SIGTERM, SIG_IGN);
661 	signal(SIGPIPE, SIG_IGN);
662 	signal(SIGHUP, SIG_IGN);
663 
664 	config_peer(PROC_PARENT);
665 	config_peer(PROC_CONTROL);
666 	config_peer(PROC_LKA);
667 	config_peer(PROC_SCHEDULER);
668 	config_peer(PROC_PONY);
669 
670 	/* setup queue loading task */
671 	evtimer_set(&ev_qload, queue_timeout, &ev_qload);
672 	tv.tv_sec = 0;
673 	tv.tv_usec = 10;
674 	evtimer_add(&ev_qload, &tv);
675 
676 	if (pledge("stdio rpath wpath cpath flock recvfd sendfd", NULL) == -1)
677 		err(1, "pledge");
678 
679 	event_dispatch();
680 	fatalx("exited event loop");
681 
682 	return (0);
683 }
684 
685 static void
686 queue_timeout(int fd, short event, void *p)
687 {
688 	static uint32_t	 msgid = 0;
689 	struct envelope	 evp;
690 	struct event	*ev = p;
691 	struct timeval	 tv;
692 	int		 r;
693 
694 	r = queue_envelope_walk(&evp);
695 	if (r == -1) {
696 		if (msgid) {
697 			m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
698 			    0, 0, -1);
699 			m_add_msgid(p_scheduler, msgid);
700 			m_close(p_scheduler);
701 		}
702 		log_debug("debug: queue: done loading queue into scheduler");
703 		return;
704 	}
705 
706 	if (r) {
707 		if (msgid && evpid_to_msgid(evp.id) != msgid) {
708 			m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
709 			    0, 0, -1);
710 			m_add_msgid(p_scheduler, msgid);
711 			m_close(p_scheduler);
712 		}
713 		msgid = evpid_to_msgid(evp.id);
714 		m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
715 		m_add_envelope(p_scheduler, &evp);
716 		m_close(p_scheduler);
717 	}
718 
719 	tv.tv_sec = 0;
720 	tv.tv_usec = 10;
721 	evtimer_add(ev, &tv);
722 }
723 
724 static void
725 queue_log(const struct envelope *e, const char *prefix, const char *status)
726 {
727 	char rcpt[LINE_MAX];
728 
729 	(void)strlcpy(rcpt, "-", sizeof rcpt);
730 	if (strcmp(e->rcpt.user, e->dest.user) ||
731 	    strcmp(e->rcpt.domain, e->dest.domain))
732 		(void)snprintf(rcpt, sizeof rcpt, "%s@%s",
733 		    e->rcpt.user, e->rcpt.domain);
734 
735 	log_info("%s: %s for %016" PRIx64 ": from=<%s@%s>, to=<%s@%s>, "
736 	    "rcpt=<%s>, delay=%s, stat=%s",
737 	    e->type == D_MDA ? "delivery" : "relay",
738 	    prefix,
739 	    e->id, e->sender.user, e->sender.domain,
740 	    e->dest.user, e->dest.domain,
741 	    rcpt,
742 	    duration_to_text(time(NULL) - e->creation),
743 	    status);
744 }
745