diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-05-20 16:07:27 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-05-20 16:07:27 +0000 |
commit | 997e558b09911ee188083c1d0c85aba8bada05d9 (patch) | |
tree | 866396359302b66bc173448ca4426153e2c0e245 /usr.sbin/smtpd | |
parent | 1a4a31345f0ba791a2de3f5e7f0a11e528dc4243 (diff) |
previous commit to add reload support was missing some code, this diffs
contains the missing parts + a memleak plug
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/control.c | 26 | ||||
-rw-r--r-- | usr.sbin/smtpd/lka.c | 41 | ||||
-rw-r--r-- | usr.sbin/smtpd/mfa.c | 43 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 55 |
4 files changed, 143 insertions, 22 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c index 0eaf0e72757..7dbfe9b2492 100644 --- a/usr.sbin/smtpd/control.c +++ b/usr.sbin/smtpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.27 2009/05/20 14:29:44 gilles Exp $ */ +/* $OpenBSD: control.c,v 1.28 2009/05/20 16:07:26 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -352,7 +352,9 @@ control_dispatch_ext(int fd, short event, void *arg) imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE, 0, 0, -1, s, sizeof(*s)); break; } - case IMSG_CONF_RELOAD: + case IMSG_CONF_RELOAD: { + struct reload r; + log_debug("received reload request"); if (euid) @@ -365,10 +367,10 @@ control_dispatch_ext(int fd, short event, void *arg) } env->sc_flags |= SMTPD_CONFIGURING; - imsg_compose(env->sc_ibufs[PROC_PARENT], IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); - - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + r.fd = fd; + imsg_compose(env->sc_ibufs[PROC_PARENT], IMSG_CONF_RELOAD, 0, 0, -1, &r, sizeof(r)); break; + } case IMSG_CTL_SHUTDOWN: /* NEEDS_FIX */ log_debug("received shutdown request"); @@ -521,7 +523,21 @@ control_dispatch_parent(int sig, short event, void *p) 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(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + else + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } case IMSG_STATS: { diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 9e8b19952a6..2a622f6ad99 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.49 2009/05/20 14:36:55 gilles Exp $ */ +/* $OpenBSD: lka.c,v 1.50 2009/05/20 16:07:26 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -147,6 +147,7 @@ lka_dispatch_parent(int sig, short event, void *p) fatal("mfa_dispatch_parent: calloc"); *rule = *(struct rule *)imsg.data; + TAILQ_INIT(&rule->r_conditions); TAILQ_INSERT_TAIL(env->sc_rules_reload, rule, r_entry); break; } @@ -174,13 +175,43 @@ lka_dispatch_parent(int sig, short event, void *p) fatal("mfa_dispatch_parent: calloc"); *m = *(struct map *)imsg.data; + 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; + + /* map lookup must be done in the reloaded conf */ + env->sc_maps = env->sc_maps_reload; + rule->r_sources = map_findbyname(env, sourcemap); + 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)); + if (mapel == NULL) + fatal("mfa_dispatch_parent: calloc"); + *mapel = *(struct mapel *)imsg.data; + + TAILQ_INSERT_TAIL(&m->m_contents, mapel, me_entry); + break; + } case IMSG_CONF_END: { void *temp; struct rule *r; + struct cond *cond; struct map *m; + struct mapel *mapel; /* switch and destroy old ruleset */ temp = env->sc_rules; @@ -194,6 +225,10 @@ lka_dispatch_parent(int sig, short event, void *p) if (env->sc_rules_reload) { while ((r = TAILQ_FIRST(env->sc_rules_reload))) { TAILQ_REMOVE(env->sc_rules_reload, r, r_entry); + while ((cond = TAILQ_FIRST(&r->r_conditions))) { + TAILQ_REMOVE(&r->r_conditions, cond, c_entry); + free(cond); + } free(r); } free(env->sc_rules_reload); @@ -203,6 +238,10 @@ lka_dispatch_parent(int sig, short event, void *p) if (env->sc_maps_reload) { while ((m = TAILQ_FIRST(env->sc_maps_reload))) { TAILQ_REMOVE(env->sc_maps_reload, m, m_entry); + while ((mapel = TAILQ_FIRST(&m->m_contents))) { + TAILQ_REMOVE(&m->m_contents, mapel, me_entry); + free(mapel); + } free(m); } free(env->sc_maps_reload); diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c index 8f74d840fa7..3eadfeca52f 100644 --- a/usr.sbin/smtpd/mfa.c +++ b/usr.sbin/smtpd/mfa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa.c,v 1.28 2009/05/20 14:36:55 gilles Exp $ */ +/* $OpenBSD: mfa.c,v 1.29 2009/05/20 16:07:26 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -121,6 +121,7 @@ mfa_dispatch_parent(int sig, short event, void *p) fatal("mfa_dispatch_parent: calloc"); *rule = *(struct rule *)imsg.data; + TAILQ_INIT(&rule->r_conditions); TAILQ_INSERT_TAIL(env->sc_rules_reload, rule, r_entry); break; } @@ -148,13 +149,43 @@ mfa_dispatch_parent(int sig, short event, void *p) fatal("mfa_dispatch_parent: calloc"); *m = *(struct map *)imsg.data; + 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; + + /* map lookup must be done in the reloaded conf */ + env->sc_maps = env->sc_maps_reload; + rule->r_sources = map_findbyname(env, sourcemap); + 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)); + if (mapel == NULL) + fatal("mfa_dispatch_parent: calloc"); + *mapel = *(struct mapel *)imsg.data; + + TAILQ_INSERT_TAIL(&m->m_contents, mapel, me_entry); + break; + } case IMSG_CONF_END: { void *temp; struct rule *r; + struct cond *cond; struct map *m; + struct mapel *mapel; /* switch and destroy old ruleset */ temp = env->sc_rules; @@ -164,10 +195,14 @@ mfa_dispatch_parent(int sig, short event, void *p) temp = env->sc_maps; env->sc_maps = env->sc_maps_reload; env->sc_maps_reload = temp; - + if (env->sc_rules_reload) { while ((r = TAILQ_FIRST(env->sc_rules_reload))) { TAILQ_REMOVE(env->sc_rules_reload, r, r_entry); + while ((cond = TAILQ_FIRST(&r->r_conditions))) { + TAILQ_REMOVE(&r->r_conditions, cond, c_entry); + free(cond); + } free(r); } free(env->sc_rules_reload); @@ -177,6 +212,10 @@ mfa_dispatch_parent(int sig, short event, void *p) if (env->sc_maps_reload) { while ((m = TAILQ_FIRST(env->sc_maps_reload))) { TAILQ_REMOVE(env->sc_maps_reload, m, m_entry); + while ((mapel = TAILQ_FIRST(&m->m_contents))) { + TAILQ_REMOVE(&m->m_contents, mapel, me_entry); + free(mapel); + } free(m); } free(env->sc_maps_reload); diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 2ed5eaa0549..0a701fa6f7b 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.62 2009/05/20 14:29:44 gilles Exp $ */ +/* $OpenBSD: smtpd.c,v 1.63 2009/05/20 16:07:26 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -176,25 +176,32 @@ parent_send_config_ruleset(struct smtpd *env, int proc) struct rule *r; struct cond *cond; struct map *m; - + struct mapel *mapel; + log_debug("parent_send_config_ruleset: reloading rules and maps"); imsg_compose(env->sc_ibufs[proc], IMSG_CONF_START, 0, 0, -1, NULL, 0); - + + TAILQ_FOREACH(m, env->sc_maps, m_entry) { + imsg_compose(env->sc_ibufs[proc], IMSG_CONF_MAP, + 0, 0, -1, m, sizeof(*m)); + TAILQ_FOREACH(mapel, &m->m_contents, me_entry) { + imsg_compose(env->sc_ibufs[proc], IMSG_CONF_MAP_CONTENT, + 0, 0, -1, mapel, sizeof(*mapel)); + } + } + TAILQ_FOREACH(r, env->sc_rules, r_entry) { imsg_compose(env->sc_ibufs[proc], IMSG_CONF_RULE, 0, 0, -1, r, sizeof(*r)); + imsg_compose(env->sc_ibufs[proc], IMSG_CONF_RULE_SOURCE, + 0, 0, -1, &r->r_sources->m_name, sizeof(r->r_sources->m_name)); TAILQ_FOREACH(cond, &r->r_conditions, c_entry) { imsg_compose(env->sc_ibufs[proc], IMSG_CONF_CONDITION, 0, 0, -1, cond, sizeof(*cond)); } } - - TAILQ_FOREACH(m, env->sc_maps, m_entry) { - imsg_compose(env->sc_ibufs[proc], IMSG_CONF_MAP, - 0, 0, -1, m, sizeof(*m)); - } - + imsg_compose(env->sc_ibufs[proc], IMSG_CONF_END, 0, 0, -1, NULL, 0); } @@ -633,11 +640,27 @@ parent_dispatch_control(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_CONF_RELOAD: { - parent_send_config_ruleset(env, PROC_MFA); - parent_send_config_ruleset(env, PROC_LKA); - imsg_compose(env->sc_ibufs[PROC_SMTP], - IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); - imsg_compose(ibuf, IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); + struct reload *r = imsg.data; + struct smtpd newenv; + + r->ret = 0; + if (parse_config(&newenv, env->sc_config, 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_ruleset(env, PROC_MFA); + parent_send_config_ruleset(env, PROC_LKA); + imsg_compose(env->sc_ibufs[PROC_SMTP], + IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); + r->ret = 1; + } + imsg_compose(ibuf, IMSG_CONF_RELOAD, 0, 0, -1, r, sizeof(*r)); break; } case IMSG_STATS: { @@ -812,6 +835,10 @@ main(int argc, char *argv[]) if (parse_config(&env, conffile, opts)) exit(1); + if (strlcpy(env.sc_config, conffile, MAXPATHLEN) >= MAXPATHLEN) + errx(1, "config file exceeds MAXPATHLEN"); + + if (env.sc_opts & SMTPD_OPT_NOACTION) { fprintf(stderr, "configuration OK\n"); exit(0); |