shared-storage.c revision b1c42176a65dbe9c83a0af766e6bd8315530f3a5
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "lib.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "array.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "str.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "ioloop.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "var-expand.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "index-storage.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include "shared-storage.h"
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include <stdlib.h>
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#include <ctype.h>
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek#define SHARED_LIST_CONTEXT(obj) \
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek MODULE_CONTEXT(obj, shared_mailbox_list_module)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekextern struct mail_storage shared_storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekextern struct mailbox shared_mailbox;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic MODULE_CONTEXT_DEFINE_INIT(shared_mailbox_list_module,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek &mailbox_list_module_register);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic struct mail_storage *shared_alloc(void)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct shared_storage *storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek pool_t pool;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek pool = pool_alloconly_create("shared storage", 1024);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage = p_new(pool, struct shared_storage, 1);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->storage = shared_storage;
a73d70f7ebe194337d7732fd644384c94c2ce0d5Fabiano Fidêncio storage->storage.pool = pool;
1a71eeb4d71f7f6d63edb4298d69b35a94edc020Jakub Hrozek storage->storage.storage_class = &shared_storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->base_dir = p_strdup(pool, getenv("BASE_DIR"));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (storage->base_dir == NULL)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->base_dir = PKG_RUNDIR;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return &storage->storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic int shared_create(struct mail_storage *_storage, const char *data,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char **error_r)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct shared_storage *storage = (struct shared_storage *)_storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mailbox_list_settings list_set;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *driver, *p;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek char *wildcardp;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek bool have_username;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* data must begin with the actual mailbox driver */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek p = strchr(data, ':');
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (p == NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *error_r = "Shared mailbox location not prefixed with driver";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek driver = t_strdup_until(data, p);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->location = p_strdup(_storage->pool, data);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->storage_class = mail_storage_find_class(driver);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (storage->storage_class == NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *error_r = t_strconcat("Unknown shared storage driver: ",
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek driver, NULL);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek _storage->mailbox_is_file = storage->storage_class->mailbox_is_file;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek wildcardp = strchr(_storage->ns->prefix, '%');
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (wildcardp == NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *error_r = "Shared namespace prefix doesn't contain %";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->ns_prefix_pattern = p_strdup(_storage->pool, wildcardp);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek have_username = FALSE;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek for (p = storage->ns_prefix_pattern; *p != '\0'; p++) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p != '%')
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek continue;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*++p == '\0')
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p == 'u' || *p == 'n')
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek have_username = TRUE;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek else if (*p != '%' && *p != 'd')
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p != '\0') {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *error_r = "Shared namespace prefix contains unknown variables";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (!have_username) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *error_r = "Shared namespace prefix doesn't contain %u or %n";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* truncate prefix after the above checks are done, so they can log
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek the full prefix in error conditions */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *wildcardp = '\0';
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (mailbox_list_alloc("shared", &_storage->list, error_r) < 0)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek MODULE_CONTEXT_SET_FULL(_storage->list, shared_mailbox_list_module,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage, &storage->list_module_ctx);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek memset(&list_set, 0, sizeof(list_set));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek list_set.mail_storage_flags = &_storage->flags;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek list_set.lock_method = &_storage->lock_method;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mailbox_list_init(_storage->list, _storage->ns, &list_set, 0);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return 0;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic void
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekget_nonexisting_user_location(struct shared_storage *storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *username, string_t *location)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* user wasn't found. we'll still need to create the storage
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek to avoid exposing which users exist and which don't. */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append(location, storage->storage_class->name);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append_c(location, ':');
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* use a reachable but non-existing path as the mail root directory */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append(location, storage->base_dir);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append(location, "/user-not-found/");
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append(location, username);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekint shared_storage_get_namespace(struct mail_storage *_storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char **_name,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_namespace **ns_r)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct shared_storage *storage = (struct shared_storage *)_storage;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_user *user = _storage->ns->user;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek static struct var_expand_table static_tab[] = {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek { 'u', NULL, "user" },
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek { 'n', NULL, "username" },
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek { 'd', NULL, "domain" },
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek { 'h', NULL, "home" },
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek { '\0', NULL, NULL }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek };
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct var_expand_table *tab;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_namespace *ns;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_namespace_settings *ns_set;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_user *owner;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *domain = NULL, *username = NULL, *userdomain = NULL;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *name, *p, *next, **dest, *error;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek string_t *prefix, *location;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek int ret;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
1a71eeb4d71f7f6d63edb4298d69b35a94edc020Jakub Hrozek *ns_r = NULL;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek p = storage->ns_prefix_pattern;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek for (name = *_name; *p != '\0';) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p != '%') {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p != *name)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek p++; name++;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek continue;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek switch (*++p) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek case 'd':
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek dest = &domain;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek case 'n':
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek dest = &username;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek case 'u':
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek dest = &userdomain;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek default:
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* we checked this already above */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek i_unreached();
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek p++;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek next = strchr(name, *p != '\0' ? *p : _storage->ns->sep);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (next == NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *dest = name;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek name = "";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek break;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *dest = t_strdup_until(name, next);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek name = next;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*p != '\0') {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (*name == '\0' ||
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek (name[1] == '\0' && *name == _storage->ns->sep)) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* trying to open <prefix>/<user> mailbox */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek name = "INBOX";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek } else {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_storage_set_critical(_storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek "Invalid namespace prefix %s vs %s",
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek storage->ns_prefix_pattern, *_name);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* successfully matched the name. */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (userdomain == NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek i_assert(username != NULL);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek userdomain = domain == NULL ? username :
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek t_strconcat(username, "@", domain, NULL);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek } else {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek domain = strchr(userdomain, '@');
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (domain == NULL)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek username = userdomain;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek else {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek username = t_strdup_until(userdomain, domain);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek domain++;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* expand the namespace prefix and see if it already exists.
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek this should normally happen only when the mailbox is being opened */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek tab = t_malloc(sizeof(static_tab));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek memcpy(tab, static_tab, sizeof(static_tab));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek tab[0].value = userdomain;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek tab[1].value = username;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek tab[2].value = domain;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek prefix = t_str_new(128);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str_append(prefix, _storage->ns->prefix);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek var_expand(prefix, storage->ns_prefix_pattern, tab);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns = mail_namespace_find_prefix(user->namespaces, str_c(prefix));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (ns != NULL) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *_name = mail_namespace_fix_sep(ns, name);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *ns_r = ns;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return 0;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek owner = mail_user_alloc(userdomain, user->unexpanded_set);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (!var_has_key(storage->location, 'h', "home"))
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ret = 1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek else {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* we'll need to look up the user's home directory */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if ((ret = mail_user_get_home(owner, &tab[3].value)) < 0) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_storage_set_critical(_storage, "Namespace '%s': "
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek "Could not lookup home for user %s",
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek _storage->ns->prefix, userdomain);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_user_unref(&owner);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (mail_user_init(owner, &error) < 0) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_storage_set_critical(_storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek "Couldn't create namespace '%s' for user %s: %s",
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek _storage->ns->prefix, userdomain, error);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_user_unref(&owner);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek /* create the new namespace */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns = i_new(struct mail_namespace, 1);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->type = NAMESPACE_SHARED;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->user = user;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->prefix = i_strdup(str_c(prefix));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->owner = owner;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->flags = NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_HIDDEN |
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NAMESPACE_FLAG_AUTOCREATED | NAMESPACE_FLAG_INBOX;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->sep = _storage->ns->sep;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->mail_set = _storage->set;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek location = t_str_new(256);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (ret > 0)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek var_expand(location, storage->location, tab);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek else {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek get_nonexisting_user_location(storage, userdomain, location);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->flags |= NAMESPACE_FLAG_UNUSABLE;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set = p_new(user->pool, struct mail_namespace_settings, 1);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->type = "shared";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->separator = p_strdup_printf(user->pool, "%c", ns->sep);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->prefix = ns->prefix;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->location = p_strdup(user->pool, str_c(location));
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->hidden = TRUE;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns_set->list = "yes";
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->set = ns_set;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (mail_storage_create(ns, NULL, _storage->flags, &error) < 0) {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_storage_set_critical(_storage, "Namespace '%s': %s",
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ns->prefix, error);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_namespace_destroy(ns);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek _storage->ns->flags |= NAMESPACE_FLAG_USABLE;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *_name = mail_namespace_fix_sep(ns, name);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek *ns_r = ns;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_user_add_namespace(user, &ns);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return 0;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic void shared_mailbox_copy_error(struct mail_storage *shared_storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_namespace *backend_ns)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *str;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek enum mail_error error;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek str = mail_storage_get_last_error(backend_ns->storage, &error);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek mail_storage_set_error(shared_storage, error, str);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstatic int shared_mailbox_create(struct mail_storage *storage,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek const char *name, bool directory)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek{
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek struct mail_namespace *ns;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek int ret;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (shared_storage_get_namespace(storage, &name, &ns) < 0)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return -1;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek ret = mail_storage_mailbox_create(ns->storage, name, directory);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek if (ret < 0)
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek shared_mailbox_copy_error(storage, ns);
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek return ret;
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek}
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židekstruct mail_storage shared_storage = {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek MEMBER(name) SHARED_STORAGE_NAME,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek MEMBER(mailbox_is_file) FALSE, /* unknown at this point */
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek {
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NULL,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NULL,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NULL,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek shared_alloc,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek shared_create,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek index_storage_destroy,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NULL,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek NULL,
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek shared_mailbox_create
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek }
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek};
35ecfab87a24031e55798b22975e02832ee0f2adMichal Židek