diff options
| author | 2011-12-13 21:44:47 +0000 | |
|---|---|---|
| committer | 2011-12-13 21:44:47 +0000 | |
| commit | a224a58c950b87d20a9e66176e80b3fd4526dd05 (patch) | |
| tree | 09a1c850421e9fc5866c7333830c7b3a8aca4f99 | |
| parent | Fix auto-boot failure problem. The controller name should be a (diff) | |
| download | wireguard-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.c | 61 | ||||
| -rw-r--r-- | usr.sbin/smtpd/delivery_filename.c | 109 | ||||
| -rw-r--r-- | usr.sbin/smtpd/delivery_maildir.c | 109 | ||||
| -rw-r--r-- | usr.sbin/smtpd/delivery_mbox.c | 64 | ||||
| -rw-r--r-- | usr.sbin/smtpd/delivery_mda.c | 62 | ||||
| -rw-r--r-- | usr.sbin/smtpd/lka_session.c | 10 | ||||
| -rw-r--r-- | usr.sbin/smtpd/mda.c | 8 | ||||
| -rw-r--r-- | usr.sbin/smtpd/parse.y | 4 | ||||
| -rw-r--r-- | usr.sbin/smtpd/queue_fsqueue_ascii.c | 10 | ||||
| -rw-r--r-- | usr.sbin/smtpd/smtpd.c | 109 | ||||
| -rw-r--r-- | usr.sbin/smtpd/smtpd.h | 17 | ||||
| -rw-r--r-- | usr.sbin/smtpd/smtpd/Makefile | 4 |
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 \ |
