diff options
author | 2014-07-08 15:45:32 +0000 | |
---|---|---|
committer | 2014-07-08 15:45:32 +0000 | |
commit | 98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3 (patch) | |
tree | f8a8e9f7be599fee14e2d5170c13cfc872a38163 | |
parent | remove dead code. these imsgs are handled in pony.c. (diff) | |
download | wireguard-openbsd-98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3.tar.xz wireguard-openbsd-98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3.zip |
various queue improvements:
- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.
-rw-r--r-- | usr.sbin/smtpd/queue.c | 3 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_api.c | 73 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_backend.c | 35 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_fs.c | 9 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_null.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_proc.c | 63 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_ram.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd-api.h | 7 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 5 |
9 files changed, 128 insertions, 75 deletions
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index 5f68ad86f86..4e26fe600c3 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.162 2014/04/19 13:40:24 gilles Exp $ */ +/* $OpenBSD: queue.c,v 1.163 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -561,6 +561,7 @@ static void queue_shutdown(void) { log_info("info: queue handler exiting"); + queue_close(); _exit(0); } diff --git a/usr.sbin/smtpd/queue_api.c b/usr.sbin/smtpd/queue_api.c index 5c42537d236..80561410203 100644 --- a/usr.sbin/smtpd/queue_api.c +++ b/usr.sbin/smtpd/queue_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_api.c,v 1.4 2014/04/19 17:47:40 gilles Exp $ */ +/* $OpenBSD: queue_api.c,v 1.5 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -31,6 +31,7 @@ #include "smtpd-api.h" #include "log.h" +static int (*handler_close)(void); static int (*handler_message_create)(uint32_t *); static int (*handler_message_commit)(uint32_t, const char *); static int (*handler_message_delete)(uint32_t); @@ -47,8 +48,8 @@ static struct imsg imsg; static size_t rlen; static char *rdata; static struct ibuf *buf; -static char *rootpath = PATH_SPOOL; -static char *user = SMTPD_QUEUE_USER; +static const char *rootpath = PATH_SPOOL; +static const char *user = SMTPD_QUEUE_USER; static void queue_msg_get(void *dst, size_t len) @@ -105,7 +106,7 @@ queue_msg_dispatch(void) { uint64_t evpid; uint32_t msgid, version; - size_t n; + size_t n, m; char buffer[8192], path[SMTPD_MAXPATHLEN]; int r, fd; FILE *ifile, *ofile; @@ -123,6 +124,17 @@ queue_msg_dispatch(void) imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, NULL, 0); break; + case PROC_QUEUE_CLOSE: + queue_msg_end(); + + if (handler_close) + r = handler_close(); + else + r = 1; + + imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r)); + break; + case PROC_QUEUE_MESSAGE_CREATE: queue_msg_end(); @@ -157,13 +169,20 @@ queue_msg_dispatch(void) else { ifile = fdopen(imsg.fd, "r"); ofile = fdopen(fd, "w"); + m = n = 0; if (ifile && ofile) { while (!feof(ifile)) { n = fread(buffer, 1, sizeof(buffer), ifile); - fwrite(buffer, 1, n, ofile); + m = fwrite(buffer, 1, n, ofile); + if (m != n) + break; + fflush(ofile); } - r = handler_message_commit(msgid, path); + if (m != n) + r = 0; + else + r = handler_message_commit(msgid, path); } if (ifile) fclose(ifile); @@ -242,6 +261,7 @@ queue_msg_dispatch(void) queue_msg_add(buffer, r); } queue_msg_close(); + break; default: log_warnx("warn: queue-api: bad message %d", imsg.hdr.type); @@ -250,6 +270,12 @@ queue_msg_dispatch(void) } void +queue_api_on_close(int(*cb)(void)) +{ + handler_close = cb; +} + +void queue_api_on_message_create(int(*cb)(uint32_t *)) { handler_message_create = cb; @@ -309,16 +335,36 @@ queue_api_on_envelope_walk(int(*cb)(uint64_t *, char *, size_t)) handler_envelope_walk = cb; } +void +queue_api_no_chroot(void) +{ + rootpath = NULL; +} + +void +queue_api_set_chroot(const char *path) +{ + rootpath = path; +} + +void +queue_api_set_user(const char *username) +{ + user = username; +} + int queue_api_dispatch(void) { - struct passwd *pw; + struct passwd *pw = NULL; ssize_t n; - pw = getpwnam(user); - if (pw == NULL) { - log_warn("queue-api: getpwnam"); - fatalx("queue-api: exiting"); + if (user) { + pw = getpwnam(user); + if (pw == NULL) { + log_warn("queue-api: getpwnam"); + fatalx("queue-api: exiting"); + } } if (rootpath) { @@ -332,9 +378,10 @@ queue_api_dispatch(void) } } - if (setgroups(1, &pw->pw_gid) || + if (pw && + (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { + setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))) { log_warn("queue-api: cannot drop privileges"); fatalx("queue-api: exiting"); } diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c index 27a0ea56537..d70213cebbb 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.51 2014/07/07 09:11:24 eric Exp $ */ +/* $OpenBSD: queue_backend.c,v 1.52 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org> @@ -57,6 +57,7 @@ static struct tree evpcache_tree; static struct evplst evpcache_list; static struct queue_backend *backend; +static int (*handler_close)(void); static int (*handler_message_create)(uint32_t *); static int (*handler_message_commit)(uint32_t, const char*); static int (*handler_message_delete)(uint32_t); @@ -122,17 +123,12 @@ queue_init(const char *name, int server) if (!strcmp(name, "fs")) backend = &queue_backend_fs; - if (!strcmp(name, "null")) + else if (!strcmp(name, "null")) backend = &queue_backend_null; - if (!strcmp(name, "proc")) - backend = &queue_backend_proc; - if (!strcmp(name, "ram")) + else if (!strcmp(name, "ram")) backend = &queue_backend_ram; - - if (backend == NULL) { - log_warn("could not find queue backend \"%s\"", name); - return (0); - } + else + backend = &queue_backend_proc; if (server) { if (ckdir(PATH_SPOOL, 0711, 0, 0, 1) == 0) @@ -148,7 +144,7 @@ queue_init(const char *name, int server) errx(1, "error in purge directory setup"); } - r = backend->init(pwq, server); + r = backend->init(pwq, server, name); log_trace(TRACE_QUEUE, "queue-backend: queue_init(%d) -> %d", server, r); @@ -156,6 +152,15 @@ queue_init(const char *name, int server) } int +queue_close(void) +{ + if (handler_close) + return (handler_close()); + + return (1); +} + +int queue_message_create(uint32_t *msgid) { int r; @@ -634,9 +639,9 @@ queue_envelope_walk(struct envelope *ep) } log_debug("debug: invalid envelope %016" PRIx64 ": %s", ep->id, e); + (void)queue_message_corrupt(evpid_to_msgid(evpid)); } - (void)queue_message_corrupt(evpid_to_msgid(evpid)); return (0); } @@ -690,6 +695,12 @@ envelope_validate(struct envelope *ep) } void +queue_api_on_close(int(*cb)(void)) +{ + handler_close = cb; +} + +void queue_api_on_message_create(int(*cb)(uint32_t *)) { handler_message_create = cb; diff --git a/usr.sbin/smtpd/queue_fs.c b/usr.sbin/smtpd/queue_fs.c index 6bca248955d..2541e00c085 100644 --- a/usr.sbin/smtpd/queue_fs.c +++ b/usr.sbin/smtpd/queue_fs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_fs.c,v 1.5 2014/04/19 13:48:57 gilles Exp $ */ +/* $OpenBSD: queue_fs.c,v 1.6 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org> @@ -166,6 +166,9 @@ queue_fs_message_commit(uint32_t msgid, const char *path) return 0; } + /* best effort */ + sync(); + return 1; } @@ -263,7 +266,7 @@ queue_fs_envelope_create(uint32_t msgid, const char *buf, size_t len, fsqueue_envelope_incoming_path(*evpid, path, sizeof(path)); - r = fsqueue_envelope_dump(path, buf, len, 0, 1); + r = fsqueue_envelope_dump(path, buf, len, 0, 0); if (r >= 0) goto done; } @@ -615,7 +618,7 @@ fsqueue_qwalk(void *hdl, uint64_t *evpid) } static int -queue_fs_init(struct passwd *pw, int server) +queue_fs_init(struct passwd *pw, int server, const char *conf) { unsigned int n; char *paths[] = { PATH_QUEUE, PATH_CORRUPT, PATH_INCOMING }; diff --git a/usr.sbin/smtpd/queue_null.c b/usr.sbin/smtpd/queue_null.c index 31f87af0371..fcc52b845bb 100644 --- a/usr.sbin/smtpd/queue_null.c +++ b/usr.sbin/smtpd/queue_null.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_null.c,v 1.4 2013/07/19 20:37:07 eric Exp $ */ +/* $OpenBSD: queue_null.c,v 1.5 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> @@ -104,7 +104,7 @@ queue_null_envelope_walk(uint64_t *evpid, char *buf, size_t len) } static int -queue_null_init(struct passwd *pw, int server) +queue_null_init(struct passwd *pw, int server, const char *conf) { queue_api_on_message_create(queue_null_message_create); queue_api_on_message_commit(queue_null_message_commit); diff --git a/usr.sbin/smtpd/queue_proc.c b/usr.sbin/smtpd/queue_proc.c index 24efd905f96..da321715e16 100644 --- a/usr.sbin/smtpd/queue_proc.c +++ b/usr.sbin/smtpd/queue_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_proc.c,v 1.2 2013/10/27 18:21:07 eric Exp $ */ +/* $OpenBSD: queue_proc.c,v 1.3 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -24,8 +24,6 @@ #include <sys/stat.h> #include <ctype.h> -#include <err.h> -#include <errno.h> #include <event.h> #include <fcntl.h> #include <imsg.h> @@ -41,14 +39,11 @@ #include "smtpd.h" #include "log.h" -static pid_t pid; static struct imsgbuf ibuf; static struct imsg imsg; static size_t rlen; static char *rdata; -static const char *execpath = "/usr/libexec/smtpd/backend-queue"; - static void queue_proc_call(void) { @@ -117,6 +112,20 @@ queue_proc_end(void) */ static int +queue_proc_close(void) +{ + int r; + + imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, NULL, 0); + + queue_proc_call(); + queue_proc_read(&r, sizeof(r)); + queue_proc_end(); + + return (r); +} + +static int queue_proc_message_create(uint32_t *msgid) { int r; @@ -270,7 +279,7 @@ queue_proc_envelope_load(uint64_t evpid, char *buf, size_t len) } r = rlen; - queue_proc_read(&buf, rlen); + queue_proc_read(buf, rlen); queue_proc_end(); return (r); @@ -296,7 +305,7 @@ queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len) log_warnx("warn: queue-proc: len mismatch"); fatalx("queue-proc: exiting"); } - queue_proc_read(&buf, rlen); + queue_proc_read(buf, rlen); } queue_proc_end(); @@ -304,41 +313,22 @@ queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len) } static int -queue_proc_init(struct passwd *pw, int server) +queue_proc_init(struct passwd *pw, int server, const char *conf) { - int sp[2]; uint32_t version; + int fd; - errno = 0; - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { - log_warn("warn: queue-proc: socketpair"); - return (0); - } - - if ((pid = fork()) == -1) { - log_warn("warn: queue-proc: fork"); - goto err; - } - - if (pid == 0) { - /* child process */ - dup2(sp[0], STDIN_FILENO); - if (closefrom(STDERR_FILENO + 1) < 0) - exit(1); - - execl(execpath, "queue_ramproc", NULL); - err(1, "execl"); - } + fd = fork_proc_backend("queue", conf, "queue-proc"); + if (fd == -1) + fatalx("queue-proc: exiting"); - /* parent process */ - close(sp[0]); - imsg_init(&ibuf, sp[1]); + imsg_init(&ibuf, fd); version = PROC_QUEUE_API_VERSION; imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1, &version, sizeof(version)); + queue_api_on_close(queue_proc_close); queue_api_on_message_create(queue_proc_message_create); queue_api_on_message_commit(queue_proc_message_commit); queue_api_on_message_delete(queue_proc_message_delete); @@ -354,11 +344,6 @@ queue_proc_init(struct passwd *pw, int server) queue_proc_end(); return (1); - -err: - close(sp[0]); - close(sp[1]); - return (0); } struct queue_backend queue_backend_proc = { diff --git a/usr.sbin/smtpd/queue_ram.c b/usr.sbin/smtpd/queue_ram.c index 41c7a39b17b..24f2f5cf381 100644 --- a/usr.sbin/smtpd/queue_ram.c +++ b/usr.sbin/smtpd/queue_ram.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_ram.c,v 1.5 2013/07/19 20:37:07 eric Exp $ */ +/* $OpenBSD: queue_ram.c,v 1.6 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> @@ -318,7 +318,7 @@ queue_ram_envelope_walk(uint64_t *evpid, char *buf, size_t len) } static int -queue_ram_init(struct passwd *pw, int server) +queue_ram_init(struct passwd *pw, int server, const char * conf) { tree_init(&messages); diff --git a/usr.sbin/smtpd/smtpd-api.h b/usr.sbin/smtpd/smtpd-api.h index f1c9fc23d95..5b3629caf8a 100644 --- a/usr.sbin/smtpd/smtpd-api.h +++ b/usr.sbin/smtpd/smtpd-api.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd-api.h,v 1.18 2014/07/08 14:24:16 eric Exp $ */ +/* $OpenBSD: smtpd-api.h,v 1.19 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -108,6 +108,7 @@ enum { PROC_QUEUE_OK, PROC_QUEUE_FAIL, PROC_QUEUE_INIT, + PROC_QUEUE_CLOSE, PROC_QUEUE_MESSAGE_CREATE, PROC_QUEUE_MESSAGE_DELETE, PROC_QUEUE_MESSAGE_COMMIT, @@ -362,6 +363,7 @@ void filter_api_on_dataline(void(*)(uint64_t, const char *)); void filter_api_on_eom(int(*)(uint64_t, size_t)); /* queue */ +void queue_api_on_close(int(*)(void)); void queue_api_on_message_create(int(*)(uint32_t *)); void queue_api_on_message_commit(int(*)(uint32_t, const char*)); void queue_api_on_message_delete(int(*)(uint32_t)); @@ -372,6 +374,9 @@ void queue_api_on_envelope_delete(int(*)(uint64_t)); void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t)); void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t)); void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t)); +void queue_api_no_chroot(void); +void queue_api_set_chroot(const char *); +void queue_api_set_user(const char *); int queue_api_dispatch(void); /* scheduler */ diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index d39eb0e629e..b9148c88e5c 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.462 2014/07/08 13:49:09 eric Exp $ */ +/* $OpenBSD: smtpd.h,v 1.463 2014/07/08 15:45:32 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -832,7 +832,7 @@ struct mta_task { struct passwd; struct queue_backend { - int (*init)(struct passwd *, int); + int (*init)(struct passwd *, int, const char *); }; struct compress_backend { @@ -1280,6 +1280,7 @@ void queue_flow_control(void); uint32_t queue_generate_msgid(void); uint64_t queue_generate_evpid(uint32_t); int queue_init(const char *, int); +int queue_close(void); int queue_message_create(uint32_t *); int queue_message_delete(uint32_t); int queue_message_commit(uint32_t); |