bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "lib.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "ioloop.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "fdpass.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "buffer.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "hash.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "master-service-private.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "master-auth.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <unistd.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <sys/stat.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen#define SOCKET_CONNECT_RETRY_MSECS 500
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen#define MASTER_AUTH_REQUEST_TIMEOUT_MSECS (MASTER_LOGIN_TIMEOUT_SECS/2*1000)
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstruct master_auth_connection {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth *auth;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int tag;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen char *path;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct io *io;
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen struct timeout *to;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen char buf[sizeof(struct master_auth_reply)];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int buf_pos;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen master_auth_callback_t *callback;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen void *context;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen};
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstruct master_auth {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_service *service;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pool_t pool;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen const char *default_path;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int tag_counter;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen HASH_TABLE(void *, struct master_auth_connection *) connections;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen};
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstruct master_auth *
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenmaster_auth_init(struct master_service *service, const char *path)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth *auth;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pool_t pool;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pool = pool_alloconly_create("master auth", 1024);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen auth = p_new(pool, struct master_auth, 1);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen auth->pool = pool;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen auth->service = service;
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen auth->default_path = p_strdup(pool, path);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create_direct(&auth->connections, pool, 0);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return auth;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic void
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenmaster_auth_connection_deinit(struct master_auth_connection **_conn)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth_connection *conn = *_conn;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *_conn = NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen if (conn->tag != 0)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen hash_table_remove(conn->auth->connections,
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen POINTER_CAST(conn->tag));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (conn->callback != NULL)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen conn->callback(NULL, conn->context);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&conn->to);
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipek io_remove(&conn->io);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (conn->fd != -1) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (close(conn->fd) < 0)
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen i_fatal("close(%s) failed: %m", conn->path);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->fd = -1;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen i_free(conn->path);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_free(conn);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen}
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenvoid master_auth_deinit(struct master_auth **_auth)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth *auth = *_auth;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct hash_iterate_context *iter;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen void *key;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen struct master_auth_connection *conn;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *_auth = NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen iter = hash_table_iterate_init(auth->connections);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, auth->connections, &key, &conn)) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->tag = 0;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen master_auth_connection_deinit(&conn);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen hash_table_iterate_deinit(&iter);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen hash_table_destroy(&auth->connections);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pool_unref(&auth->pool);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic void master_auth_connection_input(struct master_auth_connection *conn)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const struct master_auth_reply *reply;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = read(conn->fd, conn->buf + conn->buf_pos,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen sizeof(conn->buf) - conn->buf_pos);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (ret <= 0) {
f9ee758af881bcecc3f47d45e62cd110673bb92cTimo Sirainen if (ret == 0 || errno == ECONNRESET) {
f9ee758af881bcecc3f47d45e62cd110673bb92cTimo Sirainen i_error("read(%s) failed: Remote closed connection "
086dacad037a033f783be55842918ba40bbf4ed4Timo Sirainen "(destination service { process_limit } reached?)",
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path);
f9ee758af881bcecc3f47d45e62cd110673bb92cTimo Sirainen } else {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (errno == EAGAIN)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return;
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen i_error("read(%s) failed: %m", conn->path);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen master_auth_connection_deinit(&conn);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->buf_pos += ret;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (conn->buf_pos < sizeof(conn->buf))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* reply is now read */
e5de04b9d8818d1301c430469f736fcadc2572f0Timo Sirainen reply = (const void *)conn->buf;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->buf_pos = 0;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (conn->tag != reply->tag)
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen i_error("master(%s): Received reply with unknown tag %u",
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path, reply->tag);
892b4c153ad432f5e7e6ce3f84c0f7a9657d0158Timo Sirainen else if (conn->callback == NULL) {
892b4c153ad432f5e7e6ce3f84c0f7a9657d0158Timo Sirainen /* request aborted */
892b4c153ad432f5e7e6ce3f84c0f7a9657d0158Timo Sirainen } else {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->callback(reply, conn->context);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->callback = NULL;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen master_auth_connection_deinit(&conn);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainenstatic void master_auth_connection_timeout(struct master_auth_connection *conn)
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen{
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen i_error("master(%s): Auth request timed out (received %u/%u bytes)",
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path, conn->buf_pos,
47eefec8a72cc2777f344017261c2864e47bcaadTimo Sirainen (unsigned int)sizeof(conn->buf));
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen master_auth_connection_deinit(&conn);
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen}
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainenvoid master_auth_request_full(struct master_auth *auth,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen const struct master_auth_request_params *params,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen master_auth_callback_t *callback, void *context,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen unsigned int *tag_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth_connection *conn;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth_request req;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen buffer_t *buf;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct stat st;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ssize_t ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen i_assert(params->request.client_pid != 0);
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen i_assert(params->request.auth_pid != 0);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn = i_new(struct master_auth_connection, 1);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->auth = auth;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->callback = callback;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->context = context;
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path = params->socket_path != NULL ?
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen i_strdup(params->socket_path) : i_strdup(auth->default_path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen req = params->request;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen req.tag = ++auth->tag_counter;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (req.tag == 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen req.tag = ++auth->tag_counter;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen if (fstat(params->client_fd, &st) < 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_fatal("fstat(auth dest fd) failed: %m");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen req.ino = st.st_ino;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi buf = t_buffer_create(sizeof(req) + req.data_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen buffer_append(buf, &req, sizeof(req));
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen buffer_append(buf, params->data, req.data_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->fd = net_connect_unix_with_retries(conn->path,
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen SOCKET_CONNECT_RETRY_MSECS);
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen if (conn->fd == -1) {
b52230a2649019208b13dcbc0469eecde80f76d2Timo Sirainen i_error("net_connect_unix(%s) failed: %m%s",
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path, errno != EAGAIN ? "" :
b52230a2649019208b13dcbc0469eecde80f76d2Timo Sirainen " - http://wiki2.dovecot.org/SocketUnavailable");
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen master_auth_connection_deinit(&conn);
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen return;
405fbb38e0d4bd33a82b547dc9590245885f0b62Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen ret = fd_send(conn->fd, params->client_fd, buf->data, buf->used);
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen if (ret < 0) {
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen i_error("fd_send(%s, %d) failed: %m", conn->path,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen params->client_fd);
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen } else if ((size_t)ret != buf->used) {
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen i_error("fd_send(%s) sent only %d of %d bytes",
9498baa8f374be5b878c0571d07e8ad060a1fdecTimo Sirainen conn->path, (int)ret, (int)buf->used);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = -1;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (ret < 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen master_auth_connection_deinit(&conn);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->tag = req.tag;
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen conn->to = timeout_add(MASTER_AUTH_REQUEST_TIMEOUT_MSECS,
6bee43694f513ae65566f09a39e1f34a64ef7a20Timo Sirainen master_auth_connection_timeout, conn);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->io = io_add(conn->fd, IO_READ,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen master_auth_connection_input, conn);
fd05c47210cad1f6d8effbda5cba7f7d938ca9a0Timo Sirainen i_assert(hash_table_lookup(auth->connections, POINTER_CAST(req.tag)) == NULL);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen hash_table_insert(auth->connections, POINTER_CAST(req.tag), conn);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *tag_r = req.tag;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainenvoid master_auth_request(struct master_auth *auth, int fd,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen const struct master_auth_request *request,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen const unsigned char *data,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen master_auth_callback_t *callback,
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen void *context, unsigned int *tag_r)
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen{
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen struct master_auth_request_params params;
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&params);
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen params.client_fd = fd;
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen params.request = *request;
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen params.data = data;
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen master_auth_request_full(auth, &params, callback, context, tag_r);
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen}
2d8e25bef14245b078868a64396da025f547ad27Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenvoid master_auth_request_abort(struct master_auth *auth, unsigned int tag)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct master_auth_connection *conn;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen conn = hash_table_lookup(auth->connections, POINTER_CAST(tag));
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (conn == NULL)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_panic("master_auth_request_abort(): tag %u not found", tag);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen conn->callback = NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}