Mercurial > dovecot > core-2.2
changeset 9011:c37f7113b1ee HEAD
doveconf now checks that all settings are ok by calling check functions.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 09 Feb 2009 18:00:59 -0500 |
parents | 185cc7ad6a30 |
children | 8d4052450e09 |
files | src/auth/auth-settings.c src/config/config-parser.c src/config/settings-get.pl src/imap/imap-settings.c src/lib-settings/settings-parser.c src/lib-settings/settings-parser.h src/lib-storage/mail-storage-settings.c src/lib-storage/mail-storage-settings.h src/login-common/login-settings.c src/master/master-settings.c src/plugins/expire/expire-settings.c src/pop3/pop3-settings.c |
diffstat | 12 files changed, 341 insertions(+), 123 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/auth/auth-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -12,6 +12,8 @@ extern struct setting_parser_info auth_setting_parser_info; extern struct setting_parser_info auth_root_setting_parser_info; +static bool auth_settings_check(void *_set, const char **error_r); + #undef DEF #define DEF(type, name) \ { type, #name, offsetof(struct auth_socket_unix_settings, name), NULL } @@ -239,7 +241,8 @@ MEMBER(parent_offset) offsetof(struct auth_settings, root), MEMBER(type_offset) offsetof(struct auth_settings, name), - MEMBER(struct_size) sizeof(struct auth_settings) + MEMBER(struct_size) sizeof(struct auth_settings), + MEMBER(check_func) auth_settings_check }; #undef DEF @@ -283,14 +286,18 @@ } } -static void auth_settings_check(struct auth_settings *set) +/* <settings checks> */ +static bool auth_settings_check(void *_set ATTR_UNUSED, + const char **error_r ATTR_UNUSED) { +#ifndef CONFIG_BINARY + struct auth_settings *set = _set; struct auth_socket_unix_settings *const *u; struct auth_socket_settings *const *sockets; unsigned int i, j, count, count2; if (!array_is_created(&set->sockets)) - return; + return TRUE; sockets = array_get(&set->sockets, &count); for (i = 0; i < count; i++) { @@ -305,13 +312,17 @@ fix_base_path(set, &u[j]->path); } } +#endif + return TRUE; } +/* </settings checks> */ struct auth_settings *auth_settings_read(const char *name) { struct setting_parser_context *parser; struct auth_root_settings *set; struct auth_settings *const *auths; + const char *error; unsigned int i, count; if (settings_pool == NULL) @@ -330,16 +341,17 @@ settings_parser_get_error(parser)); } + if (settings_parser_check(parser, &error) < 0) + i_fatal("Invalid settings: %s", error); + set = settings_parser_get(parser); settings_parser_deinit(&parser); if (array_is_created(&set->auths)) { auths = array_get(&set->auths, &count); for (i = 0; i < count; i++) { - if (strcmp(auths[i]->name, name) == 0) { - auth_settings_check(auths[i]); + if (strcmp(auths[i]->name, name) == 0) return auths[i]; - } } } i_fatal("Error reading configuration: No auth section: %s", name);
--- a/src/config/config-parser.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/config/config-parser.c Mon Feb 09 18:00:59 2009 -0500 @@ -311,6 +311,7 @@ ARRAY_DEFINE(pathlen_stack, unsigned int); ARRAY_TYPE(const_string) auth_defaults; const struct setting_parser_info *info; + struct config_setting_parser_list *l; unsigned int pathlen = 0; unsigned int counter = 0, auth_counter = 0, cur_counter; const char *errormsg, *name, *type_name; @@ -573,5 +574,15 @@ if (line == NULL && input != NULL) goto prevfile; + for (l = config_setting_parsers; l->module_name != NULL; l++) { + if (l->parser == NULL) + continue; + + if (!settings_parser_check(l->parser, &errormsg)) { + i_fatal("Error in configuration file %s: %s", + path, errormsg); + } + } + config_export(dest); }
--- a/src/config/settings-get.pl Tue Feb 03 12:05:35 2009 -0500 +++ b/src/config/settings-get.pl Mon Feb 09 18:00:59 2009 -0500 @@ -2,9 +2,11 @@ use strict; print '#include "lib.h"'."\n"; +print '#include "array.h"'."\n"; print '#include "settings-parser.h"'."\n"; print '#include "all-settings.h"'."\n"; print '#include <stddef.h>'."\n"; +print '#include <unistd.h>'."\n"; print '#define CONFIG_BINARY'."\n"; my %parsers = {}; @@ -16,6 +18,8 @@ my $state = 0; my $file_contents = ""; my $externs = ""; + my $code = ""; + my %funcs; while (<$f>) { my $write = 0; @@ -29,6 +33,9 @@ $parsers{$2} = 1; } elsif (/^extern struct setting_parser_info (.*);/) { $externs .= "extern struct setting_parser_info $1;\n"; + } elsif (/\/\* <settings checks> \*\//) { + $state = 4; + $code .= $_; } if (/#define.*DEF/ || /^#undef.*DEF/) { @@ -38,6 +45,9 @@ } elsif ($state == 2) { $write = 1; $state = 0 if (!/\\$/); + } elsif ($state == 4) { + $code .= $_; + $state = 0 if (/\/\* <\/settings checks> \*\//); } if ($state == 1 || $state == 3) { @@ -68,6 +78,7 @@ print "/* $file */\n"; print $externs; + print $code; print $file_contents; close $f;
--- a/src/imap/imap-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/imap/imap-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -7,6 +7,9 @@ #include <stddef.h> #include <stdlib.h> +#include <unistd.h> + +static bool imap_settings_check(void *_set, const char **error_r); #undef DEF #undef DEFLIST @@ -67,7 +70,8 @@ MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, - MEMBER(struct_size) sizeof(struct imap_settings) + MEMBER(struct_size) sizeof(struct imap_settings), + MEMBER(check_func) imap_settings_check }; static pool_t settings_pool = NULL; @@ -80,6 +84,48 @@ } } +/* <settings checks> */ +static bool imap_settings_check(void *_set, const char **error_r) +{ + struct imap_settings *set = _set; + +#ifndef CONFIG_BINARY + fix_base_path(set, &set->auth_socket_path); +#endif + + 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; + } + return TRUE; +} +/* </settings checks> */ + +static void +parse_expand_vars(struct setting_parser_context *parser, const char *value) +{ + const char *const *expanded; + + expanded = t_strsplit(value, " "); + settings_parse_set_keys_expandeded(parser, settings_pool, expanded); + /* settings from userdb are in the VARS_EXPANDED list. for each + unknown setting in the list assume it's a plugin setting. */ + for (; *expanded != NULL; expanded++) { + if (settings_parse_is_valid_key(parser, *expanded)) + continue; + + value = getenv(t_str_ucase(*expanded)); + if (value == NULL) + continue; + + settings_parse_line(parser, t_strconcat("plugin/", *expanded, + "=", value, NULL)); + } +} + void imap_settings_read(const struct imap_settings **set_r, const struct mail_user_settings **user_set_r) { @@ -88,8 +134,7 @@ &mail_user_setting_parser_info }; struct setting_parser_context *parser; - struct imap_settings *set; - const char *const *expanded, *value; + const char *value, *error; void **sets; if (settings_pool == NULL) @@ -108,27 +153,15 @@ settings_parser_get_error(parser)); } - expanded = t_strsplit(getenv("VARS_EXPANDED"), " "); - settings_parse_set_keys_expandeded(parser, settings_pool, expanded); - /* settings from userdb are in the VARS_EXPANDED list. for each - unknown setting in the list assume it's a plugin setting. */ - for (; *expanded != NULL; expanded++) { - if (settings_parse_is_valid_key(parser, *expanded)) - continue; + value = getenv("VARS_EXPANDED"); + if (value != NULL) + parse_expand_vars(parser, value); - value = getenv(t_str_ucase(*expanded)); - if (value == NULL) - continue; - - settings_parse_line(parser, t_strconcat("plugin/", *expanded, - "=", value, NULL)); - } + if (settings_parser_check(parser, &error) < 0) + i_fatal("Invalid settings: %s", error); sets = settings_parser_get_list(parser); - set = sets[0]; - fix_base_path(set, &set->auth_socket_path); - - *set_r = set; + *set_r = sets[0]; *user_set_r = sets[1]; settings_parser_deinit(&parser); }
--- a/src/lib-settings/settings-parser.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/lib-settings/settings-parser.c Mon Feb 09 18:00:59 2009 -0500 @@ -642,6 +642,51 @@ return ret; } +static bool settings_parser_check_info(const struct setting_parser_info *info, + void *set, const char **error_r) +{ + const struct setting_define *def; + const ARRAY_TYPE(void_array) *val; + void *const *children; + unsigned int i, count; + + if (info->check_func != NULL) { + if (!info->check_func(set, error_r)) + return FALSE; + } + + for (def = info->defines; def->key != NULL; def++) { + if (def->type != SET_DEFLIST) + continue; + + val = CONST_PTR_OFFSET(set, def->offset);; + if (!array_is_created(val)) + continue; + + children = array_get(val, &count); + for (i = 0; i < count; i++) { + if (!settings_parser_check_info(def->list_info, + children[i], error_r)) + return FALSE; + } + } + return TRUE; +} + +bool settings_parser_check(struct setting_parser_context *ctx, + const char **error_r) +{ + unsigned int i; + + for (i = 0; i < ctx->root_count; i++) { + if (!settings_parser_check_info(ctx->roots[i].info, + ctx->roots[i].set_struct, + error_r)) + return FALSE; + } + return TRUE; +} + void settings_parse_set_expanded(struct setting_parser_context *ctx, bool is_expanded) {
--- a/src/lib-settings/settings-parser.h Tue Feb 03 12:05:35 2009 -0500 +++ b/src/lib-settings/settings-parser.h Mon Feb 09 18:00:59 2009 -0500 @@ -57,6 +57,7 @@ size_t parent_offset; size_t type_offset; size_t struct_size; + bool (*check_func)(void *set, const char **error_r); }; ARRAY_DEFINE_TYPE(setting_parser_info, struct setting_parser_info); @@ -118,6 +119,9 @@ int settings_parse_exec(struct setting_parser_context *ctx, const char *bin_path, const char *config_path, const char *service); +/* Call all check_func()s to see if currently parsed settings are valid. */ +bool settings_parser_check(struct setting_parser_context *ctx, + const char **error_r); /* While parsing values, specifies if STR_VARS strings are already expanded. */ void settings_parse_set_expanded(struct setting_parser_context *ctx,
--- a/src/lib-storage/mail-storage-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/lib-storage/mail-storage-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -11,6 +11,9 @@ #include <stddef.h> +static bool mail_storage_settings_check(void *_set, const char **error_r); +static bool namespace_settings_check(void *_set, const char **error_r); + #undef DEF #define DEF(type, name) \ { type, #name, offsetof(struct mail_storage_settings, name), NULL } @@ -66,7 +69,8 @@ MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, - MEMBER(struct_size) sizeof(struct mail_storage_settings) + MEMBER(struct_size) sizeof(struct mail_storage_settings), + MEMBER(check_func) mail_storage_settings_check }; #undef DEF @@ -108,9 +112,10 @@ MEMBER(parent) &mail_user_setting_parser_info, MEMBER(dynamic_parsers) NULL, - MEMBER(parent_offset) (size_t)-1, + MEMBER(parent_offset) offsetof(struct mail_namespace_settings, user_set), MEMBER(type_offset) offsetof(struct mail_namespace_settings, type), - MEMBER(struct_size) sizeof(struct mail_namespace_settings) + MEMBER(struct_size) sizeof(struct mail_namespace_settings), + MEMBER(check_func) namespace_settings_check }; #undef DEF @@ -208,3 +213,60 @@ settings_parser_info_update(pool, parsers[j-1].info->parent, parsers); } + +/* <settings checks> */ +static bool mail_storage_settings_check(void *_set, const char **error_r) +{ + const struct mail_storage_settings *set = _set; + + 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->fsync_disable) { + *error_r = "mail_nfs_index=yes requires fsync_disable=no"; + return FALSE; + } + return TRUE; +} + +static bool namespace_settings_check(void *_set, 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 != NULL && + 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 (ns->alias_for != NULL) { + namespaces = array_get(&ns->user_set->namespaces, &count); + 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; +} +/* </settings checks> */
--- a/src/lib-storage/mail-storage-settings.h Tue Feb 03 12:05:35 2009 -0500 +++ b/src/lib-storage/mail-storage-settings.h Mon Feb 09 18:00:59 2009 -0500 @@ -35,6 +35,8 @@ bool hidden; const char *list; bool subscriptions; + + struct mail_user_settings *user_set; }; struct mail_user_settings {
--- a/src/login-common/login-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/login-common/login-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -7,6 +7,8 @@ #include <stddef.h> #include <unistd.h> +static bool login_settings_check(void *_set, const char **error_r); + #undef DEF #define DEF(type, name) \ { type, #name, offsetof(struct login_settings, name), NULL } @@ -86,66 +88,58 @@ MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, - MEMBER(struct_size) sizeof(struct login_settings) + MEMBER(struct_size) sizeof(struct login_settings), + MEMBER(check_func) login_settings_check }; static pool_t settings_pool = NULL; -static int ssl_settings_check(struct login_settings *set ATTR_UNUSED) +/* <settings checks> */ +static int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r) { + struct login_settings *set = _set; + #ifndef HAVE_SSL - i_error("SSL support not compiled in but ssl_disable=no"); + *error_r = "SSL support not compiled in but ssl_disable=no"; return FALSE; #else if (*set->ssl_cert_file == '\0') { - i_error("ssl_cert_file not set"); + *error_r = "ssl_cert_file not set"; return FALSE; } if (access(set->ssl_cert_file, R_OK) < 0) { - i_error("ssl_cert_file: access(%s) failed: %m", - set->ssl_cert_file); + *error_r = t_strdup_printf("ssl_cert_file: access(%s) failed: %m", + set->ssl_cert_file); return FALSE; } if (*set->ssl_key_file == '\0') { - i_error("ssl_key_file not set"); + *error_r = "ssl_key_file not set"; return FALSE; } if (access(set->ssl_key_file, R_OK) < 0) { - i_error("ssl_key_file: access(%s) failed: %m", - set->ssl_key_file); + *error_r = t_strdup_printf("ssl_key_file: access(%s) failed: %m", + set->ssl_key_file); return FALSE; } - if (*set->ssl_ca_file != '\0' && - access(set->ssl_ca_file, R_OK) < 0) { - i_error("ssl_ca_file: access(%s) failed: %m", - set->ssl_ca_file); + if (*set->ssl_ca_file != '\0' && access(set->ssl_ca_file, R_OK) < 0) { + *error_r = t_strdup_printf("ssl_ca_file: access(%s) failed: %m", + set->ssl_ca_file); return FALSE; } if (set->ssl_verify_client_cert && *set->ssl_ca_file == '\0') { - i_error("ssl_verify_client_cert set, but ssl_ca_file not"); + *error_r = "ssl_verify_client_cert set, but ssl_ca_file not"; return FALSE; } return TRUE; #endif } -static void login_settings_check(struct login_settings *set) +static bool login_settings_check(void *_set, const char **error_r) { - if (strcmp(set->ssl, "no") == 0) { - /* disabled */ - } else if (strcmp(set->ssl, "yes") == 0) { - if (!ssl_settings_check(set)) - set->ssl = "no"; - } else if (strcmp(set->ssl, "required") == 0) { - if (!ssl_settings_check(set)) - i_fatal("Couldn't initialize ssl with ssl=required"); - set->disable_plaintext_auth = TRUE; - } else { - i_fatal("Unknown ssl setting value: %s", set->ssl); - } + struct login_settings *set = _set; set->log_format_elements_split = t_strsplit(set->login_log_format_elements, " "); @@ -154,14 +148,34 @@ /* if we require valid cert, make sure we also ask for it */ set->ssl_verify_client_cert = TRUE; } - if (set->login_max_connections < 1) - i_fatal("login_max_connections must be at least 1"); + if (set->login_max_connections < 1) { + *error_r = "login_max_connections must be at least 1"; + return FALSE; + } + + if (strcmp(set->ssl, "no") == 0) { + /* disabled */ + } else if (strcmp(set->ssl, "yes") == 0) { + if (!ssl_settings_check(set, error_r)) + return FALSE; + } else if (strcmp(set->ssl, "required") == 0) { + if (!ssl_settings_check(set, error_r)) + return FALSE; + set->disable_plaintext_auth = TRUE; + } else { + *error_r = t_strdup_printf("Unknown ssl setting value: %s", + set->ssl); + return FALSE; + } + return TRUE; } +/* </settings checks> */ struct login_settings *login_settings_read(void) { struct setting_parser_context *parser; struct login_settings *set; + const char *error; if (settings_pool == NULL) settings_pool = pool_alloconly_create("settings pool", 512); @@ -177,8 +191,10 @@ settings_parser_get_error(parser)); } + if (settings_parser_check(parser, &error) < 0) + i_fatal("Invalid settings: %s", error); + set = settings_parser_get(parser); settings_parser_deinit(&parser); - login_settings_check(set); return set; }
--- a/src/master/master-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/master/master-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -699,16 +699,8 @@ return FALSE; } - if (strcmp(set->ssl, "no") != 0 && - strcmp(set->ssl, "yes") != 0 && - strcmp(set->ssl, "required") != 0) { - i_error("ssl setting: Invalid value: %s", set->ssl); - return FALSE; - } #ifndef HAVE_SSL if (strcmp(set->ssl, "no") != 0) { - - i_error("SSL support not compiled in but ssl=%s", set->ssl); return FALSE; } @@ -726,6 +718,10 @@ i_error("max_mail_processes must be at least 1"); return FALSE; } + if (strcmp(set->login_dir, set->base_dir) == 0) { + i_error("login_dir can't be the same as base_dir"); + return FALSE; + } if (set->last_valid_uid != 0 && set->first_valid_uid > set->last_valid_uid) { @@ -755,30 +751,13 @@ return FALSE; } -#if 0 //FIXME - if (set->mail_nfs_index && !set->mmap_disable) { - i_error("mail_nfs_index=yes requires mmap_disable=yes"); - return FALSE; - } - if (set->mail_nfs_index && set->fsync_disable) { - i_error("mail_nfs_index=yes requires fsync_disable=no"); - return FALSE; - } -#ifdef HAVE_MODULES - if (*set->mail_plugins != '\0' && - access(set->mail_plugin_dir, R_OK | X_OK) < 0) { - i_error("mail_plugin_dir: Can't access directory: %s: %m", - set->mail_plugin_dir); - return FALSE; - } -#else +#ifndef HAVE_MODULES if (*set->mail_plugins != '\0') { i_error("mail_plugins: Plugin support wasn't built into Dovecot, " "can't load plugins: %s", set->mail_plugins); return FALSE; } #endif -#endif return TRUE; }
--- a/src/plugins/expire/expire-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/plugins/expire/expire-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -46,6 +46,28 @@ } } +static void +parse_expand_vars(struct setting_parser_context *parser, const char *value) +{ + const char *const *expanded; + + expanded = t_strsplit(value, " "); + settings_parse_set_keys_expandeded(parser, settings_pool, expanded); + /* settings from userdb are in the VARS_EXPANDED list. for each + unknown setting in the list assume it's a plugin setting. */ + for (; *expanded != NULL; expanded++) { + if (settings_parse_is_valid_key(parser, *expanded)) + continue; + + value = getenv(t_str_ucase(*expanded)); + if (value == NULL) + continue; + + settings_parse_line(parser, t_strconcat("plugin/", *expanded, + "=", value, NULL)); + } +} + void expire_settings_read(const struct expire_settings **set_r, const struct mail_user_settings **user_set_r) { @@ -55,7 +77,7 @@ }; struct setting_parser_context *parser; struct expire_settings *set; - const char *const *expanded, *value; + const char *value; void **sets; if (settings_pool == NULL) @@ -74,21 +96,9 @@ settings_parser_get_error(parser)); } - expanded = t_strsplit(getenv("VARS_EXPANDED"), " "); - settings_parse_set_keys_expandeded(parser, settings_pool, expanded); - /* settings from userdb are in the VARS_EXPANDED list. for each - unknown setting in the list assume it's a plugin setting. */ - for (; *expanded != NULL; expanded++) { - if (settings_parse_is_valid_key(parser, *expanded)) - continue; - - value = getenv(t_str_ucase(*expanded)); - if (value == NULL) - continue; - - settings_parse_line(parser, t_strconcat("plugin/", *expanded, - "=", value, NULL)); - } + value = getenv("VARS_EXPANDED"); + if (value != NULL) + parse_expand_vars(parser, value); sets = settings_parser_get_list(parser); set = sets[0];
--- a/src/pop3/pop3-settings.c Tue Feb 03 12:05:35 2009 -0500 +++ b/src/pop3/pop3-settings.c Mon Feb 09 18:00:59 2009 -0500 @@ -7,6 +7,9 @@ #include <stddef.h> #include <stdlib.h> +#include <unistd.h> + +static bool pop3_settings_check(void *_set, const char **error_r); #undef DEF #undef DEFLIST @@ -66,7 +69,8 @@ MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, - MEMBER(struct_size) sizeof(struct pop3_settings) + MEMBER(struct_size) sizeof(struct pop3_settings), + MEMBER(check_func) pop3_settings_check }; static pool_t settings_pool = NULL; @@ -79,6 +83,48 @@ } } +/* <settings checks> */ +static bool pop3_settings_check(void *_set, const char **error_r) +{ + struct pop3_settings *set = _set; + +#ifndef CONFIG_BINARY + fix_base_path(set, &set->auth_socket_path); +#endif + + 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; + } + return TRUE; +} +/* </settings checks> */ + +static void +parse_expand_vars(struct setting_parser_context *parser, const char *value) +{ + const char *const *expanded; + + expanded = t_strsplit(value, " "); + settings_parse_set_keys_expandeded(parser, settings_pool, expanded); + /* settings from userdb are in the VARS_EXPANDED list. for each + unknown setting in the list assume it's a plugin setting. */ + for (; *expanded != NULL; expanded++) { + if (settings_parse_is_valid_key(parser, *expanded)) + continue; + + value = getenv(t_str_ucase(*expanded)); + if (value == NULL) + continue; + + settings_parse_line(parser, t_strconcat("plugin/", *expanded, + "=", value, NULL)); + } +} + void pop3_settings_read(const struct pop3_settings **set_r, const struct mail_user_settings **user_set_r) { @@ -87,8 +133,7 @@ &mail_user_setting_parser_info }; struct setting_parser_context *parser; - struct pop3_settings *set; - const char *const *expanded, *value; + const char *value, *error; void **sets; if (settings_pool == NULL) @@ -107,27 +152,15 @@ settings_parser_get_error(parser)); } - expanded = t_strsplit(getenv("VARS_EXPANDED"), " "); - settings_parse_set_keys_expandeded(parser, settings_pool, expanded); - /* settings from userdb are in the VARS_EXPANDED list. for each - unknown setting in the list assume it's a plugin setting. */ - for (; *expanded != NULL; expanded++) { - if (settings_parse_is_valid_key(parser, *expanded)) - continue; + value = getenv("VARS_EXPANDED"); + if (value != NULL) + parse_expand_vars(parser, value); - value = getenv(t_str_ucase(*expanded)); - if (value == NULL) - continue; - - settings_parse_line(parser, t_strconcat("plugin/", *expanded, - "=", value, NULL)); - } + if (settings_parser_check(parser, &error) < 0) + i_fatal("Invalid settings: %s", error); sets = settings_parser_get_list(parser); - set = sets[0]; - fix_base_path(set, &set->auth_socket_path); - - *set_r = set; + *set_r = sets[0]; *user_set_r = sets[1]; settings_parser_deinit(&parser); }