shared-storage.c revision c0a87e5f3316a57e6f915882fa1951d0fbb74a61
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2008-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "var-expand.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mailbox-list-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "shared-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdlib.h>
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen#include <ctype.h>
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenextern struct mail_storage shared_storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct mail_storage *shared_storage_alloc(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct shared_storage *storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool_t pool;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool = pool_alloconly_create("shared storage", 1024);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen storage = p_new(pool, struct shared_storage, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen storage->storage = shared_storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen storage->storage.pool = pool;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return &storage->storage;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen}
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenstatic int
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenshared_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const char **error_r)
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen{
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen const char *driver, *p;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen char *wildcardp, key;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen bool have_username;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen /* location must begin with the actual mailbox driver */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen p = strchr(ns->set->location, ':');
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (p == NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *error_r = "Shared mailbox location not prefixed with driver";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen driver = t_strdup_until(ns->set->location, p);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen storage->location = p_strdup(_storage->pool, ns->set->location);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen storage->unexpanded_location =
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen p_strdup(_storage->pool, ns->unexpanded_set->location);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen storage->storage_class = mail_storage_find_class(driver);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (storage->storage_class == NULL) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = t_strconcat("Unknown shared storage driver: ",
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen driver, NULL);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen _storage->class_flags = storage->storage_class->class_flags;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen wildcardp = strchr(ns->prefix, '%');
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (wildcardp == NULL) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix doesn't contain %";
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen storage->ns_prefix_pattern = p_strdup(_storage->pool, wildcardp);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen have_username = FALSE;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (p = storage->ns_prefix_pattern; *p != '\0'; p++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (*p != '%')
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen continue;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen key = p[1];
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (key == 'u' || key == 'n')
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen have_username = TRUE;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen else if (key != '%' && key != 'd')
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen break;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (*p != '\0') {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix contains unknown variables";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (!have_username) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *error_r = "Shared namespace prefix doesn't contain %u or %n";
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* truncate prefix after the above checks are done, so they can log
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen the full prefix in error conditions */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *wildcardp = '\0';
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ns->prefix_len = strlen(ns->prefix);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenstatic void
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenshared_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen struct mailbox_list_settings *set)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen set->layout = "shared";
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen}
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainenstatic void
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenget_nonexistent_user_location(struct shared_storage *storage,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen const char *username, string_t *location)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
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 str_append_c(location, ':');
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
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 Sirainen str_append(location, "/user-not-found/");
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen str_append(location, username);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen}
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainenint shared_storage_get_namespace(struct mail_namespace **_ns,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen const char **_name)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen struct mail_storage *_storage = (*_ns)->storage;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen struct mailbox_list *list = (*_ns)->list;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen struct mail_user *user = _storage->user;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen static struct var_expand_table static_tab[] = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'u', NULL, "user" },
659fe5d24825b160cae512538088020d97a60239Timo Sirainen { 'n', NULL, "username" },
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen { 'd', NULL, "domain" },
659fe5d24825b160cae512538088020d97a60239Timo Sirainen { 'h', NULL, "home" },
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen { '\0', NULL, NULL }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen };
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct var_expand_table *tab;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen struct mail_namespace *new_ns, *ns = *_ns;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_namespace_settings *ns_set, *unexpanded_ns_set;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen struct mail_user *owner;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen const char *domain = NULL, *username = NULL, *userdomain = NULL;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen const char *name, *p, *next, **dest, *error;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen string_t *prefix, *location;
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen char ns_sep = mail_namespace_get_sep(ns);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen int ret;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen p = storage->ns_prefix_pattern;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (name = *_name; *p != '\0';) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (*p != '%') {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (*p != *name)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen break;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen p++; name++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen switch (*++p) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case 'd':
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen dest = &domain;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen break;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen case 'n':
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest = &username;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen break;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen case 'u':
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen dest = &userdomain;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen break;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen default:
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* we checked this already above */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen i_unreached();
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen }
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen p++;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen next = strchr(name, *p != '\0' ? *p : ns_sep);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (next == NULL) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *dest = name;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen name = "";
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen break;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen *dest = t_strdup_until(name, next);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen name = next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (*p != '\0') {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen if (*name == '\0' ||
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen (name[1] == '\0' && *name == ns_sep)) {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* trying to open <prefix>/<user> mailbox */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen name = "INBOX";
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen } else {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen mailbox_list_set_critical(list,
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen "Invalid namespace prefix %s vs %s",
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen storage->ns_prefix_pattern, *_name);
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen return -1;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen }
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen }
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* successfully matched the name. */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen if (userdomain != NULL) {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* user@domain given */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen domain = strchr(userdomain, '@');
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (domain == NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen username = userdomain;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen else {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen username = t_strdup_until(userdomain, domain);
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen domain++;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen }
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen } else if (username == NULL) {
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* trying to open namespace "shared/domain"
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen namespace prefix. */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(*_name));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen return -1;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen } else {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (domain == NULL) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* no domain given, use ours (if we have one) */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen domain = strchr(user->username, '@');
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (domain != NULL) domain++;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen userdomain = domain == NULL ? username :
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen t_strconcat(username, "@", domain, NULL);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (*userdomain == '\0') {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen "Empty username doesn't exist");
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen return -1;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
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 tab = t_malloc(sizeof(static_tab));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen tab[0].value = userdomain;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen tab[1].value = username;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen tab[2].value = domain;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen prefix = t_str_new(128);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen str_append(prefix, ns->prefix);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen var_expand(prefix, storage->ns_prefix_pattern, tab);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen *_ns = mail_namespace_find_prefix(user->namespaces, str_c(prefix));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (*_ns != NULL) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen *_name = mailbox_list_get_storage_name(ns->list,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen t_strconcat(ns->prefix, name, NULL));
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen return 0;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen owner = mail_user_alloc(userdomain, user->set_info,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen user->unexpanded_set);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (!var_has_key(storage->location, 'h', "home"))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ret = 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen else {
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",
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen ns->prefix, userdomain);
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen mail_user_unref(&owner);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen }
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen if (mail_user_init(owner, &error) < 0) {
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen mailbox_list_set_critical(list,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Couldn't create namespace '%s' for user %s: %s",
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns->prefix, userdomain, error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_user_unref(&owner);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* create the new namespace */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen new_ns = i_new(struct mail_namespace, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->refcount = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->type = NAMESPACE_SHARED;
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainen new_ns->user = user;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->prefix = i_strdup(str_c(prefix));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen new_ns->owner = owner;
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;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->mail_set = _storage->set;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen location = t_str_new(256);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen var_expand(location, storage->location, tab);
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen else {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen get_nonexistent_user_location(storage, userdomain, location);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen new_ns->flags |= NAMESPACE_FLAG_UNUSABLE;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen if (ns->user->mail_debug) {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen i_debug("shared: Tried to access mails of "
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen "nonexistent user %s", userdomain);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen }
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen }
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set = p_new(user->pool, struct mail_namespace_settings, 1);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->type = "shared";
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->separator = p_strdup_printf(user->pool, "%c", ns_sep);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->prefix = new_ns->prefix;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ns_set->location = p_strdup(user->pool, str_c(location));
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ns_set->hidden = TRUE;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ns_set->list = "yes";
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen new_ns->set = ns_set;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen unexpanded_ns_set =
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen p_new(user->pool, struct mail_namespace_settings, 1);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen *unexpanded_ns_set = *ns_set;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen unexpanded_ns_set->location =
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen p_strdup(user->pool, storage->unexpanded_location);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen new_ns->unexpanded_set = unexpanded_ns_set;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
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",
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen new_ns->prefix, error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_namespace_destroy(new_ns);
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen return -1;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen }
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen ns->flags |= NAMESPACE_FLAG_USABLE;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen *_name = mailbox_list_get_storage_name(new_ns->list,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen t_strconcat(new_ns->prefix, name, NULL));
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen *_ns = new_ns;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen mail_user_add_namespace(user, &new_ns);
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen return 0;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen}
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstruct mail_storage shared_storage = {
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen .name = SHARED_STORAGE_NAME,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen .class_flags = 0, /* unknown at this point */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen .v = {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen NULL,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen shared_storage_alloc,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen shared_storage_create,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen NULL,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen NULL,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen shared_storage_get_list_settings,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen NULL,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen NULL,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen NULL
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen};
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen