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