shared-storage.c revision 1a5573ebc32fae2fe576ec544e1781323c1db609
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2008-2014 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_storage *shared_storage_alloc(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("shared storage", 1024);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage = p_new(pool, struct shared_storage, 1);
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainenshared_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen const char **error_r)
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen const char *driver, *p;
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen /* location must begin with the actual mailbox driver */
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen *error_r = "Shared mailbox location not prefixed with driver";
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen driver = t_strdup_until(ns->set->location, p);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->location = p_strdup(_storage->pool, ns->set->location);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen p_strdup(_storage->pool, ns->unexpanded_set->location);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage_class_name = p_strdup(_storage->pool, driver);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage_class = mail_user_get_storage_class(_storage->user, driver);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen _storage->class_flags = storage_class->class_flags;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *error_r = t_strconcat("Unknown shared storage driver: ",
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen *error_r = "Shared namespace prefix doesn't contain %";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->ns_prefix_pattern = p_strdup(_storage->pool, wildcardp);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen for (p = storage->ns_prefix_pattern; *p != '\0'; p++) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (*p != '%')
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (*p != '\0') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *error_r = "Shared namespace prefix contains unknown variables";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *error_r = "Shared namespace prefix doesn't contain %u or %n";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *error_r = "Shared namespace prefix doesn't end with hierarchy separator";
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen /* truncate prefix after the above checks are done, so they can log
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen the full prefix in error conditions */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenshared_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenget_nonexistent_user_location(struct shared_storage *storage,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* user wasn't found. we'll still need to create the storage
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen to avoid exposing which users exist and which don't. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_append(location, storage->storage_class_name);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* use a reachable but nonexistent path as the mail root directory */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_append(location, storage->storage.user->set->base_dir);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic bool shared_namespace_exists(struct mail_namespace *ns)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen path = mailbox_list_get_root_forced(ns->list, MAILBOX_LIST_PATH_TYPE_DIR);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* we can't know if this exists */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint shared_storage_get_namespace(struct mail_namespace **_ns,
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen const char **_name)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_storage *_storage = (*_ns)->storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
547e916f4e6f01af682f8b6e032c337f2a699364Timo Sirainen static struct var_expand_table static_tab[] = {
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen struct mail_namespace_settings *ns_set, *unexpanded_ns_set;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *domain = NULL, *username = NULL, *userdomain = NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*p != '%') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen switch (*++p) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* we checked this already above */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen next = strchr(name, *p != '\0' ? *p : ns_sep);
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen if (*p != '\0') {
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen /* trying to open <prefix>/<user> mailbox */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Invalid namespace prefix %s vs %s",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* successfully matched the name. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* user@domain given */
fbd918f47f591f8084fd52b207ef29515ddd11b9Timo Sirainen username = t_strdup_until(userdomain, domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* trying to open namespace "shared/domain"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen namespace prefix. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
5539418f448cd9bb38fc085e654861479dd1130bTimo Sirainen /* no domain given, use ours (if we have one) */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Empty username doesn't exist");
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* expand the namespace prefix and see if it already exists.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen this should normally happen only when the mailbox is being opened */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen var_expand(prefix, storage->ns_prefix_pattern, tab);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *_ns = mail_namespace_find_prefix(user->namespaces, str_c(prefix));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *_name = mailbox_list_get_storage_name(ns->list,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen owner = mail_user_alloc(userdomain, user->set_info,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Couldn't create namespace '%s' for user %s: %s",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else if (!var_has_key(storage->location, 'h', "home")) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* we'll need to look up the user's home directory */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ret = mail_user_get_home(owner, &tab[3].value)) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mailbox_list_set_critical(list, "Namespace '%s': "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Could not lookup home for user %s",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* create the new namespace */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen new_ns->flags = (NAMESPACE_FLAG_SUBSCRIPTIONS & ns->flags) |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_HIDDEN |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NAMESPACE_FLAG_AUTOCREATED | NAMESPACE_FLAG_INBOX_ANY;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen get_nonexistent_user_location(storage, userdomain, location);
NULL,
NULL,
NULL,