summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-04-20 15:34:57 +0000
committerJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-04-20 15:34:57 +0000
commit318ca7cef0691f6d5daeca58557bfd79b3220e12 (patch)
treef6eae7893a3065a5685c10c071f6b64305ed5286 /usr.sbin
parent001b3d12570bfa08c409e5bc9e1a8a299473cb9e (diff)
Kill *2400* lines of code by abstracting common bits of the imsg handlers.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/config.c6
-rw-r--r--usr.sbin/smtpd/control.c422
-rw-r--r--usr.sbin/smtpd/lka.c686
-rw-r--r--usr.sbin/smtpd/mda.c332
-rw-r--r--usr.sbin/smtpd/mfa.c270
-rw-r--r--usr.sbin/smtpd/mta.c421
-rw-r--r--usr.sbin/smtpd/queue.c576
-rw-r--r--usr.sbin/smtpd/runner.c461
-rw-r--r--usr.sbin/smtpd/smtp.c660
-rw-r--r--usr.sbin/smtpd/smtpd.c626
-rw-r--r--usr.sbin/smtpd/smtpd.h7
11 files changed, 1044 insertions, 3423 deletions
diff --git a/usr.sbin/smtpd/config.c b/usr.sbin/smtpd/config.c
index 2f2142d6119..577b09c992e 100644
--- a/usr.sbin/smtpd/config.c
+++ b/usr.sbin/smtpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.9 2009/11/12 12:35:03 jacekm Exp $ */
+/* $OpenBSD: config.c,v 1.10 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -218,7 +218,9 @@ config_peers(struct smtpd *env, struct peer *p, u_int peercount)
env->sc_pipes[src][dst][count]);
env->sc_ievs[dst][count].handler = p[i].cb;
env->sc_ievs[dst][count].events = EV_READ;
- env->sc_ievs[dst][count].data = env;
+ env->sc_ievs[dst][count].proc = dst;
+ env->sc_ievs[dst][count].data = &env->sc_ievs[dst][count];
+ env->sc_ievs[dst][count].env = env;
event_set(&(env->sc_ievs[dst][count].ev),
env->sc_ievs[dst][count].ibuf.fd,
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c
index 53d94339755..26c1b3897c3 100644
--- a/usr.sbin/smtpd/control.c
+++ b/usr.sbin/smtpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.46 2010/01/10 16:42:35 gilles Exp $ */
+/* $OpenBSD: control.c,v 1.47 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -45,6 +45,7 @@ struct {
int fd;
} control_state;
+void control_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void control_shutdown(void);
int control_init(void);
void control_listen(struct smtpd *);
@@ -54,16 +55,72 @@ struct ctl_conn *control_connbyfd(int);
void control_close(struct smtpd *, int);
void control_sig_handler(int, short, void *);
void control_dispatch_ext(int, short, void *);
-void control_dispatch_lka(int, short, void *);
-void control_dispatch_mfa(int, short, void *);
-void control_dispatch_queue(int, short, void *);
-void control_dispatch_runner(int, short, void *);
-void control_dispatch_smtp(int, short, void *);
-void control_dispatch_parent(int, short, void *);
struct ctl_connlist ctl_conns;
void
+control_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
+{
+ struct ctl_conn *c;
+ struct reload *reload;
+ struct remove *rem;
+ struct sched *sched;
+
+ if (iev->proc == PROC_SMTP) {
+ switch (imsg->hdr.type) {
+ case IMSG_SMTP_ENQUEUE:
+ c = control_connbyfd(imsg->hdr.peerid);
+ if (c == NULL)
+ return;
+ imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0,
+ imsg->fd, NULL, 0);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
+ case IMSG_RUNNER_SCHEDULE:
+ sched = imsg->data;
+ c = control_connbyfd(sched->fd);
+ if (c == NULL)
+ return;
+ imsg_compose_event(&c->iev,
+ sched->ret ? IMSG_CTL_OK : IMSG_CTL_FAIL, 0, 0, -1,
+ NULL, 0);
+ return;
+
+ case IMSG_RUNNER_REMOVE:
+ rem = imsg->data;
+ c = control_connbyfd(rem->fd);
+ if (c == NULL)
+ return;
+ imsg_compose_event(&c->iev,
+ rem->ret ? IMSG_CTL_OK : IMSG_CTL_FAIL, 0, 0,
+ -1, NULL, 0);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CONF_RELOAD:
+ env->sc_flags &= ~SMTPD_CONFIGURING;
+ reload = imsg->data;
+ c = control_connbyfd(reload->fd);
+ if (c == NULL)
+ return;
+ imsg_compose_event(&c->iev,
+ reload->ret ? IMSG_CTL_OK : IMSG_CTL_FAIL, 0, 0,
+ -1, NULL, 0);
+ return;
+ }
+ }
+
+ fatalx("control_imsg: unexpected imsg");
+}
+
+void
control_sig_handler(int sig, short event, void *p)
{
switch (sig) {
@@ -88,11 +145,11 @@ control(struct smtpd *env)
struct event ev_sigint;
struct event ev_sigterm;
struct peer peers [] = {
- { PROC_QUEUE, control_dispatch_queue },
- { PROC_RUNNER, control_dispatch_runner },
- { PROC_SMTP, control_dispatch_smtp },
- { PROC_MFA, control_dispatch_mfa },
- { PROC_PARENT, control_dispatch_parent },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_MFA, imsg_dispatch },
+ { PROC_PARENT, imsg_dispatch },
};
switch (pid = fork()) {
@@ -158,6 +215,7 @@ control(struct smtpd *env)
fatal("control: cannot drop privileges");
#endif
+ imsg_callback = control_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, control_sig_handler, env);
@@ -535,343 +593,3 @@ badcred:
imsg_event_add(&c->iev);
}
-
-void
-control_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_CONF_RELOAD: {
- struct reload *r = imsg.data;
- struct ctl_conn *c;
-
- IMSG_SIZE_CHECK(r);
-
- env->sc_flags &= ~SMTPD_CONFIGURING;
- if ((c = control_connbyfd(r->fd)) == NULL) {
- log_warn("control_dispatch_parent: fd %d not found", r->fd);
- return;
- }
-
- if (r->ret)
- imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
- else
- imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0);
- break;
- }
- default:
- log_warnx("control_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-control_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("control_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-control_dispatch_mfa(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MFA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_mfa: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("control_dispatch_mfa: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_mfa: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-control_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("control_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-control_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_RUNNER_SCHEDULE: {
- struct sched *s = imsg.data;
- struct ctl_conn *c;
-
- IMSG_SIZE_CHECK(s);
-
- if ((c = control_connbyfd(s->fd)) == NULL) {
- log_warn("control_dispatch_runner: fd %d not found", s->fd);
- imsg_free(&imsg);
- return;
- }
-
- if (s->ret)
- imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
- else
- imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0);
- break;
- }
- case IMSG_RUNNER_REMOVE: {
- struct remove *s = imsg.data;
- struct ctl_conn *c;
-
- IMSG_SIZE_CHECK(s);
-
- if ((c = control_connbyfd(s->fd)) == NULL) {
- log_warn("control_dispatch_runner: fd %d not found", s->fd);
- imsg_free(&imsg);
- return;
- }
-
- if (s->ret)
- imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
- else
- imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0);
- break;
- }
- default:
- log_warnx("control_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-control_dispatch_smtp(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("control_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_SMTP_ENQUEUE: {
- struct ctl_conn *c;
- int client_fd;
-
- client_fd = imsg.hdr.peerid;
-
- if ((c = control_connbyfd(client_fd)) == NULL) {
- log_warn("control_dispatch_smtp: fd %d not found", client_fd);
- imsg_free(&imsg);
- return;
- }
-
- imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0,
- imsg.fd, NULL, 0);
- break;
- }
- default:
- log_warnx("control_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("control_dispatch_smtp: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c
index 192f83cf333..dc4bc499238 100644
--- a/usr.sbin/smtpd/lka.c
+++ b/usr.sbin/smtpd/lka.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka.c,v 1.101 2010/02/17 17:27:47 gilles Exp $ */
+/* $OpenBSD: lka.c,v 1.102 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -41,14 +41,9 @@
#include "smtpd.h"
+void lka_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void lka_shutdown(void);
void lka_sig_handler(int, short, void *);
-void lka_dispatch_parent(int, short, void *);
-void lka_dispatch_mfa(int, short, void *);
-void lka_dispatch_smtp(int, short, void *);
-void lka_dispatch_queue(int, short, void *);
-void lka_dispatch_runner(int, short, void *);
-void lka_dispatch_mta(int, short, void *);
void lka_setup_events(struct smtpd *);
void lka_disable_events(struct smtpd *);
void lka_expand_pickup(struct smtpd *, struct lkasession *);
@@ -69,543 +64,223 @@ void lka_expansion_done(struct smtpd *, struct lkasession *);
void lka_session_fail(struct smtpd *, struct lkasession *, struct submit_status *);
void
-lka_sig_handler(int sig, short event, void *p)
+lka_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- int status;
- pid_t pid;
-
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- lka_shutdown();
- break;
- case SIGCHLD:
- do {
- pid = waitpid(-1, &status, WNOHANG);
- } while (pid > 0 || (pid == -1 && errno == EINTR));
- break;
- default:
- fatalx("lka_sig_handler: unexpected signal");
+ struct lkasession skey;
+ struct submit_status *ss;
+ struct forward_req *fwreq;
+ struct lkasession *s;
+ struct secret *secret;
+ struct mapel *mapel;
+ struct cond *cond;
+ struct rule *rule;
+ struct path *path;
+ struct map *map;
+ void *tmp;
+
+ if (imsg->hdr.type == IMSG_DNS_A || imsg->hdr.type == IMSG_DNS_MX ||
+ imsg->hdr.type == IMSG_DNS_PTR) {
+ dns_async(env, iev, imsg->hdr.type, imsg->data);
+ return;
}
-}
-void
-lka_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_MFA) {
+ switch (imsg->hdr.type) {
+ case IMSG_LKA_MAIL:
+ ss = imsg->data;
+ ss->code = 530;
+ if (ss->u.path.user[0] == '\0' &&
+ ss->u.path.domain[0] == '\0')
+ ss->code = 250;
+ else
+ if (lka_verify_mail(env, &ss->u.path))
+ ss->code = 250;
+ imsg_compose_event(iev, IMSG_LKA_MAIL, 0, 0, -1, ss,
+ sizeof *ss);
+ return;
+
+ case IMSG_LKA_RULEMATCH:
+ ss = imsg->data;
+ ss->code = 530;
+ rule = ruleset_match(env, ss->msg.tag, &ss->u.path,
+ &ss->ss);
+ if (rule) {
+ ss->code = 250;
+ ss->u.path.rule = *rule;
+ }
+ imsg_compose_event(iev, IMSG_LKA_RULEMATCH, 0, 0, -1,
+ ss, sizeof *ss);
+ return;
+
+ case IMSG_LKA_RCPT:
+ ss = imsg->data;
+ ss->code = 250;
+ path = &ss->u.path;
+ s = lka_session_init(env, ss);
+ if (! lka_resolve_path(env, s, path))
+ lka_session_fail(env, s, ss);
+ else
+ lka_expand_pickup(env, s);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
+ if (iev->proc == PROC_MTA) {
+ switch (imsg->hdr.type) {
+ case IMSG_LKA_SECRET:
+ secret = imsg->data;
+ map = map_findbyname(env, "secrets");
+ if (map == NULL)
+ fatalx("lka: secrets map not found");
+ tmp = map_lookup(env, map->m_id, secret->host);
+ log_debug("lka: %s secret lookup (%d)", secret->host,
+ tmp != NULL);
+ secret->secret[0] = '\0';
+ if (tmp == NULL)
+ log_warnx("%s secret not found", secret->host);
+ else if (lka_encode_credentials(secret->secret,
+ sizeof secret->secret, tmp) == 0)
+ log_warnx("%s secret parse fail", secret->host);
+ imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, secret,
+ sizeof *secret);
+ free(tmp);
+ return;
+ }
}
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
case IMSG_CONF_START:
- if ((env->sc_rules_reload = calloc(1, sizeof(*env->sc_rules))) == NULL)
- fatal("mfa_dispatch_parent: calloc");
- if ((env->sc_maps_reload = calloc(1, sizeof(*env->sc_maps))) == NULL)
- fatal("mfa_dispatch_parent: calloc");
+ env->sc_rules_reload = calloc(1, sizeof *env->sc_rules);
+ if (env->sc_rules_reload == NULL)
+ fatal(NULL);
+ env->sc_maps_reload = calloc(1, sizeof *env->sc_maps);
+ if (env->sc_maps_reload == NULL)
+ fatal(NULL);
TAILQ_INIT(env->sc_rules_reload);
TAILQ_INIT(env->sc_maps_reload);
- break;
- case IMSG_CONF_RULE: {
- struct rule *rule = imsg.data;
-
- IMSG_SIZE_CHECK(rule);
+ return;
- rule = calloc(1, sizeof(*rule));
+ case IMSG_CONF_RULE:
+ rule = calloc(1, sizeof *rule);
if (rule == NULL)
- fatal("mfa_dispatch_parent: calloc");
- *rule = *(struct rule *)imsg.data;
-
+ fatal(NULL);
+ *rule = *(struct rule *)imsg->data;
TAILQ_INIT(&rule->r_conditions);
TAILQ_INSERT_TAIL(env->sc_rules_reload, rule, r_entry);
- break;
- }
- case IMSG_CONF_CONDITION: {
- struct rule *r = TAILQ_LAST(env->sc_rules_reload, rulelist);
- struct cond *cond = imsg.data;
-
- IMSG_SIZE_CHECK(cond);
+ return;
- cond = calloc(1, sizeof(*cond));
+ case IMSG_CONF_CONDITION:
+ rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
+ cond = calloc(1, sizeof *cond);
if (cond == NULL)
- fatal("mfa_dispatch_parent: calloc");
- *cond = *(struct cond *)imsg.data;
-
- TAILQ_INSERT_TAIL(&r->r_conditions, cond, c_entry);
- break;
- }
- case IMSG_CONF_MAP: {
- struct map *m = imsg.data;
-
- IMSG_SIZE_CHECK(m);
-
- m = calloc(1, sizeof(*m));
- if (m == NULL)
- fatal("mfa_dispatch_parent: calloc");
- *m = *(struct map *)imsg.data;
+ fatal(NULL);
+ *cond = *(struct cond *)imsg->data;
+ TAILQ_INSERT_TAIL(&rule->r_conditions, cond, c_entry);
+ return;
- TAILQ_INIT(&m->m_contents);
- TAILQ_INSERT_TAIL(env->sc_maps_reload, m, m_entry);
- break;
- }
- case IMSG_CONF_RULE_SOURCE: {
- struct rule *rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
- char *sourcemap = imsg.data;
- void *temp = env->sc_maps;
+ case IMSG_CONF_MAP:
+ map = calloc(1, sizeof *map);
+ if (map == NULL)
+ fatal(NULL);
+ *map = *(struct map *)imsg->data;
+ TAILQ_INIT(&map->m_contents);
+ TAILQ_INSERT_TAIL(env->sc_maps_reload, map, m_entry);
+ return;
- /* map lookup must be done in the reloaded conf */
+ case IMSG_CONF_RULE_SOURCE:
+ rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
+ tmp = env->sc_maps;
env->sc_maps = env->sc_maps_reload;
- rule->r_sources = map_findbyname(env, sourcemap);
+ rule->r_sources = map_findbyname(env, imsg->data);
if (rule->r_sources == NULL)
- fatalx("maps inconsistency");
- env->sc_maps = temp;
- break;
- }
- case IMSG_CONF_MAP_CONTENT: {
- struct map *m = TAILQ_LAST(env->sc_maps_reload, maplist);
- struct mapel *mapel = imsg.data;
-
- IMSG_SIZE_CHECK(mapel);
-
- mapel = calloc(1, sizeof(*mapel));
+ fatalx("lka: maps inconsistency");
+ env->sc_maps = tmp;
+ return;
+
+ case IMSG_CONF_MAP_CONTENT:
+ map = TAILQ_LAST(env->sc_maps_reload, maplist);
+ mapel = calloc(1, sizeof *mapel);
if (mapel == NULL)
- fatal("mfa_dispatch_parent: calloc");
- *mapel = *(struct mapel *)imsg.data;
+ fatal(NULL);
+ *mapel = *(struct mapel *)imsg->data;
+ TAILQ_INSERT_TAIL(&map->m_contents, mapel, me_entry);
+ return;
- TAILQ_INSERT_TAIL(&m->m_contents, mapel, me_entry);
- break;
- }
- case IMSG_CONF_END: {
- /* switch and destroy old ruleset */
+ case IMSG_CONF_END:
if (env->sc_rules)
purge_config(env, PURGE_RULES);
if (env->sc_maps)
purge_config(env, PURGE_MAPS);
env->sc_rules = env->sc_rules_reload;
env->sc_maps = env->sc_maps_reload;
- break;
- }
- case IMSG_PARENT_FORWARD_OPEN: {
- int fd;
- struct forward_req *fwreq = imsg.data;
- struct lkasession key;
- struct lkasession *lkasession;
- struct path *path;
-
- IMSG_SIZE_CHECK(fwreq);
-
- key.id = fwreq->id;
- lkasession = SPLAY_FIND(lkatree, &env->lka_sessions, &key);
- if (lkasession == NULL)
- fatal("lka_dispatch_parent: lka session is gone");
- fd = imsg.fd;
- --lkasession->pending;
-
- strlcpy(lkasession->path.pw_name, fwreq->pw_name,
- sizeof(lkasession->path.pw_name));
- lkasession->path.flags |= F_PATH_FORWARDED;
-
- /* received a descriptor, we have a forward file ... */
- if (fd != -1) {
- if (! forwards_get(fd, &lkasession->expandtree)) {
- lkasession->ss.code = 530;
- lkasession->flags |= F_ERROR;
- }
- close(fd);
- lkasession->path.flags |= F_PATH_FORWARDED;
- lka_expand_pickup(env, lkasession);
- break;
- }
-
- /* did not receive a descriptor but expected one ... */
- if (! fwreq->status) {
- lkasession->ss.code = 530;
- lkasession->flags |= F_ERROR;
- lka_expand_pickup(env, lkasession);
- break;
- }
-
- /* no forward file, convert pw_name to a struct path ... */
- path = path_dup(&lkasession->path);
- strlcpy(path->pw_name, fwreq->pw_name, sizeof(path->pw_name));
- TAILQ_INSERT_TAIL(&lkasession->deliverylist, path, entry);
- lka_expand_pickup(env, lkasession);
- break;
- }
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("lka_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-lka_dispatch_mfa(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MFA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_mfa: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_LKA_MAIL: {
- struct submit_status *ss = imsg.data;
-
- IMSG_SIZE_CHECK(ss);
-
- ss->code = 530;
-
- if (ss->u.path.user[0] == '\0' && ss->u.path.domain[0] == '\0')
- ss->code = 250;
- else
- if (lka_verify_mail(env, &ss->u.path))
- ss->code = 250;
-
- imsg_compose_event(iev, IMSG_LKA_MAIL, 0, 0, -1,
- ss, sizeof(*ss));
- break;
- }
- case IMSG_LKA_RULEMATCH: {
- struct submit_status *ss = imsg.data;
- struct rule *r;
-
- IMSG_SIZE_CHECK(ss);
-
- ss->code = 530;
-
- r = ruleset_match(env, ss->msg.tag, &ss->u.path, &ss->ss);
- if (r != NULL) {
- ss->code = 250;
- ss->u.path.rule = *r;
+ case IMSG_PARENT_FORWARD_OPEN:
+ fwreq = imsg->data;
+ skey.id = fwreq->id;
+ s = SPLAY_FIND(lkatree, &env->lka_sessions, &skey);
+ if (s == NULL)
+ fatalx("lka: session missing");
+ s->pending--;
+ strlcpy(s->path.pw_name, fwreq->pw_name,
+ sizeof s->path.pw_name);
+ s->path.flags |= F_PATH_FORWARDED;
+
+ if (imsg->fd != -1) {
+ /* opened .forward okay */
+ if (! forwards_get(imsg->fd, &s->expandtree)) {
+ s->ss.code = 530;
+ s->flags |= F_ERROR;
+ }
+ close(imsg->fd);
+ s->path.flags |= F_PATH_FORWARDED;
+ lka_expand_pickup(env, s);
+ } else {
+ if (fwreq->status) {
+ /* .forward not present */
+ path = path_dup(&s->path);
+ strlcpy(path->pw_name, fwreq->pw_name,
+ sizeof path->pw_name);
+ TAILQ_INSERT_TAIL(&s->deliverylist, path, entry);
+ lka_expand_pickup(env, s);
+ } else {
+ /* opening .forward failed */
+ s->ss.code = 530;
+ s->flags |= F_ERROR;
+ lka_expand_pickup(env, s);
+ }
}
-
- imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_LKA_RULEMATCH, 0, 0, -1,
- ss, sizeof(*ss));
-
- break;
- }
- case IMSG_LKA_RCPT: {
- struct submit_status *ss = imsg.data;
- struct lkasession *lkasession;
- struct path *path;
-
- IMSG_SIZE_CHECK(ss);
-
- ss->code = 250;
- path = &ss->u.path;
-
- lkasession = lka_session_init(env, ss);
-
- if (! lka_resolve_path(env, lkasession, path))
- lka_session_fail(env, lkasession, ss);
- else
- lka_expand_pickup(env, lkasession);
-
- break;
- }
- default:
- log_warnx("lka_dispatch_mfa: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_mfa: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-lka_dispatch_mta(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MTA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
- }
- }
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_mta: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_LKA_SECRET: {
- struct secret *query = imsg.data;
- char *secret = NULL;
- struct map *map = NULL;
- char *mapname = "secrets";
-
- IMSG_SIZE_CHECK(query);
-
- /* should not happen */
- map = map_findbyname(env, mapname);
- if (map == NULL)
- fatalx("secrets map has disappeared");
- secret = map_lookup(env, map->m_id, query->host);
-
- log_debug("secret for %s %s", query->host,
- secret ? "found" : "not found");
-
- query->secret[0] = '\0';
-
- if (secret == NULL) {
- log_warnx("failed to lookup %s in the %s map",
- query->host, mapname);
- } else if (! lka_encode_credentials(query->secret,
- sizeof(query->secret), secret)) {
- log_warnx("parse error for %s in the %s map",
- query->host, mapname);
- }
-
- imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, query,
- sizeof(*query));
- free(secret);
- break;
- }
-
- case IMSG_DNS_MX:
- case IMSG_DNS_PTR: {
- struct dns *query = imsg.data;
-
- IMSG_SIZE_CHECK(query);
- dns_async(env, iev, imsg.hdr.type, query);
- break;
- }
-
- default:
- log_warnx("lka_dispatch_mta: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_mta: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-lka_dispatch_smtp(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_DNS_PTR: {
- struct dns *query = imsg.data;
-
- IMSG_SIZE_CHECK(query);
- dns_async(env, iev, IMSG_DNS_PTR, query);
- break;
- }
- default:
- log_warnx("lka_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_smtp: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
+ fatalx("lka_imsg: unexpected imsg");
}
void
-lka_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("lka_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-lka_dispatch_runner(int sig, short event, void *p)
+lka_sig_handler(int sig, short event, void *p)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("lka_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
+ int status;
+ pid_t pid;
- switch (imsg.hdr.type) {
- default:
- log_warnx("lka_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("lka_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ lka_shutdown();
+ break;
+ case SIGCHLD:
+ do {
+ pid = waitpid(-1, &status, WNOHANG);
+ } while (pid > 0 || (pid == -1 && errno == EINTR));
+ break;
+ default:
+ fatalx("lka_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
void
@@ -636,12 +311,12 @@ lka(struct smtpd *env)
struct event ev_sigchld;
struct peer peers[] = {
- { PROC_PARENT, lka_dispatch_parent },
- { PROC_MFA, lka_dispatch_mfa },
- { PROC_QUEUE, lka_dispatch_queue },
- { PROC_SMTP, lka_dispatch_smtp },
- { PROC_RUNNER, lka_dispatch_runner },
- { PROC_MTA, lka_dispatch_mta }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_MFA, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch },
+ { PROC_MTA, imsg_dispatch }
};
switch (pid = fork()) {
@@ -667,6 +342,7 @@ lka(struct smtpd *env)
fatal("lka: cannot drop privileges");
#endif
+ imsg_callback = lka_imsg;
event_init();
SPLAY_INIT(&env->lka_sessions);
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c
index 750f80b8c97..a9b52bdb8bb 100644
--- a/usr.sbin/smtpd/mda.c
+++ b/usr.sbin/smtpd/mda.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mda.c,v 1.39 2010/04/19 20:10:36 jacekm Exp $ */
+/* $OpenBSD: mda.c,v 1.40 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -37,11 +37,9 @@
#include "smtpd.h"
+void mda_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void mda_shutdown(void);
void mda_sig_handler(int, short, void *);
-void mda_dispatch_parent(int, short, void *);
-void mda_dispatch_queue(int, short, void *);
-void mda_dispatch_runner(int, short, void *);
void mda_setup_events(struct smtpd *);
void mda_disable_events(struct smtpd *);
void mda_store(struct mda_session *);
@@ -51,88 +49,106 @@ struct mda_session *mda_lookup(struct smtpd *, u_int32_t);
int mda_id;
void
-mda_sig_handler(int sig, short event, void *p)
+mda_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- mda_shutdown();
- break;
- default:
- fatalx("mda_sig_handler: unexpected signal");
- }
-}
+ char output[128], *error, *parent_error;
+ struct deliver deliver;
+ struct mda_session *s;
+ struct path *path;
+
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
+ case IMSG_MDA_SESS_NEW:
+ /* make new session based on provided args */
+ s = calloc(1, sizeof *s);
+ if (s == NULL)
+ fatal(NULL);
+ msgbuf_init(&s->w);
+ s->msg = *(struct message *)imsg->data;
+ s->msg.status = S_MESSAGE_TEMPFAILURE;
+ s->id = mda_id++;
+ s->datafp = fdopen(imsg->fd, "r");
+ if (s->datafp == NULL)
+ fatalx("mda: fdopen");
+ LIST_INSERT_HEAD(&env->mda_sessions, s, entry);
-void
-mda_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
+ /* request parent to fork a helper process */
+ path = &s->msg.recipient;
+ switch (path->rule.r_action) {
+ case A_EXT:
+ deliver.mode = A_EXT;
+ strlcpy(deliver.user, path->pw_name,
+ sizeof deliver.user);
+ strlcpy(deliver.to, path->rule.r_value.path,
+ sizeof deliver.to);
+ break;
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
+ case A_MBOX:
+ deliver.mode = A_EXT;
+ strlcpy(deliver.user, "root",
+ sizeof deliver.user);
+ snprintf(deliver.to, sizeof deliver.to,
+ "%s -f %s@%s %s", PATH_MAILLOCAL,
+ s->msg.sender.user, s->msg.sender.domain,
+ path->pw_name);
+ break;
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mda_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
+ case A_MAILDIR:
+ deliver.mode = A_MAILDIR;
+ strlcpy(deliver.user, path->pw_name,
+ sizeof deliver.user);
+ strlcpy(deliver.to, path->rule.r_value.path,
+ sizeof deliver.to);
+ break;
- switch (imsg.hdr.type) {
- case IMSG_PARENT_FORK_MDA: {
- struct mda_session *s;
+ case A_FILENAME:
+ deliver.mode = A_FILENAME;
+ /* XXX: unconditional SMTPD_USER is wrong. */
+ strlcpy(deliver.user, SMTPD_USER,
+ sizeof deliver.user);
+ strlcpy(deliver.to, path->u.filename,
+ sizeof deliver.to);
+ break;
- s = mda_lookup(env, imsg.hdr.peerid);
+ default:
+ fatalx("mda: unknown rule action");
+ }
- if (imsg.fd < 0)
+ imsg_compose_event(env->sc_ievs[PROC_PARENT],
+ IMSG_PARENT_FORK_MDA, s->id, 0, -1, &deliver,
+ sizeof deliver);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_FORK_MDA:
+ s = mda_lookup(env, imsg->hdr.peerid);
+
+ if (imsg->fd < 0)
fatalx("mda: fd pass fail");
- s->w.fd = imsg.fd;
+ s->w.fd = imsg->fd;
- /* send message content to the helper process */
mda_store(s);
- break;
- }
-
- case IMSG_MDA_DONE: {
- char output[128];
- struct mda_session *s;
- struct path *path;
- char *error, *parent_error;
+ return;
- s = mda_lookup(env, imsg.hdr.peerid);
+ case IMSG_MDA_DONE:
+ s = mda_lookup(env, imsg->hdr.peerid);
/*
* Grab last line of mda stdout/stderr if available.
*/
output[0] = '\0';
- if (imsg.fd != -1) {
+ if (imsg->fd != -1) {
char *ln, *buf;
FILE *fp;
size_t len;
buf = NULL;
- if (lseek(imsg.fd, 0, SEEK_SET) < 0)
+ if (lseek(imsg->fd, 0, SEEK_SET) < 0)
fatalx("lseek");
- fp = fdopen(imsg.fd, "r");
+ fp = fdopen(imsg->fd, "r");
if (fp == NULL)
fatal("mda: fdopen");
while ((ln = fgetln(fp, &len))) {
@@ -163,7 +179,7 @@ mda_dispatch_parent(int sig, short event, void *p)
* the former.
*/
error = NULL;
- parent_error = imsg.data;
+ parent_error = imsg->data;
if (strcmp(parent_error, "exited okay") == 0) {
if (!feof(s->datafp) || s->w.queued)
error = "mda exited prematurely";
@@ -218,185 +234,30 @@ mda_dispatch_parent(int sig, short event, void *p)
/* update runner's session count */
imsg_compose_event(env->sc_ievs[PROC_RUNNER],
IMSG_MDA_SESS_NEW, 0, 0, -1, NULL, 0);
- break;
- }
-
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
-
- default:
- log_warnx("mda_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("mda_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
+ return;
-void
-mda_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mda_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("mda_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("mda_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
+ fatalx("mda_imsg: unexpected imsg");
}
void
-mda_dispatch_runner(int sig, short event, void *p)
+mda_sig_handler(int sig, short event, void *p)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mda_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_MDA_SESS_NEW: {
- struct deliver deliver;
- struct mda_session *s;
- struct path *path;
-
- /* make new session based on provided args */
- s = calloc(1, sizeof *s);
- if (s == NULL)
- fatal(NULL);
- msgbuf_init(&s->w);
- s->msg = *(struct message *)imsg.data;
- s->msg.status = S_MESSAGE_TEMPFAILURE;
- s->id = mda_id++;
- s->datafp = fdopen(imsg.fd, "r");
- if (s->datafp == NULL)
- fatalx("mda: fdopen");
- LIST_INSERT_HEAD(&env->mda_sessions, s, entry);
-
- /* request parent to fork a helper process */
- path = &s->msg.recipient;
- switch (path->rule.r_action) {
- case A_EXT:
- deliver.mode = A_EXT;
- strlcpy(deliver.user, path->pw_name,
- sizeof deliver.user);
- strlcpy(deliver.to, path->rule.r_value.path,
- sizeof deliver.to);
- break;
-
- case A_MBOX:
- deliver.mode = A_EXT;
- strlcpy(deliver.user, "root",
- sizeof deliver.user);
- snprintf(deliver.to, sizeof deliver.to,
- "%s -f %s@%s %s", PATH_MAILLOCAL,
- s->msg.sender.user, s->msg.sender.domain,
- path->pw_name);
- break;
-
- case A_MAILDIR:
- deliver.mode = A_MAILDIR;
- strlcpy(deliver.user, path->pw_name,
- sizeof deliver.user);
- strlcpy(deliver.to, path->rule.r_value.path,
- sizeof deliver.to);
- break;
-
- case A_FILENAME:
- deliver.mode = A_FILENAME;
- /* XXX: unconditional SMTPD_USER is wrong. */
- strlcpy(deliver.user, SMTPD_USER,
- sizeof deliver.user);
- strlcpy(deliver.to, path->u.filename,
- sizeof deliver.to);
- break;
-
- default:
- fatalx("unknown rule action");
- }
-
- imsg_compose_event(env->sc_ievs[PROC_PARENT],
- IMSG_PARENT_FORK_MDA, s->id, 0, -1, &deliver,
- sizeof deliver);
- break;
- }
- default:
- log_warnx("mda_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("mda_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ mda_shutdown();
+ break;
+ default:
+ fatalx("mda_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
-
void
mda_shutdown(void)
{
@@ -424,9 +285,9 @@ mda(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, mda_dispatch_parent },
- { PROC_QUEUE, mda_dispatch_queue },
- { PROC_RUNNER, mda_dispatch_runner }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch }
};
switch (pid = fork()) {
@@ -463,6 +324,7 @@ mda(struct smtpd *env)
LIST_INIT(&env->mda_sessions);
+ imsg_callback = mda_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, mda_sig_handler, env);
diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c
index c9001efe249..67be9daed7a 100644
--- a/usr.sbin/smtpd/mfa.c
+++ b/usr.sbin/smtpd/mfa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfa.c,v 1.43 2010/01/03 14:37:37 chl Exp $ */
+/* $OpenBSD: mfa.c,v 1.44 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -34,12 +34,9 @@
#include "smtpd.h"
+void mfa_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void mfa_shutdown(void);
void mfa_sig_handler(int, short, void *);
-void mfa_dispatch_parent(int, short, void *);
-void mfa_dispatch_smtp(int, short, void *);
-void mfa_dispatch_lka(int, short, void *);
-void mfa_dispatch_control(int, short, void *);
void mfa_setup_events(struct smtpd *);
void mfa_disable_events(struct smtpd *);
@@ -52,249 +49,57 @@ int strip_source_route(char *, size_t);
struct rule *ruleset_match(struct smtpd *, struct path *, struct sockaddr_storage *);
void
-mfa_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- mfa_shutdown();
- break;
- default:
- fatalx("mfa_sig_handler: unexpected signal");
- }
-}
-
-void
-mfa_dispatch_parent(int sig, short event, void *p)
+mfa_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_SMTP) {
+ switch (imsg->hdr.type) {
+ case IMSG_MFA_MAIL:
+ mfa_test_mail(env, imsg->data);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mfa_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
- switch (imsg.hdr.type) {
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("mfa_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("mfa_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-mfa_dispatch_smtp(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_MFA_RCPT:
+ mfa_test_rcpt(env, imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mfa_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_MFA_MAIL: {
- struct message *m = imsg.data;
-
- IMSG_SIZE_CHECK(m);
-
- mfa_test_mail(env, m);
- break;
- }
-
- case IMSG_MFA_RCPT: {
- struct message *m = imsg.data;
-
- IMSG_SIZE_CHECK(m);
-
- mfa_test_rcpt(env, m);
- break;
- }
+ if (iev->proc == PROC_LKA) {
+ switch (imsg->hdr.type) {
+ case IMSG_LKA_MAIL:
+ case IMSG_LKA_RCPT:
+ imsg_compose_event(env->sc_ievs[PROC_SMTP],
+ IMSG_MFA_MAIL, 0, 0, -1, imsg->data,
+ sizeof(struct submit_status));
+ return;
- default:
- log_warnx("mfa_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("mfa_dispatch_smtp: unexpected imsg");
+ case IMSG_LKA_RULEMATCH:
+ mfa_test_rcpt_resume(env, imsg->data);
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
-}
-void
-mfa_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mfa_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_LKA_MAIL: {
- struct submit_status *ss = imsg.data;
-
- IMSG_SIZE_CHECK(ss);
-
- imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_MAIL,
- 0, 0, -1, ss, sizeof(*ss));
- break;
- }
- case IMSG_LKA_RCPT: {
- struct submit_status *ss = imsg.data;
-
- IMSG_SIZE_CHECK(ss);
-
- imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_RCPT,
- 0, 0, -1, ss, sizeof(*ss));
- break;
- }
- case IMSG_LKA_RULEMATCH: {
- struct submit_status *ss = imsg.data;
-
- IMSG_SIZE_CHECK(ss);
-
- mfa_test_rcpt_resume(env, ss);
- break;
- }
- default:
- log_warnx("mfa_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("mfa_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
+ fatalx("mfa_imsg: unexpected imsg");
}
void
-mfa_dispatch_control(int sig, short event, void *p)
+mfa_sig_handler(int sig, short event, void *p)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mfa_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("mfa_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("mfa_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ mfa_shutdown();
+ break;
+ default:
+ fatalx("mfa_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
void
@@ -324,10 +129,10 @@ mfa(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, mfa_dispatch_parent },
- { PROC_SMTP, mfa_dispatch_smtp },
- { PROC_LKA, mfa_dispatch_lka },
- { PROC_CONTROL, mfa_dispatch_control},
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch }
};
switch (pid = fork()) {
@@ -362,6 +167,7 @@ mfa(struct smtpd *env)
fatal("mfa: cannot drop privileges");
#endif
+ imsg_callback = mfa_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, mfa_sig_handler, env);
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index f1c10568ff3..9e79befd184 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.84 2010/01/03 14:37:37 chl Exp $ */
+/* $OpenBSD: mta.c,v 1.85 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -41,14 +41,11 @@
#include "smtpd.h"
#include "client.h"
+void mta_imsg(struct smtpd *, struct imsgev *, struct imsg *);
+
__dead void mta_shutdown(void);
void mta_sig_handler(int, short, void *);
-void mta_dispatch_parent(int, short, void *);
-void mta_dispatch_runner(int, short, void *);
-void mta_dispatch_queue(int, short, void *);
-void mta_dispatch_lka(int, short, void *);
-
struct mta_session *mta_lookup(struct smtpd *, u_int64_t);
void mta_enter_state(struct mta_session *, int, void *);
void mta_pickup(struct mta_session *, void *);
@@ -62,151 +59,22 @@ void mta_connect_done(int, short, void *);
void mta_request_datafd(struct mta_session *);
void
-mta_sig_handler(int sig, short event, void *p)
+mta_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- mta_shutdown();
- break;
- default:
- fatalx("mta_sig_handler: unexpected signal");
- }
-}
-
-void
-mta_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mta_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_CONF_START:
- if (env->sc_flags & SMTPD_CONFIGURING)
- break;
- env->sc_flags |= SMTPD_CONFIGURING;
-
- if ((env->sc_ssl = calloc(1, sizeof(*env->sc_ssl))) == NULL)
- fatal("mta_dispatch_parent: calloc");
- break;
- case IMSG_CONF_SSL: {
- struct ssl *s;
- struct ssl *x_ssl;
-
- if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
- fatal(NULL);
- x_ssl = imsg.data;
- (void)strlcpy(s->ssl_name, x_ssl->ssl_name,
- sizeof(s->ssl_name));
- s->ssl_cert_len = x_ssl->ssl_cert_len;
- if ((s->ssl_cert =
- strdup((char *)imsg.data + sizeof(*s))) == NULL)
- fatal(NULL);
- s->ssl_key_len = x_ssl->ssl_key_len;
- if ((s->ssl_key = strdup((char *)imsg.data +
- (sizeof(*s) + s->ssl_cert_len))) == NULL)
- fatal(NULL);
-
- SPLAY_INSERT(ssltree, env->sc_ssl, s);
- break;
- }
- case IMSG_CONF_END:
- if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
- env->sc_flags &= ~SMTPD_CONFIGURING;
- break;
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("mta_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("mta_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-mta_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mta_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_BATCH_CREATE: {
- struct batch *b = imsg.data;
- struct mta_session *s;
-
- IMSG_SIZE_CHECK(b);
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
+ struct mta_session *s;
+ struct mta_relay *relay;
+ struct message *m;
+ struct secret *secret;
+ struct batch *b;
+ struct dns *dns;
+ struct ssl *ssl;
+
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
+ case IMSG_BATCH_CREATE:
+ b = imsg->data;
+ s = calloc(1, sizeof *s);
+ if (s == NULL)
fatal(NULL);
s->id = b->id;
s->state = MTA_INIT;
@@ -258,190 +126,128 @@ mta_dispatch_runner(int sig, short event, void *p)
TAILQ_INIT(&s->recipients);
TAILQ_INIT(&s->relays);
SPLAY_INSERT(mtatree, &env->mta_sessions, s);
- break;
- }
-
- case IMSG_BATCH_APPEND: {
- struct message *append = imsg.data, *m;
- struct mta_session *s;
-
- IMSG_SIZE_CHECK(append);
+ return;
- s = mta_lookup(env, append->batch_id);
- if ((m = malloc(sizeof(*m))) == NULL)
+ case IMSG_BATCH_APPEND:
+ m = imsg->data;
+ s = mta_lookup(env, m->batch_id);
+ m = malloc(sizeof *m);
+ if (m == NULL)
fatal(NULL);
- *m = *append;
+ *m = *(struct message *)imsg->data;
strlcpy(m->session_errorline, "000 init",
sizeof(m->session_errorline));
TAILQ_INSERT_TAIL(&s->recipients, m, entry);
- break;
- }
-
- case IMSG_BATCH_CLOSE: {
- struct batch *b = imsg.data;
+ return;
- IMSG_SIZE_CHECK(b);
+ case IMSG_BATCH_CLOSE:
+ b = imsg->data;
mta_pickup(mta_lookup(env, b->id), NULL);
- break;
- }
-
- default:
- log_warnx("mta_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("mta_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-mta_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mta_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_LKA_SECRET: {
- struct secret *reply = imsg.data;
-
- IMSG_SIZE_CHECK(reply);
-
- mta_pickup(mta_lookup(env, reply->id), reply->secret);
- break;
- }
-
- case IMSG_DNS_A: {
- struct dns *reply = imsg.data;
- struct mta_relay *relay;
- struct mta_session *s;
-
- IMSG_SIZE_CHECK(reply);
+ if (iev->proc == PROC_LKA) {
+ switch (imsg->hdr.type) {
+ case IMSG_LKA_SECRET:
+ secret = imsg->data;
+ mta_pickup(mta_lookup(env, secret->id), secret->secret);
+ return;
- s = mta_lookup(env, reply->id);
- if ((relay = calloc(1, sizeof(*relay))) == NULL)
+ case IMSG_DNS_A:
+ dns = imsg->data;
+ s = mta_lookup(env, dns->id);
+ relay = calloc(1, sizeof *relay);
+ if (relay == NULL)
fatal(NULL);
- relay->sa = reply->ss;
+ relay->sa = dns->ss;
TAILQ_INSERT_TAIL(&s->relays, relay, entry);
- break;
- }
-
- case IMSG_DNS_A_END: {
- struct dns *reply = imsg.data;
-
- IMSG_SIZE_CHECK(reply);
-
- mta_pickup(mta_lookup(env, reply->id), &reply->error);
- break;
- }
-
- case IMSG_DNS_PTR: {
- struct dns *reply = imsg.data;
- struct mta_session *s;
- struct mta_relay *r;
+ return;
- IMSG_SIZE_CHECK(reply);
+ case IMSG_DNS_A_END:
+ dns = imsg->data;
+ mta_pickup(mta_lookup(env, dns->id), &dns->error);
+ return;
- s = mta_lookup(env, reply->id);
- r = TAILQ_FIRST(&s->relays);
- if (reply->error)
- strlcpy(r->fqdn, "<unknown>", sizeof(r->fqdn));
+ case IMSG_DNS_PTR:
+ dns = imsg->data;
+ s = mta_lookup(env, dns->id);
+ relay = TAILQ_FIRST(&s->relays);
+ if (dns->error)
+ strlcpy(relay->fqdn, "<unknown>",
+ sizeof relay->fqdn);
else
- strlcpy(r->fqdn, reply->host, sizeof(r->fqdn));
+ strlcpy(relay->fqdn, dns->host,
+ sizeof relay->fqdn);
mta_pickup(s, NULL);
- break;
- }
-
- default:
- log_warnx("mta_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("mta_dispatch_lka: unexpected imsg");
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
-}
-void
-mta_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_QUEUE) {
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_MESSAGE_FD:
+ b = imsg->data;
+ mta_pickup(mta_lookup(env, b->id), &imsg->fd);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("mta_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CONF_START:
+ if (env->sc_flags & SMTPD_CONFIGURING)
+ return;
+ env->sc_flags |= SMTPD_CONFIGURING;
+ env->sc_ssl = calloc(1, sizeof *env->sc_ssl);
+ if (env->sc_ssl == NULL)
+ fatal(NULL);
+ return;
- switch (imsg.hdr.type) {
- case IMSG_QUEUE_MESSAGE_FD: {
- struct batch *b = imsg.data;
+ case IMSG_CONF_SSL:
+ if (!(env->sc_flags & SMTPD_CONFIGURING))
+ return;
+ ssl = calloc(1, sizeof *ssl);
+ if (ssl == NULL)
+ fatal(NULL);
+ *ssl = *(struct ssl *)imsg->data;
+ ssl->ssl_cert = strdup((char *)imsg->data +
+ sizeof *ssl);
+ if (ssl->ssl_cert == NULL)
+ fatal(NULL);
+ ssl->ssl_key = strdup((char *)imsg->data +
+ sizeof *ssl + ssl->ssl_cert_len);
+ if (ssl->ssl_key == NULL)
+ fatal(NULL);
+ SPLAY_INSERT(ssltree, env->sc_ssl, ssl);
+ return;
- IMSG_SIZE_CHECK(b);
+ case IMSG_CONF_END:
+ if (!(env->sc_flags & SMTPD_CONFIGURING))
+ return;
+ env->sc_flags &= ~SMTPD_CONFIGURING;
+ return;
- mta_pickup(mta_lookup(env, b->id), &imsg.fd);
- break;
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
+ return;
}
+ }
- default:
- log_warnx("mta_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("mta_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
+ fatalx("mta_imsg: unexpected imsg");
+}
+
+void
+mta_sig_handler(int sig, short event, void *p)
+{
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ mta_shutdown();
+ break;
+ default:
+ fatalx("mta_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
void
@@ -461,10 +267,10 @@ mta(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, mta_dispatch_parent },
- { PROC_QUEUE, mta_dispatch_queue },
- { PROC_RUNNER, mta_dispatch_runner },
- { PROC_LKA, mta_dispatch_lka }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch }
};
switch (pid = fork()) {
@@ -499,6 +305,7 @@ mta(struct smtpd *env)
fatal("mta: cannot drop privileges");
#endif
+ imsg_callback = mta_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, mta_sig_handler, env);
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index a0f4be9b27d..9225facffb1 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.77 2010/01/03 14:37:37 chl Exp $ */
+/* $OpenBSD: queue.c,v 1.78 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -37,15 +37,9 @@
#include "smtpd.h"
+void queue_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void queue_shutdown(void);
void queue_sig_handler(int, short, void *);
-void queue_dispatch_parent(int, short, void *);
-void queue_dispatch_control(int, short, void *);
-void queue_dispatch_smtp(int, short, void *);
-void queue_dispatch_mda(int, short, void *);
-void queue_dispatch_mta(int, short, void *);
-void queue_dispatch_lka(int, short, void *);
-void queue_dispatch_runner(int, short, void *);
void queue_setup_events(struct smtpd *);
void queue_disable_events(struct smtpd *);
void queue_purge(char *);
@@ -57,504 +51,157 @@ int queue_remove_layout_envelope(char *, struct message *);
int queue_commit_layout_message(char *, struct message *);
int queue_open_layout_messagefile(char *, struct message *);
-void queue_submit_envelope(struct smtpd *, struct message *);
-void queue_commit_envelopes(struct smtpd *, struct message*);
-
-void
-queue_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- queue_shutdown();
- break;
- default:
- fatalx("queue_sig_handler: unexpected signal");
- }
-}
-
-void
-queue_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("got imsg %d", imsg.hdr.type);
- fatalx("queue_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-queue_dispatch_control(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("queue_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("queue_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
void
-queue_dispatch_smtp(int sig, short event, void *p)
+queue_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
+ struct submit_status ss;
+ struct message *m;
+ struct batch *b;
+ int fd, ret, verbose;
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
+ if (iev->proc == PROC_SMTP) {
+ m = imsg->data;
- switch (imsg.hdr.type) {
- case IMSG_QUEUE_CREATE_MESSAGE: {
- struct message *messagep = imsg.data;
- struct submit_status ss;
- int (*f)(char *);
-
- log_debug("queue_dispatch_smtp: creating message file");
-
- IMSG_SIZE_CHECK(messagep);
-
- ss.id = messagep->session_id;
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_CREATE_MESSAGE:
+ ss.id = m->session_id;
ss.code = 250;
- bzero(ss.u.msgid, MAX_ID_SIZE);
-
- if (messagep->flags & F_MESSAGE_ENQUEUED)
- f = enqueue_create_layout;
+ bzero(ss.u.msgid, sizeof ss.u.msgid);
+ if (m->flags & F_MESSAGE_ENQUEUED)
+ ret = enqueue_create_layout(ss.u.msgid);
else
- f = queue_create_incoming_layout;
-
- if (! f(ss.u.msgid))
+ ret = queue_create_incoming_layout(ss.u.msgid);
+ if (ret == 0)
ss.code = 421;
-
imsg_compose_event(iev, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1,
- &ss, sizeof(ss));
- break;
- }
- case IMSG_QUEUE_REMOVE_MESSAGE: {
- struct message *messagep = imsg.data;
- void (*f)(char *);
-
- IMSG_SIZE_CHECK(messagep);
+ &ss, sizeof ss);
+ return;
- if (messagep->flags & F_MESSAGE_ENQUEUED)
- f = enqueue_delete_message;
+ case IMSG_QUEUE_REMOVE_MESSAGE:
+ if (m->flags & F_MESSAGE_ENQUEUED)
+ enqueue_delete_message(m->message_id);
else
- f = queue_delete_incoming_message;
-
- f(messagep->message_id);
-
- break;
- }
- case IMSG_QUEUE_COMMIT_MESSAGE: {
- struct message *messagep = imsg.data;
- struct submit_status ss;
- size_t *counter;
- int (*f)(struct message *);
-
- IMSG_SIZE_CHECK(messagep);
-
- ss.id = messagep->session_id;
+ queue_delete_incoming_message(m->message_id);
+ return;
- if (messagep->flags & F_MESSAGE_ENQUEUED) {
- f = enqueue_commit_message;
- counter = &env->stats->queue.inserts_local;
+ case IMSG_QUEUE_COMMIT_MESSAGE:
+ ss.id = m->session_id;
+ if (m->flags & F_MESSAGE_ENQUEUED) {
+ if (enqueue_commit_message(m))
+ env->stats->queue.inserts_local++;
+ else
+ ss.code = 421;
} else {
- f = queue_commit_incoming_message;
- counter = &env->stats->queue.inserts_remote;
+ if (queue_commit_incoming_message(m))
+ env->stats->queue.inserts_remote++;
+ else
+ ss.code = 421;
}
-
- if (f(messagep))
- (*counter)++;
- else
- ss.code = 421;
-
imsg_compose_event(iev, IMSG_QUEUE_COMMIT_MESSAGE, 0, 0, -1,
- &ss, sizeof(ss));
-
- break;
- }
- case IMSG_QUEUE_MESSAGE_FILE: {
- struct message *messagep = imsg.data;
- struct submit_status ss;
- int fd;
- int (*f)(struct message *);
-
- IMSG_SIZE_CHECK(messagep);
-
- ss.id = messagep->session_id;
+ &ss, sizeof ss);
+ return;
- if (messagep->flags & F_MESSAGE_ENQUEUED)
- f = enqueue_open_messagefile;
+ case IMSG_QUEUE_MESSAGE_FILE:
+ ss.id = m->session_id;
+ if (m->flags & F_MESSAGE_ENQUEUED)
+ fd = enqueue_open_messagefile(m);
else
- f = queue_open_incoming_message_file;
-
- fd = f(messagep);
+ fd = queue_open_incoming_message_file(m);
if (fd == -1)
ss.code = 421;
-
imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FILE, 0, 0, fd,
- &ss, sizeof(ss));
- break;
- }
- default:
- log_warnx("queue_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("queue_dispatch_smtp: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-queue_dispatch_mda(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MDA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_mda: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
-
- case IMSG_QUEUE_MESSAGE_UPDATE: {
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_UPDATE_ENVELOPE,
- 0, 0, -1, imsg.data, sizeof(struct message));
- break;
- }
-
- default:
- log_warnx("got imsg %d", imsg.hdr.type);
- fatalx("queue_dispatch_mda: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-queue_dispatch_mta(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MTA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_mta: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
-
- case IMSG_QUEUE_MESSAGE_FD: {
- struct batch *batchp = imsg.data;
- int fd;
-
- IMSG_SIZE_CHECK(batchp);
-
- fd = queue_open_message_file(batchp->message_id);
- imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FD, 0, 0, fd, batchp,
- sizeof(*batchp));
- break;
- }
-
- case IMSG_QUEUE_MESSAGE_UPDATE: {
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_UPDATE_ENVELOPE,
- 0, 0, -1, imsg.data, sizeof(struct message));
- break;
- }
-
- default:
- log_warnx("got imsg %d", imsg.hdr.type);
- fatalx("queue_dispatch_mda: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-queue_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ &ss, sizeof ss);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
+ if (iev->proc == PROC_LKA) {
+ m = imsg->data;
- switch (imsg.hdr.type) {
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_SUBMIT_ENVELOPE:
+ m->id = generate_uid();
+ ss.id = m->session_id;
- case IMSG_QUEUE_SUBMIT_ENVELOPE: {
- struct message *messagep = imsg.data;
- struct submit_status ss;
- int (*f)(struct message *);
-
- IMSG_SIZE_CHECK(messagep);
-
- messagep->id = generate_uid();
- ss.id = messagep->session_id;
-
- if (IS_MAILBOX(messagep->recipient) ||
- IS_EXT(messagep->recipient))
- messagep->type = T_MDA_MESSAGE;
+ if (IS_MAILBOX(m->recipient) || IS_EXT(m->recipient))
+ m->type = T_MDA_MESSAGE;
else
- messagep->type = T_MTA_MESSAGE;
+ m->type = T_MTA_MESSAGE;
/* Write to disk */
- if (messagep->flags & F_MESSAGE_ENQUEUED)
- f = enqueue_record_envelope;
+ if (m->flags & F_MESSAGE_ENQUEUED)
+ ret = enqueue_record_envelope(m);
else
- f = queue_record_incoming_envelope;
+ ret = queue_record_incoming_envelope(m);
- if (! f(messagep)) {
+ if (ret == 0) {
ss.code = 421;
imsg_compose_event(env->sc_ievs[PROC_SMTP],
IMSG_QUEUE_TEMPFAIL, 0, 0, -1, &ss,
- sizeof(ss));
+ sizeof ss);
}
+ return;
- break;
- }
-
- case IMSG_QUEUE_COMMIT_ENVELOPES: {
- struct message *messagep = imsg.data;
- struct submit_status ss;
-
- IMSG_SIZE_CHECK(messagep);
-
- ss.id = messagep->session_id;
+ case IMSG_QUEUE_COMMIT_ENVELOPES:
+ ss.id = m->session_id;
ss.code = 250;
-
- imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_QUEUE_COMMIT_ENVELOPES,
- 0, 0, -1, &ss, sizeof(ss));
-
- break;
+ imsg_compose_event(env->sc_ievs[PROC_SMTP],
+ IMSG_QUEUE_COMMIT_ENVELOPES, 0, 0, -1, &ss,
+ sizeof ss);
+ return;
}
+ }
+
+ if (iev->proc == PROC_MTA) {
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_MESSAGE_FD:
+ b = imsg->data;
+ fd = queue_open_message_file(b->message_id);
+ imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FD, 0, 0,
+ fd, b, sizeof *b);
+ return;
- default:
- log_warnx("got imsg %d", imsg.hdr.type);
- fatalx("queue_dispatch_lka: unexpected imsg");
+ case IMSG_QUEUE_MESSAGE_UPDATE:
+ imsg_compose_event(env->sc_ievs[PROC_RUNNER],
+ IMSG_RUNNER_UPDATE_ENVELOPE, 0, 0, -1, imsg->data,
+ sizeof(struct message));
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
-}
-void
-queue_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_MDA) {
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_MESSAGE_UPDATE:
+ imsg_compose_event(env->sc_ievs[PROC_RUNNER],
+ IMSG_RUNNER_UPDATE_ENVELOPE, 0, 0, -1, imsg->data,
+ sizeof(struct message));
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_VERBOSE:
+ memcpy(&verbose, imsg->data, sizeof verbose);
+ log_verbose(verbose);
+ return;
+ }
}
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("queue_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
+ fatalx("queue_imsg: unexpected imsg");
+}
- switch (imsg.hdr.type) {
- default:
- log_warnx("got imsg %d", imsg.hdr.type);
- fatalx("queue_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
+void
+queue_sig_handler(int sig, short event, void *p)
+{
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ queue_shutdown();
+ break;
+ default:
+ fatalx("queue_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
void
@@ -584,13 +231,13 @@ queue(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, queue_dispatch_parent },
- { PROC_CONTROL, queue_dispatch_control },
- { PROC_SMTP, queue_dispatch_smtp },
- { PROC_MDA, queue_dispatch_mda },
- { PROC_MTA, queue_dispatch_mta },
- { PROC_LKA, queue_dispatch_lka },
- { PROC_RUNNER, queue_dispatch_runner }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_MDA, imsg_dispatch },
+ { PROC_MTA, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch }
};
switch (pid = fork()) {
@@ -625,6 +272,7 @@ queue(struct smtpd *env)
fatal("queue: cannot drop privileges");
#endif
+ imsg_callback = queue_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, queue_sig_handler, env);
diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c
index acbf095a648..f35068a0661 100644
--- a/usr.sbin/smtpd/runner.c
+++ b/usr.sbin/smtpd/runner.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: runner.c,v 1.79 2010/04/19 08:14:07 jacekm Exp $ */
+/* $OpenBSD: runner.c,v 1.80 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -47,15 +47,10 @@
#include "smtpd.h"
+void runner_imsg(struct smtpd *, struct imsgev *, struct imsg *);
+
__dead void runner_shutdown(void);
void runner_sig_handler(int, short, void *);
-void runner_dispatch_parent(int, short, void *);
-void runner_dispatch_control(int, short, void *);
-void runner_dispatch_queue(int, short, void *);
-void runner_dispatch_mda(int, short, void *);
-void runner_dispatch_mta(int, short, void *);
-void runner_dispatch_lka(int, short, void *);
-void runner_dispatch_smtp(int, short, void *);
void runner_setup_events(struct smtpd *);
void runner_disable_events(struct smtpd *);
@@ -85,412 +80,117 @@ int runner_force_envelope_remove(char *);
int runner_force_message_remove(char *);
void
-runner_sig_handler(int sig, short event, void *p)
+runner_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- runner_shutdown();
- break;
- default:
- fatalx("runner_sig_handler: unexpected signal");
- }
-}
+ struct message *m;
+ struct remove *rem;
+ struct sched *sched;
-void
-runner_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_QUEUE) {
+ switch (imsg->hdr.type) {
+ case IMSG_RUNNER_UPDATE_ENVELOPE:
+ env->stats->runner.active--;
+ queue_message_update(imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_PARENT_ENQUEUE_OFFLINE:
- runner_process_offline(env);
- break;
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("runner_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_parent: unexpected imsg");
+ if (iev->proc == PROC_MDA) {
+ switch (imsg->hdr.type) {
+ case IMSG_MDA_SESS_NEW:
+ env->stats->mda.sessions_active--;
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
-}
-void
-runner_dispatch_control(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_MTA) {
+ switch (imsg->hdr.type) {
+ case IMSG_BATCH_DONE:
+ env->stats->mta.sessions_active--;
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
+ if (iev->proc == PROC_SMTP) {
+ switch (imsg->hdr.type) {
+ case IMSG_SMTP_ENQUEUE:
+ m = imsg->data;
+ if (imsg->fd < 0 || !bounce_session(env, imsg->fd, m)) {
+ m->status = S_MESSAGE_TEMPFAILURE;
+ queue_message_update(m);
+ }
+ return;
+ }
}
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_CONTROL) {
+ switch (imsg->hdr.type) {
case IMSG_MDA_PAUSE:
env->sc_opts |= SMTPD_MDA_PAUSED;
- break;
+ return;
+
case IMSG_MTA_PAUSE:
env->sc_opts |= SMTPD_MTA_PAUSED;
- break;
+ return;
+
case IMSG_MDA_RESUME:
env->sc_opts &= ~SMTPD_MDA_PAUSED;
- break;
+ return;
+
case IMSG_MTA_RESUME:
env->sc_opts &= ~SMTPD_MTA_PAUSED;
- break;
- case IMSG_RUNNER_SCHEDULE: {
- struct sched *s = imsg.data;
-
- IMSG_SIZE_CHECK(s);
-
- s->ret = 0;
- if (valid_message_uid(s->mid))
- s->ret = runner_force_envelope_schedule(s->mid);
- else if (valid_message_id(s->mid))
- s->ret = runner_force_message_schedule(s->mid);
-
- imsg_compose_event(iev, IMSG_RUNNER_SCHEDULE, 0, 0, -1, s, sizeof(*s));
- break;
- }
- case IMSG_RUNNER_REMOVE: {
- struct remove *s = imsg.data;
-
- IMSG_SIZE_CHECK(s);
-
- s->ret = 0;
- if (valid_message_uid(s->mid))
- s->ret = runner_force_envelope_remove(s->mid);
- else if (valid_message_id(s->mid))
- s->ret = runner_force_message_remove(s->mid);
-
- imsg_compose_event(iev, IMSG_RUNNER_REMOVE, 0, 0, -1, s, sizeof(*s));
- break;
- }
- default:
- log_warnx("runner_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-runner_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_RUNNER_UPDATE_ENVELOPE: {
- struct message *m = imsg.data;
-
- IMSG_SIZE_CHECK(m);
-
- env->stats->runner.active--;
- queue_message_update(m);
- break;
- }
- default:
- log_warnx("runner_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-runner_dispatch_mda(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MDA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_RUNNER_SCHEDULE:
+ sched = imsg->data;
+ sched->ret = 0;
+ if (valid_message_uid(sched->mid))
+ sched->ret = runner_force_envelope_schedule(sched->mid);
+ else if (valid_message_id(sched->mid))
+ sched->ret = runner_force_message_schedule(sched->mid);
+ imsg_compose_event(iev, IMSG_RUNNER_SCHEDULE, 0, 0, -1,
+ sched, sizeof *sched);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_mda: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_MDA_SESS_NEW:
- env->stats->mda.sessions_active--;
- break;
- default:
- log_warnx("runner_dispatch_mda: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_mda: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-runner_dispatch_mta(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MTA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_RUNNER_REMOVE:
+ rem = imsg->data;
+ rem->ret = 0;
+ if (valid_message_uid(rem->mid))
+ rem->ret = runner_force_envelope_remove(rem->mid);
+ else if (valid_message_id(rem->mid))
+ rem->ret = runner_force_message_remove(rem->mid);
+ imsg_compose_event(iev, IMSG_RUNNER_REMOVE, 0, 0, -1,
+ rem, sizeof *rem);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_mta: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_BATCH_DONE:
- env->stats->mta.sessions_active--;
- break;
-
- default:
- log_warnx("runner_dispatch_mta: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_mta: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_ENQUEUE_OFFLINE:
+ runner_process_offline(env);
+ return;
-void
-runner_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("runner_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
+ fatalx("runner_imsg: unexpected imsg");
}
void
-runner_dispatch_smtp(int sig, short event, void *p)
+runner_sig_handler(int sig, short event, void *p)
{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("runner_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_SMTP_ENQUEUE: {
- struct message *m = imsg.data;
-
- IMSG_SIZE_CHECK(m);
-
- if (imsg.fd < 0 || ! bounce_session(env, imsg.fd, m)) {
- m->status = S_MESSAGE_TEMPFAILURE;
- queue_message_update(m);
- }
- break;
- }
-
- default:
- log_warnx("runner_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("runner_dispatch_smtp: unexpected imsg");
- }
- imsg_free(&imsg);
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ runner_shutdown();
+ break;
+ default:
+ fatalx("runner_sig_handler: unexpected signal");
}
- imsg_event_add(iev);
}
void
@@ -527,13 +227,13 @@ runner(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, runner_dispatch_parent },
- { PROC_CONTROL, runner_dispatch_control },
- { PROC_MDA, runner_dispatch_mda },
- { PROC_MTA, runner_dispatch_mta },
- { PROC_QUEUE, runner_dispatch_queue },
- { PROC_LKA, runner_dispatch_lka },
- { PROC_SMTP, runner_dispatch_smtp }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_MDA, imsg_dispatch },
+ { PROC_MTA, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch }
};
switch (pid = fork()) {
@@ -570,6 +270,7 @@ runner(struct smtpd *env)
SPLAY_INIT(&env->batch_queue);
+ imsg_callback = runner_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, runner_sig_handler, env);
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index 9d779887f53..cd137f710a0 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.67 2010/01/03 14:37:37 chl Exp $ */
+/* $OpenBSD: smtp.c,v 1.68 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -38,14 +38,9 @@
#include "smtpd.h"
+void smtp_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void smtp_shutdown(void);
void smtp_sig_handler(int, short, void *);
-void smtp_dispatch_parent(int, short, void *);
-void smtp_dispatch_mfa(int, short, void *);
-void smtp_dispatch_lka(int, short, void *);
-void smtp_dispatch_queue(int, short, void *);
-void smtp_dispatch_control(int, short, void *);
-void smtp_dispatch_runner(int, short, void *);
void smtp_setup_events(struct smtpd *);
void smtp_disable_events(struct smtpd *);
void smtp_pause(struct smtpd *);
@@ -55,58 +50,114 @@ struct session *smtp_new(struct listener *);
struct session *session_lookup(struct smtpd *, u_int64_t);
void
-smtp_sig_handler(int sig, short event, void *p)
+smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- smtp_shutdown();
- break;
- default:
- fatalx("smtp_sig_handler: unexpected signal");
+ struct session skey;
+ struct submit_status *ss;
+ struct listener *l;
+ struct session *s;
+ struct auth *auth;
+ struct ssl *ssl;
+ struct dns *dns;
+
+ if (iev->proc == PROC_LKA) {
+ switch (imsg->hdr.type) {
+ case IMSG_DNS_PTR:
+ dns = imsg->data;
+ s = session_lookup(env, dns->id);
+ if (s == NULL)
+ fatalx("smtp: impossible quit");
+ strlcpy(s->s_hostname,
+ dns->error ? "<unknown>" : dns->host,
+ sizeof s->s_hostname);
+ strlcpy(s->s_msg.session_hostname, s->s_hostname,
+ sizeof s->s_msg.session_hostname);
+ session_init(s->s_l, s);
+ return;
+ }
}
-}
-void
-smtp_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_MFA) {
+ switch (imsg->hdr.type) {
+ case IMSG_MFA_RCPT:
+ case IMSG_MFA_MAIL:
+ log_debug("smtp: got imsg_mfa_mail/rcpt");
+ ss = imsg->data;
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
+ if (iev->proc == PROC_QUEUE) {
+ ss = imsg->data;
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_CREATE_MESSAGE:
+ log_debug("smtp: imsg_queue_create_message returned");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ strlcpy(s->s_msg.message_id, ss->u.msgid,
+ sizeof s->s_msg.message_id);
+ session_pickup(s, ss);
+ return;
- switch (imsg.hdr.type) {
- case IMSG_CONF_RELOAD: {
- struct session *s;
+ case IMSG_QUEUE_MESSAGE_FILE:
+ log_debug("smtp: imsg_queue_message_file returned");
+ s = session_lookup(env, ss->id);
+ if (s == NULL) {
+ close(imsg->fd);
+ return;
+ }
+ s->datafp = fdopen(imsg->fd, "w");
+ if (s->datafp == NULL) {
+ /* queue may have experienced tempfail. */
+ if (ss->code != 421)
+ fatalx("smtp: fdopen");
+ close(imsg->fd);
+ }
+ session_pickup(s, ss);
+ return;
- /* reloading may invalidate various pointers our
+ case IMSG_QUEUE_TEMPFAIL:
+ log_debug("smtp: got imsg_queue_tempfail");
+ skey.s_id = ss->id;
+ s = SPLAY_FIND(sessiontree, &env->sc_sessions, &skey);
+ if (s == NULL)
+ fatalx("smtp: session is gone");
+ if (s->s_flags & F_WRITEONLY)
+ /* session is write-only, must not destroy it. */
+ s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ else
+ fatalx("smtp: corrupt session");
+ return;
+
+ case IMSG_QUEUE_COMMIT_ENVELOPES:
+ log_debug("smtp: got imsg_queue_commit_envelopes");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
+ return;
+
+ case IMSG_QUEUE_COMMIT_MESSAGE:
+ log_debug("smtp: got imsg_queue_commit_message");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CONF_RELOAD:
+ /*
+ * Reloading may invalidate various pointers our
* sessions rely upon, we better tell clients we
* want them to retry.
*/
@@ -118,474 +169,129 @@ smtp_dispatch_parent(int sig, short event, void *p)
smtp_disable_events(env);
imsg_compose_event(iev, IMSG_PARENT_SEND_CONFIG, 0, 0, -1,
NULL, 0);
- break;
- }
+ return;
+
case IMSG_CONF_START:
if (env->sc_flags & SMTPD_CONFIGURING)
- break;
+ return;
env->sc_flags |= SMTPD_CONFIGURING;
-
- if ((env->sc_listeners = calloc(1, sizeof(*env->sc_listeners))) == NULL)
- fatal("smtp_dispatch_parent: calloc");
- if ((env->sc_ssl = calloc(1, sizeof(*env->sc_ssl))) == NULL)
- fatal("smtp_dispatch_parent: calloc");
+ env->sc_listeners = calloc(1, sizeof *env->sc_listeners);
+ env->sc_ssl = calloc(1, sizeof *env->sc_ssl);
+ if (env->sc_listeners == NULL || env->sc_ssl == NULL)
+ fatal(NULL);
TAILQ_INIT(env->sc_listeners);
- break;
- case IMSG_CONF_SSL: {
- struct ssl *s;
- struct ssl *x_ssl;
+ return;
+ case IMSG_CONF_SSL:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
+ return;
+ ssl = calloc(1, sizeof *ssl);
+ if (ssl == NULL)
fatal(NULL);
- x_ssl = imsg.data;
- (void)strlcpy(s->ssl_name, x_ssl->ssl_name,
- sizeof(s->ssl_name));
- s->ssl_cert_len = x_ssl->ssl_cert_len;
- if ((s->ssl_cert =
- strdup((char *)imsg.data + sizeof(*s))) == NULL)
+ *ssl = *(struct ssl *)imsg->data;
+ ssl->ssl_cert = strdup((char *)imsg->data +
+ sizeof *ssl);
+ if (ssl->ssl_cert == NULL)
fatal(NULL);
- s->ssl_key_len = x_ssl->ssl_key_len;
- if ((s->ssl_key = strdup((char *)imsg.data +
- (sizeof(*s) + s->ssl_cert_len))) == NULL)
+ ssl->ssl_key = strdup((char *)imsg->data + sizeof *ssl +
+ ssl->ssl_cert_len);
+ if (ssl->ssl_key == NULL)
fatal(NULL);
+ SPLAY_INSERT(ssltree, env->sc_ssl, ssl);
+ return;
- SPLAY_INSERT(ssltree, env->sc_ssl, s);
- break;
- }
- case IMSG_CONF_LISTENER: {
- struct listener *l;
- struct ssl key;
-
+ case IMSG_CONF_LISTENER:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
-
- if ((l = calloc(1, sizeof(*l))) == NULL)
+ return;
+ l = calloc(1, sizeof *l);
+ if (l == NULL)
fatal(NULL);
- memcpy(l, imsg.data, sizeof(*l));
-
- if ((l->fd = imsg.fd) == -1)
- fatal("cannot get fd");
-
- (void)strlcpy(key.ssl_name, l->ssl_cert_name,
- sizeof(key.ssl_name));
-
- if (l->flags & F_SSL)
- if ((l->ssl = SPLAY_FIND(ssltree,
- env->sc_ssl, &key)) == NULL)
- fatal("parent and smtp desynchronized");
-
+ *l = *(struct listener *)imsg->data;
+ l->fd = imsg->fd;
+ if (l->fd < 0)
+ fatalx("smtp: listener pass failed");
+ if (l->flags & F_SSL) {
+ struct ssl key;
+
+ strlcpy(key.ssl_name, l->ssl_cert_name,
+ sizeof key.ssl_name);
+ l->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key);
+ if (l->ssl == NULL)
+ fatalx("smtp: ssltree out of sync");
+ }
TAILQ_INSERT_TAIL(env->sc_listeners, l, entry);
- break;
- }
+ return;
+
case IMSG_CONF_END:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
+ return;
smtp_setup_events(env);
env->sc_flags &= ~SMTPD_CONFIGURING;
- break;
- case IMSG_PARENT_AUTHENTICATE: {
- struct auth *reply = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_parent: got auth reply");
-
- IMSG_SIZE_CHECK(reply);
-
- if ((s = session_lookup(env, reply->id)) == NULL)
- break;
+ return;
- if (reply->success) {
+ case IMSG_PARENT_AUTHENTICATE:
+ auth = imsg->data;
+ s = session_lookup(env, auth->id);
+ if (s == NULL)
+ return;
+ if (auth->success) {
s->s_flags |= F_AUTHENTICATED;
s->s_msg.flags |= F_MESSAGE_AUTHENTICATED;
} else {
s->s_flags &= ~F_AUTHENTICATED;
s->s_msg.flags &= ~F_MESSAGE_AUTHENTICATED;
}
-
session_pickup(s, NULL);
- break;
- }
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("smtp_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_mfa(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MFA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_mfa: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_MFA_MAIL:
- case IMSG_MFA_RCPT: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_mfa: mfa handled return path");
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- session_pickup(s, ss);
- break;
- }
- default:
- log_warnx("smtp_dispatch_mfa: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_mfa: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_DNS_PTR: {
- struct dns *reply = imsg.data;
- struct session *s;
- struct session key;
-
- IMSG_SIZE_CHECK(reply);
-
- key.s_id = reply->id;
-
- s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key);
- if (s == NULL)
- fatal("smtp_dispatch_lka: session is gone");
-
- strlcpy(s->s_hostname,
- reply->error ? "<unknown>" : reply->host,
- sizeof(s->s_hostname));
-
- strlcpy(s->s_msg.session_hostname, s->s_hostname,
- sizeof(s->s_msg.session_hostname));
-
- session_init(s->s_l, s);
-
- break;
- }
- default:
- log_warnx("smtp_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_QUEUE_CREATE_MESSAGE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_queue: queue handled message creation");
-
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- (void)strlcpy(s->s_msg.message_id, ss->u.msgid,
- sizeof(s->s_msg.message_id));
- session_pickup(s, ss);
- break;
- }
- case IMSG_QUEUE_MESSAGE_FILE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
- int fd;
-
- log_debug("smtp_dispatch_queue: queue handled message creation");
-
- IMSG_SIZE_CHECK(ss);
-
- fd = imsg.fd;
-
- if ((s = session_lookup(env, ss->id)) == NULL) {
- close(fd);
- break;
- }
-
- if ((s->datafp = fdopen(fd, "w")) == NULL) {
- /* queue may have experienced tempfail. */
- if (ss->code != 421)
- fatal("smtp_dispatch_queue: fdopen");
- close(fd);
- }
-
- session_pickup(s, ss);
- break;
- }
- case IMSG_QUEUE_TEMPFAIL: {
- struct submit_status *ss = imsg.data;
- struct session *s;
- struct session key;
-
- log_debug("smtp_dispatch_queue: tempfail in queue");
-
- IMSG_SIZE_CHECK(ss);
-
- key.s_id = ss->id;
- s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key);
- if (s == NULL)
- fatalx("smtp_dispatch_queue: session is gone");
-
- if (s->s_flags & F_WRITEONLY) {
- /*
- * Session is write-only, can't destroy it.
- */
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
- } else
- fatalx("smtp_dispatch_queue: corrupt session");
- break;
- }
-
- case IMSG_QUEUE_COMMIT_ENVELOPES:
- case IMSG_QUEUE_COMMIT_MESSAGE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_queue: queue acknowledged message submission");
-
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- session_pickup(s, ss);
- break;
- }
- default:
- log_warnx("smtp_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_control(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_CONTROL) {
+ switch (imsg->hdr.type) {
case IMSG_SMTP_ENQUEUE:
imsg_compose_event(iev, IMSG_SMTP_ENQUEUE,
- imsg.hdr.peerid, 0, smtp_enqueue(env, imsg.data),
+ imsg->hdr.peerid, 0, smtp_enqueue(env, imsg->data),
NULL, 0);
- break;
+ return;
+
case IMSG_SMTP_PAUSE:
smtp_pause(env);
- break;
+ return;
+
case IMSG_SMTP_RESUME:
smtp_resume(env);
- break;
- default:
- log_warnx("smtp_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
case IMSG_SMTP_ENQUEUE:
imsg_compose_event(iev, IMSG_SMTP_ENQUEUE, 0, 0,
- smtp_enqueue(env, NULL), imsg.data,
+ smtp_enqueue(env, NULL), imsg->data,
sizeof(struct message));
- break;
- default:
- log_warnx("smtp_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_runner: unexpected imsg");
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
+
+ fatalx("smtp_imsg: unexpected imsg");
+}
+
+void
+smtp_sig_handler(int sig, short event, void *p)
+{
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ smtp_shutdown();
+ break;
+ default:
+ fatalx("smtp_sig_handler: unexpected signal");
+ }
}
void
@@ -605,12 +311,12 @@ smtp(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, smtp_dispatch_parent },
- { PROC_MFA, smtp_dispatch_mfa },
- { PROC_QUEUE, smtp_dispatch_queue },
- { PROC_LKA, smtp_dispatch_lka },
- { PROC_CONTROL, smtp_dispatch_control },
- { PROC_RUNNER, smtp_dispatch_runner }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_MFA, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch }
};
switch (pid = fork()) {
@@ -646,6 +352,7 @@ smtp(struct smtpd *env)
fatal("smtp: cannot drop privileges");
#endif
+ imsg_callback = smtp_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, smtp_sig_handler, env);
@@ -813,6 +520,7 @@ smtp_accept(int fd, short event, void *p)
fatal("smtp_accept");
}
+ s->s_flags |= F_WRITEONLY;
dns_query_ptr(l->env, &s->s_ss, s->s_id);
}
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 536b269cfa7..4e97facd3df 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.100 2010/04/20 01:01:43 jacekm Exp $ */
+/* $OpenBSD: smtpd.c,v 1.101 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -46,20 +46,13 @@
#include "smtpd.h"
+void parent_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void usage(void);
void parent_shutdown(struct smtpd *);
void parent_send_config(int, short, void *);
void parent_send_config_listeners(struct smtpd *);
void parent_send_config_client_certs(struct smtpd *);
void parent_send_config_ruleset(struct smtpd *, int);
-void parent_dispatch_lka(int, short, void *);
-void parent_dispatch_mda(int, short, void *);
-void parent_dispatch_mfa(int, short, void *);
-void parent_dispatch_mta(int, short, void *);
-void parent_dispatch_smtp(int, short, void *);
-void parent_dispatch_runner(int, short, void *);
-void parent_dispatch_queue(int, short, void *);
-void parent_dispatch_control(int, short, void *);
void parent_sig_handler(int, short, void *);
void forkmda(struct smtpd *, struct imsgev *, u_int32_t,
@@ -76,9 +69,121 @@ void child_del(struct smtpd *, pid_t);
struct child *child_lookup(struct smtpd *, pid_t);
extern char **environ;
+void (*imsg_callback)(struct smtpd *, struct imsgev *, struct imsg *);
int __b64_pton(char const *, unsigned char *, size_t);
+void
+parent_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
+{
+ struct smtpd newenv;
+ struct forward_req *fwreq;
+ struct reload *reload;
+ struct auth *auth;
+ int fd;
+
+ if (iev->proc == PROC_SMTP) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_SEND_CONFIG:
+ parent_send_config_listeners(env);
+ return;
+
+ case IMSG_PARENT_AUTHENTICATE:
+ auth = imsg->data;
+ auth->success = authenticate_user(auth->user,
+ auth->pass);
+ imsg_compose_event(iev, IMSG_PARENT_AUTHENTICATE, 0, 0,
+ -1, auth, sizeof *auth);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_LKA) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_FORWARD_OPEN:
+ fwreq = imsg->data;
+ fd = parent_forward_open(fwreq->pw_name);
+ fwreq->status = 0;
+ if (fd == -2) {
+ /* no ~/.forward, however it's optional. */
+ fwreq->status = 1;
+ fd = -1;
+ } else if (fd != -1)
+ fwreq->status = 1;
+ imsg_compose_event(iev, IMSG_PARENT_FORWARD_OPEN, 0, 0,
+ fd, fwreq, sizeof *fwreq);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_ENQUEUE_OFFLINE:
+ if (! parent_enqueue_offline(env, imsg->data))
+ imsg_compose_event(iev,
+ IMSG_PARENT_ENQUEUE_OFFLINE, 0, 0, -1,
+ NULL, 0);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_MDA) {
+ switch (imsg->hdr.type) {
+ case IMSG_PARENT_FORK_MDA:
+ forkmda(env, iev, imsg->hdr.peerid, imsg->data);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_CONTROL) {
+ switch (imsg->hdr.type) {
+ case IMSG_CONF_RELOAD:
+ reload->ret = 0;
+ if (parse_config(&newenv, env->sc_conffile, 0) == 0) {
+ strlcpy(env->sc_hostname, newenv.sc_hostname,
+ sizeof env->sc_hostname);
+ env->sc_listeners = newenv.sc_listeners;
+ env->sc_maps = newenv.sc_maps;
+ env->sc_rules = newenv.sc_rules;
+ env->sc_rules = newenv.sc_rules;
+ env->sc_ssl = newenv.sc_ssl;
+
+ parent_send_config_client_certs(env);
+ parent_send_config_ruleset(env, PROC_MFA);
+ parent_send_config_ruleset(env, PROC_LKA);
+ imsg_compose_event(env->sc_ievs[PROC_SMTP],
+ IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0);
+ reload->ret = 1;
+ }
+ imsg_compose_event(iev, IMSG_CONF_RELOAD, 0, 0, -1,
+ reload, sizeof *reload);
+ return;
+
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
+
+ /* forward to other processes */
+ imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_MDA], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CTL_VERBOSE,
+ 0, 0, -1, imsg->data, sizeof(int));
+ return;
+ }
+ }
+
+ fatalx("parent_imsg: unexpected imsg");
+}
+
__dead void
usage(void)
{
@@ -226,458 +331,6 @@ parent_send_config_ruleset(struct smtpd *env, int proc)
}
void
-parent_dispatch_lka(int imsgfd, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_PARENT_FORWARD_OPEN: {
- struct forward_req *fwreq = imsg.data;
- int fd;
-
- IMSG_SIZE_CHECK(fwreq);
-
- fd = parent_forward_open(fwreq->pw_name);
- fwreq->status = 0;
- if (fd == -2) {
- /* user has no ~/.forward. it is optional, so
- * set status to ok. */
- fwreq->status = 1;
- fd = -1;
- } else if (fd != -1)
- fwreq->status = 1;
- imsg_compose_event(iev, IMSG_PARENT_FORWARD_OPEN, 0, 0, fd, fwreq, sizeof(*fwreq));
- break;
- }
- default:
- log_warnx("parent_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_mfa(int fd, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MFA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_mfa: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("parent_dispatch_mfa: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_mfa: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_mta(int fd, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MTA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_mta: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("parent_dispatch_mta: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_mta: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_mda(int imsgfd, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MDA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_mda: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_PARENT_FORK_MDA:
- forkmda(env, iev, imsg.hdr.peerid, imsg.data);
- break;
-
- default:
- log_warnx("parent_dispatch_mda: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_mda: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_smtp(int fd, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_SMTP];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_smtp: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_PARENT_SEND_CONFIG: {
- parent_send_config_listeners(env);
- break;
- }
- case IMSG_PARENT_AUTHENTICATE: {
- struct auth *req = imsg.data;
-
- IMSG_SIZE_CHECK(req);
-
- req->success = authenticate_user(req->user, req->pass);
-
- imsg_compose_event(iev, IMSG_PARENT_AUTHENTICATE, 0, 0,
- -1, req, sizeof(*req));
- break;
- }
- default:
- log_warnx("parent_dispatch_smtp: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_smtp: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- default:
- log_warnx("parent_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_PARENT_ENQUEUE_OFFLINE:
- if (! parent_enqueue_offline(env, imsg.data))
- imsg_compose_event(iev, IMSG_PARENT_ENQUEUE_OFFLINE,
- 0, 0, -1, NULL, 0);
- break;
- default:
- log_warnx("parent_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_runner: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-parent_dispatch_control(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("parent_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_CONF_RELOAD: {
- struct reload *r = imsg.data;
- struct smtpd newenv;
-
- r->ret = 0;
- if (parse_config(&newenv, env->sc_conffile, 0) == 0) {
-
- (void)strlcpy(env->sc_hostname, newenv.sc_hostname,
- sizeof(env->sc_hostname));
- env->sc_listeners = newenv.sc_listeners;
- env->sc_maps = newenv.sc_maps;
- env->sc_rules = newenv.sc_rules;
- env->sc_rules = newenv.sc_rules;
- env->sc_ssl = newenv.sc_ssl;
-
- parent_send_config_client_certs(env);
- parent_send_config_ruleset(env, PROC_MFA);
- parent_send_config_ruleset(env, PROC_LKA);
- imsg_compose_event(env->sc_ievs[PROC_SMTP],
- IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0);
- r->ret = 1;
- }
- imsg_compose_event(iev, IMSG_CONF_RELOAD, 0, 0, -1, r, sizeof(*r));
- break;
- }
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
-
- /* forward to other processes */
- imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_MDA], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CTL_VERBOSE,
- 0, 0, -1, &verbose, sizeof(verbose));
- break;
- }
- default:
- log_warnx("parent_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("parent_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
parent_sig_handler(int sig, short event, void *p)
{
struct smtpd *env = p;
@@ -775,14 +428,14 @@ main(int argc, char *argv[])
struct event ev_sighup;
struct timeval tv;
struct peer peers[] = {
- { PROC_CONTROL, parent_dispatch_control },
- { PROC_LKA, parent_dispatch_lka },
- { PROC_MDA, parent_dispatch_mda },
- { PROC_MFA, parent_dispatch_mfa },
- { PROC_MTA, parent_dispatch_mta },
- { PROC_SMTP, parent_dispatch_smtp },
- { PROC_QUEUE, parent_dispatch_queue },
- { PROC_RUNNER, parent_dispatch_runner }
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_MDA, imsg_dispatch },
+ { PROC_MFA, imsg_dispatch },
+ { PROC_MTA, imsg_dispatch },
+ { PROC_SMTP, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch }
};
opts = 0;
@@ -865,6 +518,7 @@ main(int argc, char *argv[])
fork_peers(&env);
+ imsg_callback = parent_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, parent_sig_handler, &env);
@@ -1509,4 +1163,38 @@ child_cmp(struct child *c1, struct child *c2)
return (0);
}
+void
+imsg_dispatch(int fd, short event, void *p)
+{
+ struct imsgev *iev = p;
+ struct imsg imsg;
+ ssize_t n;
+
+ if (event & EV_READ) {
+ if ((n = imsg_read(&iev->ibuf)) == -1)
+ fatal("imsg_read");
+ if (n == 0) {
+ /* this pipe is dead, so remove the event handler */
+ event_del(&iev->ev);
+ event_loopexit(NULL);
+ return;
+ }
+ }
+
+ if (event & EV_WRITE) {
+ if (msgbuf_write(&iev->ibuf.w) == -1)
+ fatal("msgbuf_write");
+ }
+
+ for (;;) {
+ if ((n = imsg_get(&iev->ibuf, &imsg)) == -1)
+ fatal("imsg_get");
+ if (n == 0)
+ break;
+ imsg_callback(iev->env, iev, &imsg);
+ imsg_free(&imsg);
+ }
+ imsg_event_add(iev);
+}
+
SPLAY_GENERATE(childtree, child, entry, child_cmp);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index f1f66d07f9a..96651f0ce9b 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.173 2010/04/19 10:12:48 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.174 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -202,6 +202,8 @@ struct imsgev {
void (*handler)(int, short, void *);
struct event ev;
void *data;
+ struct smtpd *env;
+ int proc;
short events;
};
@@ -817,6 +819,8 @@ struct mta_session {
void *pcb;
};
+extern void (*imsg_callback)(struct smtpd *, struct imsgev *, struct imsg *);
+
/* aliases.c */
int aliases_exist(struct smtpd *, objid_t, char *);
int aliases_get(struct smtpd *, objid_t, struct expandtree *, char *);
@@ -874,6 +878,7 @@ SPLAY_PROTOTYPE(childtree, child, entry, child_cmp);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, pid_t,
int, void *, u_int16_t);
+void imsg_dispatch(int, short, void *);
/* lka.c */
pid_t lka(struct smtpd *);