diff options
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/queue.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_backend.c | 41 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_fsqueue.c | 186 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 8 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 7 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 9 |
6 files changed, 128 insertions, 127 deletions
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index 9437e95ca50..6fb660bfb71 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.119 2012/06/20 20:45:23 eric Exp $ */ +/* $OpenBSD: queue.c,v 1.120 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -69,7 +69,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) return; case IMSG_QUEUE_REMOVE_MESSAGE: - queue_message_delete(evpid_to_msgid(e->id)); + queue_message_incoming_delete(evpid_to_msgid(e->id)); return; case IMSG_QUEUE_COMMIT_MESSAGE: diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c index 50625760ac5..b817075b06b 100644 --- a/usr.sbin/smtpd/queue_backend.c +++ b/usr.sbin/smtpd/queue_backend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_backend.c,v 1.25 2012/07/02 17:00:05 eric Exp $ */ +/* $OpenBSD: queue_backend.c,v 1.26 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -25,6 +25,7 @@ #include <ctype.h> #include <event.h> +#include <fcntl.h> #include <imsg.h> #include <inttypes.h> #include <libgen.h> @@ -42,6 +43,37 @@ static const char* envelope_validate(struct envelope *, uint64_t); extern struct queue_backend queue_backend_fs; +int +queue_message_incoming_path(u_int32_t msgid, char *buf, size_t len) +{ + return bsnprintf(buf, len, "%s/%08x", + PATH_INCOMING, + msgid); +} + +int +queue_envelope_incoming_path(u_int64_t evpid, char *buf, size_t len) +{ + return bsnprintf(buf, len, "%s/%08x%s/%016" PRIx64, + PATH_INCOMING, + evpid_to_msgid(evpid), + PATH_ENVELOPES, + evpid); +} + +int +queue_message_incoming_delete(u_int32_t msgid) +{ + char rootdir[MAXPATHLEN]; + + if (! queue_message_incoming_path(msgid, rootdir, sizeof(rootdir))) + fatal("queue_message_incoming_delete: snprintf"); + + if (rmtree(rootdir, 0) == -1) + fatal("queue_message_incoming_delete: rmtree"); + + return 1; +} struct queue_backend * queue_backend_lookup(const char *name) @@ -85,7 +117,12 @@ queue_message_fd_r(u_int32_t msgid) int queue_message_fd_rw(u_int32_t msgid) { - return env->sc_queue->message(QOP_FD_RW, &msgid); + char msgpath[MAXPATHLEN]; + + queue_message_incoming_path(msgid, msgpath, sizeof msgpath); + strlcat(msgpath, PATH_MESSAGE, sizeof(msgpath)); + + return open(msgpath, O_RDWR | O_CREAT | O_EXCL, 0600); } int diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c index 1488b356ff2..f498fbf71aa 100644 --- a/usr.sbin/smtpd/queue_fsqueue.c +++ b/usr.sbin/smtpd/queue_fsqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_fsqueue.c,v 1.43 2012/07/02 13:22:14 eric Exp $ */ +/* $OpenBSD: queue_fsqueue.c,v 1.44 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -42,25 +42,18 @@ #include "smtpd.h" #include "log.h" -enum queue_kind { - Q_INCOMING, - Q_QUEUE, - Q_CORRUPT -}; - -static int fsqueue_envelope_load(enum queue_kind, struct envelope *); -static int fsqueue_envelope_update(enum queue_kind, struct envelope *); -static int fsqueue_envelope_delete(enum queue_kind, struct envelope *); +static int fsqueue_envelope_load(struct envelope *); +static int fsqueue_envelope_update(struct envelope *); +static int fsqueue_envelope_delete(struct envelope *); -static int fsqueue_message_create(enum queue_kind, u_int32_t *); -static int fsqueue_message_commit(enum queue_kind, u_int32_t); -static int fsqueue_message_fd_r(enum queue_kind, u_int32_t); -static int fsqueue_message_fd_rw(enum queue_kind, u_int32_t); -static int fsqueue_message_delete(enum queue_kind, u_int32_t); -static int fsqueue_message_corrupt(enum queue_kind, u_int32_t); +static int fsqueue_message_create(u_int32_t *); +static int fsqueue_message_commit(u_int32_t); +static int fsqueue_message_fd_r(u_int32_t); +static int fsqueue_message_delete(u_int32_t); +static int fsqueue_message_corrupt(u_int32_t); -static int fsqueue_message_path(enum queue_kind, uint32_t, char *, size_t); -static int fsqueue_envelope_path(enum queue_kind, u_int64_t, char *, size_t); +static int fsqueue_message_path(uint32_t, char *, size_t); +static int fsqueue_envelope_path(u_int64_t, char *, size_t); static int fsqueue_envelope_dump_atomic(char *, struct envelope *); static int fsqueue_init(int); @@ -71,13 +64,9 @@ static void *fsqueue_qwalk_new(u_int32_t); static int fsqueue_qwalk(void *, u_int64_t *); static void fsqueue_qwalk_close(void *); -#define PATH_INCOMING "/incoming" #define PATH_QUEUE "/queue" #define PATH_CORRUPT "/corrupt" -#define PATH_MESSAGE "/message" -#define PATH_ENVELOPES "/envelopes" - #define PATH_EVPTMP PATH_INCOMING "/envelope.tmp" struct queue_backend queue_backend_fs = { @@ -90,46 +79,30 @@ struct queue_backend queue_backend_fs = { }; static int -fsqueue_message_path(enum queue_kind qkind, uint32_t msgid, char *buf, size_t len) +fsqueue_message_path(uint32_t msgid, char *buf, size_t len) { - switch (qkind) { - case Q_QUEUE: - return bsnprintf(buf, len, "%s/%03x/%08x", - PATH_QUEUE, - msgid & 0xfff, - msgid); - case Q_INCOMING: - case Q_CORRUPT: - return bsnprintf(buf, len, "%s/%08x", - qkind == Q_INCOMING ? PATH_INCOMING : PATH_CORRUPT, - msgid); - default: - fatalx("fsqueue_message_path: unsupported queue kind."); - } - return (0); + return bsnprintf(buf, len, "%s/%03x/%08x", + PATH_QUEUE, + msgid & 0xfff, + msgid); } static int -fsqueue_envelope_path(enum queue_kind qkind, uint64_t evpid, char *buf, size_t len) +fsqueue_message_corrupt_path(uint32_t msgid, char *buf, size_t len) { - switch (qkind) { - case Q_QUEUE: - return bsnprintf(buf, len, "%s/%03x/%08x%s/%016" PRIx64, - PATH_QUEUE, - evpid_to_msgid(evpid) & 0xfff, - evpid_to_msgid(evpid), - PATH_ENVELOPES, evpid); - case Q_INCOMING: - case Q_CORRUPT: - return bsnprintf(buf, len, "%s/%08x%s/%016" PRIx64, - qkind == Q_INCOMING ? PATH_INCOMING : PATH_CORRUPT, - evpid_to_msgid(evpid), - PATH_ENVELOPES, evpid); - default: - fatalx("fsqueue_envelope_path: unsupported queue kind."); - } + return bsnprintf(buf, len, "%s/%08x", + PATH_CORRUPT, + msgid); +} - return (0); +static int +fsqueue_envelope_path(uint64_t evpid, char *buf, size_t len) +{ + return bsnprintf(buf, len, "%s/%03x/%08x%s/%016" PRIx64, + PATH_QUEUE, + evpid_to_msgid(evpid) & 0xfff, + evpid_to_msgid(evpid), + PATH_ENVELOPES, evpid); } static int @@ -178,7 +151,7 @@ tempfail: } static int -fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep) +fsqueue_envelope_create(struct envelope *ep) { char evpname[MAXPATHLEN]; u_int64_t evpid; @@ -186,7 +159,11 @@ fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep) again: evpid = queue_generate_evpid(evpid_to_msgid(ep->id)); - fsqueue_envelope_path(qkind, evpid, evpname, sizeof(evpname)); + if (ep->type == D_BOUNCE) + fsqueue_envelope_path(evpid, evpname, sizeof(evpname)); + else + queue_envelope_incoming_path(evpid, evpname, sizeof(evpname)); + if (stat(evpname, &sb) != -1 || errno != ENOENT) goto again; ep->id = evpid; @@ -195,13 +172,13 @@ again: } static int -fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep) +fsqueue_envelope_load(struct envelope *ep) { char pathname[MAXPATHLEN]; FILE *fp; int ret; - fsqueue_envelope_path(qkind, ep->id, pathname, sizeof(pathname)); + fsqueue_envelope_path(ep->id, pathname, sizeof(pathname)); fp = fopen(pathname, "r"); if (fp == NULL) { @@ -217,23 +194,23 @@ fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep) } static int -fsqueue_envelope_update(enum queue_kind qkind, struct envelope *ep) +fsqueue_envelope_update(struct envelope *ep) { char dest[MAXPATHLEN]; - fsqueue_envelope_path(qkind, ep->id, dest, sizeof(dest)); + fsqueue_envelope_path(ep->id, dest, sizeof(dest)); return (fsqueue_envelope_dump_atomic(dest, ep)); } static int -fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep) +fsqueue_envelope_delete(struct envelope *ep) { char pathname[MAXPATHLEN]; log_debug("#### %s: queue_envelope_delete: %016" PRIx64, __func__, ep->id); - fsqueue_envelope_path(qkind, ep->id, pathname, sizeof(pathname)); + fsqueue_envelope_path(ep->id, pathname, sizeof(pathname)); if (unlink(pathname) == -1) { log_debug("######: %s [errno: %d]", pathname, errno); @@ -243,13 +220,13 @@ fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep) *strrchr(pathname, '/') = '\0'; if (rmdir(pathname) != -1) - fsqueue_message_delete(qkind, evpid_to_msgid(ep->id)); + fsqueue_message_delete(evpid_to_msgid(ep->id)); return 1; } static int -fsqueue_message_create(enum queue_kind qkind, u_int32_t *msgid) +fsqueue_message_create(u_int32_t *msgid) { char rootdir[MAXPATHLEN]; char evpdir[MAXPATHLEN]; @@ -259,11 +236,11 @@ again: *msgid = queue_generate_msgid(); /* prevent possible collision later when moving to Q_QUEUE */ - fsqueue_message_path(Q_QUEUE, *msgid, rootdir, sizeof(rootdir)); + fsqueue_message_path(*msgid, rootdir, sizeof(rootdir)); if (stat(rootdir, &sb) != -1 || errno != ENOENT) goto again; - fsqueue_message_path(qkind, *msgid, rootdir, sizeof(rootdir)); + queue_message_incoming_path(*msgid, rootdir, sizeof(rootdir)); if (mkdir(rootdir, 0700) == -1) { if (errno == EEXIST) goto again; @@ -291,14 +268,14 @@ again: } static int -fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid) +fsqueue_message_commit(u_int32_t msgid) { - char rootdir[MAXPATHLEN]; + char incomingdir[MAXPATHLEN]; char queuedir[MAXPATHLEN]; char msgdir[MAXPATHLEN]; - fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir)); - fsqueue_message_path(Q_QUEUE, msgid, msgdir, sizeof(msgdir)); + queue_message_incoming_path(msgid, incomingdir, sizeof(incomingdir)); + fsqueue_message_path(msgid, msgdir, sizeof(msgdir)); strlcpy(queuedir, msgdir, sizeof(queuedir)); *strrchr(queuedir, '/') = '\0'; @@ -309,7 +286,7 @@ fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid) fatal("fsqueue_message_commit: mkdir"); } - if (rename(rootdir, msgdir) == -1) { + if (rename(incomingdir, msgdir) == -1) { if (errno == ENOSPC) return 0; fatal("fsqueue_message_commit: rename"); @@ -319,12 +296,12 @@ fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid) } static int -fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid) +fsqueue_message_fd_r(u_int32_t msgid) { int fd; char path[MAXPATHLEN]; - fsqueue_message_path(qkind, msgid, path, sizeof(path)); + fsqueue_message_path(msgid, path, sizeof(path)); strlcat(path, PATH_MESSAGE, sizeof(path)); if ((fd = open(path, O_RDONLY)) == -1) @@ -334,22 +311,12 @@ fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid) } static int -fsqueue_message_fd_rw(enum queue_kind qkind, u_int32_t msgid) -{ - char path[MAXPATHLEN]; - - fsqueue_message_path(qkind, msgid, path, sizeof(path)); - strlcat(path, PATH_MESSAGE, sizeof(path)); - - return open(path, O_CREAT|O_EXCL|O_RDWR, 0600); -} - -static int -fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid) +fsqueue_message_delete(u_int32_t msgid) { char rootdir[MAXPATHLEN]; - fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir)); + if (! fsqueue_message_path(msgid, rootdir, sizeof(rootdir))) + fatal("fsqueue_message_delete: snprintf"); if (rmtree(rootdir, 0) == -1) fatal("fsqueue_message_delete: rmtree"); @@ -358,7 +325,7 @@ fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid) } static int -fsqueue_message_corrupt(enum queue_kind qkind, u_int32_t msgid) +fsqueue_message_corrupt(u_int32_t msgid) { struct stat sb; char rootdir[MAXPATHLEN]; @@ -366,11 +333,12 @@ fsqueue_message_corrupt(enum queue_kind qkind, u_int32_t msgid) char buf[64]; int retry = 0; - fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir)); - fsqueue_message_path(Q_CORRUPT, msgid, corruptdir, sizeof(corruptdir)); + fsqueue_message_path(msgid, rootdir, sizeof(rootdir)); + fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir)); + again: if (stat(corruptdir, &sb) != -1 || errno != ENOENT) { - fsqueue_message_path(Q_CORRUPT, msgid, corruptdir, sizeof(corruptdir)); + fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir)); snprintf(buf, sizeof(buf), ".%i", retry++); strlcat(corruptdir, buf, sizeof(corruptdir)); goto again; @@ -386,17 +354,12 @@ static int fsqueue_init(int server) { unsigned int n; - char *paths[] = { PATH_INCOMING, PATH_QUEUE, PATH_CORRUPT }; + char *paths[] = { PATH_QUEUE, PATH_CORRUPT }; char path[MAXPATHLEN]; int ret; - if (!fsqueue_envelope_path(Q_QUEUE, 0, path, sizeof(path))) + if (!fsqueue_envelope_path(0, path, sizeof(path))) errx(1, "cannot store envelope path in %s", PATH_QUEUE); - if (!fsqueue_envelope_path(Q_INCOMING, 0, path, sizeof(path))) - errx(1, "cannot store envelope path in %s", PATH_INCOMING); - - if (server) - mvpurge(PATH_SPOOL PATH_INCOMING, PATH_SPOOL PATH_PURGE); ret = 1; for (n = 0; n < nitems(paths); n++) { @@ -416,22 +379,19 @@ fsqueue_message(enum queue_op qop, u_int32_t *msgid) { switch (qop) { case QOP_CREATE: - return fsqueue_message_create(Q_INCOMING, msgid); + return fsqueue_message_create(msgid); case QOP_DELETE: - return fsqueue_message_delete(Q_INCOMING, *msgid); + return fsqueue_message_delete(*msgid); case QOP_COMMIT: - return fsqueue_message_commit(Q_INCOMING, *msgid); + return fsqueue_message_commit(*msgid); case QOP_FD_R: - return fsqueue_message_fd_r(Q_QUEUE, *msgid); - - case QOP_FD_RW: - return fsqueue_message_fd_rw(Q_INCOMING, *msgid); + return fsqueue_message_fd_r(*msgid); case QOP_CORRUPT: - return fsqueue_message_corrupt(Q_QUEUE, *msgid); + return fsqueue_message_corrupt(*msgid); default: fatalx("queue_fsqueue_message: unsupported operation."); @@ -445,20 +405,16 @@ fsqueue_envelope(enum queue_op qop, struct envelope *m) { switch (qop) { case QOP_CREATE: - /* currently, only bounce envelopes are created in queued - * messages - */ - return fsqueue_envelope_create( - m->type == D_BOUNCE ? Q_QUEUE : Q_INCOMING, m); + return fsqueue_envelope_create(m); case QOP_DELETE: - return fsqueue_envelope_delete(Q_QUEUE, m); + return fsqueue_envelope_delete(m); case QOP_LOAD: - return fsqueue_envelope_load(Q_QUEUE, m); + return fsqueue_envelope_load(m); case QOP_UPDATE: - return fsqueue_envelope_update(Q_QUEUE, m); + return fsqueue_envelope_update(m); default: fatalx("queue_fsqueue_envelope: unsupported operation."); diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 68e518ccb6a..0f825e656ad 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.142 2012/07/02 17:00:05 eric Exp $ */ +/* $OpenBSD: runner.c,v 1.143 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -456,8 +456,7 @@ runner_process_batch(enum delivery_type type, u_int64_t evpid) /* FIXME */ if (! scheduler->fetch(batch, &evpid)) goto end; - if (! queue_envelope_load(evpid, - &evp)) + if (! queue_envelope_load(evpid, &evp)) goto end; bzero(&mta_batch, sizeof mta_batch); @@ -469,8 +468,7 @@ runner_process_batch(enum delivery_type type, u_int64_t evpid) sizeof mta_batch); while (scheduler->fetch(batch, &evpid)) { - if (! queue_envelope_load(evpid, - &evp)) + if (! queue_envelope_load(evpid, &evp)) goto end; evp.lasttry = time(NULL); /* FIXME */ evp.batch_id = mta_batch.id; diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 0f3a0e76f2d..fc84a771b73 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.152 2012/07/02 17:00:05 eric Exp $ */ +/* $OpenBSD: smtpd.c,v 1.153 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -539,6 +539,11 @@ main(int argc, char *argv[]) if (ckdir(PATH_SPOOL PATH_PURGE, 0700, env->sc_pw->pw_uid, 0, 1) == 0) errx(1, "error in purge directory setup"); + mvpurge(PATH_SPOOL PATH_INCOMING, PATH_SPOOL PATH_PURGE); + + if (ckdir(PATH_SPOOL PATH_INCOMING, 0700, env->sc_pw->pw_uid, 0, 1) == 0) + errx(1, "error in incoming directory setup"); + log_debug("using \"%s\" queue backend", backend_queue); log_debug("using \"%s\" scheduler backend", backend_scheduler); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index f3df0852c1a..c15cf9498f4 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.302 2012/07/02 17:00:05 eric Exp $ */ +/* $OpenBSD: smtpd.h,v 1.303 2012/07/08 18:13:08 chl Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -67,6 +67,9 @@ #define PATH_SPOOL "/var/spool/smtpd" #define PATH_OFFLINE "/offline" #define PATH_PURGE "/purge" +#define PATH_INCOMING "/incoming" +#define PATH_ENVELOPES "/envelopes" +#define PATH_MESSAGE "/message" /* number of MX records to lookup */ #define MAX_MX_COUNT 10 @@ -894,7 +897,6 @@ enum queue_op { QOP_COMMIT, QOP_LOAD, QOP_FD_R, - QOP_FD_RW, QOP_CORRUPT, }; @@ -1110,6 +1112,9 @@ void queue_commit_envelopes(struct envelope *); u_int32_t queue_generate_msgid(void); u_int64_t queue_generate_evpid(u_int32_t msgid); struct queue_backend *queue_backend_lookup(const char *); +int queue_message_incoming_path(u_int32_t, char *, size_t); +int queue_envelope_incoming_path(u_int64_t, char *, size_t); +int queue_message_incoming_delete(u_int32_t); int queue_message_create(u_int32_t *); int queue_message_delete(u_int32_t); int queue_message_commit(u_int32_t); |