summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorSunil Nimmagadda <sunil@cvs.openbsd.org>2015-11-30 12:26:56 +0000
committerSunil Nimmagadda <sunil@cvs.openbsd.org>2015-11-30 12:26:56 +0000
commitefea10f55504efd0ae59c25e98375664f8b50480 (patch)
tree836429a27b1ec41a56fd19c8ce4454382308a9e3 /usr.sbin/smtpd
parente8fdbdc794672e8d3885e49f535826182682d6f8 (diff)
While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default. Ok gilles@ jung@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/envelope.c10
-rw-r--r--usr.sbin/smtpd/lka_session.c4
-rw-r--r--usr.sbin/smtpd/mda.c15
-rw-r--r--usr.sbin/smtpd/parse.y18
-rw-r--r--usr.sbin/smtpd/smtpd.conf.514
-rw-r--r--usr.sbin/smtpd/smtpd.h4
6 files changed, 49 insertions, 16 deletions
diff --git a/usr.sbin/smtpd/envelope.c b/usr.sbin/smtpd/envelope.c
index 7faf7c7899b..a64caa7da4d 100644
--- a/usr.sbin/smtpd/envelope.c
+++ b/usr.sbin/smtpd/envelope.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: envelope.c,v 1.32 2015/10/14 20:57:17 gilles Exp $ */
+/* $OpenBSD: envelope.c,v 1.33 2015/11/30 12:26:55 sunil Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -214,6 +214,7 @@ envelope_dump_buffer(const struct envelope *ep, char *dest, size_t len)
envelope_ascii_dump(ep, &dest, &len, "mda-method");
envelope_ascii_dump(ep, &dest, &len, "mda-user");
envelope_ascii_dump(ep, &dest, &len, "mda-usertable");
+ envelope_ascii_dump(ep, &dest, &len, "mda-delivery-user");
break;
case D_MTA:
envelope_ascii_dump(ep, &dest, &len, "mta-relay");
@@ -487,6 +488,10 @@ ascii_load_field(const char *field, struct envelope *ep, char *buf)
return ascii_load_string(ep->agent.mda.usertable, buf,
sizeof ep->agent.mda.usertable);
+ if (strcasecmp("mda-delivery-user", field) == 0)
+ return ascii_load_string(ep->agent.mda.delivery_user, buf,
+ sizeof ep->agent.mda.delivery_user);
+
if (strcasecmp("mta-relay", field) == 0) {
int ret;
uint16_t flags = ep->agent.mta.relay.flags;
@@ -814,6 +819,9 @@ ascii_dump_field(const char *field, const struct envelope *ep,
if (strcasecmp(field, "mda-user") == 0)
return ascii_dump_string(ep->agent.mda.username, buf, len);
+ if (strcasecmp(field, "mda-delivery-user") == 0)
+ return ascii_dump_string(ep->agent.mda.delivery_user, buf, len);
+
if (strcasecmp(field, "mda-usertable") == 0)
return ascii_dump_string(ep->agent.mda.usertable, buf, len);
diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c
index cf5e403b8ed..9720b173bd7 100644
--- a/usr.sbin/smtpd/lka_session.c
+++ b/usr.sbin/smtpd/lka_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka_session.c,v 1.75 2015/11/30 11:14:01 gilles Exp $ */
+/* $OpenBSD: lka_session.c,v 1.76 2015/11/30 12:26:55 sunil Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -544,6 +544,8 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn)
sizeof ep->agent.mda.usertable);
(void)strlcpy(ep->agent.mda.username, lk.userinfo.username,
sizeof ep->agent.mda.username);
+ strlcpy(ep->agent.mda.delivery_user, rule->r_delivery_user,
+ sizeof ep->agent.mda.delivery_user);
if (xn->type == EXPAND_FILENAME) {
ep->agent.mda.method = A_FILENAME;
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c
index a5b5460a74f..0d6d38823d9 100644
--- a/usr.sbin/smtpd/mda.c
+++ b/usr.sbin/smtpd/mda.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mda.c,v 1.112 2015/10/27 21:20:11 jung Exp $ */
+/* $OpenBSD: mda.c,v 1.113 2015/11/30 12:26:55 sunil Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -345,7 +345,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg)
case A_LMTP:
deliver.mode = A_LMTP;
deliver.userinfo = *userinfo;
- (void)strlcpy(deliver.user, userinfo->username,
+ (void)strlcpy(deliver.user, e->user,
sizeof(deliver.user));
(void)strlcpy(deliver.from, e->sender,
sizeof(deliver.from));
@@ -830,13 +830,20 @@ mda_user(const struct envelope *evp)
m_create(p_lka, IMSG_MDA_LOOKUP_USERINFO, 0, 0, -1);
m_add_id(p_lka, u->id);
m_add_string(p_lka, evp->agent.mda.usertable);
- m_add_string(p_lka, evp->agent.mda.username);
+ if (evp->agent.mda.delivery_user[0])
+ m_add_string(p_lka, evp->agent.mda.delivery_user);
+ else
+ m_add_string(p_lka, evp->agent.mda.username);
m_close(p_lka);
u->flags |= USER_WAITINFO;
stat_increment("mda.user", 1);
- log_debug("mda: new user %llx for \"%s\"", u->id, mda_user_to_text(u));
+ if (evp->agent.mda.delivery_user[0])
+ log_debug("mda: new user %016" PRIx64 " for \"%s\" delivering as \"%s\"",
+ u->id, mda_user_to_text(u), evp->agent.mda.delivery_user);
+ else
+ log_debug("mda: new user %016" PRIx64 " for \"%s\"", u->id, mda_user_to_text(u));
return (u);
}
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 3a5b5ce0a60..77511d00726 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.156 2015/11/05 12:35:58 jung Exp $ */
+/* $OpenBSD: parse.y,v 1.157 2015/11/30 12:26:55 sunil Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -960,6 +960,16 @@ userbase : USERBASE tables {
}
;
+deliver_as : AS STRING {
+ if (strlcpy(rule->r_delivery_user, $2,
+ sizeof(rule->r_delivery_user))
+ >= sizeof(rule->r_delivery_user))
+ fatal("username too long");
+ free($2);
+ }
+ | /* empty */ {}
+ ;
+
deliver_action : DELIVER TO MAILDIR {
rule->r_action = A_MAILDIR;
if (strlcpy(rule->r_value.buffer, "~/Maildir",
@@ -982,7 +992,7 @@ deliver_action : DELIVER TO MAILDIR {
>= sizeof(rule->r_value.buffer))
fatal("pathname too long");
}
- | DELIVER TO LMTP STRING {
+ | DELIVER TO LMTP STRING deliver_as {
rule->r_action = A_LMTP;
if (strchr($4, ':') || $4[0] == '/') {
if (strlcpy(rule->r_value.buffer, $4,
@@ -993,7 +1003,7 @@ deliver_action : DELIVER TO MAILDIR {
fatal("invalid lmtp destination");
free($4);
}
- | DELIVER TO LMTP STRING RCPTTO {
+ | DELIVER TO LMTP STRING RCPTTO deliver_as {
rule->r_action = A_LMTP;
if (strchr($4, ':') || $4[0] == '/') {
if (strlcpy(rule->r_value.buffer, $4,
@@ -1008,7 +1018,7 @@ deliver_action : DELIVER TO MAILDIR {
fatal("invalid lmtp destination");
free($4);
}
- | DELIVER TO MDA STRING {
+ | DELIVER TO MDA STRING deliver_as {
rule->r_action = A_MDA;
if (strlcpy(rule->r_value.buffer, $4,
sizeof(rule->r_value.buffer))
diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5
index 3626e694bf8..3bbd8239f2a 100644
--- a/usr.sbin/smtpd/smtpd.conf.5
+++ b/usr.sbin/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.130 2015/10/27 21:20:11 jung Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.131 2015/11/30 12:26:55 sunil Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -17,7 +17,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: October 27 2015 $
+.Dd $Mdocdate: November 30 2015 $
.Dt SMTPD.CONF 5
.Os
.Sh NAME
@@ -279,13 +279,15 @@ Finally, the method of delivery is specified:
.Ic deliver to lmtp
.Op Ar host : Ns Ar port | socket
.Op Ic rcpt-to
+.Op Ic as Ar user
.Xc
Mail is delivered to
.Ar host : Ns Ar port ,
or to the
.Ux
.Ar socket
-over LMTP.
+over LMTP with the privileges of the specified
+.Ar user .
.Pp
Optionally,
.Ic rcpt-to
@@ -305,10 +307,12 @@ is assumed.
.It Ic deliver to mbox
Mail is delivered to the local user's system mailbox in
.Pa /var/mail .
-.It Ic deliver to mda Ar program
+.It Ic deliver to mda Ar program Op Ic as Ar user
Mail is piped to the specified
.Ar program ,
-which is run with the privileges of the user the message is destined to.
+which is run with the privileges of the specified
+.Ar user
+or the user the message is destined to.
This parameter may use conversion specifiers that are expanded before use
.Pq see Sx FORMAT SPECIFIERS .
.It Xo
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 4e13f1f70d1..e96df108deb 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.485 2015/11/23 21:50:12 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.486 2015/11/30 12:26:55 sunil Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -398,6 +398,7 @@ struct rule {
struct table *r_userbase;
time_t r_qexpire;
uint8_t r_forwardonly;
+ char r_delivery_user[LINE_MAX];
};
struct delivery_mda {
@@ -405,6 +406,7 @@ struct delivery_mda {
char usertable[PATH_MAX];
char username[LOGIN_NAME_MAX];
char buffer[EXPAND_BUFFER];
+ char delivery_user[LINE_MAX];
};
struct delivery_mta {