Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4772:d36a5df3f492 HEAD
Handle LDAP requests while being disconnected more correctly.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 07 Nov 2006 18:16:11 +0200 |
parents | 7576055e5377 |
children | 5cd0924c8031 |
files | src/auth/db-ldap.c src/auth/db-ldap.h src/auth/passdb-ldap.c |
diffstat | 3 files changed, 71 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/db-ldap.c Tue Nov 07 17:19:34 2006 +0200 +++ b/src/auth/db-ldap.c Tue Nov 07 18:16:11 2006 +0200 @@ -137,6 +137,20 @@ return ldap_err2string(err); } +void db_ldap_add_delayed_request(struct ldap_connection *conn, + struct ldap_request *request) +{ + i_assert(!conn->connected); + + request->next = NULL; + + if (conn->delayed_requests_head == NULL) + conn->delayed_requests_head = request; + else + conn->delayed_requests_tail->next = request; + conn->delayed_requests_tail = request; +} + void db_ldap_search(struct ldap_connection *conn, struct ldap_request *request, int scope) { @@ -165,21 +179,24 @@ request->callback(conn, request, NULL); return; } + hash_insert(conn->requests, POINTER_CAST(msgid), request); + } else { + db_ldap_add_delayed_request(conn, request); } - - 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; + struct ldap_request *request, **p, *next; void *key, *value; - bool have_binds = FALSE; + bool have_hash_binds = FALSE; i_assert(conn->connected); - if (hash_size(conn->requests) == 0) + if (hash_size(conn->requests) == 0 && + conn->delayed_requests_head == NULL) return; old_requests = conn->requests; @@ -189,11 +206,11 @@ /* first retry all the search requests */ iter = hash_iterate_init(old_requests); while (hash_iterate(iter, &key, &value)) { - struct ldap_request *request = value; + request = value; if (request->filter == NULL) { /* bind request */ - have_binds = TRUE; + have_hash_binds = TRUE; } else { i_assert(conn->connected); db_ldap_search(conn, request, conn->set.ldap_scope); @@ -201,21 +218,47 @@ } hash_iterate_deinit(iter); - if (have_binds && conn->set.auth_bind) { + /* then delayed search requests */ + p = &conn->delayed_requests_head; + while (*p != NULL) { + request = *p; + + if (request->filter != NULL) { + *p = request->next; + + i_assert(conn->connected); + db_ldap_search(conn, request, conn->set.ldap_scope); + } else { + p = &(*p)->next; + } + } + + if (have_hash_binds && conn->set.auth_bind) { /* next retry all the bind requests. without auth binds the only bind request can be the initial connection binding, which we don't care to retry. */ iter = hash_iterate_init(old_requests); while (hash_iterate(iter, &key, &value)) { - struct ldap_request *request = value; + request = value; if (request->filter == NULL) request->callback(conn, request, NULL); } hash_iterate_deinit(iter); } + if (conn->delayed_requests_head != NULL && conn->set.auth_bind) { + request = conn->delayed_requests_head; + for (; request != NULL; request = next) { + next = request->next; + + i_assert(request->filter == NULL); + request->callback(conn, request, NULL); + } + } hash_destroy(old_requests); + i_assert(conn->delayed_requests_head == NULL); + conn->delayed_requests_tail = NULL; conn->retrying = FALSE; } @@ -486,17 +529,27 @@ static void ldap_conn_close(struct ldap_connection *conn, bool flush_requests) { struct hash_iterate_context *iter; + struct ldap_request *request, *next; void *key, *value; if (flush_requests) { iter = hash_iterate_init(conn->requests); while (hash_iterate(iter, &key, &value)) { - struct ldap_request *request = value; + request = value; request->callback(conn, request, NULL); } hash_iterate_deinit(iter); hash_clear(conn->requests, FALSE); + + request = conn->delayed_requests_head; + for (; request != NULL; request = next) { + next = request->next; + + request->callback(conn, request, NULL); + } + conn->delayed_requests_head = NULL; + conn->delayed_requests_tail = NULL; } conn->connected = FALSE;
--- a/src/auth/db-ldap.h Tue Nov 07 17:19:34 2006 +0200 +++ b/src/auth/db-ldap.h Tue Nov 07 18:16:11 2006 +0200 @@ -57,7 +57,9 @@ LDAP *ld; int fd; /* only set when connected/connecting */ struct io *io; + struct hash_table *requests; + struct ldap_request *delayed_requests_head, *delayed_requests_tail; char **pass_attr_names, **user_attr_names; struct hash_table *pass_attr_map, *user_attr_map; @@ -69,6 +71,8 @@ }; struct ldap_request { + struct ldap_request *next; /* in conn->delayed_requests */ + db_search_callback_t *callback; void *context; @@ -85,6 +89,8 @@ const char *authzid; }; +void db_ldap_add_delayed_request(struct ldap_connection *conn, + struct ldap_request *request); void db_ldap_search(struct ldap_connection *conn, struct ldap_request *request, int scope);
--- a/src/auth/passdb-ldap.c Tue Nov 07 17:19:34 2006 +0200 +++ b/src/auth/passdb-ldap.c Tue Nov 07 18:16:11 2006 +0200 @@ -268,14 +268,16 @@ auth_request); return; } + hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request); auth_request_log_debug(auth_request, "ldap", "bind: dn=%s", ldap_request->base); + } else { + db_ldap_add_delayed_request(conn, ldap_request); } /* Bind started */ auth_request_ref(auth_request); - hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request); } static void