summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2009-05-20 16:07:27 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2009-05-20 16:07:27 +0000
commit997e558b09911ee188083c1d0c85aba8bada05d9 (patch)
tree866396359302b66bc173448ca4426153e2c0e245 /usr.sbin/smtpd
parent1a4a31345f0ba791a2de3f5e7f0a11e528dc4243 (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.c26
-rw-r--r--usr.sbin/smtpd/lka.c41
-rw-r--r--usr.sbin/smtpd/mfa.c43
-rw-r--r--usr.sbin/smtpd/smtpd.c55
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);