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