dovecot-1.2: Use permissions based on mail root directory when c...

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 20 23:20:23 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/ab1c170b1559
changeset: 8037:ab1c170b1559
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 20 23:20:19 2008 +0300
description:
Use permissions based on mail root directory when creating new files/dirs under it.

diffstat:

11 files changed, 132 insertions(+), 49 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c     |    7 ++
src/lib-storage/index/dbox/dbox-storage.c       |    7 ++
src/lib-storage/index/index-storage.c           |   38 +++++++++++++--
src/lib-storage/index/maildir/maildir-storage.c |   58 +++++++++--------------
src/lib-storage/index/maildir/maildir-util.c    |    3 -
src/lib-storage/index/mbox/mbox-storage.c       |    7 +-
src/lib-storage/list/mailbox-list-fs.c          |    7 +-
src/lib-storage/list/subscription-file.c        |   13 +++--
src/lib-storage/mailbox-list.c                  |   15 +++++
src/lib-storage/mailbox-list.h                  |    4 +
src/plugins/quota/quota-maildir.c               |   22 +++++++-

diffs (truncated from 425 to 300 lines):

diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Sun Jul 20 23:20:19 2008 +0300
@@ -130,7 +130,12 @@ static int cydir_create(struct mail_stor
 
 static int create_cydir(struct mail_storage *storage, const char *path)
 {
-	if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
+	mode_t mode;
+	gid_t gid;
+
+	mailbox_list_get_dir_permissions(storage->list, &mode, &gid);
+	if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 &&
+	    errno != EEXIST) {
 		if (!mail_storage_set_error_from_errno(storage)) {
 			mail_storage_set_critical(storage,
 				"mkdir(%s) failed: %m", path);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Sun Jul 20 23:20:19 2008 +0300
@@ -146,7 +146,12 @@ static int dbox_create(struct mail_stora
 
 static int create_dbox(struct mail_storage *storage, const char *path)
 {
-	if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
+	mode_t mode;
+	gid_t gid;
+
+	mailbox_list_get_dir_permissions(storage->list, &mode, &gid);
+	if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 &&
+	    errno != EEXIST) {
 		if (!mail_storage_set_error_from_errno(storage)) {
 			mail_storage_set_critical(storage,
 				"mkdir(%s) failed: %m", path);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/index-storage.c	Sun Jul 20 23:20:19 2008 +0300
@@ -17,8 +17,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#define CREATE_MODE 0770 /* umask() should limit it more */
-
 #define DEFAULT_CACHE_FIELDS ""
 #define DEFAULT_NEVER_CACHE_FIELDS "imap.envelope"
 
@@ -69,9 +67,38 @@ static void index_list_free(struct index
 	i_free(list);
 }
 
+static int stat_parent(struct mail_storage *storage, const char *path,
+		       mode_t *mode_r, gid_t *gid_r)
+{
+	struct stat st;
+	const char *p;
+
+	while ((p = strrchr(path, '/')) != NULL) {
+		path = t_strdup_until(path, p);
+		if (stat(path, &st) == 0) {
+			*mode_r = st.st_mode;
+			*gid_r = (st.st_mode & S_ISGID) != 0 ||
+				st.st_gid == getegid() ?
+				(gid_t)-1 : st.st_gid;
+			return 0;
+		}
+		if (errno != ENOENT) {
+			mail_storage_set_critical(storage,
+						  "stat(%s) failed: %m", path);
+			return -1;
+		}
+	}
+	/* use default permissions */
+	*mode_r = 0700;
+	*gid_r = (gid_t)-1;
+	return 0;
+}
+
 static int create_index_dir(struct mail_storage *storage, const char *name)
 {
 	const char *root_dir, *index_dir;
+	mode_t mode;
+	gid_t gid;
 
 	root_dir = mailbox_list_get_path(storage->list, name,
 					 MAILBOX_LIST_PATH_TYPE_MAILBOX);
@@ -80,7 +107,12 @@ static int create_index_dir(struct mail_
 	if (strcmp(index_dir, root_dir) == 0 || *index_dir == '\0')
 		return 0;
 
-	if (mkdir_parents(index_dir, CREATE_MODE) < 0 && errno != EEXIST) {
+	/* get permissions from the parent directory */
+	if (stat_parent(storage, index_dir, &mode, &gid) < 0)
+		return -1;
+
+	if (mkdir_parents_chown(index_dir, mode, (uid_t)-1, gid) < 0 &&
+	    errno != EEXIST) {
 		mail_storage_set_critical(storage, "mkdir(%s) failed: %m",
 					  index_dir);
 		return -1;
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Sun Jul 20 23:20:19 2008 +0300
@@ -20,8 +20,6 @@
 #include <dirent.h>
 #include <unistd.h>
 #include <sys/stat.h>
-
-#define CREATE_MODE 0777 /* umask() should limit it more */
 
 #define MAILDIR_PLUSPLUS_DRIVER_NAME "maildir++"
 #define MAILDIR_SUBFOLDER_FILENAME "maildirfolder"
@@ -290,7 +288,7 @@ static bool maildir_autodetect(const cha
 }
 
 static int mkdir_verify(struct mail_storage *storage,
-			const char *dir, bool verify)
+			const char *dir, mode_t mode, gid_t gid, bool verify)
 {
 	struct stat st;
 
@@ -305,7 +303,7 @@ static int mkdir_verify(struct mail_stor
 		}
 	}
 
-	if (mkdir_parents(dir, CREATE_MODE) == 0)
+	if (mkdir_parents_chown(dir, mode, (uid_t)-1, gid) == 0)
 		return 0;
 
 	if (errno == EEXIST) {
@@ -355,8 +353,10 @@ static int maildir_check_tmp(struct mail
 
 /* create or fix maildir, ignore if it already exists */
 static int create_maildir(struct mail_storage *storage,
-			  const char *dir, bool verify)
-{
+			  const char *dir, mode_t mode, gid_t gid, bool verify)
+{
+	const char *path;
+	unsigned int i;
 	int ret;
 
 	ret = maildir_check_tmp(storage, dir);
@@ -372,12 +372,11 @@ static int create_maildir(struct mail_st
 		return -1;
 
 	/* doesn't exist, create */
-	if (mkdir_verify(storage, t_strconcat(dir, "/cur", NULL), verify) < 0)
-		return -1;
-	if (mkdir_verify(storage, t_strconcat(dir, "/new", NULL), verify) < 0)
-		return -1;
-	if (mkdir_verify(storage, t_strconcat(dir, "/tmp", NULL), verify) < 0)
-		return -1;
+	for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
+		path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
+		if (mkdir_verify(storage, path, mode, gid, verify) < 0)
+			return -1;
+	}
 	return 0;
 }
 
@@ -474,6 +473,8 @@ maildir_mailbox_open(struct mail_storage
 	struct maildir_storage *storage = (struct maildir_storage *)_storage;
 	const char *path;
 	struct stat st;
+	mode_t mode;
+	gid_t gid;
 	int ret;
 
 	if (input != NULL) {
@@ -488,7 +489,8 @@ maildir_mailbox_open(struct mail_storage
 	if (strcmp(name, "INBOX") == 0 &&
 	    (_storage->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
 		/* INBOX always exists */
-		if (create_maildir(_storage, path, TRUE) < 0)
+		mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+		if (create_maildir(_storage, path, mode, gid, TRUE) < 0)
 			return NULL;
 		return maildir_open(storage, "INBOX", flags);
 	}
@@ -506,7 +508,8 @@ maildir_mailbox_open(struct mail_storage
 	/* tmp/ directory doesn't exist. does the maildir? */
 	if (stat(path, &st) == 0) {
 		/* yes, we'll need to create the missing dirs */
-		if (create_maildir(_storage, path, TRUE) < 0)
+		mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+		if (create_maildir(_storage, path, mode, gid, TRUE) < 0)
 			return NULL;
 
 		return maildir_open(storage, name, flags);
@@ -526,7 +529,6 @@ static int maildir_create_shared(struct 
 {
 	const char *path;
 	mode_t old_mask;
-	unsigned int i;
 	int fd;
 
 	/* add the execute bit if either read or write bit is set */
@@ -534,23 +536,10 @@ static int maildir_create_shared(struct 
 	if ((mode & 0060) != 0) mode |= 0010;
 	if ((mode & 0006) != 0) mode |= 0001;
 
+	if (create_maildir(storage, dir, mode, gid, FALSE) < 0)
+		return -1;
+
 	old_mask = umask(0777 ^ mode);
-	if (create_maildir(storage, dir, FALSE) < 0) {
-		umask(old_mask);
-		return -1;
-	}
-	if (chown(dir, (uid_t)-1, gid) < 0) {
-		mail_storage_set_critical(storage,
-					  "chown(%s) failed: %m", dir);
-	}
-	for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
-		path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
-		if (chown(path, (uid_t)-1, gid) < 0) {
-			mail_storage_set_critical(storage,
-						  "chown(%s) failed: %m", path);
-		}
-	}
-
 	path = t_strconcat(dir, "/dovecot-shared", NULL);
 	fd = open(path, O_WRONLY | O_CREAT, mode & 0666);
 	umask(old_mask);
@@ -590,9 +579,10 @@ static int maildir_mailbox_create(struct
 					  st.st_mode & 0666, st.st_gid) < 0)
 			return -1;
 	} else {
-		st.st_mode = CREATE_MODE;
-		st.st_gid = (gid_t)-1;
-		if (create_maildir(_storage, path, FALSE) < 0)
+		mailbox_list_get_dir_permissions(_storage->list,
+						 &st.st_mode, &st.st_gid);
+		if (create_maildir(_storage, path, st.st_mode, st.st_gid,
+				   FALSE) < 0)
 			return -1;
 	}
 
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/maildir/maildir-util.c	Sun Jul 20 23:20:19 2008 +0300
@@ -115,7 +115,8 @@ static int maildir_create_subdirs(struct
 						  "stat(%s) failed: %m", path);
 			break;
 		}
-		if (mkdir_parents(path, box->dir_create_mode) < 0 &&
+		if (mkdir_parents_chown(path, box->dir_create_mode,
+					(uid_t)-1, box->file_create_gid) < 0 &&
 		    errno != EEXIST) {
 			if (errno == ENOENT) {
 				/* mailbox was being deleted just now */
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Jul 20 23:20:19 2008 +0300
@@ -692,8 +692,9 @@ static int mbox_mailbox_create(struct ma
 {
 	const char *path, *p;
 	struct stat st;
+	mode_t mode;
+	gid_t gid;
 	int fd;
-
 
 	/* make sure it doesn't exist already */
 	path = mailbox_list_get_path(_storage->list, name,
@@ -719,7 +720,9 @@ static int mbox_mailbox_create(struct ma
 	p = directory ? path + strlen(path) : strrchr(path, '/');
 	if (p != NULL) {
 		p = t_strdup_until(path, p);
-		if (mkdir_parents(p, CREATE_MODE) < 0 && errno != EEXIST) {
+		mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+		if (mkdir_parents_chown(p, mode, (uid_t)-1, gid) < 0 &&
+		    errno != EEXIST) {
 			if (!mail_storage_set_error_from_errno(_storage)) {
 				mail_storage_set_critical(_storage,
 					"mkdir_parents(%s) failed: %m", p);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/list/mailbox-list-fs.c
--- a/src/lib-storage/list/mailbox-list-fs.c	Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/list/mailbox-list-fs.c	Sun Jul 20 23:20:19 2008 +0300
@@ -11,7 +11,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#define CREATE_MODE 0770 /* umask() should limit it more */
 #define GLOBAL_TEMP_PREFIX ".temp."
 
 extern struct mailbox_list fs_mailbox_list;
@@ -283,6 +282,8 @@ static int fs_list_rename_mailbox(struct
 {
 	const char *oldpath, *newpath, *old_indexdir, *new_indexdir, *p;
 	struct stat st;
+	mode_t mode;
+	gid_t gid;
 
 	oldpath = mailbox_list_get_path(list, oldname,
 					MAILBOX_LIST_PATH_TYPE_DIR);
@@ -292,8 +293,10 @@ static int fs_list_rename_mailbox(struct
 	/* create the hierarchy */
 	p = strrchr(newpath, '/');
 	if (p != NULL) {


More information about the dovecot-cvs mailing list