main.c revision 183bea41fa640dc8117f3eb45ff935cd81377a84
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "login-common.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "ioloop.h"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include "randgen.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "process-title.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "restrict-access.h"
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#include "restrict-process-size.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "master-auth.h"
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#include "master-service.h"
436adac819e7cbeef04af08dcc6a4f3ecd4a1d9eMartti Rannanjärvi#include "master-interface.h"
905457e0982fc15930d90e174f271dc69f9afcf9Timo Sirainen#include "client-common.h"
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#include "access-lookup.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "anvil-client.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "auth-client.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "ssl-proxy.h"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include "login-proxy.h"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include <stdlib.h>
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include <unistd.h>
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include <syslog.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#define DEFAULT_LOGIN_SOCKET "login"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct login_access_lookup {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct master_service_connection conn;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct io *io;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen char **sockets, **next_socket;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct access_lookup *access;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct auth_client *auth_client;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstruct master_auth *master_auth;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenbool closing_down;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstruct anvil_client *anvil;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
5948e3e120c5dcaf0aeb44405566381045fa82d6Timo Sirainenconst struct login_settings *global_login_settings;
7fc0ca6c1f664de6506afa816200d115f9f80391Timo Sirainenvoid **global_other_settings;
7fc0ca6c1f664de6506afa816200d115f9f80391Timo Sirainen
7fc0ca6c1f664de6506afa816200d115f9f80391Timo Sirainenstatic struct timeout *auth_client_to;
5948e3e120c5dcaf0aeb44405566381045fa82d6Timo Sirainenstatic bool shutting_down = FALSE;
5948e3e120c5dcaf0aeb44405566381045fa82d6Timo Sirainenstatic bool ssl_connections = FALSE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid login_refresh_proctitle(void)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct client *client = clients;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen const char *addr;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!global_login_settings->verbose_proctitle)
5b7ff90a6c078b07406bce434c719017a0f51825Timo Sirainen return;
5b7ff90a6c078b07406bce434c719017a0f51825Timo Sirainen
5b7ff90a6c078b07406bce434c719017a0f51825Timo Sirainen if (clients_get_count() == 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen process_title_set("");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else if (clients_get_count() > 1 || client == NULL) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen process_title_set(t_strdup_printf("[%u connections (%u TLS)]",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen clients_get_count(), ssl_proxy_get_count()));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else if ((addr = net_ip2addr(&client->ip)) != NULL) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen process_title_set(t_strdup_printf(client->tls ?
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "[%s TLS]" : "[%s]", addr));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen process_title_set(client->tls ? "[TLS]" : "");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void auth_client_idle_timeout(struct auth_client *auth_client)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen auth_client_disconnect(auth_client);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen timeout_remove(&auth_client_to);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainenvoid login_client_destroyed(void)
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen{
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen if (clients == NULL && auth_client_to == NULL) {
212e9e43a7d49242446331fd43ba519eda936d60Timo Sirainen auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen auth_client_idle_timeout,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen auth_client);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void login_die(void)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen shutting_down = TRUE;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen login_proxy_kill_idle();
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen if (!auth_client_is_connected(auth_client)) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* we don't have auth client, and we might never get one */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen clients_destroy_all();
7fc0ca6c1f664de6506afa816200d115f9f80391Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenclient_connected_finish(const struct master_service_connection *conn)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct client *client;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct ssl_proxy *proxy;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct ip_addr local_ip;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const struct login_settings *set;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int local_port;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen int fd_ssl;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen void **other_sets;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (net_getsockname(conn->fd, &local_ip, &local_port) < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memset(&local_ip, 0, sizeof(local_ip));
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen local_port = 0;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen pool = pool_alloconly_create("login client", 5*1024);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen set = login_settings_read(pool, &local_ip,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen &conn->remote_ip, NULL, &other_sets);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (!ssl_connections && !conn->ssl) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen client = client_create(conn->fd, FALSE, pool, set, other_sets,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen &local_ip, &conn->remote_ip);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else {
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, set,
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen &proxy);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (fd_ssl == -1) {
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen net_disconnect(conn->fd);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen pool_unref(&pool);
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen master_service_client_connection_destroyed(master_service);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen client = client_create(fd_ssl, TRUE, pool, set, other_sets,
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen &local_ip, &conn->remote_ip);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen client->ssl_proxy = proxy;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen ssl_proxy_set_client(proxy, client);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen ssl_proxy_start(proxy);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen }
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen client->remote_port = conn->remote_port;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen client->local_port = local_port;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen if (auth_client_to != NULL)
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen timeout_remove(&auth_client_to);
8f90ef65db62946aabe1969755edcdefb4eb430aTimo Sirainen}
8f90ef65db62946aabe1969755edcdefb4eb430aTimo Sirainen
8f90ef65db62946aabe1969755edcdefb4eb430aTimo Sirainenstatic void login_access_lookup_free(struct login_access_lookup *lookup)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen{
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen if (lookup->io != NULL)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen io_remove(&lookup->io);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (lookup->access != NULL)
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen access_lookup_destroy(&lookup->access);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (lookup->conn.fd != -1) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (close(lookup->conn.fd) < 0)
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen i_error("close(client) failed: %m");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_client_connection_destroyed(master_service);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen p_strsplit_free(default_pool, lookup->sockets);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_free(lookup);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void login_access_callback(bool success, void *context)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct login_access_lookup *lookup = context;
504337186520df7012315687fc0f88c945775471Timo Sirainen
504337186520df7012315687fc0f88c945775471Timo Sirainen if (!success) {
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen i_info("access(%s): Client refused (rip=%s)",
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen *lookup->next_socket,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen net_ip2addr(&lookup->conn.remote_ip));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_access_lookup_free(lookup);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen } else {
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen lookup->next_socket++;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_access_lookup_next(lookup);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (*lookup->next_socket == NULL) {
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen /* last one */
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (lookup->io != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen io_remove(&lookup->io);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen client_connected_finish(&lookup->conn);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup->conn.fd = -1;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_access_lookup_free(lookup);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi return;
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi }
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi login_binary.protocol,
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi login_access_callback, lookup);
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi if (lookup->access == NULL)
825b0e819a7c48a366ddca23ec78b87e8c30e9b4Aki Tuomi login_access_lookup_free(lookup);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void client_input_error(struct login_access_lookup *lookup)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen char c;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen int ret;
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen if (ret <= 0) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_info("access(%s): Client disconnected during lookup (rip=%s)",
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen *lookup->next_socket,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen net_ip2addr(&lookup->conn.remote_ip));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_access_lookup_free(lookup);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen } else {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* actual input. stop listening until lookup is done. */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen io_remove(&lookup->io);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen const char *access_sockets =
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen global_login_settings->login_access_sockets;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct login_access_lookup *lookup;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_client_connection_accept(conn);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen /* make sure we're connected (or attempting to connect) to auth */
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen auth_client_connect(auth_client);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (*access_sockets == '\0') {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* no access checks */
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen client_connected_finish(conn);
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen return;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup = i_new(struct login_access_lookup, 1);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup->conn = *conn;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen lookup->next_socket = lookup->sockets;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen login_access_lookup_next(lookup);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainenstatic void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bool connected, void *context ATTR_UNUSED)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen{
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen if (connected)
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen clients_notify_auth_connected();
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen else if (shutting_down)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen clients_destroy_all();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainenstatic bool anvil_reconnect_callback(void)
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen{
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen master_service_stop_new_connections(master_service);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return FALSE;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void main_preinit(bool allow_core_dumps)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int max_fds;
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen random_init();
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen /* Initialize SSL proxy so it can read certificate and private
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen key file. */
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen ssl_proxy_init();
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen /* set the number of fds we want to use. it may get increased or
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen decreased. leave a couple of extra fds for auth sockets and such.
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen worst case each connection can use:
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen - 1 for client
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen - 1 for login proxy
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen - 2 for client-side ssl proxy
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen - 2 for server-side ssl proxy (with login proxy)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen max_fds = MASTER_LISTEN_FD_FIRST + 16 +
d85a1a9d9af4a36ded4d30cb277905c807de2ec5Timo Sirainen master_service_get_socket_count(master_service) +
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_get_client_limit(master_service)*6;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen restrict_fd_limit(max_fds);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen io_loop_set_max_fd_count(current_ioloop, max_fds);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_assert(strcmp(global_login_settings->ssl, "no") == 0 ||
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ssl_initialized);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (global_login_settings->mail_max_userip_connections > 0) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (anvil_client_connect(anvil, TRUE) < 0)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_fatal("Couldn't connect to anvil");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen restrict_access_by_env(NULL, TRUE);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (allow_core_dumps)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen restrict_access_allow_coredumps(TRUE);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Boschstatic void main_init(const char *login_socket)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* make sure we can't fork() */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen restrict_process_size((unsigned int)-1, 1);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen if (restrict_access_get_current_chroot() == NULL) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (chdir("login") < 0)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_fatal("chdir(login) failed: %m");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_set_avail_overflow_callback(master_service,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen client_destroy_oldest);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_set_die_callback(master_service, login_die);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_client = auth_client_init(login_socket, (unsigned int)getpid(),
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen FALSE);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_auth = master_auth_init(master_service, login_binary.protocol);
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen clients_init();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_proxy_init("proxy-notify");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void main_deinit(void)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ssl_proxy_deinit();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_proxy_deinit();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen clients_deinit();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_client_deinit(&auth_client);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_auth_deinit(&master_auth);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (anvil != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen anvil_client_deinit(&anvil);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (auth_client_to != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen timeout_remove(&auth_client_to);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_settings_deinit();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenint main(int argc, char *argv[])
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen enum master_service_flags service_flags =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN |
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen pool_t set_pool;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bool allow_core_dumps = FALSE;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const char *login_socket = DEFAULT_LOGIN_SOCKET;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen int c;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service = master_service_init(login_binary.process_name,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen service_flags, &argc, &argv, "DS");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen master_service_init_log(master_service, t_strconcat(
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen login_binary.process_name, ": ", NULL));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
a406615fbcef37b1d12f0be95a70abf23238c5efTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
a406615fbcef37b1d12f0be95a70abf23238c5efTimo Sirainen switch (c) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case 'D':
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen allow_core_dumps = TRUE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case 'S':
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ssl_connections = TRUE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen default:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return FATAL_DEFAULT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (argv[optind] != NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen login_socket = argv[optind];
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen login_process_preinit();
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen set_pool = pool_alloconly_create("global login settings", 4096);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen global_login_settings =
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen login_settings_read(set_pool, NULL, NULL, NULL,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &global_other_settings);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* main_preinit() needs to know the client limit, which is set by
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen this. so call it first. */
a406615fbcef37b1d12f0be95a70abf23238c5efTimo Sirainen master_service_init_finish(master_service);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen main_preinit(allow_core_dumps);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen main_init(login_socket);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen master_service_run(master_service, client_connected);
03010dbaa74ec70f062994dfe3cd39bedc99a28bTimo Sirainen main_deinit();
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_unref(&set_pool);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen master_service_deinit(&master_service);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen