dovecot-2.0: When creating shared directories, preserve parent d...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jun 4 20:05:35 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/0dfd28b930b3
changeset: 11477:0dfd28b930b3
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jun 04 18:05:28 2010 +0100
description:
When creating shared directories, preserve parent dir's permissions if it has setgid bit enabled.
This works only if location path uses %variables. The directories up to
last variable are created by preserving parent directory's modes, while
the rest of the directories are created with 0700. For example
with "/var/mail/%d/%2n/%n/Maildir", "/var/mail/domain/nn" preserves /var/mail's
permissions, while the "username/Maildir" directories have 0700 mode.

diffstat:

 src/lib-storage/index/dbox-multi/mdbox-file.c        |   12 +-
 src/lib-storage/index/dbox-multi/mdbox-map-private.h |    3 +-
 src/lib-storage/index/dbox-multi/mdbox-map.c         |   14 +-
 src/lib-storage/index/index-storage.c                |   19 +-
 src/lib-storage/index/maildir/maildir-util.c         |   29 ++--
 src/lib-storage/mail-namespace.c                     |   17 +-
 src/lib-storage/mail-namespace.h                     |    2 +-
 src/lib-storage/mailbox-list-private.h               |    4 +
 src/lib-storage/mailbox-list.c                       |  154 ++++++++++++++++++++++
 9 files changed, 205 insertions(+), 49 deletions(-)

diffs (truncated from 468 to 300 lines):

diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/index/dbox-multi/mdbox-file.c
--- a/src/lib-storage/index/dbox-multi/mdbox-file.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/index/dbox-multi/mdbox-file.c	Fri Jun 04 18:05:28 2010 +0100
@@ -13,6 +13,7 @@
 #include "fdatasync-path.h"
 #include "eacces-error.h"
 #include "str.h"
+#include "mailbox-list-private.h"
 #include "mdbox-storage.h"
 #include "mdbox-map-private.h"
 #include "mdbox-file.h"
