dovecot-2.0: auth: Fixes to destroying pending async userdb requ...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 2 18:48:59 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/1e890076c4e9
changeset: 11456:1e890076c4e9
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 02 16:48:55 2010 +0100
description:
auth: Fixes to destroying pending async userdb requests at deinit.
diffstat:
src/auth/auth-master-connection.c | 32 ++++++++++++++++++++++++++++----
src/auth/auth-master-connection.h | 2 ++
src/auth/auth-request-handler.c | 6 +-----
src/auth/auth-request-handler.h | 2 --
src/auth/auth-request.c | 10 +++++++++-
src/auth/auth-request.h | 1 +
6 files changed, 41 insertions(+), 12 deletions(-)
diffs (200 lines):
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-master-connection.c
--- a/src/auth/auth-master-connection.c Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-master-connection.c Wed Jun 02 16:48:55 2010 +0100
@@ -3,6 +3,7 @@
#include "auth-common.h"
#include "array.h"
#include "hash.h"
+#include "llist.h"
#include "str.h"
#include "strescape.h"
#include "str-sanitize.h"
@@ -26,6 +27,12 @@
#define MAX_INBUF_SIZE 1024
#define MAX_OUTBUF_SIZE (1024*50)
+struct auth_request_list {
+ struct auth_request_list *prev, *next;
+
+ struct auth_request *auth_request;
+};
+
struct master_userdb_request {
struct auth_master_connection *conn;
unsigned int id;
@@ -116,6 +123,7 @@
const char **error_r)
{
struct auth_request *auth_request;
+ struct auth_request_list *request_list;
const char *const *list, *name, *arg;
unsigned int id;
@@ -129,9 +137,14 @@
auth_request = auth_request_new_dummy();
auth_request->id = id;
- auth_request->context = conn;
+ auth_request->master = conn;
auth_master_connection_ref(conn);
+ request_list = p_new(auth_request->pool, struct auth_request_list, 1);
+ request_list->auth_request = auth_request;
+ DLLIST_PREPEND(&conn->requests, request_list);
+ auth_request->context = request_list;
+
if (!auth_request_set_username(auth_request, list[1], error_r)) {
*request_r = auth_request;
return 0;
@@ -152,8 +165,9 @@
if (auth_request->service == NULL) {
i_error("BUG: Master sent %s request without service", cmd);
+ DLLIST_REMOVE(&conn->requests, request_list);
+ auth_request_unref(&auth_request);
auth_master_connection_unref(&conn);
- auth_request_unref(&auth_request);
return -1;
}
@@ -166,7 +180,8 @@
user_callback(enum userdb_result result,
struct auth_request *auth_request)
{
- struct auth_master_connection *conn = auth_request->context;
+ struct auth_master_connection *conn = auth_request->master;
+ struct auth_request_list *list = auth_request->context;
struct auth_stream_reply *reply = auth_request->userdb_reply;
string_t *str;
const char *value;
@@ -198,6 +213,8 @@
str_append_c(str, '\n');
(void)o_stream_send(conn->output, str_data(str), str_len(str));
+
+ DLLIST_REMOVE(&conn->requests, list);
auth_request_unref(&auth_request);
auth_master_connection_unref(&conn);
}
@@ -229,7 +246,8 @@
size_t size ATTR_UNUSED,
struct auth_request *auth_request)
{
- struct auth_master_connection *conn = auth_request->context;
+ struct auth_master_connection *conn = auth_request->master;
+ struct auth_request_list *list = auth_request->context;
struct auth_stream_reply *reply = auth_request->extra_fields;
string_t *str;
@@ -257,6 +275,8 @@
str_append_c(str, '\n');
(void)o_stream_send(conn->output, str_data(str), str_len(str));
+
+ DLLIST_REMOVE(&conn->requests, list);
auth_request_unref(&auth_request);
auth_master_connection_unref(&conn);
}
@@ -512,6 +532,7 @@
{
struct auth_master_connection *conn = *_conn;
struct auth_master_connection *const *masters;
+ struct auth_request_list *list;
unsigned int idx;
*_conn = NULL;
@@ -519,6 +540,9 @@
return;
conn->destroyed = TRUE;
+ for (list = conn->requests; list != NULL; list = list->next)
+ list->auth_request->destroyed = TRUE;
+
array_foreach(&auth_master_connections, masters) {
if (*masters == conn) {
idx = array_foreach_idx(&auth_master_connections,
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-master-connection.h
--- a/src/auth/auth-master-connection.h Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-master-connection.h Wed Jun 02 16:48:55 2010 +0100
@@ -12,6 +12,8 @@
struct ostream *output;
struct io *io;
+ struct auth_request_list *requests;
+
unsigned int version_received:1;
unsigned int destroyed:1;
unsigned int userdb_only:1;
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-request-handler.c Wed Jun 02 16:48:55 2010 +0100
@@ -74,6 +74,7 @@
while (hash_table_iterate(iter, &key, &value)) {
struct auth_request *auth_request = value;
+ auth_request->destroyed = TRUE;
auth_request_unref(&auth_request);
}
hash_table_iterate_deinit(&iter);
@@ -97,11 +98,6 @@
auth_request_handler_unref(&handler);
}
-bool auth_request_handler_is_destroyed(struct auth_request_handler *handler)
-{
- return handler->destroyed;
-}
-
void auth_request_handler_set(struct auth_request_handler *handler,
unsigned int connect_uid,
unsigned int client_pid)
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-request-handler.h
--- a/src/auth/auth-request-handler.h Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-request-handler.h Wed Jun 02 16:48:55 2010 +0100
@@ -25,8 +25,6 @@
#endif
void auth_request_handler_destroy(struct auth_request_handler **handler);
-bool auth_request_handler_is_destroyed(struct auth_request_handler *handler);
-
void auth_request_handler_set(struct auth_request_handler *handler,
unsigned int connect_uid,
unsigned int client_pid);
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-request.c
--- a/src/auth/auth-request.c Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-request.c Wed Jun 02 16:48:55 2010 +0100
@@ -390,7 +390,7 @@
strlen(request->passdb_password));
}
- if (auth_request_handler_is_destroyed(request->handler)) {
+ if (request->destroyed) {
/* the passdb may have been freed already. this request won't
be sent anywhere anyway, so just fail it immediately. */
*result = PASSDB_RESULT_INTERNAL_FAILURE;
@@ -742,6 +742,14 @@
{
struct userdb_module *userdb = request->userdb->userdb;
+ if (request->destroyed) {
+ /* the userdb may have been freed already. this request won't
+ be sent anywhere anyway, so just fail it immediately. */
+ request->private_callback.
+ userdb(USERDB_RESULT_INTERNAL_FAILURE, request);
+ return;
+ }
+
if (result != USERDB_RESULT_OK && request->userdb->next != NULL) {
/* try next userdb. */
if (result == USERDB_RESULT_INTERNAL_FAILURE)
diff -r 50a0c05fb4e7 -r 1e890076c4e9 src/auth/auth-request.h
--- a/src/auth/auth-request.h Wed Jun 02 16:15:58 2010 +0100
+++ b/src/auth/auth-request.h Wed Jun 02 16:48:55 2010 +0100
@@ -108,6 +108,7 @@
unsigned int userdb_lookup:1;
unsigned int userdb_lookup_failed:1;
unsigned int secured:1;
+ unsigned int destroyed:1;
/* ... mechanism specific data ... */
};
More information about the dovecot-cvs
mailing list