settings.c revision ad56ed098867ae42af11132577b9ad3f1c5c17df
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include "lib.h"
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include "ibuffer.h"
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include "settings.h"
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include <stdio.h>
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include <unistd.h>
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include <fcntl.h>
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include <pwd.h>
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen#include <sys/stat.h>
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainentypedef enum {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_STR,
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_INT,
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen} SettingType;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainentypedef struct {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen const char *name;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SettingType type;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen void *ptr;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen} Setting;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic Setting settings[] = {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "log_path", SET_STR, &set_log_path },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "log_timestamp", SET_STR, &set_log_timestamp },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "imap_port", SET_INT, &set_imap_port },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "imaps_port", SET_INT, &set_imaps_port },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "imap_listen", SET_STR, &set_imap_listen },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "imaps_listen", SET_STR, &set_imaps_listen },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "ssl_cert_file", SET_STR, &set_ssl_cert_file },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "ssl_key_file", SET_STR, &set_ssl_key_file },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "ssl_parameters_file",SET_STR, &set_ssl_parameters_file },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "ssl_parameters_regenerate",
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen SET_INT, &set_ssl_parameters_regenerate },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "disable_plaintext_auth",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL,&set_disable_plaintext_auth },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_executable", SET_STR, &set_login_executable },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_user", SET_STR, &set_login_user },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_dir", SET_STR, &set_login_dir },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_chroot", SET_BOOL,&set_login_chroot },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_process_per_connection",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL,&set_login_process_per_connection },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "login_processes_count",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_INT, &set_login_processes_count },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "max_logging_users", SET_INT, &set_max_logging_users },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen { "imap_executable", SET_STR, &set_imap_executable },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "valid_chroot_dirs", SET_STR, &set_valid_chroot_dirs },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "max_imap_processes", SET_INT, &set_max_imap_processes },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "verbose_proctitle", SET_BOOL,&set_verbose_proctitle },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "first_valid_uid", SET_INT, &set_first_valid_uid },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "last_valid_uid", SET_INT, &set_last_valid_uid },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "first_valid_gid", SET_INT, &set_first_valid_gid },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "last_valid_gid", SET_INT, &set_last_valid_gid },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "mail_cache_fields", SET_STR, &set_mail_cache_fields },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "mail_never_cache_fields",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_STR, &set_mail_never_cache_fields },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "mailbox_check_interval",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_INT, &set_mailbox_check_interval },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "mail_save_crlf", SET_BOOL,&set_mail_save_crlf },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "maildir_copy_with_hardlinks",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL,&set_maildir_copy_with_hardlinks },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "maildir_check_content_changes",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL,&set_maildir_check_content_changes },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "overwrite_incompatible_index",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen SET_BOOL,&set_overwrite_incompatible_index },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { "umask", SET_INT, &set_umask },
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen { NULL, 0, NULL }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen};
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* common */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_log_path = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_log_timestamp = DEFAULT_FAILURE_STAMP_FORMAT;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* general */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_imap_port = 143;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_imaps_port = 993;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_imap_listen = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_imaps_listen = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainenchar *set_ssl_cert_file = "/etc/ssl/certs/imapd.pem";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_ssl_key_file = "/etc/ssl/private/imapd.pem";
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainenchar *set_ssl_parameters_file = PKG_RUNDIR"/ssl-parameters.dat";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_ssl_parameters_regenerate = 24;
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainenint set_disable_plaintext_auth = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* login */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_login_executable = PKG_LIBDIR "/imap-login";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_login_user = "imapd";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_login_dir = PKG_RUNDIR"/login";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_login_chroot = TRUE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_login_process_per_connection = TRUE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_login_processes_count = 3;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_login_max_processes_count = 128;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_max_logging_users = 256;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenuid_t set_login_uid; /* generated from set_login_user */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainengid_t set_login_gid; /* generated from set_login_user */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* imap */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_imap_executable = PKG_LIBDIR "/imap";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_valid_chroot_dirs = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_max_imap_processes = 1024;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_verbose_proctitle = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_first_valid_uid = 500, set_last_valid_uid = 0;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_first_valid_gid = 1, set_last_valid_gid = 0;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_mail_cache_fields = "MessagePart";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenchar *set_mail_never_cache_fields = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_mailbox_check_interval = 30;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_mail_save_crlf = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_maildir_copy_with_hardlinks = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_maildir_check_content_changes = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenint set_overwrite_incompatible_index = FALSE;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenunsigned int set_umask = 0077;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen/* auth */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo SirainenAuthConfig *auth_processes_config = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic void get_login_uid(void)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen struct passwd *pw;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if ((pw = getpwnam(set_login_user)) == NULL)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Login user doesn't exist: %s", set_login_user);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_login_uid = pw->pw_uid;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_login_gid = pw->pw_gid;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic void auth_settings_verify(void)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen AuthConfig *auth;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen for (auth = auth_processes_config; auth != NULL; auth = auth->next) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (access(auth->executable, X_OK) < 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Can't use auth executable %s: %m",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->executable);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (auth->chroot != NULL && *auth->chroot != '\0' &&
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen access(auth->chroot, X_OK) < 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Can't access auth chroot directory %s: %m",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->chroot);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic void settings_verify(void)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen get_login_uid();
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (access(set_login_executable, X_OK) < 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Can't use login executable %s: %m",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_login_executable);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (access(set_imap_executable, X_OK) < 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Can't use imap executable %s: %m",
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_imap_executable);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen /* since they're under /var/run by default, they may have been
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen deleted */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen (void)mkdir(PKG_RUNDIR, 0700);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (mkdir(set_login_dir, 0700) == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen (void)chown(set_login_dir, set_login_uid, set_login_gid);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (access(set_login_dir, X_OK) < 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("Can't access login directory %s: %m", set_login_dir);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (set_max_imap_processes < 1)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("max_imap_processes must be at least 1");
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (set_login_processes_count < 1)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("login_processes_count must be at least 1");
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen if (set_max_logging_users < 1)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("max_logging_users must be at least 1");
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (set_last_valid_uid != 0 &&
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_first_valid_uid > set_last_valid_uid)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("first_valid_uid can't be larger than last_valid_uid");
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (set_last_valid_gid != 0 &&
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen set_first_valid_gid > set_last_valid_gid)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_fatal("first_valid_gid can't be larger than last_valid_gid");
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth_settings_verify();
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic AuthConfig *auth_config_new(const char *name)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen AuthConfig *auth;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth = i_new(AuthConfig, 1);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->name = i_strdup(name);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->executable = i_strdup(PKG_LIBDIR "/imap-auth");
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->count = 1;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->next = auth_processes_config;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth_processes_config = auth;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen return auth;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic void auth_config_free(AuthConfig *auth)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->name);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->methods);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->realms);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->userinfo);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->userinfo_args);
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen i_free(auth->executable);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->user);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->chroot);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic const char *parse_new_auth(const char *name)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen AuthConfig *auth;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (strchr(name, '/') != NULL)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen return "Authentication process name must not contain '/'";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen for (auth = auth_processes_config; auth != NULL; auth = auth->next) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (strcmp(auth->name, name) == 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen return "Authentication process already exists "
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen "with the same name";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen (void)auth_config_new(name);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen return NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen}
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainenstatic const char *parse_auth(const char *key, const char *value)
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen{
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen AuthConfig *auth = auth_processes_config;
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen const char *p;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen char **ptr;
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (auth == NULL)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen return "Authentication process name not defined yet";
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen /* check the easy string values first */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (strcmp(key, "auth_methods") == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = &auth->methods;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen else if (strcmp(key, "auth_realms") == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = &auth->realms;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen else if (strcmp(key, "auth_executable") == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = &auth->executable;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen else if (strcmp(key, "auth_user") == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = &auth->user;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen else if (strcmp(key, "auth_chroot") == 0)
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = &auth->chroot;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen else
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen ptr = NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (ptr != NULL) {
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen i_strdup_replace(ptr, value);
01f54478a7c69b88ab13840c99bbab19a0d7d754Timo Sirainen return NULL;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen }
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen if (strcmp(key, "auth_userinfo") == 0) {
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen /* split it into userinfo + userinfo_args */
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen for (p = value; *p != ' ' && *p != '\0'; )
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen p++;
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen i_free(auth->userinfo);
c1252a5812eb11fcb81508b9ed37597a5bc84100Timo Sirainen auth->userinfo = i_strdup_until(value, p);
while (*p == ' ') p++;
i_free(auth->userinfo_args);
auth->userinfo_args = i_strdup(p);
return NULL;
}
if (strcmp(key, "auth_count") == 0) {
if (!sscanf(value, "%i", &auth->count))
return t_strconcat("Invalid number: ", value, NULL);
return NULL;
}
return t_strconcat("Unknown setting: ", key, NULL);
}
static const char *parse_setting(const char *key, const char *value)
{
Setting *set;
if (strcmp(key, "auth") == 0)
return parse_new_auth(value);
if (strncmp(key, "auth_", 5) == 0)
return parse_auth(key, value);
for (set = settings; set->name != NULL; set++) {
if (strcmp(set->name, key) == 0) {
switch (set->type) {
case SET_STR:
i_strdup_replace((char **) set->ptr, value);
break;
case SET_INT:
/* use %i so we can handle eg. 0600
as octal value with umasks */
if (!sscanf(value, "%i", (int *) set->ptr))
return t_strconcat("Invalid number: ",
value, NULL);
break;
case SET_BOOL:
if (strcasecmp(value, "yes") == 0)
*((int *) set->ptr) = TRUE;
else if (strcasecmp(value, "no") == 0)
*((int *) set->ptr) = FALSE;
else
return t_strconcat("Invalid boolean: ",
value, NULL);
break;
}
return NULL;
}
}
return t_strconcat("Unknown setting: ", key, NULL);
}
static void settings_free(void)
{
while (auth_processes_config != NULL) {
AuthConfig *auth = auth_processes_config;
auth_processes_config = auth->next;
auth_config_free(auth);
}
}
#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
void settings_read(const char *path)
{
IBuffer *inbuf;
const char *errormsg;
char *line, *key, *p;
int fd, linenum;
settings_free();
fd = open(path, O_RDONLY);
if (fd < 0)
i_fatal("Can't open configuration file %s: %m", path);
linenum = 0;
inbuf = i_buffer_create_file(fd, default_pool, 2048, TRUE);
for (;;) {
line = i_buffer_next_line(inbuf);
if (line == NULL) {
if (i_buffer_read(inbuf) <= 0)
break;
continue;
}
linenum++;
/* skip whitespace */
while (IS_WHITE(*line))
line++;
/* ignore comments or empty lines */
if (*line == '#' || *line == '\0')
continue;
/* all lines must be in format "key = value" */
key = line;
while (!IS_WHITE(*line) && *line != '\0')
line++;
if (IS_WHITE(*line)) {
*line++ = '\0';
while (IS_WHITE(*line)) line++;
}
if (*line != '=') {
errormsg = "Missing value";
} else {
/* skip whitespace after '=' */
*line++ = '\0';
while (IS_WHITE(*line)) line++;
/* skip trailing whitespace */
p = line + strlen(line);
while (p > line && IS_WHITE(p[-1]))
p--;
*p = '\0';
errormsg = parse_setting(key, line);
}
if (errormsg != NULL) {
i_fatal("Error in configuration file %s line %d: %s",
path, linenum, errormsg);
}
};
i_buffer_unref(inbuf);
settings_verify();
}
void settings_init(void)
{
Setting *set;
/* strdup() all default settings */
for (set = settings; set->name != NULL; set++) {
if (set->type == SET_STR) {
char **str = set->ptr;
*str = i_strdup(*str);
}
}
}