/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "ioloop.h"
#include "var-expand.h"
#include "index-storage.h"
#include "mail-storage-service.h"
#include "mailbox-list-private.h"
#include "fail-mail-storage.h"
#include "shared-storage.h"
#include <ctype.h>
extern struct mail_storage shared_storage;
{
}
static int
const char **error_r)
{
const char *driver, *p;
bool have_username;
/* location must begin with the actual mailbox driver */
if (p == NULL) {
*error_r = "Shared mailbox location not prefixed with driver";
return -1;
}
return -1;
}
*error_r = "Shared namespace prefix doesn't contain %";
return -1;
}
if (*p != '%')
continue;
key = p[1];
break;
}
if (*p != '\0') {
*error_r = "Shared namespace prefix contains unknown variables";
return -1;
}
if (!have_username) {
*error_r = "Shared namespace prefix doesn't contain %u or %n";
return -1;
}
NAMESPACE_FLAG_LIST_CHILDREN)) != 0) {
*error_r = "Shared namespace prefix doesn't end with hierarchy separator";
return -1;
}
/* truncate prefix after the above checks are done, so they can log
the full prefix in error conditions */
*wildcardp = '\0';
return 0;
}
static void
struct mailbox_list_settings *set)
{
}
static void
{
/* user wasn't found. we'll still need to create the storage
to avoid exposing which users exist and which don't. */
/* use a reachable but nonexistent path as the mail root directory */
}
{
const char *path;
/* we can't know if this exists */
return TRUE;
}
}
const char **_name)
{
int ret;
p = storage->ns_prefix_pattern;
if (*p != '%') {
if (*p != *name)
break;
p++; name++;
continue;
}
switch (*++p) {
case 'd':
break;
case 'n':
break;
case 'u':
dest = &userdomain;
break;
default:
/* we checked this already above */
i_unreached();
}
p++;
name = "";
break;
}
}
if (*p != '\0') {
if (*name == '\0' ||
/* trying to open <prefix>/<user> mailbox */
name = "INBOX";
} else {
"Invalid namespace prefix %s vs %s",
return -1;
}
}
/* successfully matched the name. */
if (userdomain != NULL) {
/* user@domain given */
else {
domain++;
}
namespace prefix. */
return -1;
} else {
/* no domain given, use ours (if we have one) */
}
}
if (*userdomain == '\0') {
"Empty username doesn't exist");
return -1;
}
/* expand the namespace prefix and see if it already exists.
this should normally happen only when the mailbox is being opened */
};
"Failed to expand namespace prefix '%s': %s",
return -1;
}
return 0;
}
if (!owner->nonexistent) {
"Couldn't create namespace '%s' for user %s: %s",
return -1;
}
ret = 0;
ret = 1;
} else {
/* we'll need to look up the user's home directory */
"Could not lookup home for user %s",
return -1;
}
}
if (ret > 0 &&
"Failed to expand namespace location '%s': %s",
return -1;
}
/* create the new namespace */
if (ret <= 0) {
i_debug("shared: Tried to access mails of "
"nonexistent user %s", userdomain);
}
}
*unexpanded_ns_set = *ns_set;
/* We need to create a prefix="" namespace for the owner */
/* owner gets freed by namespace deinit */
return -1;
}
MAIL_STORAGE_FLAG_NO_AUTOVERIFY, &error) < 0) {
/* owner gets freed by namespace deinit */
return -1;
}
/* this user doesn't have a usable storage */
}
/* mark the shared namespace root as usable, since it now has
child namespaces */
if (_storage->class_flags == 0) {
/* flags are unset if we were using "auto" storage */
}
return 0;
}
.class_flags = 0, /* unknown at this point */
.v = {
NULL,
NULL,
NULL,
NULL,
NULL,
}
};