imap-settings.c revision b215a8a123623782554a83f3025ef4e771bd8f01
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen/* Copyright (c) 2005-2008 Dovecot authors, see the included COPYING file */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "lib.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "settings-parser.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "mail-storage-settings.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "imap-settings.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stddef.h>
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stdlib.h>
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen#include <unistd.h>
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic bool imap_settings_check(void *_set, const char **error_r);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#undef DEF
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#undef DEFLIST
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#define DEF(type, name) \
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { type, #name, offsetof(struct imap_settings, name), NULL }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#define DEFLIST(field, name, defines) \
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { SET_DEFLIST, name, offsetof(struct imap_settings, field), defines }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic struct setting_define imap_setting_defines[] = {
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen DEF(SET_STR, base_dir),
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen DEF(SET_STR, auth_socket_path),
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, mail_debug),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, shutdown_clients),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, verbose_proctitle),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, mail_plugins),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, mail_plugin_dir),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_UINT, imap_max_line_length),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, imap_capability),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, imap_client_workarounds),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, imap_logout_format),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, imap_id_send),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, imap_id_log),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen SETTING_DEFINE_LIST_END
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic struct imap_settings imap_default_settings = {
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen MEMBER(base_dir) PKG_RUNDIR,
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen MEMBER(auth_socket_path) "auth-master",
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(mail_debug) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(shutdown_clients) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(verbose_proctitle) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(mail_plugins) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(mail_plugin_dir) MODULEDIR"/imap",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* RFC-2683 recommends at least 8000 bytes. Some clients however don't
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen break large message sets to multiple commands, so we're pretty
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen liberal by default. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_max_line_length) 65536,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_capability) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_client_workarounds) "outlook-idle",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_logout_format) "bytes=%i/%o",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_id_send) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(imap_id_log) ""
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstruct setting_parser_info imap_setting_parser_info = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(defines) imap_setting_defines,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(defaults) &imap_default_settings,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(parent) NULL,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(dynamic_parsers) NULL,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(parent_offset) (size_t)-1,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(type_offset) (size_t)-1,
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen MEMBER(struct_size) sizeof(struct imap_settings),
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen MEMBER(check_func) imap_settings_check
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic pool_t settings_pool = NULL;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainenstatic void fix_base_path(struct imap_settings *set, const char **str)
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen{
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen if (*str != NULL && **str != '\0' && **str != '/') {
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen *str = p_strconcat(settings_pool,
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen set->base_dir, "/", *str, NULL);
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen }
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen}
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen/* <settings checks> */
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic bool imap_settings_check(void *_set, const char **error_r)
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen{
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen struct imap_settings *set = _set;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen#ifndef CONFIG_BINARY
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen fix_base_path(set, &set->auth_socket_path);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen#endif
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (*set->mail_plugins != '\0' &&
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen access(set->mail_plugin_dir, R_OK | X_OK) < 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = t_strdup_printf(
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen "mail_plugin_dir: access(%s) failed: %m",
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen set->mail_plugin_dir);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return FALSE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return TRUE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen}
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen/* </settings checks> */
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic void
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenparse_expand_vars(struct setting_parser_context *parser, const char *value)
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen{
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen const char *const *expanded;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen expanded = t_strsplit(value, " ");
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen settings_parse_set_keys_expandeded(parser, settings_pool, expanded);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen /* settings from userdb are in the VARS_EXPANDED list. for each
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen unknown setting in the list assume it's a plugin setting. */
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen for (; *expanded != NULL; expanded++) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (settings_parse_is_valid_key(parser, *expanded))
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen continue;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen value = getenv(t_str_ucase(*expanded));
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (value == NULL)
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen continue;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen settings_parse_line(parser, t_strconcat("plugin/", *expanded,
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen "=", value, NULL));
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen}
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenvoid imap_settings_read(const struct imap_settings **set_r,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct mail_user_settings **user_set_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen static const struct setting_parser_info *roots[] = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen &imap_setting_parser_info,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen &mail_user_setting_parser_info
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen };
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct setting_parser_context *parser;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen const char *value, *error;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen void **sets;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (settings_pool == NULL)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen settings_pool = pool_alloconly_create("imap settings", 2048);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen p_clear(settings_pool);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mail_storage_namespace_defines_init(settings_pool);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen parser = settings_parser_init_list(settings_pool,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen roots, N_ELEMENTS(roots),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (settings_parse_environ(parser) < 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_fatal("Error reading configuration: %s",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen settings_parser_get_error(parser));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen value = getenv("VARS_EXPANDED");
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (value != NULL)
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen parse_expand_vars(parser, value);
ad0f1d2f2e7f1d42b2de403b04a0ffe1675109ccTimo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (settings_parser_check(parser, &error) < 0)
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen i_fatal("Invalid settings: %s", error);
e5e526b31fb261f2333e6537e42ac356d7fa34d0Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen sets = settings_parser_get_list(parser);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *set_r = sets[0];
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen *user_set_r = sets[1];
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen settings_parser_deinit(&parser);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}