@@ -275,11 +276,12 @@
 	if (fd == -1 && errno == ENOENT && parents &&
 	    (p = strrchr(path, '/')) != NULL) {
 		dir = t_strdup_until(path, p);
-		if (mkdir_parents_chgrp(dir, map->create_dir_mode,
-					map->create_gid,
-					map->create_gid_origin) < 0) {
-			mail_storage_set_critical(&file->storage->storage,
-				"mkdir_parents(%s) failed: %m", dir);
+		if (mailbox_list_mkdir(map->root_list, dir,
+				       path != file->alt_path ?
+				       MAILBOX_LIST_PATH_TYPE_DIR :
+				       MAILBOX_LIST_PATH_TYPE_ALT_DIR) < 0) {
+			mail_storage_copy_list_error(&file->storage->storage,
+						     map->root_list);
 			return -1;
 		}
 		/* try again */
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/index/dbox-multi/mdbox-map-private.h
--- a/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Fri Jun 04 18:05:28 2010 +0100
@@ -20,7 +20,8 @@
 
 	uint32_t map_ext_id, ref_ext_id;
 
-	mode_t create_mode, create_dir_mode;
+	struct mailbox_list *root_list;
+	mode_t create_mode;
 	gid_t create_gid;
 	const char *create_gid_origin;
 };
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/index/dbox-multi/mdbox-map.c
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c	Fri Jun 04 18:05:28 2010 +0100
@@ -6,6 +6,7 @@
 #include "ostream.h"
 #include "mkdir-parents.h"
 #include "unlink-old-files.h"
+#include "mailbox-list-private.h"
 #include "mdbox-storage.h"
 #include "mdbox-file.h"
 #include "mdbox-map-private.h"
@@ -48,14 +49,13 @@
 	       const char *path)
 {
 	struct mdbox_map *map;
-	gid_t tmp_gid;
-	const char *tmp_origin;
 
 	map = i_new(struct mdbox_map, 1);
 	map->storage = storage;
 	map->set = storage->set;
 	map->path = i_strdup(path);
 	map->index = mail_index_alloc(path, MDBOX_GLOBAL_INDEX_PREFIX);
+	map->root_list = root_list;
 	map->map_ext_id = mail_index_ext_register(map->index, "map",
 				sizeof(struct mdbox_map_mail_index_header),
 				sizeof(struct mdbox_map_mail_index_record),
@@ -66,8 +66,6 @@
 
 	mailbox_list_get_permissions(root_list, NULL, &map->create_mode,
 				     &map->create_gid, &map->create_gid_origin);
-	mailbox_list_get_dir_permissions(root_list, NULL, &map->create_dir_mode,
-					 &tmp_gid, &tmp_origin);
 	mail_index_set_permissions(map->index, map->create_mode,
 				   map->create_gid, map->create_gid_origin);
 	return map;
@@ -90,11 +88,9 @@
 
 static int mdbox_map_mkdir_storage(struct mdbox_map *map)
 {
-	if (mkdir_parents_chgrp(map->path, map->create_dir_mode,
-				map->create_gid, map->create_gid_origin) < 0 &&
-	    errno != EEXIST) {
-		mail_storage_set_critical(MAP_STORAGE(map),
-					  "mkdir(%s) failed: %m", map->path);
+	if (mailbox_list_mkdir(map->root_list, map->path,
+			       MAILBOX_LIST_PATH_TYPE_DIR) < 0) {
+		mail_storage_copy_list_error(MAP_STORAGE(map), map->root_list);
 		return -1;
 	}
 	return 0;
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/index/index-storage.c	Fri Jun 04 18:05:28 2010 +0100
@@ -29,11 +29,10 @@
 int index_list_create_missing_index_dir(struct mailbox_list *list,
 					const char *name)
 {
-	const char *root_dir, *index_dir, *p, *parent_dir;
-	const char *origin, *parent_origin;
-	mode_t mode, parent_mode;
-	gid_t gid, parent_gid;
-	int n = 0;
+	const char *root_dir, *index_dir, *parent_dir, *p, *origin;
+	mode_t mode;
+	gid_t gid;
+	unsigned int n = 0;
 
 	root_dir = mailbox_list_get_path(list, name,
 					 MAILBOX_LIST_PATH_TYPE_MAILBOX);
@@ -54,16 +53,10 @@
 			return -1;
 		}
 		/* create the parent directory first */
-		mailbox_list_get_dir_permissions(list, NULL, &parent_mode,
-						 &parent_gid, &parent_origin);
 		parent_dir = t_strdup_until(index_dir, p);
-		if (mkdir_parents_chgrp(parent_dir, parent_mode,
-					parent_gid, parent_origin) < 0 &&
-		    errno != EEXIST) {
-			mailbox_list_set_critical(list,
-				"mkdir(%s) failed: %m", parent_dir);
+		if (mailbox_list_mkdir(list, parent_dir,
+				       MAILBOX_LIST_PATH_TYPE_INDEX) < 0)
 			return -1;
-		}
 	}
 	return 0;
 }
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-util.c	Fri Jun 04 18:05:28 2010 +0100
@@ -5,6 +5,7 @@
 #include "ioloop.h"
 #include "str.h"
 #include "mkdir-parents.h"
+#include "mailbox-list-private.h"
 #include "maildir-storage.h"
 #include "maildir-uidlist.h"
 #include "maildir-keywords.h"
@@ -131,11 +132,9 @@
 }
 
 static int maildir_create_path(struct mailbox *box, const char *path,
-			       bool is_mail_dir)
+			       enum mailbox_list_path_type type, bool retry)
 {
-	const char *p, *parent, *origin;
-	mode_t parent_mode;
-	gid_t parent_gid;
+	const char *p, *parent;
 
 	if (mkdir_chgrp(path, box->dir_create_mode, box->file_create_gid,
 			box->file_create_gid_origin) == 0)
@@ -146,20 +145,17 @@
 		return 0;
 	case ENOENT:
 		p = strrchr(path, '/');
-		if (is_mail_dir || p == NULL) {
+		if (type == MAILBOX_LIST_PATH_TYPE_MAILBOX ||
+		    p == NULL || !retry) {
 			/* mailbox was being deleted just now */
 			mailbox_set_deleted(box);
 			return -1;
 		}
 		/* create index/control root directory */
 		parent = t_strdup_until(path, p);
-		mailbox_list_get_dir_permissions(box->list, NULL, &parent_mode,
-						 &parent_gid, &origin);
-		if (mkdir_parents_chgrp(parent, parent_mode, parent_gid,
-					origin) == 0 ||
-		    errno == EEXIST) {
+		if (mailbox_list_mkdir(box->list, parent, type) == 0) {
 			/* should work now, try again */
-			return maildir_create_path(box, path, TRUE);
+			return maildir_create_path(box, path, type, FALSE);
 		}
 		/* fall through */
 		path = parent;
@@ -174,16 +170,20 @@
 {
 	static const char *subdirs[] = { "cur", "new", "tmp" };
 	const char *dirs[N_ELEMENTS(subdirs) + 2];
+	enum mailbox_list_path_type types[N_ELEMENTS(subdirs) + 2];
 	struct stat st;
 	const char *path;
 	unsigned int i;
-	bool is_mail_dir;
 
 	/* @UNSAFE: get a list of directories we want to create */
-	for (i = 0; i < N_ELEMENTS(subdirs); i++)
+	for (i = 0; i < N_ELEMENTS(subdirs); i++) {
+		types[i] = MAILBOX_LIST_PATH_TYPE_MAILBOX;
 		dirs[i] = t_strconcat(box->path, "/", subdirs[i], NULL);
+	}
+	types[i] = MAILBOX_LIST_PATH_TYPE_CONTROL;
 	dirs[i++] = mailbox_list_get_path(box->list, box->name,
 					  MAILBOX_LIST_PATH_TYPE_CONTROL);
+	types[i] = MAILBOX_LIST_PATH_TYPE_INDEX;
 	dirs[i++] = mailbox_list_get_path(box->list, box->name,
 					  MAILBOX_LIST_PATH_TYPE_INDEX);
 	i_assert(i == N_ELEMENTS(dirs));
@@ -197,8 +197,7 @@
 						  "stat(%s) failed: %m", path);
 			break;
 		}
-		is_mail_dir = i < N_ELEMENTS(subdirs);
-		if (maildir_create_path(box, path, is_mail_dir) < 0)
+		if (maildir_create_path(box, path, types[i], TRUE) < 0)
 			break;
 	}
 	return i == N_ELEMENTS(dirs) ? 0 : -1;
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/mail-namespace.c	Fri Jun 04 18:05:28 2010 +0100
@@ -60,6 +60,7 @@
 static int
 namespace_add(struct mail_user *user,
 	      struct mail_namespace_settings *ns_set,
+	      struct mail_namespace_settings *unexpanded_ns_set,
 	      const struct mail_storage_settings *mail_set,
 	      struct mail_namespace **ns_p, const char **error_r)
 {
@@ -115,6 +116,7 @@
 		ns_set->location = mail_set->mail_location;
 
 	ns->set = ns_set;
+	ns->unexpanded_set = unexpanded_ns_set;
 	ns->mail_set = mail_set;
 	ns->prefix = i_strdup(ns_set->prefix);
 
@@ -253,24 +255,29 @@
 {
 	const struct mail_storage_settings *mail_set;
 	struct mail_namespace_settings *const *ns_set;
+	struct mail_namespace_settings *const *unexpanded_ns_set;
 	struct mail_namespace *namespaces, *ns, **ns_p;
 	struct mail_namespace_settings *inbox_set;
 	const char *error, *driver, *location_source;
-	unsigned int i, count;
+	unsigned int i, count, count2;
 
 	i_assert(user->initialized);
 
         namespaces = NULL; ns_p = &namespaces;
 
 	mail_set = mail_user_set_get_storage_set(user);
-	if (array_is_created(&user->set->namespaces))
+	if (array_is_created(&user->set->namespaces)) {
 		ns_set = array_get(&user->set->namespaces, &count);
-	else {
-		ns_set = NULL;
+		unexpanded_ns_set =
+			array_get(&user->unexpanded_set->namespaces, &count2);
+		i_assert(count == count2);
+	} else {
+		ns_set = unexpanded_ns_set = NULL;
 		count = 0;
 	}
 	for (i = 0; i < count; i++) {
-		if (namespace_add(user, ns_set[i], mail_set, ns_p, error_r) < 0)
+		if (namespace_add(user, ns_set[i], unexpanded_ns_set[i],
+				  mail_set, ns_p, error_r) < 0)
 			return -1;
 		ns_p = &(*ns_p)->next;
 	}
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/mail-namespace.h
--- a/src/lib-storage/mail-namespace.h	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/mail-namespace.h	Fri Jun 04 18:05:28 2010 +0100
@@ -62,7 +62,7 @@
 	/* FIXME: we should support multiple storages in one namespace */
 	struct mail_storage *storage;
 
-	const struct mail_namespace_settings *set;
+	const struct mail_namespace_settings *set, *unexpanded_set;
 	const struct mail_storage_settings *mail_set;
 };
 
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/mailbox-list-private.h
--- a/src/lib-storage/mailbox-list-private.h	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/mailbox-list-private.h	Fri Jun 04 18:05:28 2010 +0100
@@ -140,9 +140,13 @@
 int mailbox_list_settings_parse(struct mail_user *user, const char *data,
 				struct mailbox_list_settings *set_r,
 				const char **error_r);
+const char *mailbox_list_get_unexpanded_path(struct mailbox_list *list,
+					     enum mailbox_list_path_type type);
 const char *
 mailbox_list_get_root_path(const struct mailbox_list_settings *set,
 			   enum mailbox_list_path_type type);
+int mailbox_list_mkdir(struct mailbox_list *list, const char *path,
+		       enum mailbox_list_path_type type);
 
 int mailbox_list_delete_index_control(struct mailbox_list *list,
 				      const char *name);
diff -r 3e51c846f293 -r 0dfd28b930b3 src/lib-storage/mailbox-list.c
--- a/src/lib-storage/mailbox-list.c	Fri Jun 04 16:59:31 2010 +0100
+++ b/src/lib-storage/mailbox-list.c	Fri Jun 04 18:05:28 2010 +0100


More information about the dovecot-cvs mailing list