summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/smtpd/parse.y32
-rw-r--r--usr.sbin/smtpd/smtpd.c18
-rw-r--r--usr.sbin/smtpd/smtpd.h4
3 files changed, 42 insertions, 12 deletions
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index f6eaeb5de33..f92e7178e73 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.40 2009/10/11 17:40:49 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.41 2009/10/19 20:00:46 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -119,7 +119,7 @@ typedef struct {
%token DNS DB TFILE EXTERNAL DOMAIN CONFIG SOURCE
%token RELAY VIA DELIVER TO MAILDIR MBOX HOSTNAME
%token ACCEPT REJECT INCLUDE NETWORK ERROR MDA FROM FOR
-%token ARROW ENABLE AUTH TLS LOCAL VIRTUAL
+%token ARROW ENABLE AUTH TLS LOCAL VIRTUAL USER
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.map> map
@@ -127,7 +127,7 @@ typedef struct {
%type <v.cond> condition
%type <v.tv> interval
%type <v.object> mapref
-%type <v.string> certname
+%type <v.string> certname user
%%
@@ -733,14 +733,30 @@ conditions : condition {
| '{' condition_list '}'
;
-action : DELIVER TO MAILDIR {
+user : USER STRING {
+ struct passwd *pw;
+
+ pw = getpwnam($2);
+ if (pw == NULL) {
+ yyerror("user '%s' does not exist.", $2);
+ free($2);
+ YYERROR;
+ }
+ $$ = $2;
+ }
+ | /* empty */ { $$ = NULL; }
+ ;
+
+action : DELIVER TO MAILDIR user {
+ rule->r_user = $4;
rule->r_action = A_MAILDIR;
if (strlcpy(rule->r_value.path, "~/Maildir",
sizeof(rule->r_value.path)) >=
sizeof(rule->r_value.path))
fatal("pathname too long");
}
- | DELIVER TO MAILDIR STRING {
+ | DELIVER TO MAILDIR STRING user {
+ rule->r_user = $5;
rule->r_action = A_MAILDIR;
if (strlcpy(rule->r_value.path, $4,
sizeof(rule->r_value.path)) >=
@@ -748,14 +764,15 @@ action : DELIVER TO MAILDIR {
fatal("pathname too long");
free($4);
}
- | DELIVER TO MBOX {
+ | DELIVER TO MBOX {
rule->r_action = A_MBOX;
if (strlcpy(rule->r_value.path, _PATH_MAILDIR "/%u",
sizeof(rule->r_value.path))
>= sizeof(rule->r_value.path))
fatal("pathname too long");
}
- | DELIVER TO MDA STRING {
+ | DELIVER TO MDA STRING user {
+ rule->r_user = $5;
rule->r_action = A_EXT;
if (strlcpy(rule->r_value.command, $4,
sizeof(rule->r_value.command))
@@ -952,6 +969,7 @@ lookup(char *s)
{ "tls", TLS },
{ "to", TO },
{ "type", TYPE },
+ { "user", USER },
{ "via", VIA },
{ "virtual", VIRTUAL },
};
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 735ee4167b4..6df2f9b7005 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.86 2009/10/07 18:19:39 gilles Exp $ */
+/* $OpenBSD: smtpd.c,v 1.87 2009/10/19 20:00:46 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -454,11 +454,15 @@ parent_dispatch_mda(int imsgfd, short event, void *p)
fatalx("parent_dispatch_mda: unknown action");
file = path->rule.r_value.path;
- pw_name = path->pw_name;
+
if (path->rule.r_action == A_FILENAME) {
file = path->u.filename;
pw_name = SMTPD_USER;
}
+ else if (path->rule.r_user != NULL)
+ pw_name = path->rule.r_user;
+ else
+ pw_name = path->pw_name;
errno = 0;
pw = getpwnam(pw_name);
@@ -493,7 +497,6 @@ parent_dispatch_mda(int imsgfd, short event, void *p)
IMSG_SIZE_CHECK(batchp);
fd = parent_open_message_file(batchp);
-
imsg_compose_event(iev, IMSG_PARENT_MESSAGE_OPEN,
0, 0, fd, batchp, sizeof(struct batch));
@@ -506,6 +509,7 @@ parent_dispatch_mda(int imsgfd, short event, void *p)
struct path *path;
struct passwd *pw;
int ret;
+ char *pw_name;
IMSG_SIZE_CHECK(batchp);
@@ -514,8 +518,14 @@ parent_dispatch_mda(int imsgfd, short event, void *p)
path = &batchp->message.sender;
}
+
+ if (path->rule.r_user != NULL)
+ pw_name = path->rule.r_user;
+ else
+ pw_name = path->pw_name;
+
errno = 0;
- pw = getpwnam(path->pw_name);
+ pw = getpwnam(pw_name);
if (pw == NULL) {
if (errno)
parent_mda_tempfail(env, batchp);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index d8b3c83f3a3..2b7920f9b24 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.147 2009/10/12 22:34:37 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.148 2009/10/19 20:00:46 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -332,6 +332,8 @@ struct rule {
char command[MAXCOMMANDLEN];
} r_value;
TAILQ_HEAD(optlist, opt) r_options;
+
+ char *r_user;
};
enum path_flags {