mailbox-list.c revision 94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
863ea896fb31a16d1baec31e57650243b5547db6Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
863ea896fb31a16d1baec31e57650243b5547db6Timo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen then start renaming them to larger names from end to beginning, which
471e447023ab73a73f0f78da2afc0c55905330ddTimo Sirainen eventually would start causing the failures when trying to use too
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen long mailbox names. */
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen struct mailbox_list_iterate_context *backend_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (i = 0; i < count; i++) {
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen unsigned int idx;
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen array_append(&mailbox_list_drivers, &list, 1);
d9fda7e3a0fa5551547ac3e3054b837fc77f4bfbTimo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen unsigned int idx;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mailbox_list_create(const char *driver, struct mail_namespace *ns,
45e62043058738e294f89504c319d852e25943ccTimo Sirainen enum mailbox_list_flags flags, const char **error_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen unsigned int idx;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
c0d1bfc45e224251cb549de8d8804861e8acb517Timo Sirainen /* copy settings */
c0d1bfc45e224251cb549de8d8804861e8acb517Timo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
c0d1bfc45e224251cb549de8d8804861e8acb517Timo Sirainen list->set.index_dir = set->index_dir == NULL ||
c0d1bfc45e224251cb549de8d8804861e8acb517Timo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen list->set.control_dir = set->control_dir == NULL ||
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
6321d9d33937c7fc13a8ff04c220a9e377efeeb8Timo Sirainen p_strdup(list->pool, set->subscription_fname);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen list->set.maildir_name = set->maildir_name == NULL ||
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen (list->props & MAILBOX_LIST_PROP_NO_MAILDIR_NAME) != 0 ? "" :
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen if (set->mailbox_dir_name == NULL || *set->mailbox_dir_name == '\0')
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (set->mailbox_dir_name[strlen(set->mailbox_dir_name)-1] == '/') {
6ded8819b9002150a95a7615e4f64f091c250464Timo Sirainen p_strconcat(list->pool, set->mailbox_dir_name, "/", NULL);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
92dab926b2f2270057b40a907a00cf8eb2309ed6Timo Sirainen list->set.root_dir == NULL ? "" : list->set.root_dir,
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
args++;
args++;
args++;
return str;
value++;
struct mail_namespace *
return mode;
struct mail_user *
const char *path;
path);
const char *name,
const char **gid_origin_r)
const char *name,
const char **gid_origin_r)
const char *pattern)
const char *name)
const char *name)
int ret;
T_BEGIN {
} T_END;
return pattern;
const char *name,
struct mailbox_list_iterate_context *
struct mailbox_list_iterate_context *
const char *const *patterns,
static struct mail_namespace *
return ns;
static const struct mailbox_info *
return info;
int ret;
return ret;
struct mailbox_list_iterate_context *
const char *const *patterns,
unsigned int i, count;
for (i = 0; i < count; i++)
const struct mailbox_info *
return info;
const char *oldname,
const char *name)
const char *name)
if (created) {
if (create_flags != 0)
if (p == NULL)
const char *name)
T_BEGIN {
} T_END;
return TRUE;
levels++;
level_len = 0;
level_len++;
return TRUE;
return TRUE;
return FALSE;
#ifdef HAVE_DIRENT_D_TYPE
switch (d->d_type) {
case DT_UNKNOWN:
case DT_REG:
case DT_DIR:
case DT_LNK:
return type;
const char **name)
return FALSE;
return TRUE;
return FALSE;
return TRUE;
return TRUE;
return FALSE;
const char *error_string;
return FALSE;
return TRUE;