dovecot-2.0: auth: Fixed support for per-service auth settings.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Mar 19 17:24:25 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/bdef690d41d5
changeset: 10953:bdef690d41d5
user: Timo Sirainen <tss at iki.fi>
date: Fri Mar 19 17:24:22 2010 +0200
description:
auth: Fixed support for per-service auth settings.
diffstat:
src/auth/auth-settings.c | 21 +++++++++++----------
src/auth/auth-settings.h | 6 +++++-
src/auth/auth.c | 41 +++++++++++++++++++++++++++--------------
src/auth/auth.h | 7 ++++---
src/auth/main.c | 34 +++++++++++++++++++++++++++++++---
5 files changed, 78 insertions(+), 31 deletions(-)
diffs (284 lines):
diff -r 30e2d65eb67a -r bdef690d41d5 src/auth/auth-settings.c
--- 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];
}
diff -r 30e2d65eb67a -r bdef690d41d5 src/auth/auth-settings.h
--- 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
diff -r 30e2d65eb67a -r bdef690d41d5 src/auth/auth.c
--- 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);
}
}
diff -r 30e2d65eb67a -r bdef690d41d5 src/auth/auth.h
--- 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);
diff -r 30e2d65eb67a -r bdef690d41d5 src/auth/main.c
--- 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 :
More information about the dovecot-cvs
mailing list