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