summaryrefslogtreecommitdiffstats
path: root/usr.sbin/smtpd/queue_api.c
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2014-07-08 15:45:32 +0000
committereric <eric@openbsd.org>2014-07-08 15:45:32 +0000
commit98f67d1688f1b9fc1ab749b00f67fbe7f50e49a3 (patch)
treef8a8e9f7be599fee14e2d5170c13cfc872a38163 /usr.sbin/smtpd/queue_api.c
parentremove dead code. these imsgs are handled in pony.c. (diff)
downloadwireguard-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.
Diffstat (limited to 'usr.sbin/smtpd/queue_api.c')
-rw-r--r--usr.sbin/smtpd/queue_api.c73
1 files changed, 60 insertions, 13 deletions
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");
}