dovecot: Added pass/userdb_register_module() functions and used ...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 6 23:43:33 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/7c81e6d848f6
changeset: 6187:7c81e6d848f6
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 06 23:16:43 2007 +0300
description:
Added pass/userdb_register_module() functions and used them to register the
build-in functions instead of having a predefined array.

diffstat:

5 files changed, 385 insertions(+), 291 deletions(-)
src/auth/main.c   |    4 
src/auth/passdb.c |  353 +++++++++++++++++++++++++++++------------------------
src/auth/passdb.h |    6 
src/auth/userdb.c |  307 +++++++++++++++++++++++++---------------------
src/auth/userdb.h |    6 

diffs (truncated from 788 to 300 lines):

diff -r 9a3a7ad297cf -r 7c81e6d848f6 src/auth/main.c
--- a/src/auth/main.c	Mon Aug 06 22:48:48 2007 +0300
+++ b/src/auth/main.c	Mon Aug 06 23:16:43 2007 +0300
@@ -192,6 +192,8 @@ static void drop_privileges(void)
 
 	/* Initialize databases so their configuration files can be readable
 	   only by root. Also load all modules here. */
+	passdbs_init();
+	userdbs_init();
 	auth = auth_preinit();
         password_schemes_init();
 
@@ -284,6 +286,8 @@ static void main_deinit(void)
         auth_worker_server_deinit();
 	auth_master_listeners_deinit();
 	auth_deinit(&auth);
+	userdbs_deinit();
+	passdbs_deinit();
 	mech_deinit();
 
         password_schemes_deinit();
diff -r 9a3a7ad297cf -r 7c81e6d848f6 src/auth/passdb.c
--- a/src/auth/passdb.c	Mon Aug 06 22:48:48 2007 +0300
+++ b/src/auth/passdb.c	Mon Aug 06 23:16:43 2007 +0300
@@ -1,12 +1,188 @@
 /* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "common.h"
+#include "array.h"
 #include "auth-module.h"
 #include "password-scheme.h"
 #include "auth-worker-server.h"
 #include "passdb.h"
 
 #include <stdlib.h>
+
+static ARRAY_DEFINE(passdb_interfaces, struct passdb_module_interface *);
+
+static struct passdb_module_interface *passdb_interface_find(const char *name)
+{
+	struct passdb_module_interface *const *ifaces;
+	unsigned int i, count;
+
+	ifaces = array_get(&passdb_interfaces, &count);
+	for (i = 0; i < count; i++) {
+		if (strcmp(ifaces[i]->name, name) == 0)
+			return ifaces[i];
+	}
+	return NULL;
+}
+
+void passdb_register_module(struct passdb_module_interface *iface)
+{
+	if (passdb_interface_find(iface->name) != NULL) {
+		i_panic("passdb_register_module(%s): Already registered",
+			iface->name);
+	}
+	array_append(&passdb_interfaces, &iface, 1);
+}
+
+void passdb_unregister_module(struct passdb_module_interface *iface)
+{
+	struct passdb_module_interface *const *ifaces;
+	unsigned int i, count;
+
+	ifaces = array_get(&passdb_interfaces, &count);
+	for (i = 0; i < count; i++) {
+		if (ifaces[i] == iface) {
+			array_delete(&passdb_interfaces, i, 1);
+			return;
+		}
+	}
+	i_panic("passdb_unregister_module(%s): Not registered", iface->name);
+}
+
+bool passdb_get_credentials(struct auth_request *auth_request,
+			    const char *input, const char *input_scheme,
+			    const unsigned char **credentials_r, size_t *size_r)
+{
+	const char *wanted_scheme = auth_request->credentials_scheme;
+	const char *plaintext;
+	int ret;
+
+	ret = password_decode(input, input_scheme, credentials_r, size_r);
+	if (ret <= 0) {
+		if (ret < 0) {
+			auth_request_log_error(auth_request, "password",
+				"Invalid password format for scheme %s",
+				input_scheme);
+		} else {
+			auth_request_log_error(auth_request, "password",
+				"Unknown scheme %s", input_scheme);
+		}
+		return FALSE;
+	}
+
+	if (*wanted_scheme == '\0') {
+		/* anything goes. change the credentials_scheme to what we
+		   actually got, so blocking passdbs work. */
+		auth_request->credentials_scheme =
+			p_strdup(auth_request->pool, input_scheme);
+		return TRUE;
+	}
+
+	if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
+		if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
+			auth_request_log_info(auth_request, "password",
+				"Requested %s scheme, but we have only %s",
+				wanted_scheme, input_scheme);
+			return FALSE;
+		}
+
+		/* we can generate anything out of plaintext passwords */
+		plaintext = t_strndup(*credentials_r, *size_r);
+		if (!password_generate(plaintext, auth_request->user,
+				       wanted_scheme, credentials_r, size_r)) {
+			auth_request_log_error(auth_request, "password",
+				"Requested unknown scheme %s", wanted_scheme);
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+void passdb_handle_credentials(enum passdb_result result,
+			       const char *password, const char *scheme,
+			       lookup_credentials_callback_t *callback,
+                               struct auth_request *auth_request)
+{
+	const unsigned char *credentials;
+	size_t size = 0;
+
+	if (result != PASSDB_RESULT_OK) {
+		callback(result, NULL, 0, auth_request);
+		return;
+	}
+
+	if (password == NULL ||
+	    !passdb_get_credentials(auth_request, password, scheme,
+				    &credentials, &size))
+		result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
+
+	callback(result, credentials, size, auth_request);
+}
+
+struct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
+				   const char *args, unsigned int id)
+{
+	struct passdb_module_interface *iface;
+        struct auth_passdb *auth_passdb;
+
+	if (args == NULL) args = "";
+
+	auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
+	auth_passdb->auth = auth;
+        auth_passdb->args = p_strdup(auth->pool, args);
+        auth_passdb->id = id;
+
+	iface = passdb_interface_find(driver);
+#ifdef HAVE_MODULES
+	if (iface == NULL)
+		auth_passdb->module = auth_module_open(driver);
+	if (auth_passdb->module != NULL) {
+		iface = auth_module_sym(auth_passdb->module,
+					t_strconcat("passdb_", driver, NULL));
+	}
+#endif
+
+	if (iface == NULL) {
+		i_fatal("Unknown passdb driver '%s' "
+			"(typo, or Dovecot was built without support for it? "
+			"Check with dovecot --build-options)",
+			driver);
+	}
+
+	if (iface->preinit == NULL) {
+		auth_passdb->passdb =
+			p_new(auth->pool, struct passdb_module, 1);
+	} else {
+		auth_passdb->passdb =
+			iface->preinit(auth_passdb, auth_passdb->args);
+	}
+	auth_passdb->passdb->iface = *iface;
+	return auth_passdb;
+}
+
+void passdb_init(struct auth_passdb *passdb)
+{
+	if (passdb->passdb->iface.init != NULL)
+		passdb->passdb->iface.init(passdb->passdb, passdb->args);
+
+	i_assert(passdb->passdb->default_pass_scheme != NULL ||
+		 passdb->passdb->cache_key == NULL);
+
+	if (passdb->passdb->blocking && !worker) {
+		/* blocking passdb - we need an auth server */
+		auth_worker_server_init();
+	}
+}
+
+void passdb_deinit(struct auth_passdb *passdb)
+{
+	if (passdb->passdb->iface.deinit != NULL)
+		passdb->passdb->iface.deinit(passdb->passdb);
+#ifdef HAVE_MODULES
+	if (passdb->module != NULL)
+                auth_module_close(&passdb->module);
+#endif
+}
 
 extern struct passdb_module_interface passdb_passwd;
 extern struct passdb_module_interface passdb_bsdauth;
