diff options
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 820c6750c28..9e55df0cfcb 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.239 2015/06/03 02:24:36 millert Exp $ */ +/* $OpenBSD: smtpd.c,v 1.240 2015/10/02 00:37:53 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -352,7 +352,8 @@ parent_sig_handler(int sig, short event, void *p) } else len = asprintf(&cause, "exited okay"); } else - fatalx("smtpd: unexpected cause of SIGCHLD"); + /* WIFSTOPPED or WIFCONTINUED */ + continue; if (len == -1) fatal("asprintf"); @@ -1073,19 +1074,34 @@ offline_enqueue(char *name) if (pid == 0) { char *envp[2], *p, *tmp; + int fd; FILE *fp; size_t len; arglist args; + if (closefrom(STDERR_FILENO + 1) == -1) + _exit(1); + memset(&args, 0, sizeof(args)); - if (lstat(path, &sb) == -1) { - log_warn("warn: smtpd: lstat: %s", path); + if ((fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK)) == -1) { + log_warn("warn: smtpd: open: %s", path); _exit(1); } - if (chflags(path, 0) == -1) { - log_warn("warn: smtpd: chflags: %s", path); + if (fstat(fd, &sb) == -1) { + log_warn("warn: smtpd: fstat: %s", path); + _exit(1); + } + + if (! S_ISREG(sb.st_mode)) { + log_warnx("warn: smtpd: file %s (uid %d) not regular", + path, sb.st_uid); + _exit(1); + } + + if (sb.st_nlink != 1) { + log_warnx("warn: smtpd: file %s is hard-link", path); _exit(1); } @@ -1096,19 +1112,17 @@ offline_enqueue(char *name) _exit(1); } - if (! S_ISREG(sb.st_mode)) { - log_warnx("warn: smtpd: file %s (uid %d) not regular", - path, sb.st_uid); + if (fchflags(fd, 0) == -1) { + log_warn("warn: smtpd: chflags: %s", path); _exit(1); } if (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) || - closefrom(STDERR_FILENO + 1) == -1) + setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) _exit(1); - if ((fp = fopen(path, "r")) == NULL) + if ((fp = fdopen(fd, "r")) == NULL) _exit(1); if (chdir(pw->pw_dir) == -1 && chdir("/") == -1) @@ -1208,7 +1222,7 @@ parent_forward_open(char *username, char *directory, uid_t uid, gid_t gid) } do { - fd = open(pathname, O_RDONLY); + fd = open(pathname, O_RDONLY|O_NOFOLLOW|O_NONBLOCK); } while (fd == -1 && errno == EINTR); if (fd == -1) { if (errno == ENOENT) @@ -1217,7 +1231,11 @@ parent_forward_open(char *username, char *directory, uid_t uid, gid_t gid) errno = EAGAIN; return -1; } - log_warn("warn: smtpd: parent_forward_open: %s", pathname); + if (errno == ELOOP) + log_warnx("warn: smtpd: parent_forward_open: %s: " + "cannot follow symbolic links", pathname); + else + log_warn("warn: smtpd: parent_forward_open: %s", pathname); return -1; } |