auth-settings.c revision bcb4e51a409d94ae670de96afb8483a4f7855294
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainenstatic bool auth_settings_check(void *_set, pool_t pool, const char **error_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool auth_passdb_settings_check(void *_set, pool_t pool, const char **error_r);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainenstatic bool auth_userdb_settings_check(void *_set, pool_t pool, const char **error_r);
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen/* <settings checks> */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic struct file_listener_settings auth_unix_listeners_array[] = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { "auth-login", 0600, "$default_internal_user", "" },
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { "auth-client", 0600, "$default_internal_user", "" },
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen { "auth-userdb", 0666, "$default_internal_user", "" },
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic struct file_listener_settings *auth_unix_listeners[] = {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen auth_unix_listeners, sizeof(auth_unix_listeners), { NULL, }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen/* </settings checks> */
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainenstruct service_settings auth_service_settings = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen .unix_listeners = { { &auth_unix_listeners_buf,
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen/* <settings checks> */
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainenstatic struct file_listener_settings auth_worker_unix_listeners_array[] = {
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen { "auth-worker", 0600, "$default_internal_user", "" }
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainenstatic struct file_listener_settings *auth_worker_unix_listeners[] = {
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainenstatic buffer_t auth_worker_unix_listeners_buf = {
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen auth_worker_unix_listeners, sizeof(auth_worker_unix_listeners), { NULL, }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* </settings checks> */
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstruct service_settings auth_worker_service_settings = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen .unix_listeners = { { &auth_worker_unix_listeners_buf,
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen { type, #name, offsetof(struct auth_passdb_settings, name), NULL }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const struct setting_define auth_passdb_setting_defines[] = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const struct auth_passdb_settings auth_passdb_default_settings = {
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen .skip = "never:authenticated:unauthenticated",
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst struct setting_parser_info auth_passdb_setting_parser_info = {
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen .type_offset = offsetof(struct auth_passdb_settings, name),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen .struct_size = sizeof(struct auth_passdb_settings),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { type, #name, offsetof(struct auth_userdb_settings, name), NULL }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const struct setting_define auth_userdb_setting_defines[] = {
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainenstatic const struct auth_userdb_settings auth_userdb_default_settings = {
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen /* NOTE: when adding fields, update also auth.c:userdb_dummy_set */
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenconst struct setting_parser_info auth_userdb_setting_parser_info = {
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen .type_offset = offsetof(struct auth_userdb_settings, name),
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen .struct_size = sizeof(struct auth_userdb_settings),
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen/* we're kind of kludging here to avoid "auth_" prefix in the struct fields */
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen { type, "auth_"#name, offsetof(struct auth_settings, name), NULL }
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen { type, #name, offsetof(struct auth_settings, name), NULL }
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen { SET_DEFLIST, name, offsetof(struct auth_settings, field), defines }
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenstatic const struct setting_define auth_setting_defines[] = {
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen DEFLIST(passdbs, "passdb", &auth_passdb_setting_parser_info),
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen DEFLIST(userdbs, "userdb", &auth_userdb_setting_parser_info),
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainenstatic const struct auth_settings auth_default_settings = {
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen .username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen .policy_request_attributes = "login=%{orig_username} pwhash=%{hashed_password} remote=%{rip} device_id=%{client_id} protocol=%s",
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenconst struct setting_parser_info auth_setting_parser_info = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* <settings checks> */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenauth_settings_set_self_ips(struct auth_settings *set, pool_t pool,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen const char **error_r)
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen const char *const *tmp;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen set->proxy_self_ips = p_new(pool, struct ip_addr, 1);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen tmp = t_strsplit_spaces(set->proxy_self, " ");
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen ret = net_gethostbyname(*tmp, &ips, &ips_count);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen *error_r = t_strdup_printf("auth_proxy_self_ips: "
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen "gethostbyname(%s) failed: %s",
d9515a2eaa94c8287188c38fc28028727671e729Timo Sirainen set->proxy_self_ips = array_idx(&ips_array, 0);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainenauth_verify_verbose_password(struct auth_settings *set,
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen const char **error_r)
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen const char *p, *value = set->verbose_passwords;
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen unsigned int num;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("auth_verbose_passwords: "
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen /* just use it as alias for "plain" */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = "auth_verbose_passwords: Invalid value";
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenstatic bool auth_settings_check(void *_set, pool_t pool,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const char **error_r)
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen const char *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = "auth_worker_max_count must be above zero";
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (set->cache_size > 0 && set->cache_size < 1024) {
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen /* probably a configuration error.
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen older versions used megabyte numbers */
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen *error_r = t_strdup_printf("auth_cache_size value is too small "
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (!auth_verify_verbose_password(set, error_r))
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen /* all chars are allowed */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (p = set->username_chars; *p != '\0'; p++)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->username_chars_map[(int)(uint8_t)*p] = 1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->username_translation_map[(int)(uint8_t)*p] = p[1];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (const char *const *)p_strsplit_spaces(pool, set->realms, " ");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *error_r = "auth_policy_hash_nonce must be set when policy server is used";
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen const struct hash_method *digest = hash_method_lookup(set->policy_hash_mech);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen *error_r = "invalid auth_policy_hash_mech given";
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen if (set->policy_hash_truncate > 0 && set->policy_hash_truncate >= digest->digest_size*8) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *error_r = t_strdup_printf("policy_hash_truncate is not smaller than digest size (%u >= %u)",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!auth_settings_set_self_ips(set, pool, error_r))
8b5c520883aa37bb55646286d375fdbae294d710Timo Sirainenauth_passdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen const char **error_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->driver == NULL || *set->driver == '\0') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->pass && strcmp(set->result_success, "return-ok") != 0) {
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen *error_r = "Obsolete pass=yes setting mixed with non-default result_success";
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainenauth_userdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen const char **error_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->driver == NULL || *set->driver == '\0') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen/* </settings checks> */
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainenauth_settings_read(const char *service, pool_t pool,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct master_service_settings_output *output_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen static const struct setting_parser_info *set_roots[] = {
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen if (master_service_settings_read(master_service, &input,
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen i_fatal("Error reading configuration: %s", error);
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen set_parser = settings_parser_dup(master_service->set_parser, pool);
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen if (!settings_parser_check(set_parser, pool, &error))