@@ -19,179 +195,42 @@ extern struct passdb_module_interface pa
 extern struct passdb_module_interface passdb_sql;
 extern struct passdb_module_interface passdb_sia;
 
-struct passdb_module_interface *passdb_interfaces[] = {
+void passdbs_init(void)
+{
+	i_array_init(&passdb_interfaces, 16);
 #ifdef PASSDB_PASSWD
-	&passdb_passwd,
+	passdb_register_module(&passdb_passwd);
 #endif
 #ifdef PASSDB_BSDAUTH
-	&passdb_bsdauth,
+	passdb_register_module(&passdb_bsdauth);
 #endif
 #ifdef PASSDB_PASSWD_FILE
-	&passdb_passwd_file,
+	passdb_register_module(&passdb_passwd_file);
 #endif
 #ifdef PASSDB_PAM
-	&passdb_pam,
+	passdb_register_module(&passdb_pam);
 #endif
 #ifdef PASSDB_CHECKPASSWORD
-	&passdb_checkpassword,
+	passdb_register_module(&passdb_checkpassword);
 #endif
 #ifdef PASSDB_SHADOW
-	&passdb_shadow,
+	passdb_register_module(&passdb_shadow);
 #endif
 #ifdef PASSDB_VPOPMAIL
-	&passdb_vpopmail,
+	passdb_register_module(&passdb_vpopmail);
 #endif
 #ifdef PASSDB_LDAP
-	&passdb_ldap,
+	passdb_register_module(&passdb_ldap);
 #endif
 #ifdef PASSDB_SQL
-	&passdb_sql,
+	passdb_register_module(&passdb_sql);
 #endif
 #ifdef PASSDB_SIA
-	&passdb_sia,
-#endif
-	NULL
-};
-
-bool passdb_get_credentials(struct auth_request *auth_request,
-			    const char *input, const char *input_scheme,
-			    const unsigned char **credentials_r, size_t *size_r)
-{
-	const char *wanted_scheme = auth_request->credentials_scheme;
-	const char *plaintext;
-	int ret;
-
-	ret = password_decode(input, input_scheme, credentials_r, size_r);
-	if (ret <= 0) {
-		if (ret < 0) {
-			auth_request_log_error(auth_request, "password",
-				"Invalid password format for scheme %s",
-				input_scheme);
-		} else {
-			auth_request_log_error(auth_request, "password",
-				"Unknown scheme %s", input_scheme);
-		}
-		return FALSE;
-	}
-
-	if (*wanted_scheme == '\0') {
-		/* anything goes. change the credentials_scheme to what we
-		   actually got, so blocking passdbs work. */
-		auth_request->credentials_scheme =
-			p_strdup(auth_request->pool, input_scheme);
-		return TRUE;
-	}
-
-	if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
-		if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
-			auth_request_log_info(auth_request, "password",
-				"Requested %s scheme, but we have only %s",
-				wanted_scheme, input_scheme);
-			return FALSE;
-		}
-


More information about the dovecot-cvs mailing list