Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3731:0a7beabfe332 HEAD
If LDAP lookup fails because connection gets closed, try retrying it again
after reconnect.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 06 Dec 2005 18:48:20 +0200 |
parents | fd0df9ddd688 |
children | bdeac77a4127 |
files | src/auth/db-ldap.c src/auth/db-ldap.h src/auth/passdb-ldap.c src/auth/userdb-ldap.c |
diffstat | 4 files changed, 80 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/db-ldap.c Tue Dec 06 17:08:32 2005 +0200 +++ b/src/auth/db-ldap.c Tue Dec 06 18:48:20 2005 +0200 @@ -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)
--- a/src/auth/db-ldap.h Tue Dec 06 17:08:32 2005 +0200 +++ b/src/auth/db-ldap.h Tue Dec 06 18:48:20 2005 +0200 @@ -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,
--- a/src/auth/passdb-ldap.c Tue Dec 06 17:08:32 2005 +0200 +++ b/src/auth/passdb-ldap.c Tue Dec 06 18:48:20 2005 +0200 @@ -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
--- a/src/auth/userdb-ldap.c Tue Dec 06 17:08:32 2005 +0200 +++ b/src/auth/userdb-ldap.c Tue Dec 06 18:48:20 2005 +0200 @@ -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; - 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)); - - str_truncate(str, 0); - var_expand(str, conn->set.user_filter, vars); - filter = 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; + vars = auth_request_get_var_expand_table(auth_request, ldap_escape); + + str = t_str_new(512); + var_expand(str, conn->set.base, vars); + request->request.base = p_strdup(auth_request->pool, str_c(str)); + + str_truncate(str, 0); + var_expand(str, conn->set.user_filter, vars); + request->request.filter = p_strdup(auth_request->pool, str_c(str)); + + 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 *