changeset 3840:935f12d0d2fe HEAD

Added fast authbinding and auth_bind_userdn setting. Patch by Geff <boing@boing.com>
author Timo Sirainen <tss@iki.fi>
date Sat, 07 Jan 2006 03:25:05 +0200
parents b48d071d4ea5
children 6b9e9d614c9a
files doc/dovecot-ldap.conf src/auth/db-ldap.c src/auth/db-ldap.h src/auth/passdb-ldap.c
diffstat 4 files changed, 59 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/doc/dovecot-ldap.conf	Sat Jan 07 03:13:53 2006 +0200
+++ b/doc/dovecot-ldap.conf	Sat Jan 07 03:25:05 2006 +0200
@@ -23,6 +23,14 @@
 # NOTE: pass_attrs option will (naturally) be ignored if you enable this.
 #auth_bind = no
 
+# If authentication binding is used, you can save one LDAP request per login
+# if users' DN can be specified with a common template. The template can use
+# the standard %variables (see user_filter). For example:
+#
+#   auth_bind_userdn = cn=%u,ou=people,o=org
+#
+#auth_bind_userdn =
+
 # LDAP protocol version to use. Likely 2 or 3.
 #ldap_version = 2
 
--- a/src/auth/db-ldap.c	Sat Jan 07 03:13:53 2006 +0200
+++ b/src/auth/db-ldap.c	Sat Jan 07 03:25:05 2006 +0200
@@ -34,6 +34,7 @@
 	DEF(SET_STR, dn),
 	DEF(SET_STR, dnpass),
 	DEF(SET_BOOL, auth_bind),
+	DEF(SET_STR, auth_bind_userdn),
 	DEF(SET_STR, deref),
 	DEF(SET_STR, scope),
 	DEF(SET_STR, base),
@@ -53,6 +54,7 @@
 	MEMBER(dn) NULL,
 	MEMBER(dnpass) NULL,
 	MEMBER(auth_bind) FALSE,
+	MEMBER(auth_bind_userdn) NULL,
 	MEMBER(deref) "never",
 	MEMBER(scope) "subtree",
 	MEMBER(base) NULL,
--- a/src/auth/db-ldap.h	Sat Jan 07 03:13:53 2006 +0200
+++ b/src/auth/db-ldap.h	Sat Jan 07 03:25:05 2006 +0200
@@ -16,6 +16,7 @@
 	const char *dn;
 	const char *dnpass;
 	int auth_bind;
+	const char *auth_bind_userdn;
 	const char *deref;
 	const char *scope;
 	const char *base;
--- a/src/auth/passdb-ldap.c	Sat Jan 07 03:13:53 2006 +0200
+++ b/src/auth/passdb-ldap.c	Sat Jan 07 03:25:05 2006 +0200
@@ -219,6 +219,29 @@
 	passdb_ldap_request->callback.verify_plain(passdb_result, auth_request);
 }
 
+static void authbind_start(struct ldap_connection *conn,
+			   struct ldap_request *ldap_request, const char *dn)
+{
+	struct passdb_ldap_request *passdb_ldap_request =
+		(struct passdb_ldap_request *)ldap_request;
+	struct auth_request *auth_request = ldap_request->context;
+	int msgid;
+
+	msgid = ldap_bind(conn->ld, dn, auth_request->mech_password,
+			  LDAP_AUTH_SIMPLE);
+	if (msgid == -1) {
+		i_error("ldap_bind(%s) failed: %s", dn, ldap_get_error(conn));
+		passdb_ldap_request->callback.
+			verify_plain(PASSDB_RESULT_INTERNAL_FAILURE,
+				     auth_request);
+		return;
+	}
+
+	/* Bind started */
+	auth_request_ref(auth_request);
+	hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
+}
+
 static void
 handle_request_authbind_search(struct ldap_connection *conn,
 			       struct ldap_request *ldap_request,
@@ -228,32 +251,16 @@
 		(struct passdb_ldap_request *)ldap_request;
 	struct auth_request *auth_request = ldap_request->context;
 	LDAPMessage *entry;
-	const char *dn;
-	int msgid;
 
 	entry = handle_request_get_entry(conn, auth_request,
 					 passdb_ldap_request, res);
 	if (entry == NULL)
 		return;
 
-	dn = ldap_get_dn(conn->ld, entry);
-
 	/* switch the handler to the authenticated bind handler */
 	ldap_request->callback = handle_request_authbind;
 
-	msgid = ldap_bind(conn->ld, dn, auth_request->mech_password,
-			  LDAP_AUTH_SIMPLE);
-	if (msgid == -1) {
-		i_error("ldap_bind() failed: %s", ldap_get_error(conn));
-		passdb_ldap_request->callback.
-			verify_plain(PASSDB_RESULT_INTERNAL_FAILURE,
-				     auth_request);
-		return;
-	}
-
-	/* Bind started */
-	auth_request_ref(auth_request);
-	hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
+        authbind_start(conn, ldap_request, ldap_get_dn(conn->ld, entry));
 }
 
 static void ldap_lookup_pass(struct auth_request *auth_request,
@@ -292,6 +299,27 @@
 }
 
 static void
+ldap_verify_plain_auth_bind_userdn(struct auth_request *auth_request,
+				   struct ldap_request *ldap_request)
+{
+	struct passdb_module *_module = auth_request->passdb->passdb;
+	struct ldap_passdb_module *module =
+		(struct ldap_passdb_module *)_module;
+	struct ldap_connection *conn = module->conn;
+        const struct var_expand_table *vars;
+	string_t *dn;
+
+	vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
+	dn = t_str_new(512);
+	var_expand(dn, conn->set.auth_bind_userdn, vars);
+
+	ldap_request->callback = handle_request_authbind;
+	ldap_request->context = auth_request;
+
+        authbind_start(conn, ldap_request, str_c(dn));
+}
+
+static void
 ldap_verify_plain_authbind(struct auth_request *auth_request,
 			   struct ldap_request *ldap_request)
 {
@@ -341,7 +369,9 @@
 	ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
 	ldap_request->callback.verify_plain = callback;
 
-	if (conn->set.auth_bind)
+	if (conn->set.auth_bind_userdn != NULL)
+		ldap_verify_plain_auth_bind_userdn(request, &ldap_request->request);
+	else if (conn->set.auth_bind)
 		ldap_verify_plain_authbind(request, &ldap_request->request);
 	else
 		ldap_lookup_pass(request, &ldap_request->request);