mail-storage-settings.c revision 4c0e20db10034bb572d278f62beff12e3deb17d9
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2005-2014 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen#include "array.h"
18398a5d21c88cbb34c601c6b6c1f9dea502e1caTimo Sirainen#include "hash-format.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "var-expand.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "unichar.h"
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen#include "settings-parser.h"
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen#include "mail-index.h"
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen#include "mail-user.h"
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen#include "mail-namespace.h"
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen#include "mail-storage-private.h"
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen#include "mail-storage-settings.h"
366eb7178f2c90d97134e0c2d1958f93fcdaba12Timo Sirainen
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen#include <stddef.h>
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen
fadd878cd6098f5b873c21c121209a922679dae4Timo Sirainenstatic bool mail_storage_settings_check(void *_set, pool_t pool, const char **error_r);
fadd878cd6098f5b873c21c121209a922679dae4Timo Sirainenstatic bool namespace_settings_check(void *_set, pool_t pool, const char **error_r);
471e447023ab73a73f0f78da2afc0c55905330ddTimo Sirainenstatic bool mailbox_settings_check(void *_set, pool_t pool, const char **error_r);
471e447023ab73a73f0f78da2afc0c55905330ddTimo Sirainenstatic bool mail_user_settings_check(void *_set, pool_t pool, const char **error_r);
471e447023ab73a73f0f78da2afc0c55905330ddTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen#undef DEF
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen#define DEF(type, name) \
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen { type, #name, offsetof(struct mail_storage_settings, name), NULL }
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenstatic const struct setting_define mail_storage_setting_defines[] = {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen DEF(SET_STR_VARS, mail_location),
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen { SET_ALIAS, "mail", 0, NULL },
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen DEF(SET_STR_VARS, mail_attachment_fs),
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen DEF(SET_STR_VARS, mail_attachment_dir),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, mail_attachment_hash),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_SIZE, mail_attachment_min_size),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR_VARS, mail_attribute_dict),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, mail_prefetch_count),
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen DEF(SET_STR, mail_cache_fields),
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen DEF(SET_STR, mail_always_cache_fields),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, mail_never_cache_fields),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, mail_cache_min_mail_count),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_TIME, mailbox_idle_check_interval),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, mail_max_keyword_length),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_TIME, mail_max_lock_timeout),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_TIME, mail_temp_scan_interval),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, mail_save_crlf),
55a210942dc7da58b2fd0b11bed8da6b030af5c1Timo Sirainen DEF(SET_ENUM, mail_fsync),
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen DEF(SET_BOOL, mmap_disable),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, dotlock_use_excl),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_BOOL, mail_nfs_storage),
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen DEF(SET_BOOL, mail_nfs_index),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, mailbox_list_index),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, mailbox_list_index_very_dirty_syncs),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, mail_debug),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, mail_full_filesystem_access),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, maildir_stat_dirs),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_BOOL, mail_shared_explicit_inbox),
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen DEF(SET_ENUM, lock_method),
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen DEF(SET_STR, pop3_uidl_format),
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen DEF(SET_STR, ssl_client_ca_dir),
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen DEF(SET_STR, ssl_client_ca_file),
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen DEF(SET_STR, ssl_crypto_device),
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen SETTING_DEFINE_LIST_END
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen};
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainenconst struct mail_storage_settings mail_storage_default_settings = {
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen .mail_location = "",
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen .mail_attachment_fs = "sis posix",
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .mail_attachment_dir = "",
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .mail_attachment_hash = "%{sha1}",
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen .mail_attachment_min_size = 1024*128,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen .mail_attribute_dict = "",
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen .mail_prefetch_count = 0,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen .mail_cache_fields = "flags",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mail_always_cache_fields = "",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mail_never_cache_fields = "imap.envelope",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mail_cache_min_mail_count = 0,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mailbox_idle_check_interval = 30,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mail_max_keyword_length = 50,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .mail_max_lock_timeout = 0,
45e62043058738e294f89504c319d852e25943ccTimo Sirainen .mail_temp_scan_interval = 7*24*60*60,
45e62043058738e294f89504c319d852e25943ccTimo Sirainen .mail_save_crlf = FALSE,
45e62043058738e294f89504c319d852e25943ccTimo Sirainen .mail_fsync = "optimized:never:always",
45e62043058738e294f89504c319d852e25943ccTimo Sirainen .mmap_disable = FALSE,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .dotlock_use_excl = TRUE,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .mail_nfs_storage = FALSE,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .mail_nfs_index = FALSE,
d5960ce1c0adda5c9e259bc429123ebc29c60baeTimo Sirainen .mailbox_list_index = FALSE,
d5960ce1c0adda5c9e259bc429123ebc29c60baeTimo Sirainen .mailbox_list_index_very_dirty_syncs = FALSE,
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen .mail_debug = FALSE,
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen .mail_full_filesystem_access = FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .maildir_stat_dirs = FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .mail_shared_explicit_inbox = FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .lock_method = "fcntl:flock:dotlock",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .pop3_uidl_format = "%08Xu%08Xv",
6eb30032b4a50c383dea4c9c74342d906de6ad36Timo Sirainen
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen .ssl_client_ca_dir = "",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen .ssl_client_ca_file = "",
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .ssl_crypto_device = ""
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen};
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenconst struct setting_parser_info mail_storage_setting_parser_info = {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen .module_name = "mail",
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .defines = mail_storage_setting_defines,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen .defaults = &mail_storage_default_settings,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen .type_offset = (size_t)-1,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen .struct_size = sizeof(struct mail_storage_settings),
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen .parent_offset = (size_t)-1,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen .parent = &mail_user_setting_parser_info,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen .check_func = mail_storage_settings_check
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen#undef DEF
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen#define DEF(type, name) \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { type, #name, offsetof(struct mailbox_settings, name), NULL }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainenstatic const struct setting_define mailbox_setting_defines[] = {
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen DEF(SET_STR, name),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { SET_ENUM, "auto", offsetof(struct mailbox_settings, autocreate), NULL } ,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, special_use),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, driver),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen SETTING_DEFINE_LIST_END
b87a4156eca6dcf6b29c504eb0cb9be2fdb11b63Timo Sirainen};
b87a4156eca6dcf6b29c504eb0cb9be2fdb11b63Timo Sirainen
b87a4156eca6dcf6b29c504eb0cb9be2fdb11b63Timo Sirainenconst struct mailbox_settings mailbox_default_settings = {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .name = "",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen .autocreate = MAILBOX_SET_AUTO_NO":"
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen MAILBOX_SET_AUTO_CREATE":"
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen MAILBOX_SET_AUTO_SUBSCRIBE,
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .special_use = "",
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .driver = ""
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen};
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenconst struct setting_parser_info mailbox_setting_parser_info = {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .defines = mailbox_setting_defines,
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen .defaults = &mailbox_default_settings,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
.type_offset = offsetof(struct mailbox_settings, name),
.struct_size = sizeof(struct mailbox_settings),
.parent_offset = (size_t)-1,
.parent = &mail_user_setting_parser_info,
.check_func = mailbox_settings_check
};
#undef DEF
#undef DEFLIST_UNIQUE
#define DEF(type, name) \
{ type, #name, offsetof(struct mail_namespace_settings, name), NULL }
#define DEFLIST_UNIQUE(field, name, defines) \
{ SET_DEFLIST_UNIQUE, name, \
offsetof(struct mail_namespace_settings, field), defines }
static const struct setting_define mail_namespace_setting_defines[] = {
DEF(SET_STR, name),
DEF(SET_ENUM, type),
DEF(SET_STR, separator),
DEF(SET_STR_VARS, prefix),
DEF(SET_STR_VARS, location),
{ SET_ALIAS, "mail", 0, NULL },
{ SET_ALIAS, "mail_location", 0, NULL },
DEF(SET_STR_VARS, alias_for),
DEF(SET_BOOL, inbox),
DEF(SET_BOOL, hidden),
DEF(SET_ENUM, list),
DEF(SET_BOOL, subscriptions),
DEF(SET_BOOL, ignore_on_failure),
DEF(SET_BOOL, disabled),
DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info),
SETTING_DEFINE_LIST_END
};
const struct mail_namespace_settings mail_namespace_default_settings = {
.name = "",
.type = "private:shared:public",
.separator = "",
.prefix = "",
.location = "",
.alias_for = NULL,
.inbox = FALSE,
.hidden = FALSE,
.list = "yes:no:children",
.subscriptions = TRUE,
.ignore_on_failure = FALSE,
.disabled = FALSE,
.mailboxes = ARRAY_INIT
};
const struct setting_parser_info mail_namespace_setting_parser_info = {
.defines = mail_namespace_setting_defines,
.defaults = &mail_namespace_default_settings,
.type_offset = offsetof(struct mail_namespace_settings, name),
.struct_size = sizeof(struct mail_namespace_settings),
.parent_offset = offsetof(struct mail_namespace_settings, user_set),
.parent = &mail_user_setting_parser_info,
.check_func = namespace_settings_check
};
#undef DEF
#undef DEFLIST_UNIQUE
#define DEF(type, name) \
{ type, #name, offsetof(struct mail_user_settings, name), NULL }
#define DEFLIST_UNIQUE(field, name, defines) \
{ SET_DEFLIST_UNIQUE, name, \
offsetof(struct mail_user_settings, field), defines }
static const struct setting_define mail_user_setting_defines[] = {
DEF(SET_STR, base_dir),
DEF(SET_STR, auth_socket_path),
DEF(SET_STR_VARS, mail_temp_dir),
DEF(SET_STR, mail_uid),
DEF(SET_STR, mail_gid),
DEF(SET_STR_VARS, mail_home),
DEF(SET_STR_VARS, mail_chroot),
DEF(SET_STR, mail_access_groups),
DEF(SET_STR, mail_privileged_group),
DEF(SET_STR, valid_chroot_dirs),
DEF(SET_UINT, first_valid_uid),
DEF(SET_UINT, last_valid_uid),
DEF(SET_UINT, first_valid_gid),
DEF(SET_UINT, last_valid_gid),
DEF(SET_STR, mail_plugins),
DEF(SET_STR, mail_plugin_dir),
DEF(SET_STR, mail_log_prefix),
DEFLIST_UNIQUE(namespaces, "namespace", &mail_namespace_setting_parser_info),
{ SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL },
SETTING_DEFINE_LIST_END
};
static const struct mail_user_settings mail_user_default_settings = {
.base_dir = PKG_RUNDIR,
.auth_socket_path = "auth-userdb",
.mail_temp_dir = "/tmp",
.mail_uid = "",
.mail_gid = "",
.mail_home = "",
.mail_chroot = "",
.mail_access_groups = "",
.mail_privileged_group = "",
.valid_chroot_dirs = "",
.first_valid_uid = 500,
.last_valid_uid = 0,
.first_valid_gid = 1,
.last_valid_gid = 0,
.mail_plugins = "",
.mail_plugin_dir = MODULEDIR,
.mail_log_prefix = "%s(%u): ",
.namespaces = ARRAY_INIT,
.plugin_envs = ARRAY_INIT
};
const struct setting_parser_info mail_user_setting_parser_info = {
.module_name = "mail",
.defines = mail_user_setting_defines,
.defaults = &mail_user_default_settings,
.type_offset = (size_t)-1,
.struct_size = sizeof(struct mail_user_settings),
.parent_offset = (size_t)-1,
.check_func = mail_user_settings_check
};
const void *
mail_user_set_get_driver_settings(const struct setting_parser_info *info,
const struct mail_user_settings *set,
const char *driver)
{
const void *dset;
dset = settings_find_dynamic(info, set, driver);
if (dset == NULL) {
i_panic("Default settings not found for storage driver %s",
driver);
}
return dset;
}
const struct mail_storage_settings *
mail_user_set_get_storage_set(struct mail_user *user)
{
return mail_user_set_get_driver_settings(user->set_info, user->set,
MAIL_STORAGE_SET_DRIVER_NAME);
}
const void *mail_storage_get_driver_settings(struct mail_storage *storage)
{
return mail_user_set_get_driver_settings(storage->user->set_info,
storage->user->set,
storage->name);
}
const struct dynamic_settings_parser *
mail_storage_get_dynamic_parsers(pool_t pool)
{
struct dynamic_settings_parser *parsers;
struct mail_storage *const *storages;
unsigned int i, j, count;
storages = array_get(&mail_storage_classes, &count);
parsers = p_new(pool, struct dynamic_settings_parser, 1 + count + 1);
parsers[0].name = MAIL_STORAGE_SET_DRIVER_NAME;
parsers[0].info = &mail_storage_setting_parser_info;
for (i = 0, j = 1; i < count; i++) {
if (storages[i]->v.get_setting_parser_info == NULL)
continue;
parsers[j].name = storages[i]->name;
parsers[j].info = storages[i]->v.get_setting_parser_info();
j++;
}
parsers[j] = NULL;
return parsers;
}
static void
fix_base_path(struct mail_user_settings *set, pool_t pool, const char **str)
{
if (*str != NULL && **str != '\0' && **str != '/')
*str = p_strconcat(pool, set->base_dir, "/", *str, NULL);
}
/* <settings checks> */
static bool mail_storage_settings_check(void *_set, pool_t pool ATTR_UNUSED,
const char **error_r)
{
struct mail_storage_settings *set = _set;
struct hash_format *format;
const char *p, *error;
bool uidl_format_ok;
char c;
if (set->mailbox_idle_check_interval == 0) {
*error_r = "mailbox_idle_check_interval must not be 0";
return FALSE;
}
if (strcmp(set->mail_fsync, "optimized") == 0)
set->parsed_fsync_mode = FSYNC_MODE_OPTIMIZED;
else if (strcmp(set->mail_fsync, "never") == 0)
set->parsed_fsync_mode = FSYNC_MODE_NEVER;
else if (strcmp(set->mail_fsync, "always") == 0)
set->parsed_fsync_mode = FSYNC_MODE_ALWAYS;
else {
*error_r = t_strdup_printf("Unknown mail_fsync: %s",
set->mail_fsync);
return FALSE;
}
if (set->mail_nfs_index && !set->mmap_disable) {
*error_r = "mail_nfs_index=yes requires mmap_disable=yes";
return FALSE;
}
if (set->mail_nfs_index &&
set->parsed_fsync_mode != FSYNC_MODE_ALWAYS) {
*error_r = "mail_nfs_index=yes requires mail_fsync=always";
return FALSE;
}
if (!file_lock_method_parse(set->lock_method,
&set->parsed_lock_method)) {
*error_r = t_strdup_printf("Unknown lock_method: %s",
set->lock_method);
return FALSE;
}
uidl_format_ok = FALSE;
for (p = set->pop3_uidl_format; *p != '\0'; p++) {
if (p[0] != '%' || p[1] == '\0')
continue;
c = var_get_key(++p);
switch (c) {
case 'v':
case 'u':
case 'm':
case 'f':
case 'g':
uidl_format_ok = TRUE;
break;
case '%':
break;
default:
*error_r = t_strdup_printf(
"Unknown pop3_uidl_format variable: %%%c", c);
return FALSE;
}
}
if (!uidl_format_ok) {
*error_r = "pop3_uidl_format setting doesn't contain any "
"%% variables.";
return FALSE;
}
if (strchr(set->mail_attachment_hash, '/') != NULL) {
*error_r = "mail_attachment_hash setting "
"must not contain '/' characters";
return FALSE;
}
if (hash_format_init(set->mail_attachment_hash, &format, &error) < 0) {
*error_r = t_strconcat("Invalid mail_attachment_hash setting: ",
error, NULL);
return FALSE;
}
if (strchr(set->mail_attachment_hash, '-') != NULL) {
*error_r = "mail_attachment_hash setting "
"must not contain '-' characters";
return FALSE;
}
hash_format_deinit_free(&format);
#ifndef CONFIG_BINARY
if (*set->ssl_client_ca_dir != '\0' &&
access(set->ssl_client_ca_dir, X_OK) < 0) {
*error_r = t_strdup_printf(
"ssl_client_ca_dir: access(%s) failed: %m",
set->ssl_client_ca_dir);
return FALSE;
}
#endif
return TRUE;
}
static bool namespace_settings_check(void *_set, pool_t pool ATTR_UNUSED,
const char **error_r)
{
struct mail_namespace_settings *ns = _set;
struct mail_namespace_settings *const *namespaces;
const char *name;
unsigned int i, count;
name = ns->prefix != NULL ? ns->prefix : "";
if (ns->separator[0] != '\0' && ns->separator[1] != '\0') {
*error_r = t_strdup_printf("Namespace '%s': "
"Hierarchy separator must be only one character long",
name);
return FALSE;
}
if (!uni_utf8_str_is_valid(name)) {
*error_r = t_strdup_printf("Namespace prefix not valid UTF8: %s",
name);
return FALSE;
}
if (ns->alias_for != NULL && !ns->disabled) {
if (array_is_created(&ns->user_set->namespaces)) {
namespaces = array_get(&ns->user_set->namespaces,
&count);
} else {
namespaces = NULL;
count = 0;
}
for (i = 0; i < count; i++) {
if (strcmp(namespaces[i]->prefix, ns->alias_for) == 0)
break;
}
if (i == count) {
*error_r = t_strdup_printf(
"Namespace '%s': alias_for points to "
"unknown namespace: %s", name, ns->alias_for);
return FALSE;
}
if (namespaces[i]->alias_for != NULL) {
*error_r = t_strdup_printf(
"Namespace '%s': alias_for chaining isn't "
"allowed: %s -> %s", name, ns->alias_for,
namespaces[i]->alias_for);
return FALSE;
}
}
return TRUE;
}
static bool mailbox_special_use_exists(const char *name)
{
if (name[0] != '\\')
return FALSE;
name++;
if (strcasecmp(name, "All") == 0)
return TRUE;
if (strcasecmp(name, "Archive") == 0)
return TRUE;
if (strcasecmp(name, "Drafts") == 0)
return TRUE;
if (strcasecmp(name, "Flagged") == 0)
return TRUE;
if (strcasecmp(name, "Junk") == 0)
return TRUE;
if (strcasecmp(name, "Sent") == 0)
return TRUE;
if (strcasecmp(name, "Trash") == 0)
return TRUE;
return FALSE;
}
static bool
mailbox_special_use_check(struct mailbox_settings *set, pool_t pool,
const char **error_r)
{
const char *const *uses, *str;
unsigned int i;
uses = t_strsplit_spaces(set->special_use, " ");
for (i = 0; uses[i] != NULL; i++) {
if (!mailbox_special_use_exists(uses[i])) {
*error_r = t_strdup_printf(
"mailbox %s: unknown special_use: %s",
set->name, uses[i]);
return FALSE;
}
}
/* make sure there are no extra spaces */
str = t_strarray_join(uses, " ");
if (strcmp(str, set->special_use) != 0)
set->special_use = p_strdup(pool, str);
return TRUE;
}
static bool mailbox_settings_check(void *_set, pool_t pool,
const char **error_r)
{
struct mailbox_settings *set = _set;
if (!uni_utf8_str_is_valid(set->name)) {
*error_r = t_strdup_printf("mailbox %s: name isn't valid UTF-8",
set->name);
return FALSE;
}
if (*set->special_use != '\0') {
if (!mailbox_special_use_check(set, pool, error_r))
return FALSE;
}
return TRUE;
}
static bool mail_user_settings_check(void *_set, pool_t pool ATTR_UNUSED,
const char **error_r ATTR_UNUSED)
{
struct mail_user_settings *set = _set;
#ifndef CONFIG_BINARY
fix_base_path(set, pool, &set->auth_socket_path);
#else
if (*set->mail_plugins != '\0' &&
access(set->mail_plugin_dir, R_OK | X_OK) < 0) {
*error_r = t_strdup_printf(
"mail_plugin_dir: access(%s) failed: %m",
set->mail_plugin_dir);
return FALSE;
}
#endif
return TRUE;
}
/* </settings checks> */