bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "lib.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "ioloop.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "array.h"
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen#include "str.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "restrict-access.h"
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen#include "process-title.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "master-interface.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "master-service.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "master-service-settings.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "auth-connection.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "doveadm-connection.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "login-connection.h"
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen#include "notify-connection.h"
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen#include "user-directory.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director-host.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director-connection.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director-request.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "mail-host.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
ae46f6ba5bb9eee8900254d3042e89d490023be0Timo Sirainen#include <stdio.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include <unistd.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
3f3ad16ff74d694796d22501250a9a29997c0729Timo Sirainen#define AUTH_SOCKET_PATH "auth-login"
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen#define AUTH_USERDB_SOCKET_PATH "auth-userdb"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenenum director_socket_type {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen DIRECTOR_SOCKET_TYPE_UNKNOWN = 0,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen DIRECTOR_SOCKET_TYPE_AUTH,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen DIRECTOR_SOCKET_TYPE_USERDB,
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen DIRECTOR_SOCKET_TYPE_AUTHREPLY,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen DIRECTOR_SOCKET_TYPE_RING,
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen DIRECTOR_SOCKET_TYPE_DOVEADM,
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen DIRECTOR_SOCKET_TYPE_PROXY_NOTIFY,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen};
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
8cafec427a378daf68c253929232d498509d548cTimo Sirainenstatic struct director *director;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainenstatic struct timeout *to_proctitle_refresh;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic ARRAY(enum director_socket_type) listener_socket_types;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomistatic unsigned int director_total_users_count(void)
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi{
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi struct mail_tag *const *tagp;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi unsigned int count = 0;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi array_foreach(mail_hosts_get_tags(director->mail_hosts), tagp)
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi count += user_directory_count((*tagp)->users);
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi return count;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi}
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainenstatic void director_refresh_proctitle_timeout(void *context ATTR_UNUSED)
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen{
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen static uint64_t prev_requests = 0, prev_input = 0, prev_output;
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen static uint64_t prev_incoming_requests = 0;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen string_t *str;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen str = t_str_new(64);
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi str_printfa(str, "[%u users", director_total_users_count());
4dc8d682c855ca78db8874e04302e885465c1d65Timo Sirainen if (director->requests_delayed_count > 0)
4dc8d682c855ca78db8874e04302e885465c1d65Timo Sirainen str_printfa(str, ", %u delayed", director->requests_delayed_count);
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen if (director->users_moving_count > 0)
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen str_printfa(str, ", %u moving", director->users_moving_count);
5754fa860405e9af20c38981942f6aa97ce3158dTimo Sirainen if (director->users_kicking_count > 0)
5754fa860405e9af20c38981942f6aa97ce3158dTimo Sirainen str_printfa(str, ", %u kicking", director->users_kicking_count);
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen str_printfa(str, ", %"PRIu64"+%"PRIu64" req/s",
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen director->num_requests - prev_requests,
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen director->num_incoming_requests - prev_incoming_requests);
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi str_printfa(str, ", %"PRIu64"+%"PRIu64" kB/s",
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi (director->ring_traffic_input - prev_input)/1024,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi (director->ring_traffic_output - prev_output)/1024);
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen str_append_c(str, ']');
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen prev_requests = director->num_requests;
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen prev_incoming_requests = director->num_incoming_requests;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen prev_input = director->ring_traffic_input;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen prev_output = director->ring_traffic_output;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen process_title_set(str_c(str));
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic enum director_socket_type
6468191d64827a2d1481c091ec499874583c834eTimo Sirainendirector_socket_type_get_from_name(const char *path)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen{
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen const char *name, *suffix;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen name = strrchr(path, '/');
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (name == NULL)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen name = path;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen name++;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen suffix = strrchr(name, '-');
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (suffix == NULL)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen suffix = name;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen suffix++;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (strcmp(suffix, "auth") == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_AUTH;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else if (strcmp(suffix, "userdb") == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_USERDB;
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen else if (strcmp(suffix, "authreply") == 0)
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen return DIRECTOR_SOCKET_TYPE_AUTHREPLY;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else if (strcmp(suffix, "ring") == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_RING;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else if (strcmp(suffix, "admin") == 0 ||
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen strcmp(suffix, "doveadm") == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_DOVEADM;
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen else if (strcmp(suffix, "notify") == 0)
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen return DIRECTOR_SOCKET_TYPE_PROXY_NOTIFY;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen else
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_UNKNOWN;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen}
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic enum director_socket_type
5545acdd3aa90a6e0cca2b665f909ec4c2fb2513Baofenglistener_get_socket_type_fallback(int listen_fd)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen{
009217abb57a24a4076092e8e4e165545747839eStephan Bosch in_port_t local_port;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
973c8fc1d7e9f982f7caf6385adb78dfacd9fb80Timo Sirainen if (net_getsockname(listen_fd, NULL, &local_port) == 0 &&
973c8fc1d7e9f982f7caf6385adb78dfacd9fb80Timo Sirainen local_port != 0) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* TCP/IP connection */
5545acdd3aa90a6e0cca2b665f909ec4c2fb2513Baofeng return DIRECTOR_SOCKET_TYPE_RING;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen }
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen return DIRECTOR_SOCKET_TYPE_AUTH;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen}
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
c1d01419ffbeb0e00f86a653db70bfd47110e7fcTimo Sirainenstatic void listener_sockets_init(struct ip_addr *listen_ip_r,
009217abb57a24a4076092e8e4e165545747839eStephan Bosch in_port_t *listen_port_r)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen{
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen const char *name;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch unsigned int i, socket_count;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen struct ip_addr ip;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch in_port_t port;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen enum director_socket_type type;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen *listen_port_r = 0;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen i_array_init(&listener_socket_types, 8);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen socket_count = master_service_get_socket_count(master_service);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen for (i = 0; i < socket_count; i++) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen int listen_fd = MASTER_LISTEN_FD_FIRST + i;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen name = master_service_get_socket_name(master_service, listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen type = director_socket_type_get_from_name(name);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (type == DIRECTOR_SOCKET_TYPE_UNKNOWN) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* mainly for backwards compatibility */
5545acdd3aa90a6e0cca2b665f909ec4c2fb2513Baofeng type = listener_get_socket_type_fallback(listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen }
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (type == DIRECTOR_SOCKET_TYPE_RING && *listen_port_r == 0 &&
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen net_getsockname(listen_fd, &ip, &port) == 0 && port > 0) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen *listen_ip_r = ip;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen *listen_port_r = port;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen }
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen array_idx_set(&listener_socket_types, listen_fd, &type);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen }
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen}
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic int director_client_connected(int fd, const struct ip_addr *ip)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct director_host *host;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen host = director_host_lookup_ip(director, ip);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen if (host == NULL || host->removed) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_warning("Connection from %s: Server not listed in "
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "director_servers, dropping", net_ip2addr(ip));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen (void)director_connection_init_in(director, fd, ip);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
db693bf6fcae96d834567f1782257517b7207655Timo Sirainenstatic void client_connected(struct master_service_connection *conn)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct auth_connection *auth;
faec0abfd648c647030027e86de2ce8911df683bTimo Sirainen const char *socket_path;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen const enum director_socket_type *typep;
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen bool userdb;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen if (conn->fifo) {
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen master_service_client_connection_accept(conn);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen notify_connection_init(director, conn->fd, TRUE);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen return;
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen }
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen typep = array_idx(&listener_socket_types, conn->listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen switch (*typep) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen case DIRECTOR_SOCKET_TYPE_UNKNOWN:
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen i_unreached();
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen case DIRECTOR_SOCKET_TYPE_AUTH:
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen case DIRECTOR_SOCKET_TYPE_USERDB:
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* a) userdb connection, probably for lmtp proxy
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen b) login connection
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen Both of them are handled exactly the same, except for which
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen auth socket they connect to. */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen userdb = *typep == DIRECTOR_SOCKET_TYPE_USERDB;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen socket_path = userdb ? AUTH_USERDB_SOCKET_PATH :
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen AUTH_SOCKET_PATH;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen auth = auth_connection_init(socket_path);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (auth_connection_connect(auth) < 0) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen auth_connection_deinit(&auth);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen break;
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen }
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen master_service_client_connection_accept(conn);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen (void)login_connection_init(director, conn->fd, auth,
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen userdb ? LOGIN_CONNECTION_TYPE_USERDB :
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen LOGIN_CONNECTION_TYPE_AUTH);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen break;
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen case DIRECTOR_SOCKET_TYPE_AUTHREPLY:
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen master_service_client_connection_accept(conn);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen (void)login_connection_init(director, conn->fd, NULL,
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen LOGIN_CONNECTION_TYPE_AUTHREPLY);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen break;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen case DIRECTOR_SOCKET_TYPE_RING:
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (director_client_connected(conn->fd, &conn->remote_ip) == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen master_service_client_connection_accept(conn);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen break;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen case DIRECTOR_SOCKET_TYPE_DOVEADM:
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen master_service_client_connection_accept(conn);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen (void)doveadm_connection_init(director, conn->fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen break;
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen case DIRECTOR_SOCKET_TYPE_PROXY_NOTIFY:
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen master_service_client_connection_accept(conn);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen notify_connection_init(director, conn->fd, FALSE);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen break;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_state_changed(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_request *const *requestp;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct director_request *) new_requests;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen bool ret;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5a444fdfabcc0c75708c21e84dc8b87eddab7335Timo Sirainen if (!dir->ring_synced)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* if there are any pending client requests, finish them now */
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen t_array_init(&new_requests, 8);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_foreach(&dir->pending_requests, requestp) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ret = director_request_continue(*requestp);
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen if (!ret) {
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen /* a) request for a user being killed
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen b) user is weak */
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen array_append(&new_requests, requestp, 1);
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_clear(&dir->pending_requests);
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen array_append_array(&dir->pending_requests, &new_requests);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5b4d189a01d248458496068f838128f1bafdcf2eTimo Sirainen if (dir->to_request != NULL && array_count(&new_requests) == 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen timeout_remove(&dir->to_request);
6ecc5475f7efd4dcdf4ce727191693de24c5cf51Timo Sirainen doveadm_connections_ring_synced();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
7ee226c2a66aa4dce7f13e8b17687db285c981bdTimo Sirainenstatic void main_preinit(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct director_settings *set;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr listen_ip;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch in_port_t listen_port;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen /* make sure we die with master even with shutdown_clients=no.
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen otherwise there will be two director processes and everything is
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen broken. it's only the login processes that need to stay alive. */
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen master_service_set_die_with_master(master_service, TRUE);
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen if (master_service_settings_get(master_service)->verbose_proctitle) {
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen to_proctitle_refresh =
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen timeout_add(1000, director_refresh_proctitle_timeout,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek NULL);
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen set = master_service_settings_get_others(master_service)[0];
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
c1d01419ffbeb0e00f86a653db70bfd47110e7fcTimo Sirainen listener_sockets_init(&listen_ip, &listen_port);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (listen_port == 0 && *set->director_servers != '\0') {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("No inet_listeners defined for director service "
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "(for standalone keep director_servers empty)");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen directors_init();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director = director_init(set, &listen_ip, listen_port,
16a5712c1a774b7bd3bbf22032b61ccc9398499eAki Tuomi director_state_changed,
16a5712c1a774b7bd3bbf22032b61ccc9398499eAki Tuomi doveadm_connections_kick_callback);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_host_add_from_string(director, set->director_servers);
c4900d31385344bfadaee53a897daeafdb3063d8Timo Sirainen director_find_self(director);
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen if (mail_hosts_parse_and_add(director->mail_hosts,
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen set->director_mail_servers) < 0)
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen i_fatal("Invalid value for director_mail_servers setting");
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen director->orig_config_hosts = mail_hosts_dup(director->mail_hosts);
69b22a0c0c84087e5bdeec71faae7ea77295240fTimo Sirainen
816d20be0cf95fc4eb1a8aa716639e73b8ba525eMartti Rannanjärvi restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
69b22a0c0c84087e5bdeec71faae7ea77295240fTimo Sirainen restrict_access_allow_coredumps(TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void main_deinit(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&to_proctitle_refresh);
57d65ae19a2339d1303a522e680c30ee1ef68d6dTimo Sirainen notify_connections_deinit();
faa01447c2f699b63ceccf129430a9ed46458083Timo Sirainen /* deinit doveadm connections before director, so it can clean up
faa01447c2f699b63ceccf129430a9ed46458083Timo Sirainen its pending work, such as abort user moves. */
faa01447c2f699b63ceccf129430a9ed46458083Timo Sirainen doveadm_connections_deinit();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_deinit(&director);
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen directors_deinit();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen login_connections_deinit();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen auth_connections_deinit();
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen array_free(&listener_socket_types);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenint main(int argc, char *argv[])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct setting_parser_info *set_roots[] = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen &director_setting_parser_info,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen NULL
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen };
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen const enum master_service_flags service_flags =
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen MASTER_SERVICE_FLAG_NO_IDLE_DIE;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch in_port_t test_port = 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *error;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen bool debug = FALSE;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen int c;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen master_service = master_service_init("director", service_flags,
f9f77e06a148fd0816004e0e1b0f585307148a7dTimo Sirainen &argc, &argv, "Dt:");
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen switch (c) {
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen case 'D':
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen debug = TRUE;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen break;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen case 't':
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (net_str2port(optarg, &test_port) < 0)
009217abb57a24a4076092e8e4e165545747839eStephan Bosch i_fatal("-t: Not a port number: %s", optarg);
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen break;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen default:
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen return FATAL_DEFAULT;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen }
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (master_service_settings_read_simple(master_service, set_roots,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen &error) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("Error reading configuration: %s", error);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen master_service_init_log(master_service, "director: ");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
7ee226c2a66aa4dce7f13e8b17687db285c981bdTimo Sirainen main_preinit();
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen director->test_port = test_port;
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen director_debug = debug;
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainen director_connect(director, "Initial connection");
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if (director->test_port != 0) {
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen /* we're testing, possibly writing to same log file.
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen make it clear which director we are. */
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen master_service_init_log(master_service,
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen t_strdup_printf("director(%s): ",
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen net_ip2addr(&director->self_ip)));
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen }
d6b3cfd855c0eebed68be50d3111de1b5a6afeb0Timo Sirainen master_service_init_finish(master_service);
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen master_service_run(master_service, client_connected);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen main_deinit();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen master_service_deinit(&master_service);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}