summaryrefslogtreecommitdiff
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
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.
-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];
};