From: Timo Sirainen Date: Tue, 19 Sep 2017 08:18:30 +0000 (+0300) Subject: lib-storage: Fail if two namespaces try to wrongly share the same LISTINDEX X-Git-Tag: 2.3.0.rc1~995 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25b3208d3b238179e291ab67a8154e1e45a87beb;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Fail if two namespaces try to wrongly share the same LISTINDEX If they have different mailboxes-path, they can't be sharing the same mailbox list index. The previous behavior caused Dovecot to silently overwrite the list index whenever each of the namespaces were accessed, resulting in bad performance. --- diff --git a/src/lib-storage/mail-namespace.c b/src/lib-storage/mail-namespace.c index 26bc961c42..40ac3b0595 100644 --- a/src/lib-storage/mail-namespace.c +++ b/src/lib-storage/mail-namespace.c @@ -258,6 +258,56 @@ namespace_set_alias_for(struct mail_namespace *ns, return 0; } +static bool get_listindex_path(struct mail_namespace *ns, const char **path_r) +{ + const char *root; + + if (ns->list->set.list_index_fname[0] == '\0' || + !mailbox_list_get_root_path(ns->list, + MAILBOX_LIST_PATH_TYPE_LIST_INDEX, + &root)) + return FALSE; + + *path_r = t_strconcat(root, "/", ns->list->set.list_index_fname, NULL); + return TRUE; +} + +static bool +namespace_has_duplicate_listindex(struct mail_namespace *ns, + const char **error_r) +{ + struct mail_namespace *ns2; + const char *ns_list_index_path, *ns_mailboxes_root; + const char *ns2_list_index_path, *ns2_mailboxes_root; + + if (!ns->mail_set->mailbox_list_index) { + /* mailbox list indexes not in use */ + return FALSE; + } + + if (!get_listindex_path(ns, &ns_list_index_path) || + !mailbox_list_get_root_path(ns->list, MAILBOX_LIST_PATH_TYPE_MAILBOX, + &ns_mailboxes_root)) + return FALSE; + + for (ns2 = ns->next; ns2 != NULL; ns2 = ns2->next) { + if (!get_listindex_path(ns2, &ns2_list_index_path) || + !mailbox_list_get_root_path(ns2->list, MAILBOX_LIST_PATH_TYPE_MAILBOX, + &ns2_mailboxes_root)) + continue; + + if (strcmp(ns_list_index_path, ns2_list_index_path) == 0 && + strcmp(ns_mailboxes_root, ns2_mailboxes_root) != 0) { + *error_r = t_strdup_printf( + "Namespaces '%s' and '%s' have different mailboxes paths, but duplicate LISTINDEX path. " + "Add a unique LISTINDEX=", + ns->prefix, ns2->prefix); + return TRUE; + } + } + return FALSE; +} + static bool namespaces_check(struct mail_namespace *namespaces, const char **error_r) { @@ -287,6 +337,8 @@ namespaces_check(struct mail_namespace *namespaces, const char **error_r) } if (namespace_set_alias_for(ns, namespaces, error_r) < 0) return FALSE; + if (namespace_has_duplicate_listindex(ns, error_r)) + return FALSE; if (*ns->prefix != '\0' && (ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |