dovecot-2.0: auth: Aborting pending async requests on deinit cau...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jun 1 18:38:03 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/3ef582c3fb72
changeset: 11441:3ef582c3fb72
user: Timo Sirainen <tss at iki.fi>
date: Tue Jun 01 16:37:59 2010 +0100
description:
auth: Aborting pending async requests on deinit caused crashes.
diffstat:
src/auth/auth-client-connection.c | 2 +-
src/auth/auth-request-handler.c | 21 ++++++++++++++++++++-
src/auth/auth-request-handler.h | 4 +++-
src/auth/auth-request.c | 16 ++++++++++++++++
4 files changed, 40 insertions(+), 3 deletions(-)
diffs (111 lines):
diff -r 941608f8b3fb -r 3ef582c3fb72 src/auth/auth-client-connection.c
--- a/src/auth/auth-client-connection.c Tue Jun 01 16:01:21 2010 +0100
+++ b/src/auth/auth-client-connection.c Tue Jun 01 16:37:59 2010 +0100
@@ -348,7 +348,7 @@
conn->fd = -1;
if (conn->request_handler != NULL)
- auth_request_handler_unref(&conn->request_handler);
+ auth_request_handler_destroy(&conn->request_handler);
master_service_client_connection_destroyed(master_service);
auth_client_connection_unref(&conn);
diff -r 941608f8b3fb -r 3ef582c3fb72 src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c Tue Jun 01 16:01:21 2010 +0100
+++ b/src/auth/auth-request-handler.c Tue Jun 01 16:37:59 2010 +0100
@@ -29,6 +29,8 @@
void *context;
auth_request_callback_t *master_callback;
+
+ unsigned int destroyed:1;
};
static ARRAY_DEFINE(auth_failures_arr, struct auth_request *);
@@ -57,7 +59,7 @@
return handler;
}
-void auth_request_handler_unref(struct auth_request_handler **_handler)
+static void auth_request_handler_unref(struct auth_request_handler **_handler)
{
struct auth_request_handler *handler = *_handler;
struct hash_iterate_context *iter;
@@ -83,6 +85,23 @@
pool_unref(&handler->pool);
}
+void auth_request_handler_destroy(struct auth_request_handler **_handler)
+{
+ struct auth_request_handler *handler = *_handler;
+
+ *_handler = NULL;
+
+ i_assert(!handler->destroyed);
+
+ handler->destroyed = TRUE;
+ 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 941608f8b3fb -r 3ef582c3fb72 src/auth/auth-request-handler.h
--- a/src/auth/auth-request-handler.h Tue Jun 01 16:01:21 2010 +0100
+++ b/src/auth/auth-request-handler.h Tue Jun 01 16:37:59 2010 +0100
@@ -23,7 +23,9 @@
(auth_request_callback_t *)callback, context, \
master_callback)
#endif
-void auth_request_handler_unref(struct auth_request_handler **handler);
+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,
diff -r 941608f8b3fb -r 3ef582c3fb72 src/auth/auth-request.c
--- a/src/auth/auth-request.c Tue Jun 01 16:01:21 2010 +0100
+++ b/src/auth/auth-request.c Tue Jun 01 16:37:59 2010 +0100
@@ -13,6 +13,7 @@
#include "var-expand.h"
#include "auth-cache.h"
#include "auth-request.h"
+#include "auth-request-handler.h"
#include "auth-client-connection.h"
#include "auth-master-connection.h"
#include "passdb.h"
@@ -389,6 +390,13 @@
strlen(request->passdb_password));
}
+ if (auth_request_handler_is_destroyed(request->handler)) {
+ /* 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;
+ return TRUE;
+ }
+
if (request->passdb->set->deny &&
*result != PASSDB_RESULT_USER_UNKNOWN) {
/* deny passdb. we can get through this step only if the
@@ -734,6 +742,14 @@
{
struct userdb_module *userdb = request->userdb->userdb;
+ if (auth_request_handler_is_destroyed(request->handler)) {
+ /* 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)
More information about the dovecot-cvs
mailing list