[dovecot-cvs] dovecot/src/auth db-ldap.c, 1.32, 1.33 db-ldap.h, 1.15, 1.16 passdb-ldap.c, 1.36, 1.37 userdb-ldap.c, 1.35, 1.36

cras at dovecot.org cras at dovecot.org
Tue Dec 6 18:48:22 EET 2005


Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv1475

Modified Files:
	db-ldap.c db-ldap.h passdb-ldap.c userdb-ldap.c 
Log Message:
If LDAP lookup fails because connection gets closed, try retrying it again
after reconnect.



Index: db-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- db-ldap.c	16 Oct 2005 14:06:59 -0000	1.32
+++ db-ldap.c	6 Dec 2005 16:48:20 -0000	1.33
@@ -66,7 +66,7 @@
 
 static struct ldap_connection *ldap_connections = NULL;
 
-static void ldap_conn_close(struct ldap_connection *conn);
+static void ldap_conn_close(struct ldap_connection *conn, int flush_requests);
 
 static int deref2str(const char *str)
 {
@@ -108,9 +108,7 @@
 	return ldap_err2string(err);
 }
 
-void db_ldap_search(struct ldap_connection *conn, const char *base, int scope,
-		    const char *filter, char **attributes,
-		    struct ldap_request *request)
+void db_ldap_search(struct ldap_connection *conn, struct ldap_request *request)
 {
 	int msgid;
 
@@ -121,10 +119,11 @@
 		}
 	}
 
-	msgid = ldap_search(conn->ld, base, scope, filter, attributes, 0);
+	msgid = ldap_search(conn->ld, request->base, conn->set.ldap_scope,
+			    request->filter, request->attributes, 0);
 	if (msgid == -1) {
 		i_error("LDAP: ldap_search() failed (filter %s): %s",
-			filter, ldap_get_error(conn));
+			request->filter, ldap_get_error(conn));
 		request->callback(conn, request, NULL);
 		return;
 	}
@@ -132,6 +131,41 @@
 	hash_insert(conn->requests, POINTER_CAST(msgid), request);
 }
 
+static void ldap_conn_retry_requests(struct ldap_connection *conn)
+{
+	struct hash_table *old_requests;
+        struct hash_iterate_context *iter;
+	void *key, *value;
+
+	i_assert(conn->connected);
+
+	if (hash_size(conn->requests) == 0)
+		return;
+
+	old_requests = conn->requests;
+	conn->requests = hash_create(default_pool, conn->pool, 0, NULL, NULL);
+
+	iter = hash_iterate_init(old_requests);
+	while (hash_iterate(iter, &key, &value)) {
+		struct ldap_request *request = value;
+
+		i_assert(conn->connected);
+		db_ldap_search(conn, request);
+	}
+	hash_iterate_deinit(iter);
+	hash_destroy(old_requests);
+}
+
+static void ldap_conn_reconnect(struct ldap_connection *conn)
+{
+	ldap_conn_close(conn, FALSE);
+
+	if (!db_ldap_connect(conn)) {
+		/* failed to reconnect. fail all requests. */
+		ldap_conn_close(conn, TRUE);
+	}
+}
+
 static void ldap_input(void *context)
 {
 	struct ldap_connection *conn = context;
@@ -154,8 +188,7 @@
 			if (ret < 0) {
 				i_error("LDAP: ldap_result() failed: %s",
 					ldap_get_error(conn));
-				/* reconnect */
-				ldap_conn_close(conn);
+				ldap_conn_reconnect(conn);
 			}
 			return;
 		}
@@ -237,22 +270,27 @@
 
 	net_set_nonblock(fd, TRUE);
 	conn->io = io_add(fd, IO_READ, ldap_input, conn);
+
+	/* in case there are requests waiting, retry them */
+        ldap_conn_retry_requests(conn);
 	return TRUE;
 }
 
-static void ldap_conn_close(struct ldap_connection *conn)
+static void ldap_conn_close(struct ldap_connection *conn, int flush_requests)
 {
 	struct hash_iterate_context *iter;
 	void *key, *value;
 
-	iter = hash_iterate_init(conn->requests);
-	while (hash_iterate(iter, &key, &value)) {
-		struct ldap_request *request = value;
+	if (flush_requests) {
+		iter = hash_iterate_init(conn->requests);
+		while (hash_iterate(iter, &key, &value)) {
+			struct ldap_request *request = value;
 
-		request->callback(conn, request, NULL);
+			request->callback(conn, request, NULL);
+		}
+		hash_iterate_deinit(iter);
+		hash_clear(conn->requests, FALSE);
 	}
-	hash_iterate_deinit(iter);
-	hash_clear(conn->requests, FALSE);
 
 	conn->connected = FALSE;
 
@@ -426,7 +464,7 @@
 		}
 	}
 
