main.c revision 296acbaddb68301e5ae3579a1da9325064c4dca8
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "login-common.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "ioloop.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "array.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "str.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "randgen.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "module-dir.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "process-title.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "restrict-access.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "restrict-process-size.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "master-auth.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "master-service.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "master-interface.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "iostream-ssl.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "client-common.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "access-lookup.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "anvil-client.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "auth-client.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "dsasl-client.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "master-service-ssl-settings.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "login-proxy.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <unistd.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <syslog.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct login_access_lookup {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct master_service_connection conn;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct io *io;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen char **sockets, **next_socket;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct access_lookup *access;
a21f618de284dc22a480af1371d5f5cea50a39dfTimo Sirainen};
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct login_binary *login_binary;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct auth_client *auth_client;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct master_auth *master_auth;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenbool closing_down, login_debug;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct anvil_client *anvil;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst char *login_rawlog_dir = NULL;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenunsigned int initial_service_count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct login_module_register login_module_register;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo SirainenARRAY_TYPE(string) global_alt_usernames;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenbool login_ssl_initialized;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct login_settings *global_login_settings;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct master_service_ssl_settings *global_ssl_settings;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid **global_other_settings;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct ip_addr *login_source_ips;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenunsigned int login_source_ips_idx, login_source_ips_count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic struct module *modules;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic struct timeout *auth_client_to;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic const char *post_login_socket;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool shutting_down = FALSE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool ssl_connections = FALSE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool auth_connected_once = FALSE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool get_first_client(struct client **client_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct client *client = clients;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (client == NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client = login_proxies_get_first_detached_client();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (client == NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client = clients_get_first_fd_proxy();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *client_r = client;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return client != NULL;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid login_refresh_proctitle(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct client *client;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *addr;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!global_login_settings->verbose_proctitle)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* clients_get_count() includes all the clients being served.
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen Inside that there are 3 groups:
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 1. pre-login clients
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 2. post-login clients being proxied to remote hosts
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 3. post-login clients being proxied to post-login processes
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen Currently the post-login proxying is done only for SSL/TLS
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen connections, so we're assuming that they're the same. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen string_t *str = t_str_new(64);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (clients_get_count() == 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* no clients */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else if (clients_get_count() > 1 || !get_first_client(&client)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_printfa(str, "[%u pre-login", clients_get_count() -
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_proxies_get_detached_count() -
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_get_fd_proxies_count());
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (login_proxies_get_detached_count() > 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* show detached proxies only if they exist, so
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen non-proxy servers don't unnecessarily show them. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_printfa(str, " + %u proxies",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_proxies_get_detached_count());
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (clients_get_fd_proxies_count() > 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* show post-login proxies only if they exist, so
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen proxy-only servers don't unnecessarily show them. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_printfa(str, " + %u TLS proxies",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_get_fd_proxies_count());
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(str, ']');
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(str, '[');
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen addr = net_ip2addr(&client->ip);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (addr[0] != '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_printfa(str, "%s ", addr);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (client->fd_proxying)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append(str, "TLS proxy");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen else if (client->destroyed)
d48e40d6c77d673ad402d96571198d1cce4da225Timo Sirainen str_append(str, "proxy");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen else
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append(str, "pre-login");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(str, ']');
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
a327d9301f593433c228c4cc8cca05c95b37f6fbTimo Sirainen process_title_set(str_c(str));
d48e40d6c77d673ad402d96571198d1cce4da225Timo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainenstatic void auth_client_idle_timeout(struct auth_client *auth_client)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_assert(clients == NULL);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_client_disconnect(auth_client, "idle disconnect");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen timeout_remove(&auth_client_to);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid login_client_destroyed(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen if (clients == NULL && auth_client_to == NULL) {
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_client_idle_timeout,
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_client);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen }
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen}
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenstatic void login_die(void)
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen{
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen shutting_down = TRUE;
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen login_proxy_kill_idle();
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen if (!auth_client_is_connected(auth_client)) {
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen /* we don't have auth client, and we might never get one */
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen clients_destroy_all();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenclient_connected_finish(const struct master_service_connection *conn)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct client *client;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const struct login_settings *set;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const struct master_service_ssl_settings *ssl_set;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pool_t pool;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen void **other_sets;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pool = pool_alloconly_create("login client", 8*1024);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen set = login_settings_read(pool, &conn->local_ip,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &conn->remote_ip, NULL, &ssl_set, &other_sets);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen client = client_alloc(conn->fd, pool, conn, set, ssl_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ssl_connections || conn->ssl) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (client_init_ssl(client) < 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client_unref(&client);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen net_disconnect(conn->fd);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_destroyed(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client_init(client, other_sets);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen timeout_remove(&auth_client_to);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_lookup_free(struct login_access_lookup *lookup)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen io_remove(&lookup->io);
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen if (lookup->access != NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen access_lookup_destroy(&lookup->access);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (lookup->conn.fd != -1) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (close(lookup->conn.fd) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("close(client) failed: %m");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_destroyed(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen p_strsplit_free(default_pool, lookup->sockets);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_free(lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_callback(bool success, void *context)
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct login_access_lookup *lookup = context;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch if (!success) {
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch i_info("access(%s): Client refused (rip=%s)",
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch *lookup->next_socket,
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch net_ip2addr(&lookup->conn.remote_ip));
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_access_lookup_free(lookup);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch } else {
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch lookup->next_socket++;
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_access_lookup_next(lookup);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch }
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch}
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschstatic void login_access_lookup_next(struct login_access_lookup *lookup)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch{
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch if (*lookup->next_socket == NULL) {
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch /* last one */
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch io_remove(&lookup->io);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch client_connected_finish(&lookup->conn);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch lookup->conn.fd = -1;
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_access_lookup_free(lookup);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch return;
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch }
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_binary->protocol,
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_access_callback, lookup);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch if (lookup->access == NULL)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch login_access_lookup_free(lookup);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch}
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschstatic void client_input_error(struct login_access_lookup *lookup)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch{
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch char c;
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch int ret;
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch if (ret <= 0) {
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch i_info("access(%s): Client disconnected during lookup (rip=%s)",
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen *lookup->next_socket,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen net_ip2addr(&lookup->conn.remote_ip));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_access_lookup_free(lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* actual input. stop listening until lookup is done. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen io_remove(&lookup->io);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen }
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *access_sockets =
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen global_login_settings->login_access_sockets;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct login_access_lookup *lookup;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_accept(conn);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (conn->remote_ip.family != 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* log the connection's IP address in case we crash. it's of
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen course possible that another earlier client causes the
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crash, but this is better than nothing. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_set_failure_send_ip(&conn->remote_ip);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* make sure we're connected (or attempting to connect) to auth */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_client_connect(auth_client);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*access_sockets == '\0') {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* no access checks */
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen client_connected_finish(conn);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup = i_new(struct login_access_lookup, 1);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup->conn = *conn;
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup->next_socket = lookup->sockets;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_access_lookup_next(lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen bool connected, void *context ATTR_UNUSED)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (connected) {
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen auth_connected_once = TRUE;
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen clients_notify_auth_connected();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else if (shutting_down)
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen clients_destroy_all();
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen else if (!auth_connected_once) {
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen /* auth disconnected without having ever succeeded, so the
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth process is probably misconfigured. no point in
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen keeping the client connections hanging. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_destroy_all_reason("Disconnected: Auth process broken");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
88df77efd9ffdfd9a62bca0a9c8f403ecdbea3ffTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool anvil_reconnect_callback(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* we got disconnected from anvil. we can't reconnect to it since we're
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen chrooted, so just die after we've finished handling the current
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen connections. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_stop_new_connections(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return FALSE;
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen}
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainenvoid login_anvil_init(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (anvil != NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (anvil_client_connect(anvil, TRUE) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("Couldn't connect to anvil");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic const struct ip_addr *
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenparse_login_source_ips(const char *ips_str, unsigned int *count_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ARRAY(struct ip_addr) ips;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *const *tmp;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct ip_addr *tmp_ips;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen bool skip_nonworking = FALSE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i, tmp_ips_count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen int ret;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ips_str[0] == '?') {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* try binding to the IP immediately. if it doesn't
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen work, skip it. (this allows using the same config file for
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen all the servers.) */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen skip_nonworking = TRUE;
48325adac125d7ff275ec69b05b7a92be9637630Timo Sirainen ips_str++;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen t_array_init(&ips, 4);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (tmp = t_strsplit_spaces(ips_str, ", "); *tmp != NULL; tmp++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret = net_gethostbyname(*tmp, &tmp_ips, &tmp_ips_count);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ret != 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("login_source_ips: net_gethostbyname(%s) failed: %s",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *tmp, net_gethosterror(ret));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen continue;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 0; i < tmp_ips_count; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (skip_nonworking && net_try_bind(&tmp_ips[i]) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen continue;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen array_append(&ips, &tmp_ips[i], 1);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return array_get(&ips, count_r);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_load_modules(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct module_dir_load_settings mod_set;
d368aabf3ff5411afee1b4af8261163296723e19Timo Sirainen
d368aabf3ff5411afee1b4af8261163296723e19Timo Sirainen if (global_login_settings->login_plugins[0] == '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_zero(&mod_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.abi_version = DOVECOT_ABI_VERSION;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.binary_name = login_binary->process_name;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.setting_name = "login_plugins";
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.require_init_funcs = TRUE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.debug = login_debug;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen modules = module_dir_load(global_login_settings->login_plugin_dir,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen global_login_settings->login_plugins,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &mod_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen module_dir_init(modules);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_ssl_init(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct ssl_iostream_settings ssl_set;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *error;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (strcmp(global_ssl_settings->ssl, "no") == 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_ssl_settings_to_iostream_set(global_ssl_settings,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pool_datastack_create(),
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen MASTER_SERVICE_SSL_SETTINGS_TYPE_SERVER, &ssl_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (io_stream_ssl_global_init(&ssl_set, &error) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("Failed to initialize SSL library: %s", error);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_ssl_initialized = TRUE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void main_preinit(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int max_fds;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* Initialize SSL proxy so it can read certificate and private
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen key file. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen login_ssl_init();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen dsasl_clients_init();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client_common_init();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* set the number of fds we want to use. it may get increased or
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen decreased. leave a couple of extra fds for auth sockets and such.
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen worst case each connection can use:
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 1 for client
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 1 for login proxy
00b706a9ea136a5945f4ebafaa4ba958b641635dTimo Sirainen - 2 for client-side ssl proxy
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 2 for server-side ssl proxy (with login proxy)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen However, login process nowadays supports plugins, there are rawlogs
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen and so on. Don't enforce the fd limit anymore, but use this value
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for optimizing the ioloop's fd table size.
*/
max_fds = MASTER_LISTEN_FD_FIRST + 16 +
master_service_get_socket_count(master_service) +
master_service_get_client_limit(master_service)*6;
io_loop_set_max_fd_count(current_ioloop, max_fds);
i_assert(strcmp(global_ssl_settings->ssl, "no") == 0 ||
login_ssl_initialized);
if (global_login_settings->mail_max_userip_connections > 0)
login_anvil_init();
/* read the login_source_ips before chrooting so it can access
/etc/hosts */
login_source_ips = parse_login_source_ips(global_login_settings->login_source_ips,
&login_source_ips_count);
if (login_source_ips_count > 0) {
/* randomize the initial index in case service_count=1
(although in that case it's unlikely this setting is
even used..) */
login_source_ips_idx = i_rand_limit(login_source_ips_count);
}
login_load_modules();
restrict_access_by_env(NULL, TRUE);
if (login_debug)
restrict_access_allow_coredumps(TRUE);
initial_service_count = master_service_get_service_count(master_service);
if (restrict_access_get_current_chroot() == NULL) {
if (chdir("login") < 0)
i_fatal("chdir(login) failed: %m");
}
if (login_rawlog_dir != NULL &&
access(login_rawlog_dir, W_OK | X_OK) < 0) {
i_error("access(%s, wx) failed: %m - disabling rawlog",
login_rawlog_dir);
login_rawlog_dir = NULL;
}
}
static void main_init(const char *login_socket)
{
/* make sure we can't fork() */
restrict_process_count(1);
i_array_init(&global_alt_usernames, 4);
master_service_set_avail_overflow_callback(master_service,
client_destroy_oldest);
master_service_set_die_callback(master_service, login_die);
auth_client = auth_client_init(login_socket, (unsigned int)getpid(),
FALSE);
auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
master_auth = master_auth_init(master_service, post_login_socket);
login_binary->init();
login_proxy_init(global_login_settings->login_proxy_notify_path);
}
static void main_deinit(void)
{
client_destroy_fd_proxies();
ssl_iostream_context_cache_free();
login_proxy_deinit();
login_binary->deinit();
module_dir_unload(&modules);
auth_client_deinit(&auth_client);
master_auth_deinit(&master_auth);
char **strp;
array_foreach_modifiable(&global_alt_usernames, strp)
i_free(*strp);
array_free(&global_alt_usernames);
if (anvil != NULL)
anvil_client_deinit(&anvil);
timeout_remove(&auth_client_to);
client_common_deinit();
dsasl_clients_deinit();
login_settings_deinit();
}
int login_binary_run(const struct login_binary *binary,
int argc, char *argv[])
{
enum master_service_flags service_flags =
MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN |
MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE |
MASTER_SERVICE_FLAG_USE_SSL_SETTINGS |
MASTER_SERVICE_FLAG_NO_SSL_INIT;
pool_t set_pool;
const char *login_socket;
int c;
login_binary = binary;
login_socket = binary->default_login_socket != NULL ?
binary->default_login_socket : LOGIN_DEFAULT_SOCKET;
post_login_socket = binary->protocol;
master_service = master_service_init(login_binary->process_name,
service_flags, &argc, &argv,
"Dl:R:S");
master_service_init_log(master_service, t_strconcat(
login_binary->process_name, ": ", NULL));
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'D':
login_debug = TRUE;
break;
case 'l':
post_login_socket = optarg;
break;
case 'R':
login_rawlog_dir = optarg;
break;
case 'S':
ssl_connections = TRUE;
break;
default:
return FATAL_DEFAULT;
}
}
if (argv[optind] != NULL)
login_socket = argv[optind];
login_binary->preinit();
set_pool = pool_alloconly_create("global login settings", 4096);
global_login_settings =
login_settings_read(set_pool, NULL, NULL, NULL,
&global_ssl_settings,
&global_other_settings);
main_preinit();
master_service_init_finish(master_service);
main_init(login_socket);
master_service_run(master_service, client_connected);
main_deinit();
pool_unref(&set_pool);
master_service_deinit(&master_service);
return 0;
}