summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgilles <gilles@openbsd.org>2011-12-13 21:44:47 +0000
committergilles <gilles@openbsd.org>2011-12-13 21:44:47 +0000
commita224a58c950b87d20a9e66176e80b3fd4526dd05 (patch)
tree09a1c850421e9fc5866c7333830c7b3a8aca4f99
parentFix auto-boot failure problem. The controller name should be a (diff)
downloadwireguard-openbsd-a224a58c950b87d20a9e66176e80b3fd4526dd05.tar.xz
wireguard-openbsd-a224a58c950b87d20a9e66176e80b3fd4526dd05.zip
- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend - simplify smtpd.c accordingly - rename A_EXT -> A_MDA since that's what we really do ok eric@
-rw-r--r--usr.sbin/smtpd/delivery.c61
-rw-r--r--usr.sbin/smtpd/delivery_filename.c109
-rw-r--r--usr.sbin/smtpd/delivery_maildir.c109
-rw-r--r--usr.sbin/smtpd/delivery_mbox.c64
-rw-r--r--usr.sbin/smtpd/delivery_mda.c62
-rw-r--r--usr.sbin/smtpd/lka_session.c10
-rw-r--r--usr.sbin/smtpd/mda.c8
-rw-r--r--usr.sbin/smtpd/parse.y4
-rw-r--r--usr.sbin/smtpd/queue_fsqueue_ascii.c10
-rw-r--r--usr.sbin/smtpd/smtpd.c109
-rw-r--r--usr.sbin/smtpd/smtpd.h17
-rw-r--r--usr.sbin/smtpd/smtpd/Makefile4
12 files changed, 446 insertions, 121 deletions
diff --git a/usr.sbin/smtpd/delivery.c b/usr.sbin/smtpd/delivery.c
new file mode 100644
index 00000000000..43023873756
--- /dev/null
+++ b/usr.sbin/smtpd/delivery.c
@@ -0,0 +1,61 @@
+/* $OpenBSD: delivery.c,v 1.1 2011/12/13 21:44:47 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+struct delivery_backend *deliver_backend_lookup(enum action_type type);
+
+extern struct delivery_backend delivery_backend_mbox;
+extern struct delivery_backend delivery_backend_mda;
+extern struct delivery_backend delivery_backend_maildir;
+extern struct delivery_backend delivery_backend_filename;
+
+struct delivery_backend *
+delivery_backend_lookup(enum action_type type)
+{
+ switch (type) {
+ case A_MBOX:
+ return &delivery_backend_mbox;
+ case A_MDA:
+ return &delivery_backend_mda;
+ case A_MAILDIR:
+ return &delivery_backend_maildir;
+ case A_FILENAME:
+ return &delivery_backend_filename;
+ default:
+ fatal("unsupported delivery_backend type");
+ }
+
+ return NULL;
+}
diff --git a/usr.sbin/smtpd/delivery_filename.c b/usr.sbin/smtpd/delivery_filename.c
new file mode 100644
index 00000000000..9b1a37c40ce
--- /dev/null
+++ b/usr.sbin/smtpd/delivery_filename.c
@@ -0,0 +1,109 @@
+/* $OpenBSD: delivery_filename.c,v 1.1 2011/12/13 21:44:47 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <db.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+extern char **environ;
+
+/* filename backend */
+static void delivery_filename_open(struct deliver *);
+
+struct delivery_backend delivery_backend_filename = {
+ delivery_filename_open
+};
+
+
+static void
+delivery_filename_open(struct deliver *deliver)
+{
+ struct stat sb;
+ time_t now;
+ size_t len;
+ int fd;
+ FILE *fp;
+ char *ln;
+ char *msg;
+ int n;
+
+#define error(m) { msg = m; goto err; }
+#define error2(m) { msg = m; goto err2; }
+
+ setproctitle("file delivery");
+ fd = open(deliver->to, O_CREAT | O_APPEND | O_WRONLY, 0600);
+ if (fd < 0)
+ error("open");
+ if (fstat(fd, &sb) < 0)
+ error("fstat");
+ if (S_ISREG(sb.st_mode) && flock(fd, LOCK_EX) < 0)
+ error("flock");
+ fp = fdopen(fd, "a");
+ if (fp == NULL)
+ error("fdopen");
+ time(&now);
+ fprintf(fp, "From %s@%s %s", SMTPD_USER, env->sc_hostname,
+ ctime(&now));
+ while ((ln = fgetln(stdin, &len)) != NULL) {
+ if (ln[len - 1] == '\n')
+ len--;
+ if (len >= 5 && memcmp(ln, "From ", 5) == 0)
+ putc('>', fp);
+ fprintf(fp, "%.*s\n", (int)len, ln);
+ if (ferror(fp))
+ break;
+ }
+ if (ferror(stdin))
+ error2("read error");
+ putc('\n', fp);
+ if (fflush(fp) == EOF || ferror(fp))
+ error2("write error");
+ if (fsync(fd) < 0)
+ error2("fsync");
+ if (fclose(fp) == EOF)
+ error2("fclose");
+ _exit(0);
+
+err2:
+ n = errno;
+ ftruncate(fd, sb.st_size);
+ errno = n;
+
+err:
+ perror(msg);
+ _exit(1);
+}
diff --git a/usr.sbin/smtpd/delivery_maildir.c b/usr.sbin/smtpd/delivery_maildir.c
new file mode 100644
index 00000000000..802755de7f1
--- /dev/null
+++ b/usr.sbin/smtpd/delivery_maildir.c
@@ -0,0 +1,109 @@
+/* $OpenBSD: delivery_maildir.c,v 1.1 2011/12/13 21:44:47 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <db.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+extern char **environ;
+
+/* maildir backend */
+static void delivery_maildir_open(struct deliver *);
+
+struct delivery_backend delivery_backend_maildir = {
+ delivery_maildir_open
+};
+
+
+static void
+delivery_maildir_open(struct deliver *deliver)
+{
+ char tmp[PATH_MAX], new[PATH_MAX];
+ int ch, fd;
+ FILE *fp;
+ char *msg;
+ int n;
+
+#define error(m) { msg = m; goto err; }
+#define error2(m) { msg = m; goto err2; }
+
+ setproctitle("maildir delivery");
+ if (mkdir(deliver->to, 0700) < 0 && errno != EEXIST) {
+ msg = "cannot mkdir maildir";
+ goto err;
+ }
+ if (chdir(deliver->to) < 0)
+ error("cannot cd to maildir");
+ if (mkdir("cur", 0700) < 0 && errno != EEXIST)
+ error("mkdir cur failed");
+ if (mkdir("tmp", 0700) < 0 && errno != EEXIST)
+ error("mkdir tmp failed");
+ if (mkdir("new", 0700) < 0 && errno != EEXIST)
+ error("mkdir new failed");
+ snprintf(tmp, sizeof tmp, "tmp/%lld.%d.%s",
+ (long long int) time(NULL),
+ getpid(), env->sc_hostname);
+ fd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0600);
+ if (fd < 0)
+ error("cannot open tmp file");
+ fp = fdopen(fd, "w");
+ if (fp == NULL)
+ error2("fdopen");
+ while ((ch = getc(stdin)) != EOF)
+ if (putc(ch, fp) == EOF)
+ break;
+ if (ferror(stdin))
+ error2("read error");
+ if (fflush(fp) == EOF || ferror(fp))
+ error2("write error");
+ if (fsync(fd) < 0)
+ error2("fsync");
+ if (fclose(fp) == EOF)
+ error2("fclose");
+ snprintf(new, sizeof new, "new/%s", tmp + 4);
+ if (rename(tmp, new) < 0)
+ error2("cannot rename tmp->new");
+ _exit(0);
+
+err2:
+ n = errno;
+ unlink(tmp);
+ errno = n;
+err:
+ perror(msg);
+ _exit(1);
+}
diff --git a/usr.sbin/smtpd/delivery_mbox.c b/usr.sbin/smtpd/delivery_mbox.c
new file mode 100644
index 00000000000..eeed9cea5ea
--- /dev/null
+++ b/usr.sbin/smtpd/delivery_mbox.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: delivery_mbox.c,v 1.1 2011/12/13 21:44:47 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <db.h>
+#include <ctype.h>
+#include <err.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+#define PATH_MAILLOCAL "/usr/libexec/mail.local"
+
+extern char **environ;
+
+/* mbox backend */
+static void delivery_mbox_open(struct deliver *);
+
+struct delivery_backend delivery_backend_mbox = {
+ delivery_mbox_open
+};
+
+
+static void
+delivery_mbox_open(struct deliver *deliver)
+{
+ char *environ_new[2];
+
+ environ_new[0] = "PATH=" _PATH_DEFPATH;
+ environ_new[1] = (char *)NULL;
+ environ = environ_new;
+ execle("/bin/sh", "/bin/sh", "-c", deliver->to, (char *)NULL,
+ environ_new);
+ perror("execle");
+ _exit(1);
+}
diff --git a/usr.sbin/smtpd/delivery_mda.c b/usr.sbin/smtpd/delivery_mda.c
new file mode 100644
index 00000000000..443464f8189
--- /dev/null
+++ b/usr.sbin/smtpd/delivery_mda.c
@@ -0,0 +1,62 @@
+/* $OpenBSD: delivery_mda.c,v 1.1 2011/12/13 21:44:47 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <db.h>
+#include <ctype.h>
+#include <err.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+extern char **environ;
+
+/* mda backend */
+static void delivery_mda_open(struct deliver *);
+
+struct delivery_backend delivery_backend_mda = {
+ delivery_mda_open
+};
+
+
+static void
+delivery_mda_open(struct deliver *deliver)
+{
+ char *environ_new[2];
+
+ environ_new[0] = "PATH=" _PATH_DEFPATH;
+ environ_new[1] = (char *)NULL;
+ environ = environ_new;
+ execle("/bin/sh", "/bin/sh", "-c", deliver->to, (char *)NULL,
+ environ_new);
+ perror("execle");
+ _exit(1);
+}
diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c
index e7da231fadd..4423cb4199c 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.14 2011/12/12 16:45:16 chl Exp $ */
+/* $OpenBSD: lka_session.c,v 1.15 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -126,7 +126,7 @@ lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep)
break;
case A_MAILDIR:
case A_FILENAME:
- case A_EXT:
+ case A_MDA:
ep->agent.mda.method = ep->rule.r_action;
(void)strlcpy(ep->agent.mda.to.buffer,
ep->rule.r_value.buffer,
@@ -381,7 +381,7 @@ lka_session_deliver(struct lka_session *lks, struct envelope *ep)
switch (d_mda->method) {
case A_MAILDIR:
case A_FILENAME:
- case A_EXT: {
+ case A_MDA: {
char *buf = d_mda->to.buffer;
size_t bufsz = sizeof(d_mda->to.buffer);
if (! lka_session_expand_format(buf, bufsz, new_ep))
@@ -483,7 +483,7 @@ lka_session_resolve_node(struct envelope *ep, struct expandnode *xn)
xn->u.buffer);
ep->type = D_MDA;
ep->agent.mda.to = xn->u;
- ep->agent.mda.method = A_EXT;
+ ep->agent.mda.method = A_MDA;
(void)strlcpy(ep->agent.mda.as_user, xn->as_user,
sizeof (ep->agent.mda.as_user));
break;
@@ -621,7 +621,7 @@ lka_session_rcpt_action(struct envelope *ep)
case A_MBOX:
case A_MAILDIR:
case A_FILENAME:
- case A_EXT:
+ case A_MDA:
ep->type = D_MDA;
break;
default:
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c
index 0a86f5fd405..0fa9e49be93 100644
--- a/usr.sbin/smtpd/mda.c
+++ b/usr.sbin/smtpd/mda.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mda.c,v 1.63 2011/11/14 19:23:41 chl Exp $ */
+/* $OpenBSD: mda.c,v 1.64 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -81,8 +81,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
ep = &s->msg;
d_mda = &s->msg.agent.mda;
switch (d_mda->method) {
- case A_EXT:
- deliver.mode = A_EXT;
+ case A_MDA:
+ deliver.mode = A_MDA;
strlcpy(deliver.user, d_mda->as_user,
sizeof (deliver.user));
strlcpy(deliver.to, d_mda->to.buffer,
@@ -90,7 +90,7 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
break;
case A_MBOX:
- deliver.mode = A_EXT;
+ deliver.mode = A_MDA;
strlcpy(deliver.user, "root",
sizeof (deliver.user));
snprintf(deliver.to, sizeof (deliver.to),
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 3cef3d0de45..e4a135a749b 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.83 2011/12/08 17:04:19 todd Exp $ */
+/* $OpenBSD: parse.y,v 1.84 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -990,7 +990,7 @@ action : DELIVER TO MAILDIR user {
}
| DELIVER TO MDA STRING user {
rule->r_user = $5;
- rule->r_action = A_EXT;
+ rule->r_action = A_MDA;
if (strlcpy(rule->r_value.buffer, $4,
sizeof(rule->r_value.buffer))
>= sizeof(rule->r_value.buffer))
diff --git a/usr.sbin/smtpd/queue_fsqueue_ascii.c b/usr.sbin/smtpd/queue_fsqueue_ascii.c
index 912d1e69f38..80bb96a85ba 100644
--- a/usr.sbin/smtpd/queue_fsqueue_ascii.c
+++ b/usr.sbin/smtpd/queue_fsqueue_ascii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_fsqueue_ascii.c,v 1.6 2011/11/06 16:55:32 eric Exp $ */
+/* $OpenBSD: queue_fsqueue_ascii.c,v 1.7 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -158,8 +158,8 @@ ascii_load_mda_method(struct envelope *ep, char *buf)
ep->agent.mda.method = A_MAILDIR;
else if (strcasecmp(buf, "filename") == 0)
ep->agent.mda.method = A_FILENAME;
- else if (strcasecmp(buf, "external") == 0)
- ep->agent.mda.method = A_EXT;
+ else if (strcasecmp(buf, "mda") == 0)
+ ep->agent.mda.method = A_MDA;
else
return 0;
return 1;
@@ -179,8 +179,8 @@ ascii_dump_mda_method(struct envelope *ep, FILE *fp)
case A_FILENAME:
fprintf(fp, "filename\n");
break;
- case A_EXT:
- fprintf(fp, "external\n");
+ case A_MDA:
+ fprintf(fp, "mda\n");
break;
default:
return 0;
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 5d832e902f1..5acc38e4b0b 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.140 2011/12/12 17:20:36 eric Exp $ */
+/* $OpenBSD: smtpd.c,v 1.141 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -692,7 +692,8 @@ forkmda(struct imsgev *iev, u_int32_t id,
struct deliver *deliver)
{
char ebuf[128], sfn[32];
- struct user_backend *ub;
+ struct user_backend *ub;
+ struct delivery_backend *db;
struct mta_user u;
struct child *child;
pid_t pid;
@@ -710,6 +711,10 @@ forkmda(struct imsgev *iev, u_int32_t id,
return;
}
+ db = delivery_backend_lookup(deliver->mode);
+ if (db == NULL)
+ return;
+
/* lower privs early to allow fork fail due to ulimit */
if (seteuid(u.uid) < 0)
fatal("cannot lower privileges");
@@ -788,109 +793,11 @@ forkmda(struct imsgev *iev, u_int32_t id,
/* avoid hangs by setting 5m timeout */
alarm(300);
- if (deliver->mode == A_EXT) {
- char *environ_new[2];
-
- environ_new[0] = "PATH=" _PATH_DEFPATH;
- environ_new[1] = (char *)NULL;
- environ = environ_new;
- execle("/bin/sh", "/bin/sh", "-c", deliver->to, (char *)NULL,
- environ_new);
- error("execle");
- }
-
- if (deliver->mode == A_MAILDIR) {
- char tmp[PATH_MAX], new[PATH_MAX];
- int ch, fd;
- FILE *fp;
-
-#define error2(m) { n = errno; unlink(tmp); errno = n; error(m); }
- setproctitle("maildir delivery");
- if (mkdir(deliver->to, 0700) < 0 && errno != EEXIST)
- error("cannot mkdir maildir");
- if (chdir(deliver->to) < 0)
- error("cannot cd to maildir");
- if (mkdir("cur", 0700) < 0 && errno != EEXIST)
- error("mkdir cur failed");
- if (mkdir("tmp", 0700) < 0 && errno != EEXIST)
- error("mkdir tmp failed");
- if (mkdir("new", 0700) < 0 && errno != EEXIST)
- error("mkdir new failed");
- snprintf(tmp, sizeof tmp, "tmp/%lld.%d.%s",
- (long long int) time(NULL),
- getpid(), env->sc_hostname);
- fd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0600);
- if (fd < 0)
- error("cannot open tmp file");
- fp = fdopen(fd, "w");
- if (fp == NULL)
- error2("fdopen");
- while ((ch = getc(stdin)) != EOF)
- if (putc(ch, fp) == EOF)
- break;
- if (ferror(stdin))
- error2("read error");
- if (fflush(fp) == EOF || ferror(fp))
- error2("write error");
- if (fsync(fd) < 0)
- error2("fsync");
- if (fclose(fp) == EOF)
- error2("fclose");
- snprintf(new, sizeof new, "new/%s", tmp + 4);
- if (rename(tmp, new) < 0)
- error2("cannot rename tmp->new");
- _exit(0);
- }
-#undef error2
-
- if (deliver->mode == A_FILENAME) {
- struct stat sb;
- time_t now;
- size_t len;
- int fd;
- FILE *fp;
- char *ln;
-
-#define error2(m) { n = errno; ftruncate(fd, sb.st_size); errno = n; error(m); }
- setproctitle("file delivery");
- fd = open(deliver->to, O_CREAT | O_APPEND | O_WRONLY, 0600);
- if (fd < 0)
- error("open");
- if (fstat(fd, &sb) < 0)
- error("fstat");
- if (S_ISREG(sb.st_mode) && flock(fd, LOCK_EX) < 0)
- error("flock");
- fp = fdopen(fd, "a");
- if (fp == NULL)
- error("fdopen");
- time(&now);
- fprintf(fp, "From %s@%s %s", SMTPD_USER, env->sc_hostname,
- ctime(&now));
- while ((ln = fgetln(stdin, &len)) != NULL) {
- if (ln[len - 1] == '\n')
- len--;
- if (len >= 5 && memcmp(ln, "From ", 5) == 0)
- putc('>', fp);
- fprintf(fp, "%.*s\n", (int)len, ln);
- if (ferror(fp))
- break;
- }
- if (ferror(stdin))
- error2("read error");
- putc('\n', fp);
- if (fflush(fp) == EOF || ferror(fp))
- error2("write error");
- if (fsync(fd) < 0)
- error2("fsync");
- if (fclose(fp) == EOF)
- error2("fclose");
- _exit(0);
- }
+ db->open(deliver);
error("forkmda: unknown mode");
}
#undef error
-#undef error2
static void
offline_scan(int fd, short ev, void *arg)
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 4e3b190ef08..9aedaf19f95 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.260 2011/12/12 17:20:36 eric Exp $ */
+/* $OpenBSD: smtpd.h,v 1.261 2011/12/13 21:44:47 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -303,7 +303,7 @@ enum action_type {
A_MAILDIR,
A_MBOX,
A_FILENAME,
- A_EXT
+ A_MDA
};
#define IS_MAILBOX(x) ((x).r_action == A_MAILDIR || (x).r_action == A_MBOX || (x).r_action == A_FILENAME)
@@ -585,7 +585,6 @@ struct ramqueue {
TAILQ_HEAD(,ramqueue_envelope) queue;
};
-
struct smtpd {
char sc_conffile[MAXPATHLEN];
size_t sc_maxsize;
@@ -954,6 +953,14 @@ struct user_backend {
};
+/* delivery_backend */
+struct delivery_backend {
+ void (*open)(struct deliver *);
+};
+
+
+
+
extern struct smtpd *env;
extern void (*imsg_callback)(struct imsgev *, struct imsg *);
@@ -998,6 +1005,10 @@ void session_socket_no_linger(int);
int session_socket_error(int);
+/* delivery_backend.c */
+struct delivery_backend *delivery_backend_lookup(enum action_type);
+
+
/* dns.c */
void dns_query_host(char *, int, u_int64_t);
void dns_query_mx(char *, int, u_int64_t);
diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile
index 0e9c42f4a7f..bbabed1ccc3 100644
--- a/usr.sbin/smtpd/smtpd/Makefile
+++ b/usr.sbin/smtpd/smtpd/Makefile
@@ -1,7 +1,9 @@
-# $OpenBSD: Makefile,v 1.31 2011/10/23 09:30:07 gilles Exp $
+# $OpenBSD: Makefile,v 1.32 2011/12/13 21:44:47 gilles Exp $
PROG= smtpd
SRCS= aliases.c auth_backend.c bounce.c client.c \
+ delivery.c delivery_filename.c \
+ delivery_maildir.c delivery_mbox.c delivery_mda.c \
config.c control.c dns.c expand.c forward.c \
lka.c lka_session.c log.c map.c map_backend.c \
map_backend_db.c map_backend_stdio.c \