-	ldap_conn_close(conn);
+	ldap_conn_close(conn, TRUE);
 
 	hash_destroy(conn->requests);
 	if (conn->pass_attr_map != NULL)

Index: db-ldap.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- db-ldap.h	22 Jul 2005 11:32:57 -0000	1.15
+++ db-ldap.h	6 Dec 2005 16:48:20 -0000	1.16
@@ -56,11 +56,13 @@
 struct ldap_request {
 	db_search_callback_t *callback;
 	void *context;
+
+	const char *base;
+	const char *filter;
+	char **attributes; /* points to pass_attr_names / user_attr_names */
 };
 
-void db_ldap_search(struct ldap_connection *conn, const char *base, int scope,
-		    const char *filter, char **attributes,
-		    struct ldap_request *request);
+void db_ldap_search(struct ldap_connection *conn, struct ldap_request *request);
 
 void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
 		       char ***attr_names_r, struct hash_table *attr_map,

Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- passdb-ldap.c	28 Oct 2005 12:02:36 -0000	1.36
+++ passdb-ldap.c	6 Dec 2005 16:48:20 -0000	1.37
@@ -179,30 +179,30 @@
 	struct ldap_connection *conn = module->conn;
         const struct var_expand_table *vars;
 	const char **attr_names = (const char **)conn->pass_attr_names;
-	const char *filter, *base;
 	string_t *str;
 
 	vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
 
 	str = t_str_new(512);
 	var_expand(str, conn->set.base, vars);
-	base = t_strdup(str_c(str));
+	ldap_request->base = p_strdup(auth_request->pool, str_c(str));
 
 	str_truncate(str, 0);
 	var_expand(str, conn->set.pass_filter, vars);
-	filter = str_c(str);
+	ldap_request->filter = p_strdup(auth_request->pool, str_c(str));
 
 	auth_request_ref(auth_request);
 	ldap_request->callback = handle_request;
 	ldap_request->context = auth_request;
+	ldap_request->attributes = conn->pass_attr_names;
 
 	auth_request_log_debug(auth_request, "ldap",
 			       "base=%s scope=%s filter=%s fields=%s",
-			       base, conn->set.scope, filter,
+			       ldap_request->base, conn->set.scope,
+			       ldap_request->filter,
 			       t_strarray_join(attr_names, ","));
 
-	db_ldap_search(conn, base, conn->set.ldap_scope, filter,
-		       conn->pass_attr_names, ldap_request);
+	db_ldap_search(conn, ldap_request);
 }
 
 static void

Index: userdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-ldap.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- userdb-ldap.c	16 Oct 2005 14:34:39 -0000	1.35
+++ userdb-ldap.c	6 Dec 2005 16:48:20 -0000	1.36
@@ -176,31 +176,32 @@
         const struct var_expand_table *vars;
 	const char **attr_names = (const char **)conn->user_attr_names;
 	struct userdb_ldap_request *request;
-	const char *filter, *base;
 	string_t *str;
 
+	request = p_new(auth_request->pool, struct userdb_ldap_request, 1);
+	request->request.callback = handle_request;
+	request->auth_request = auth_request;
+	request->userdb_callback = callback;
+
 	vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
 
 	str = t_str_new(512);
 	var_expand(str, conn->set.base, vars);
-	base = t_strdup(str_c(str));
+	request->request.base = p_strdup(auth_request->pool, str_c(str));
 
 	str_truncate(str, 0);
 	var_expand(str, conn->set.user_filter, vars);
-	filter = str_c(str);
+	request->request.filter = p_strdup(auth_request->pool, str_c(str));
 
-	request = p_new(auth_request->pool, struct userdb_ldap_request, 1);
-	request->request.callback = handle_request;
-	request->auth_request = auth_request;
-	request->userdb_callback = callback;
+	request->request.attributes = conn->user_attr_names;
 
 	auth_request_log_debug(auth_request, "ldap",
 			       "base=%s scope=%s filter=%s fields=%s",
-			       base, conn->set.scope, filter,
+			       request->request.base, conn->set.scope,
+			       request->request.filter,
 			       t_strarray_join(attr_names, ","));
 
-	db_ldap_search(conn, base, conn->set.ldap_scope, filter,
-		       conn->user_attr_names, &request->request);
+	db_ldap_search(conn, &request->request);
 }
 
 static struct userdb_module *



More information about the dovecot-cvs mailing list