Mercurial > dovecot > core-2.2
changeset 10953:bdef690d41d5 HEAD
auth: Fixed support for per-service auth settings.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 19 Mar 2010 17:24:22 +0200 |
parents | 30e2d65eb67a |
children | bcd43231f723 |
files | src/auth/auth-settings.c src/auth/auth-settings.h src/auth/auth.c src/auth/auth.h src/auth/main.c |
diffstat | 5 files changed, 78 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-settings.c Fri Mar 19 17:23:56 2010 +0200 +++ b/src/auth/auth-settings.c Fri Mar 19 17:24:22 2010 +0200 @@ -3,16 +3,13 @@ #include "lib.h" #include "array.h" #include "settings-parser.h" -#include "master-service.h" +#include "master-service-private.h" #include "master-service-settings.h" #include "service-settings.h" #include "auth-settings.h" #include <stddef.h> -extern const struct setting_parser_info auth_setting_parser_info; -extern const struct setting_parser_info auth_root_setting_parser_info; - static bool auth_settings_check(void *_set, pool_t pool, const char **error_r); static bool auth_passdb_settings_check(void *_set, pool_t pool, const char **error_r); static bool auth_userdb_settings_check(void *_set, pool_t pool, const char **error_r); @@ -306,25 +303,29 @@ struct auth_settings *global_auth_settings; -struct auth_settings *auth_settings_read(const char *service) +struct auth_settings * +auth_settings_read(const char *service, pool_t pool, + struct master_service_settings_output *output_r) { static const struct setting_parser_info *set_roots[] = { &auth_setting_parser_info, NULL }; struct master_service_settings_input input; - struct master_service_settings_output output; + struct setting_parser_context *set_parser; const char *error; - void **sets; memset(&input, 0, sizeof(input)); input.roots = set_roots; input.module = "auth"; input.service = service; if (master_service_settings_read(master_service, &input, - &output, &error) < 0) + output_r, &error) < 0) i_fatal("Error reading configuration: %s", error); - sets = master_service_settings_get_others(master_service); - return sets[0]; + set_parser = settings_parser_dup(master_service->set_parser, pool); + if (!settings_parser_check(set_parser, pool, &error)) + i_unreached(); + + return settings_parser_get_list(set_parser)[1]; }
--- a/src/auth/auth-settings.h Fri Mar 19 17:23:56 2010 +0200 +++ b/src/auth/auth-settings.h Fri Mar 19 17:24:22 2010 +0200 @@ -2,6 +2,7 @@ #define AUTH_SETTINGS_H struct master_service; +struct master_service_settings_output; struct auth_passdb_settings { const char *driver; @@ -50,8 +51,11 @@ const char *const *realms_arr; }; +extern const struct setting_parser_info auth_setting_parser_info; extern struct auth_settings *global_auth_settings; -struct auth_settings *auth_settings_read(const char *service); +struct auth_settings * +auth_settings_read(const char *service, pool_t pool, + struct master_service_settings_output *output_r); #endif
--- a/src/auth/auth.c Fri Mar 19 17:23:56 2010 +0200 +++ b/src/auth/auth.c Fri Mar 19 17:24:22 2010 +0200 @@ -2,6 +2,8 @@ #include "auth-common.h" #include "array.h" +#include "settings-parser.h" +#include "master-service-settings.h" #include "mech.h" #include "userdb.h" #include "passdb.h" @@ -45,16 +47,14 @@ } struct auth * -auth_preinit(const struct auth_settings *set, const char *service, +auth_preinit(const struct auth_settings *set, const char *service, pool_t pool, const struct mechanisms_register *reg) { struct auth_passdb_settings *const *passdbs; struct auth_userdb_settings *const *userdbs; struct auth *auth; - pool_t pool; unsigned int i, count, db_count, passdb_count, last_passdb = 0; - pool = pool_alloconly_create("auth", 2048); auth = p_new(pool, struct auth, 1); auth->pool = pool; auth->service = p_strdup(pool, service); @@ -228,30 +228,43 @@ if (strcmp(a[i]->service, name) == 0) return a[i]; } + /* not found. maybe we can instead find a !service */ + for (i = 1; i < count; i++) { + if (a[i]->service[0] == '!' && + strcmp(a[i]->service + 1, name) != 0) + return a[i]; + } } return a[0]; } -void auths_preinit(const struct auth_settings *set, - const struct mechanisms_register *reg) +void auths_preinit(const struct auth_settings *set, pool_t pool, + const struct mechanisms_register *reg, + const char *const *services) { - static const char *services[] = { - "imap", "pop3", "lda", "lmtp", "managesieve" - }; + struct master_service_settings_output set_output; const struct auth_settings *service_set; struct auth *auth; unsigned int i; + const char *not_service = NULL; i_array_init(&auths, 8); - auth = auth_preinit(set, NULL, reg); + auth = auth_preinit(set, NULL, pool, reg); array_append(&auths, &auth, 1); - /* FIXME: this is ugly.. the service names should be coming from - the first config lookup */ - for (i = 0; i < N_ELEMENTS(services); i++) { - service_set = auth_settings_read(services[i]); - auth = auth_preinit(service_set, services[i], reg); + for (i = 0; services[i] != NULL; i++) { + if (services[i][0] == '!') { + if (not_service != NULL) { + i_fatal("Can't have multiple protocol " + "!services (seen %s and %s)", + not_service, services[i]); + } + not_service = services[i]; + } + service_set = auth_settings_read(services[i], pool, + &set_output); + auth = auth_preinit(service_set, services[i], pool, reg); array_append(&auths, &auth, 1); } }
--- a/src/auth/auth.h Fri Mar 19 17:23:56 2010 +0200 +++ b/src/auth/auth.h Fri Mar 19 17:24:22 2010 +0200 @@ -33,15 +33,16 @@ extern struct auth_penalty *auth_penalty; struct auth * -auth_preinit(const struct auth_settings *set, const char *service, +auth_preinit(const struct auth_settings *set, const char *service, pool_t pool, const struct mechanisms_register *mech_reg); void auth_init(struct auth *auth); void auth_deinit(struct auth **auth); struct auth *auth_find_service(const char *name); -void auths_preinit(const struct auth_settings *set, - const struct mechanisms_register *reg); +void auths_preinit(const struct auth_settings *set, pool_t pool, + const struct mechanisms_register *reg, + const char *const *services); void auths_init(void); void auths_deinit(void);
--- a/src/auth/main.c Fri Mar 19 17:23:56 2010 +0200 +++ b/src/auth/main.c Fri Mar 19 17:24:22 2010 +0200 @@ -10,7 +10,9 @@ #include "sql-api.h" #include "module-dir.h" #include "randgen.h" +#include "settings-parser.h" #include "master-service.h" +#include "master-service-settings.h" #include "master-interface.h" #include "password-scheme.h" #include "passdb-cache.h" @@ -38,13 +40,36 @@ time_t process_start_time; struct auth_penalty *auth_penalty; +static pool_t auth_set_pool; static struct module *modules = NULL; static struct mechanisms_register *mech_reg; static ARRAY_DEFINE(listen_fd_types, enum auth_socket_type); +static const char *const *read_global_settings(void) +{ + struct master_service_settings_output set_output; + const char **services; + unsigned int i, count; + + auth_set_pool = pool_alloconly_create("auth settings", 8192); + global_auth_settings = + auth_settings_read(NULL, auth_set_pool, &set_output); + + /* strdup() the service names, because they're allocated from + set parser pool, and we'll later clear it. */ + count = str_array_length(set_output.specific_services); + services = p_new(auth_set_pool, const char *, count + 1); + for (i = 0; i < count; i++) { + services[i] = p_strdup(auth_set_pool, + set_output.specific_services[i]); + } + return services; +} + static void main_preinit(void) { struct module_dir_load_settings mod_set; + const char *const *services; /* Open /dev/urandom before chrooting */ random_init(); @@ -58,6 +83,8 @@ passdbs_init(); userdbs_init(); + services = read_global_settings(); + memset(&mod_set, 0, sizeof(mod_set)); mod_set.version = master_service_get_version_string(master_service); mod_set.require_init_funcs = TRUE; @@ -69,7 +96,8 @@ auth_penalty = auth_penalty_init(AUTH_PENALTY_ANVIL_PATH); mech_init(global_auth_settings); mech_reg = mech_register_init(global_auth_settings); - auths_preinit(global_auth_settings, mech_reg); + auths_preinit(global_auth_settings, auth_set_pool, + mech_reg, services); /* Password lookups etc. may require roots, allow it. */ restrict_access_by_env(NULL, FALSE); @@ -134,6 +162,7 @@ random_deinit(); array_free(&listen_fd_types); + pool_unref(&auth_set_pool); } static void worker_connected(const struct master_service_connection *conn) @@ -190,6 +219,7 @@ } } + int main(int argc, char *argv[]) { int c; @@ -207,9 +237,7 @@ } } - global_auth_settings = auth_settings_read(NULL); main_preinit(); - master_service_init_finish(master_service); main_init(); master_service_run(master_service, worker ? worker_connected :