master-settings.c revision 770d5738e9e3e7e65af6246272f1094f7a94fe35
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov struct auth_userdb_settings *auth_userdb;
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose#define DEF_STR(name) DEF_STRUCT_STR(name, auth_settings)
3d9bafcbb5c0fbf23351004ded4dea6aa13127fcSumit Bose#define DEF_INT(name) DEF_STRUCT_INT(name, auth_settings)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, auth_settings)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose#define DEF_STR(name) DEF_STRUCT_STR(name, socket_settings)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose#define DEF_INT(name) DEF_STRUCT_INT(name, socket_settings)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bose#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, socket_settings)
949fbc93defad394648b2651b43a7bbfa5bff42bSumit Bosestatic struct setting_def socket_setting_defs[] = {
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Bosestatic struct setting_def auth_socket_setting_defs[] = {
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Bose#define DEF_STR(name) DEF_STRUCT_STR(name, auth_passdb_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#define DEF_INT(name) DEF_STRUCT_INT(name, auth_passdb_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, auth_passdb_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic struct setting_def auth_passdb_setting_defs[] = {
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidekstatic struct setting_def auth_userdb_setting_defs[] = {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#define DEF_STR(name) DEF_STRUCT_STR(name, namespace_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#define DEF_INT(name) DEF_STRUCT_INT(name, namespace_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, namespace_settings)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic struct setting_def namespace_setting_defs[] = {
bfdb2eeed95bde6cd065a9a47a7cb1773990ccfbOndrej Kos MEMBER(log_timestamp) DEFAULT_FAILURE_STAMP_FORMAT,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* general */
a473fb88e6015cf0ccbd2e9005c7e6acca18f452Pavel Březina MEMBER(ssl_cert_file) SSLDIR"/certs/dovecot.pem",
a473fb88e6015cf0ccbd2e9005c7e6acca18f452Pavel Březina MEMBER(ssl_key_file) SSLDIR"/private/dovecot.pem",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov MEMBER(ssl_cert_username_field) "commonName",
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek MEMBER(login_log_format_elements) "user=<%u> method=%m rip=%r lip=%l %c",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov MEMBER(login_process_per_connection) TRUE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov MEMBER(mail_never_cache_fields) "imap.envelope",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MEMBER(mail_full_filesystem_access) FALSE,
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MEMBER(maildir_copy_preserve_filename) FALSE,
af58b15fa7f20e33736d79c6a4b3becb568517caLukas Slebodnik MEMBER(mail_executable) PKG_LIBEXECDIR"/imap",
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagher MEMBER(pop3_logout_format) "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s",
4f3fd1fb264a7eaf3a9d062d49e071b0d17e4debStephen Gallagherstruct auth_settings default_auth_settings = {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MEMBER(executable) PKG_LIBEXECDIR"/dovecot-auth",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MEMBER(username_chars) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher MEMBER(winbind_helper_path) "/usr/bin/ntlm_auth",
cb446b6149d28c204954ae75143b89aef14115dcSumit Bosestruct socket_settings default_socket_settings = {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov#define DEFAULT_CLIENT_SOCKET_PATH "auth-client"
cb446b6149d28c204954ae75143b89aef14115dcSumit Bosestruct namespace_settings default_namespace_settings = {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic pool_t settings_pool, settings2_pool;
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstruct server_settings *settings_root = NULL;
cb446b6149d28c204954ae75143b89aef14115dcSumit Bosestatic void fix_base_path(struct settings *set, const char **str)
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagher if (*str != NULL && **str != '\0' && **str != '/') {
505e75ba28b42bb3de7a6d55de825091b70cc2b2Stephen Gallagherstatic bool parse_uid(const char *str, uid_t *uid_r)
cb446b6149d28c204954ae75143b89aef14115dcSumit Bose if (*p == '\0')
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagherstatic bool parse_gid(const char *str, gid_t *gid_r)
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher if (*p == '\0')
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagherstatic bool get_login_uid(struct settings *set)
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher if ((pw = getpwnam(set->login_user)) == NULL) {
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher i_error("Login user doesn't exist: %s", set->login_user);
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher else if (set->server->login_gid != pw->pw_gid) {
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher i_error("All login process users must belong to same group "
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagher "(%s vs %s)", dec2str(set->server->login_gid),
45f75fc8e98092fa48faa3d180fd42f7efd51486Stephen Gallagherstatic bool auth_settings_verify(struct auth_settings *auth)
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher if ((pw = getpwnam(auth->user)) == NULL) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("Auth user doesn't exist: %s", auth->user);
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher if (auth->parent->defaults->login_uid == pw->pw_uid &&
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("login_user %s (uid %s) must not be same as auth_user",
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher if (access(t_strcut(auth->executable, ' '), X_OK) < 0) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("Can't use auth executable %s: %m",
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher fix_base_path(auth->parent->defaults, &auth->chroot);
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher if (*auth->chroot != '\0' && access(auth->chroot, X_OK) < 0) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("Can't access auth chroot directory %s: %m",
bfb40893be20b45279a40188cf16ef0eec1f9423Sumit Bose if (auth->ssl_require_client_cert || auth->ssl_username_from_cert) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher /* if we require valid cert, make sure we also ask for it */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov auth->parent->pop3->ssl_verify_client_cert = TRUE;
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher auth->parent->imap->ssl_verify_client_cert = TRUE;
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher for (s = auth->sockets; s != NULL; s = s->next) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher if (auth->count > 1 && strcmp(s->type, "listen") == 0) {
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("Currently auth process count must be 1 if "
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher "you're using auth socket listeners.");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov fix_base_path(auth->parent->defaults, &s->master.path);
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher fix_base_path(auth->parent->defaults, &s->client.path);
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidekstatic bool namespace_settings_verify(struct server_settings *server,
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek const char *name;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ns->separator[0] != '\0' && ns->separator[1] != '\0') {
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek "Hierarchy separator must be only one character long",
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher i_error("Namespace '%s': Invalid list value: %s",
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose for (n = server->namespaces; n != ns; n = n->next) {
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose if (n == ns) {
1e4a582e29c119e2c0e58a02dcb41b829e6b5e39Lukas Slebodnik i_error("Namespace '%s': alias_for chaining isn't "
cdcca90249aadb72bf2978a63c202c5b68642224Lukas Slebodnikstatic const char *get_directory(const char *path)
fdda4b659fa3be3027df91a2b053835186ec2c59Sumit Bosestatic bool settings_is_active(struct settings *set)
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose /* we're probably using this with --exec-mail */
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bosestatic bool settings_have_connect_sockets(struct settings *set)
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose for (server = set->server; server != NULL; server = server->next) {
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose for (auth = server->auths; auth != NULL; auth = auth->next) {
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bosestatic bool settings_have_nonplaintext_auths(struct settings *set)
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose const char *const *tmp;
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose for (server = set->server; server != NULL; server = server->next) {
b2c7b6fe7a6b9ef3af8d4d3037fe83d6e9bfd6a5Sumit Bose for (auth = server->auths; auth != NULL; auth = auth->next) {
return TRUE;
return FALSE;
unsigned int prefix_len;
#ifdef HAVE_MODULES
static const char *args[] = {
unsigned int pos;
if (uid != 0) {
return NULL;
&pid);
return NULL;
alarm(0);
if (status != 0) {
status);
return NULL;
pos = 0;
if (ret < 0) {
return NULL;
return NULL;
return TRUE;
return FALSE;
return TRUE;
const char *dir;
int facility;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
dir);
return FALSE;
return FALSE;
return FALSE;
#ifdef HAVE_SSL
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
#ifdef HAVE_MODULES
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
#ifdef HAVE_MODULES
return FALSE;
return TRUE;
if (nochecks)
return TRUE;
return FALSE;
int fd;
if (ret <= 0) {
if (ret == 0)
ret--;
static struct auth_settings *
return auth;
static struct auth_settings *
const char **errormsg)
return NULL;
return NULL;
static struct auth_passdb_settings *
return as;
static struct auth_userdb_settings *
return as;
static struct auth_socket_settings *
return as;
static struct auth_socket_settings *
const char **errormsg)
return NULL;
return NULL;
static struct namespace_settings *
return ns;
static struct namespace_settings *
const char **errormsg)
return NULL;
const char *error;
case SETTINGS_TYPE_ROOT:
case SETTINGS_TYPE_SERVER:
return NULL;
return error;
case SETTINGS_TYPE_AUTH:
case SETTINGS_TYPE_NAMESPACE:
case SETTINGS_TYPE_SOCKET:
case SETTINGS_TYPE_DICT:
return NULL;
case SETTINGS_TYPE_PLUGIN:
return NULL;
i_unreached();
static struct server_settings *
return server;
return TRUE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return TRUE;
return TRUE;
return TRUE;
return TRUE;
return FALSE;
errormsg);
return FALSE;
return TRUE;
return FALSE;
return TRUE;
return FALSE;
#ifdef HAVE_SETRLIMIT
unsigned int fd_count = 0;
return FALSE;
return FALSE;
return FALSE;
nofixes))
return FALSE;
return FALSE;
return FALSE;
return FALSE;
if (!nochecks) {
return FALSE;
return FALSE;
return FALSE;
if (!nochecks)
return TRUE;
const char **str;
case SET_STR: {
const char *const *strp;
for (i = 0; i < count; i++) {
case SET_INT: {
for (i = 0; i < count; i++) {
case SET_BOOL: {
for (i = 0; i < count; i++) {
if (same) {
for (i = 0; i < indent; i++)
for (i = 0; i < indent; i++)
const void *empty_defaults;
sizeof(struct auth_userdb_settings) +
sizeof(struct auth_socket_settings));
const char *const *envs;
unsigned int i, count;
if (count == 0)
const char *const *dicts;
unsigned int i, count;
if (count == 0)
unsigned int count;
count++;
count++;
void master_settings_init(void)
void master_settings_deinit(void)