summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/queue_fsqueue.c123
-rw-r--r--usr.sbin/smtpd/smtpd.c9
-rw-r--r--usr.sbin/smtpd/smtpd.h3
-rw-r--r--usr.sbin/smtpd/util.c67
4 files changed, 82 insertions, 120 deletions
diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c
index 2b76f252308..b1de423f397 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.17 2011/11/06 16:57:27 eric Exp $ */
+/* $OpenBSD: queue_fsqueue.c,v 1.18 2011/11/14 11:53:10 eric Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -484,127 +484,18 @@ fsqueue_init(void)
{
unsigned int n;
char *paths[] = { PATH_INCOMING, PATH_ENQUEUE, PATH_QUEUE,
- PATH_PURGE, PATH_OFFLINE, PATH_BOUNCE,
- PATH_CORRUPT };
- char pathname[MAXPATHLEN];
- struct stat sb;
+ PATH_PURGE, PATH_BOUNCE, PATH_CORRUPT };
+ char path[MAXPATHLEN];
int ret;
- if (! bsnprintf(pathname, sizeof(pathname), "%s", PATH_SPOOL))
- fatal("snprintf");
-
- if (stat(pathname, &sb) == -1) {
- if (errno != ENOENT) {
- warn("stat: %s", pathname);
- return 0;
- }
-
- if (mkdir(pathname, 0711) == -1) {
- warn("mkdir: %s", pathname);
- return 0;
- }
-
- if (chown(pathname, 0, 0) == -1) {
- warn("chown: %s", pathname);
- return 0;
- }
-
- if (stat(pathname, &sb) == -1)
- err(1, "stat: %s", pathname);
- }
-
- /* check if it's a directory */
- if (!S_ISDIR(sb.st_mode)) {
- warnx("%s is not a directory", pathname);
- return 0;
- }
-
- /* check that it is owned by uid/gid */
- if (sb.st_uid != 0 || sb.st_gid != 0) {
- warnx("%s must be owned by root:wheel", pathname);
- return 0;
- }
-
- /* check permission */
- if ((sb.st_mode & (S_IRUSR|S_IWUSR|S_IXUSR)) != (S_IRUSR|S_IWUSR|S_IXUSR) ||
- (sb.st_mode & (S_IRGRP|S_IWGRP|S_IXGRP)) != S_IXGRP ||
- (sb.st_mode & (S_IROTH|S_IWOTH|S_IXOTH)) != S_IXOTH) {
- warnx("%s must be rwx--x--x (0711)", pathname);
- return 0;
- }
-
ret = 1;
for (n = 0; n < nitems(paths); n++) {
- mode_t mode;
- uid_t owner;
- gid_t group;
-
- if (!strcmp(paths[n], PATH_OFFLINE)) {
- mode = 01777;
- owner = 0;
- group = 0;
- } else {
- mode = 0700;
- owner = env->sc_pw->pw_uid;
- group = 0;
- }
-
- if (! bsnprintf(pathname, sizeof(pathname), "%s%s", PATH_SPOOL,
- paths[n]))
- fatal("snprintf");
-
- if (stat(pathname, &sb) == -1) {
- if (errno != ENOENT) {
- warn("stat: %s", pathname);
- ret = 0;
- continue;
- }
-
- /* chmod is deffered to avoid umask effect */
- if (mkdir(pathname, 0) == -1) {
- ret = 0;
- warn("mkdir: %s", pathname);
- }
-
- if (chown(pathname, owner, group) == -1) {
- ret = 0;
- warn("chown: %s", pathname);
- }
-
- if (chmod(pathname, mode) == -1) {
- ret = 0;
- warn("chmod: %s", pathname);
- }
-
- if (stat(pathname, &sb) == -1)
- err(1, "stat: %s", pathname);
- }
-
- /* check if it's a directory */
- if (!S_ISDIR(sb.st_mode)) {
- ret = 0;
- warnx("%s is not a directory", pathname);
- }
+ strlcpy(path, PATH_SPOOL, sizeof(path));
+ if (strlcat(path, paths[n], sizeof(path)) >= sizeof(path))
+ errx(1, "path too long %s%s", PATH_SPOOL, paths[n]);
- /* check that it is owned by owner/group */
- if (sb.st_uid != owner) {
+ if (ckdir(path, 0700, env->sc_pw->pw_uid, 0, 1) == 0)
ret = 0;
- warnx("%s is not owned by uid %d", pathname, owner);
- }
- if (sb.st_gid != group) {
- ret = 0;
- warnx("%s is not owned by gid %d", pathname, group);
- }
-
- /* check permission */
- if ((sb.st_mode & 07777) != mode) {
- char mode_str[12];
-
- ret = 0;
- strmode(mode, mode_str);
- mode_str[10] = '\0';
- warnx("%s must be %s (%o)", pathname, mode_str + 1, mode);
- }
}
return ret;
}
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 90d95a2b6e9..17c01be3a36 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.135 2011/11/07 11:14:10 eric Exp $ */
+/* $OpenBSD: smtpd.c,v 1.136 2011/11/14 11:53:10 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -488,12 +488,17 @@ main(int argc, char *argv[])
if ((env->sc_pw = getpwnam(SMTPD_USER)) == NULL)
errx(1, "unknown user %s", SMTPD_USER);
+ if (ckdir(PATH_SPOOL, 0711, 0, 0, 1) == 0)
+ errx(1, "error in spool directory setup");
+ if (ckdir(PATH_SPOOL PATH_OFFLINE, 01777, 0, 0, 1) == 0)
+ errx(1, "error in offline directory setup");
+
env->sc_queue = queue_backend_lookup(QT_FS);
if (env->sc_queue == NULL)
errx(1, "could not find queue backend");
if (!env->sc_queue->init())
- errx(1, "invalid directory permissions");
+ errx(1, "could not initialize queue backend");
log_init(debug);
log_verbose(verbose);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index bf16fbbbe8d..cc2b2f0596f 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.248 2011/11/07 11:14:10 eric Exp $ */
+/* $OpenBSD: smtpd.h,v 1.249 2011/11/14 11:53:10 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -1226,3 +1226,4 @@ u_int64_t msgid_to_evpid(u_int32_t);
u_int32_t filename_to_msgid(char *);
u_int64_t filename_to_evpid(char *);
void log_imsg(int, int, struct imsg*);
+int ckdir(const char *, mode_t, uid_t, gid_t, int);
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index a627e5ae89d..e11307142dd 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.49 2011/10/27 14:32:57 chl Exp $ */
+/* $OpenBSD: util.c,v 1.50 2011/11/14 11:53:10 eric Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@@ -66,6 +66,71 @@ bsnprintf(char *str, size_t size, const char *format, ...)
return 1;
}
+int
+ckdir(const char *path, mode_t mode, uid_t owner, gid_t group, int create)
+{
+ char mode_str[12];
+ int ret;
+ struct stat sb;
+
+ if (stat(path, &sb) == -1) {
+ if (errno != ENOENT || create == 0) {
+ warn("stat: %s", path);
+ return (0);
+ }
+
+ /* chmod is deferred to avoid umask effect */
+ if (mkdir(path, 0) == -1) {
+ warn("mkdir: %s", path);
+ return (0);
+ }
+
+ if (chown(path, owner, group) == -1) {
+ warn("chown: %s", path);
+ return (0);
+ }
+
+ if (chmod(path, mode) == -1) {
+ warn("chmod: %s", path);
+ return (0);
+ }
+
+ if (stat(path, &sb) == -1) {
+ warn("stat: %s", path);
+ return (0);
+ }
+ }
+
+ ret = 1;
+
+ /* check if it's a directory */
+ if (!S_ISDIR(sb.st_mode)) {
+ ret = 0;
+ warnx("%s is not a directory", path);
+ }
+
+ /* check that it is owned by owner/group */
+ if (sb.st_uid != owner) {
+ ret = 0;
+ warnx("%s is not owned by uid %d", path, owner);
+ }
+ if (sb.st_gid != group) {
+ ret = 0;
+ warnx("%s is not owned by gid %d", path, group);
+ }
+
+ /* check permission */
+ if ((sb.st_mode & 07777) != mode) {
+ ret = 0;
+ strmode(mode, mode_str);
+ mode_str[10] = '\0';
+ warnx("%s must be %s (%o)", path, mode_str + 1, mode);
+ }
+
+ return ret;
+}
+
+
/* Close file, signifying temporary error condition (if any) to the caller. */
int
safe_fclose(FILE *fp)