mail-namespace.c revision 2c067d5cd0088123e59ff45bee9b059fa9c1ffb1
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2005-2016 Dovecot authors, see the included COPYING file */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenstatic struct mail_namespace_settings prefixless_ns_unexpanded_set = {
948b838c8e9896132e3a2d802fb5dad37e8dc716Timo Sirainenstatic struct mail_namespace_settings prefixless_ns_set;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenvoid mail_namespace_add_storage(struct mail_namespace *ns,
16b5dc27e7db42849510403d37e3629aba14de21Timo Sirainenvoid mail_namespace_finish_list_init(struct mail_namespace *ns,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenstatic void mail_namespace_free(struct mail_namespace *ns)
0327191888a058542f065526e82bce30319579a4Phil Carmody array_foreach_modifiable(&ns->all_storages, storagep)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (ns->owner != ns->user && ns->owner != NULL)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainennamespace_has_special_use_mailboxes(struct mail_namespace_settings *ns_set)
5c92436a61569c0b56a9374e60e779fa4455edefTimo Sirainenint mail_namespace_alloc(struct mail_user *user,
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen struct mail_namespace_settings *unexpanded_set,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const char **error_r)
64055bc6d2ed9e25b3b1db3b5b90d0bdb77cd715Timo Sirainen ns->mail_set = mail_user_set_get_storage_set(user);
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen } else if (strcmp(ns_set->type, "shared") == 0)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen *error_r = t_strdup_printf("Unknown namespace type: %s",
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen *error_r = t_strdup_printf("Invalid list setting value: %s",
0327191888a058542f065526e82bce30319579a4Phil Carmodyint mail_namespaces_init_add(struct mail_user *user,
0c3ec2538c366bb5583f0b4ca2ce60804756b51cTimo Sirainen struct mail_namespace_settings *unexpanded_ns_set,
0c3ec2538c366bb5583f0b4ca2ce60804756b51cTimo Sirainen struct mail_namespace **ns_p, const char **error_r)
0c3ec2538c366bb5583f0b4ca2ce60804756b51cTimo Sirainen const struct mail_storage_settings *mail_set =
98950c9167dc2fab6c13d6d4c968e1963ecd73d7Timo Sirainen i_debug("Namespace %s: type=%s, prefix=%s, sep=%s, "
98950c9167dc2fab6c13d6d4c968e1963ecd73d7Timo Sirainen "inbox=%s, hidden=%s, list=%s, subscriptions=%s "
bcd286622779a93f809b11993db0550f8c7cc9b5Timo Sirainen "location=%s",
bcd286622779a93f809b11993db0550f8c7cc9b5Timo Sirainen ns_set->separator == NULL ? "" : ns_set->separator,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ns_set->subscriptions ? "yes" : "no", ns_set->location);
2c42748505ef4aed83ff59b34e50ed5606900c86Timo Sirainen if ((ret = mail_namespace_alloc(user, ns_set, unexpanded_ns_set,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* autocreated prefix="" namespace */
16b5dc27e7db42849510403d37e3629aba14de21Timo Sirainen ns->special_use_mailboxes = namespace_has_special_use_mailboxes(ns_set);
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* dynamic shared namespace. the above check catches wrong
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen mixed %% usage, but still allows for specifying a shared
4ce6338bf945cccfff9e4ce7cc6aa2246851b84aTimo Sirainen namespace to an explicit location without any %% */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (mail_storage_create(ns, driver, 0, &error) < 0) {
59a63791d4ec70a134cb0dcbad1255d952075efeTimo Sirainen *error_r = t_strdup_printf("Namespace '%s': %s",
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainenstatic bool namespace_is_valid_alias_storage(struct mail_namespace *ns,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const char **error_r)
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen if (strcmp(ns->storage->name, ns->alias_for->storage->name) != 0) {
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen "Namespace %s can't have alias_for=%s "
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen "to a different storage type (%s vs %s)",
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ns->storage->name, ns->alias_for->storage->name);
5c92436a61569c0b56a9374e60e779fa4455edefTimo Sirainen if ((ns->storage->class_flags & MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT) != 0 &&
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen "Namespace %s can't have alias_for=%s "
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen "to a different storage (different root dirs)",
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainennamespace_set_alias_for(struct mail_namespace *ns,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const char **error_r)
421973339968d444d4433cb4d47d1f150e4ab288Timo Sirainen ns->alias_for = mail_namespace_find_prefix(all_namespaces,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen *error_r = t_strdup_printf("Invalid namespace alias_for: %s",
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen *error_r = t_strdup_printf("Chained namespace alias_for: %s",
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (!namespace_is_valid_alias_storage(ns, error_r))
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen if ((ns->alias_for->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen /* copy inbox=yes */
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen ns->alias_chain_next = ns->alias_for->alias_chain_next;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainennamespaces_check(struct mail_namespace *namespaces, const char **error_r)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen unsigned int subscriptions_count = 0;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {
421973339968d444d4433cb4d47d1f150e4ab288Timo Sirainen if (mail_namespace_find_prefix(ns->next, ns->prefix) != NULL) {
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen "Duplicate namespace prefix: \"%s\"",
0327191888a058542f065526e82bce30319579a4Phil Carmody /* check the inbox=yes status before alias_for changes it */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen *error_r = "There can be only one namespace with "
6cc5a850bb6c1769f4113009c2067e5a719175a0Timo Sirainen if (namespace_set_alias_for(ns, namespaces, error_r) < 0)
65d8efa66dca27db85f74ee2574188b51569a4c2Timo Sirainen "list=yes requires prefix=%s "
13fc4d6d28f05076ffe6f5a925e8f6269e4b548ePhil Carmody "list=yes requires prefix=%s "
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen *error_r = "All list=yes namespaces must use "
0327191888a058542f065526e82bce30319579a4Phil Carmody "the same separator";
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0)
ab7b5b9286104974c2a572a499ccf8b56c5d2955Timo Sirainen *error_r = "subscriptions=yes namespace missing";
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenint mail_namespaces_init_finish(struct mail_namespace *namespaces,
ab7b5b9286104974c2a572a499ccf8b56c5d2955Timo Sirainen const char **error_r)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen prefixless_ns_set = prefixless_ns_unexpanded_set;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* a pretty evil way to expand the values */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (mail_namespaces_init_add(namespaces->user,
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainen /* e.g. raw user - don't check namespaces' validity */
ab7b5b9286104974c2a572a499ccf8b56c5d2955Timo Sirainen } else if (!namespaces_check(namespaces, error_r)) {
ab7b5b9286104974c2a572a499ccf8b56c5d2955Timo Sirainen *error_r = t_strconcat("namespace configuration error: ",
T_BEGIN {
} T_END;
count = 0;
for (i = 0; i < count; i++) {
const char **error_r)
int ret;
if (default_location) {
return ret;
return ns;
void *context)
struct mail_storage *
return TRUE;
return TRUE;
return TRUE;
return FALSE;
static struct mail_namespace *
unsigned int best_len = 0;
bool inbox;
return ns;
return best;
return best;
static struct mail_namespace *
return ns;
struct mail_namespace *
return ns;
struct mail_namespace *
const char **mailbox)
const char *storage_name;
return ns;
struct mail_namespace *
const char *mailbox)
struct mail_namespace *
const char *mailbox)
struct mail_namespace *
const char *mailbox)
struct mail_namespace *
return namespaces;
struct mail_namespace *
const char *prefix)
return ns;
return NULL;
struct mail_namespace *
const char *prefix)
return ns;
return NULL;
return FALSE;
return FALSE;
return TRUE;
return FALSE;