diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-03-22 22:53:48 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-03-22 22:53:48 +0000 |
commit | 408eaa73fb87b6d62df1628d1ac7be3bb079070a (patch) | |
tree | b74698550aef98dc2a4a2d5dc101c6bf8f41d413 | |
parent | ec190bbf9f695c6eea05e314791affc4944a59d7 (diff) |
fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.
while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.
-rw-r--r-- | usr.sbin/smtpd/lka.c | 59 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 23 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 3 |
4 files changed, 61 insertions, 28 deletions
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 96c86e3e7df..19c335f24e6 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.36 2009/03/20 09:34:34 gilles Exp $ */ +/* $OpenBSD: lka.c,v 1.37 2009/03/22 22:53:47 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -57,7 +57,7 @@ int lka_forward_file(struct passwd *); size_t lka_expand(char *, size_t, struct path *); int aliases_exist(struct smtpd *, char *); int aliases_get(struct smtpd *, struct aliaseslist *, char *); -int lka_resolve_alias(struct path *, struct alias *); +int lka_resolve_alias(struct smtpd *, struct path *, struct alias *); int lka_parse_include(char *); int lka_check_source(struct smtpd *, struct map *, struct sockaddr_storage *); int lka_match_mask(struct sockaddr_storage *, struct netaddr *); @@ -135,10 +135,35 @@ lka_dispatch_parent(int sig, short event, void *p) --lkasession->pending; if (fd == -1) { - if (fwreq->pw_name[0] != '\0') { + if (! fwreq->status) { lkasession->ss.code = 530; lkasession->flags |= F_ERROR; } + else { + struct alias *alias; + struct message message; + + alias = calloc(1, sizeof(struct alias)); + if (alias == NULL) + fatal("lka_dispatch_parent: calloc"); + + alias_parse(alias, fwreq->pw_name); + + message = lkasession->message; + bzero(&message.recipient, sizeof(struct path)); + lka_resolve_alias(env, &message.recipient, alias); + lka_rcpt_action(env, &message.recipient); + + imsg_compose(env->sc_ibufs[PROC_QUEUE], + IMSG_QUEUE_SUBMIT_ENVELOPE, 0, 0, -1, + &message, sizeof(struct message)); + + if (! lkasession->pending) + imsg_compose(env->sc_ibufs[PROC_QUEUE], + IMSG_QUEUE_COMMIT_ENVELOPES, 0, 0, -1, + &message, sizeof(struct message)); + break; + } } else { if (! forwards_get(fd, &lkasession->aliaseslist)) { @@ -276,7 +301,6 @@ lka_dispatch_mfa(int sig, short event, void *p) if (ret == 0) { /* No aliases ... */ - log_debug("expansion resulted in empty list"); ss->code = 530; imsg_compose(ibuf, IMSG_LKA_RCPT, 0, 0, -1, ss, sizeof(*ss)); @@ -945,7 +969,7 @@ lka_expand(char *buf, size_t len, struct path *path) } int -lka_resolve_alias(struct path *path, struct alias *alias) +lka_resolve_alias(struct smtpd *env, struct path *path, struct alias *alias) { switch (alias->type) { case ALIAS_USERNAME: @@ -953,6 +977,16 @@ lka_resolve_alias(struct path *path, struct alias *alias) if (strlcpy(path->pw_name, alias->u.username, sizeof(path->pw_name)) >= sizeof(path->pw_name)) return 0; + if (path->user[0] == '\0') { + if (strlcpy(path->user, alias->u.username, + sizeof(path->user)) >= sizeof(path->user)) + return 0; + } + if (path->domain[0] == '\0') { + if (strlcpy(path->domain, env->sc_hostname, + sizeof(path->domain)) >= sizeof(path->domain)) + return 0; + } break; case ALIAS_FILENAME: @@ -997,21 +1031,20 @@ lka_expand_rcpt(struct smtpd *env, struct aliaseslist *aliases, struct lkasessio lkasession->ss.code = 530; lkasession->flags |= F_ERROR; } - + if (lkasession->pending || ret <= 0) break; } - + if (lkasession->pending) return; - + if (lkasession->flags & F_ERROR) { lka_clear_aliaseslist(&lkasession->aliaseslist); imsg_compose(env->sc_ibufs[PROC_MFA], IMSG_LKA_RCPT, 0, 0, -1, &lkasession->ss, sizeof(struct submit_status)); } - else if (ret == 0) { - log_debug("expansion resulted in empty list"); + else if (TAILQ_FIRST(&lkasession->aliaseslist) == NULL) { message = lkasession->message; message.recipient = lkasession->path; imsg_compose(env->sc_ibufs[PROC_QUEUE], @@ -1027,7 +1060,7 @@ lka_expand_rcpt(struct smtpd *env, struct aliaseslist *aliases, struct lkasessio while ((alias = TAILQ_FIRST(&lkasession->aliaseslist)) != NULL) { bzero(&message.recipient, sizeof(struct path)); - lka_resolve_alias(&message.recipient, alias); + lka_resolve_alias(env, &message.recipient, alias); lka_rcpt_action(env, &message.recipient); imsg_compose(env->sc_ibufs[PROC_QUEUE], @@ -1090,10 +1123,8 @@ lka_expand_rcpt_iteration(struct smtpd *env, struct aliaseslist *aliases, struct rmalias = NULL; } - if (!done && lkasession->iterations == 5) { - log_debug("loop detected"); + if (!done && lkasession->iterations == 5) return -1; - } if (TAILQ_FIRST(aliases) == NULL) return 0; diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 48176e88abf..4144c425d1d 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.36 2009/03/18 10:29:27 gilles Exp $ */ +/* $OpenBSD: runner.c,v 1.37 2009/03/22 22:53:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -868,7 +868,7 @@ batch_lookup(struct smtpd *env, struct message *message) struct batch lookup; /* We only support delivery of one message at a time, in MDA */ - if (message->flags & T_MDA_MESSAGE) + if (message->type & T_MDA_MESSAGE) return NULL; /* If message->batch_id != 0, we can retrieve batch by id */ diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index be59f9d6108..215e9998d49 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.49 2009/03/10 21:14:21 jacekm Exp $ */ +/* $OpenBSD: smtpd.c,v 1.50 2009/03/22 22:53:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -200,9 +200,11 @@ parent_dispatch_lka(int fd, short event, void *p) fwreq = imsg.data; ret = parent_forward_open(fwreq->pw_name); - if (ret == -1) + fwreq->status = 0; + if (ret == -1) { if (errno == ENOENT) - fwreq->pw_name[0] = '\0'; + fwreq->status = 1; + } imsg_compose(ibuf, IMSG_PARENT_FORWARD_OPEN, 0, 0, ret, fwreq, sizeof(*fwreq)); break; } @@ -1235,31 +1237,30 @@ parent_forward_open(char *username) fd = open(pathname, O_RDONLY); if (fd == -1) { if (errno == ENOENT) - goto clear; + goto err; return -1; } /* make sure ~/ is not writable by anyone but owner */ if (stat(pw->pw_dir, &sb) == -1) - goto clearlog; + goto errlog; if (sb.st_uid != pw->pw_uid || sb.st_mode & (S_IWGRP|S_IWOTH)) - goto clearlog; + goto errlog; /* make sure ~/.forward is not writable by anyone but owner */ if (fstat(fd, &sb) == -1) - goto clearlog; + goto errlog; if (sb.st_uid != pw->pw_uid || sb.st_mode & (S_IWGRP|S_IWOTH)) - goto clearlog; + goto errlog; return fd; -clearlog: +errlog: log_info("cannot process forward file for user %s due to wrong permissions", username); -clear: - username[0] = '\0'; +err: return -1; } diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 40e6a030cea..d02d2daa98e 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.95 2009/03/19 20:27:49 jacekm Exp $ */ +/* $OpenBSD: smtpd.h,v 1.96 2009/03/22 22:53:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -717,6 +717,7 @@ struct message_recipient { struct forward_req { u_int64_t id; + u_int8_t status; char pw_name[MAXLOGNAME]; }; |