shared-storage.c revision c0a87e5f3316a57e6f915882fa1951d0fbb74a61
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2008-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct mail_storage *shared_storage_alloc(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool = pool_alloconly_create("shared storage", 1024);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen storage = p_new(pool, struct shared_storage, 1);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenshared_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const char **error_r)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen const char *driver, *p;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen /* location must begin with the actual mailbox driver */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *error_r = "Shared mailbox location not prefixed with driver";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen driver = t_strdup_until(ns->set->location, p);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen storage->location = p_strdup(_storage->pool, ns->set->location);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen p_strdup(_storage->pool, ns->unexpanded_set->location);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen storage->storage_class = mail_storage_find_class(driver);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = t_strconcat("Unknown shared storage driver: ",
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen _storage->class_flags = storage->storage_class->class_flags;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix doesn't contain %";
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen storage->ns_prefix_pattern = p_strdup(_storage->pool, wildcardp);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (p = storage->ns_prefix_pattern; *p != '\0'; p++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (*p != '%')
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (*p != '\0') {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix contains unknown variables";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix doesn't contain %u or %n";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* truncate prefix after the above checks are done, so they can log
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen the full prefix in error conditions */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenshared_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenget_nonexistent_user_location(struct shared_storage *storage,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* user wasn't found. we'll still need to create the storage
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen to avoid exposing which users exist and which don't. */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen str_append(location, storage->storage_class->name);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* use a reachable but nonexistent path as the mail root directory */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen str_append(location, storage->storage.user->set->base_dir);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenint shared_storage_get_namespace(struct mail_namespace **_ns,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen const char **_name)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen struct mail_storage *_storage = (*_ns)->storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen static struct var_expand_table static_tab[] = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_namespace_settings *ns_set, *unexpanded_ns_set;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen const char *domain = NULL, *username = NULL, *userdomain = NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (*p != '%') {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen switch (*++p) {
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* we checked this already above */
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen next = strchr(name, *p != '\0' ? *p : ns_sep);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (*p != '\0') {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* trying to open <prefix>/<user> mailbox */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen "Invalid namespace prefix %s vs %s",
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* successfully matched the name. */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* user@domain given */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen username = t_strdup_until(userdomain, domain);
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* trying to open namespace "shared/domain"
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen namespace prefix. */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* no domain given, use ours (if we have one) */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen "Empty username doesn't exist");
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* expand the namespace prefix and see if it already exists.
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen this should normally happen only when the mailbox is being opened */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen var_expand(prefix, storage->ns_prefix_pattern, tab);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen *_ns = mail_namespace_find_prefix(user->namespaces, str_c(prefix));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen *_name = mailbox_list_get_storage_name(ns->list,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen owner = mail_user_alloc(userdomain, user->set_info,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (!var_has_key(storage->location, 'h', "home"))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* we'll need to look up the user's home directory */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((ret = mail_user_get_home(owner, &tab[3].value)) < 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mailbox_list_set_critical(list, "Namespace '%s': "
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "Could not lookup home for user %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Couldn't create namespace '%s' for user %s: %s",
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* create the new namespace */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->flags = (NAMESPACE_FLAG_SUBSCRIPTIONS & ns->flags) |
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_HIDDEN |
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen NAMESPACE_FLAG_AUTOCREATED | NAMESPACE_FLAG_INBOX_ANY;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen get_nonexistent_user_location(storage, userdomain, location);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set = p_new(user->pool, struct mail_namespace_settings, 1);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->separator = p_strdup_printf(user->pool, "%c", ns_sep);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->location = p_strdup(user->pool, str_c(location));
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen p_new(user->pool, struct mail_namespace_settings, 1);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen p_strdup(user->pool, storage->unexpanded_location);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_storage_create(new_ns, NULL, _storage->flags |
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_STORAGE_FLAG_NO_AUTOVERIFY, &error) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mailbox_list_set_critical(list, "Namespace '%s': %s",