summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd/smtpd.c')
-rw-r--r--usr.sbin/smtpd/smtpd.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 8b4ab17ed4a..0c8c3281427 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.39 2009/03/03 15:47:27 gilles Exp $ */
+/* $OpenBSD: smtpd.c,v 1.40 2009/03/03 23:23:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -65,6 +65,7 @@ int parent_mailfile_rename(struct batch *, struct path *);
int parent_maildir_open(char *, struct passwd *, struct batch *);
int parent_maildir_init(struct passwd *, char *);
int parent_external_mda(char *, struct passwd *, struct batch *);
+int parent_forward_open(char *);
int check_child(pid_t, const char *);
int setup_spool(uid_t, gid_t);
@@ -190,6 +191,19 @@ parent_dispatch_lka(int fd, short event, void *p)
break;
switch (imsg.hdr.type) {
+ case IMSG_PARENT_FORWARD_OPEN: {
+ int ret;
+ struct forward_req *fwreq;
+
+ fwreq = imsg.data;
+ ret = parent_forward_open(fwreq->pw_name);
+ if (ret == -1)
+ if (errno == ENOENT)
+ fwreq->pw_name[0] = '\0';
+ log_debug("parent will return fd %d", fd);
+ imsg_compose(ibuf, IMSG_PARENT_FORWARD_OPEN, 0, 0, ret, fwreq, sizeof(*fwreq));
+ break;
+ }
default:
log_debug("parent_dispatch_lka: unexpected imsg %d",
imsg.hdr.type);
@@ -1183,6 +1197,52 @@ lockfail:
}
int
+parent_forward_open(char *username)
+{
+ struct passwd *pw;
+ struct stat sb;
+ char pathname[MAXPATHLEN];
+ int fd;
+
+ pw = safe_getpwnam(username);
+ if (pw == NULL)
+ return -1;
+
+ if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", pw->pw_dir))
+ return -1;
+
+ fd = open(pathname, O_RDONLY);
+ if (fd == -1) {
+ if (errno == ENOENT)
+ goto clear;
+ return -1;
+ }
+
+ /* make sure ~/ is not writable by anyone but owner */
+ if (stat(pw->pw_dir, &sb) == -1)
+ goto clearlog;
+
+ if (sb.st_uid != pw->pw_uid || sb.st_mode & (S_IWGRP|S_IWOTH))
+ goto clearlog;
+
+ /* make sure ~/.forward is not writable by anyone but owner */
+ if (fstat(fd, &sb) == -1)
+ goto clearlog;
+
+ if (sb.st_uid != pw->pw_uid || sb.st_mode & (S_IWGRP|S_IWOTH))
+ goto clearlog;
+
+ return fd;
+
+clearlog:
+ log_info("cannot process forward file for user %s due to wrong permissions", username);
+
+clear:
+ username[0] = '\0';
+ return -1;
+}
+
+int
mdaproc_cmp(struct mdaproc *s1, struct mdaproc *s2)
{
if (s1->pid < s2->pid)