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);
void *context;
auth_request_callback_t *master_callback;
+
+ unsigned int destroyed:1;
};
static ARRAY_DEFINE(auth_failures_arr, struct auth_request *);
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;
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)
(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,
#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"
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
{
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)