mailbox-list.c revision 472369cba85d9f7c995dda60e7cd01d78b4a960a
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen then start renaming them to larger names from end to beginning, which
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen eventually would start causing the failures when trying to use too
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen long mailbox names. */
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen struct mailbox_list_iterate_context *backend_ctx;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen unsigned int i, count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (i = 0; i < count; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen unsigned int idx;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen array_append(&mailbox_list_drivers, &list, 1);
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int idx;
bf72c930996df0691932fb1143f360d260f27a06Timo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mailbox_list_create(const char *driver, struct mail_namespace *ns,
bbba7d0fce1b6ce5baa2d7ef946eb1b63e2ab518Timo Sirainen enum mailbox_list_flags flags, const char **error_r)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int idx;
c49a19168dab6fda80aee16ad799a8a56d3bc18fTimo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
02ccba3d3be96444abd15b5254864c9151bbeb30Timo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* copy settings */
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen list->set.index_dir = set->index_dir == NULL ||
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->set.control_dir = set->control_dir == NULL ||
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen p_strdup(list->pool, set->subscription_fname);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->set.maildir_name = set->maildir_name == NULL ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (list->props & MAILBOX_LIST_PROP_NO_MAILDIR_NAME) != 0 ? "" :
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (set->mailbox_dir_name == NULL || *set->mailbox_dir_name == '\0')
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen else if (set->mailbox_dir_name[strlen(set->mailbox_dir_name)-1] == '/') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen p_strconcat(list->pool, set->mailbox_dir_name, "/", NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->set.root_dir == NULL ? "" : list->set.root_dir,
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fix_path(struct mail_namespace *ns, const char *path,
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;
if (p == NULL)
dir);
const char *error_string;
return FALSE;
return TRUE;