summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2009-03-22 22:53:48 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2009-03-22 22:53:48 +0000
commit408eaa73fb87b6d62df1628d1ac7be3bb079070a (patch)
treeb74698550aef98dc2a4a2d5dc101c6bf8f41d413 /usr.sbin/smtpd
parentec190bbf9f695c6eea05e314791affc4944a59d7 (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.
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/lka.c59
-rw-r--r--usr.sbin/smtpd/runner.c4
-rw-r--r--usr.sbin/smtpd/smtpd.c23
-rw-r--r--usr.sbin/smtpd/smtpd.h3
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];
};