#include "auth-common.h"
#include "array.h"
#include "hash.h"
+#include "llist.h"
#include "str.h"
#include "strescape.h"
#include "str-sanitize.h"
#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;
const char **error_r)
{
struct auth_request *auth_request;
+ struct auth_request_list *request_list;
const char *const *list, *name, *arg;
unsigned int id;
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;
if (auth_request->service == NULL) {
i_error("BUG: Master sent %s request without service", cmd);
- auth_master_connection_unref(&conn);
+ DLLIST_REMOVE(&conn->requests, request_list);
auth_request_unref(&auth_request);
+ auth_master_connection_unref(&conn);
return -1;
}
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;
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);
}
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;
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);
}
{
struct auth_master_connection *conn = *_conn;
struct auth_master_connection *const *masters;
+ struct auth_request_list *list;
unsigned int idx;
*_conn = NULL;
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,
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;
{
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)