main.c revision 717bb0dbaf4bd3f745669570647845e6d493bfe0
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "login-common.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "ioloop.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen#include "randgen.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "process-title.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "restrict-access.h"
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen#include "restrict-process-size.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "master-auth.h"
146f9076cd456ea1e9b3f8536456d9d3c962fadbStephan Bosch#include "master-service.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "master-interface.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "client-common.h"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#include "access-lookup.h"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#include "anvil-client.h"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#include "auth-client.h"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen#include "ssl-proxy.h"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen#include "login-proxy.h"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen#include <stdlib.h>
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen#include <unistd.h>
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen#include <syslog.h>
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define DEFAULT_LOGIN_SOCKET "login"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct login_access_lookup {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct master_service_connection conn;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct io *io;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen char **sockets, **next_socket;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct access_lookup *access;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenconst struct login_binary *login_binary;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct auth_client *auth_client;
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainenstruct master_auth *master_auth;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool closing_down;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstruct anvil_client *anvil;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenconst char *login_rawlog_dir = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenunsigned int initial_service_count;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenconst struct login_settings *global_login_settings;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid **global_other_settings;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct timeout *auth_client_to;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic bool shutting_down = FALSE;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic bool ssl_connections = FALSE;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenstatic bool auth_connected_once = FALSE;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid login_refresh_proctitle(void)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct client *client = clients;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *addr;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (!global_login_settings->verbose_proctitle)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen return;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (clients_get_count() == 0) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen process_title_set("");
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen } else if (clients_get_count() > 1 || client == NULL) {
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen process_title_set(t_strdup_printf("[%u connections (%u TLS)]",
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen clients_get_count(), ssl_proxy_get_count()));
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen } else if ((addr = net_ip2addr(&client->ip)) != NULL) {
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen process_title_set(t_strdup_printf(client->tls ?
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen "[%s TLS]" : "[%s]", addr));
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen } else {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen process_title_set(client->tls ? "[TLS]" : "");
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen }
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen}
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainenstatic void auth_client_idle_timeout(struct auth_client *auth_client)
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen{
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen i_assert(clients == NULL);
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen auth_client_disconnect(auth_client, "idle disconnect");
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen timeout_remove(&auth_client_to);
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen}
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainenvoid login_client_destroyed(void)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen{
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (clients == NULL && auth_client_to == NULL) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen auth_client_idle_timeout,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen auth_client);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen}
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenstatic void login_die(void)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen{
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen shutting_down = TRUE;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen login_proxy_kill_idle();
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen if (!auth_client_is_connected(auth_client)) {
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen /* we don't have auth client, and we might never get one */
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen clients_destroy_all();
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen }
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainenstatic void
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenclient_connected_finish(const struct master_service_connection *conn)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct client *client;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct ssl_proxy *proxy;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct ip_addr local_ip;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const struct login_settings *set;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen unsigned int local_port;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen pool_t pool;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen int fd_ssl;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen void **other_sets;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen if (net_getsockname(conn->fd, &local_ip, &local_port) < 0) {
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen memset(&local_ip, 0, sizeof(local_ip));
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen local_port = 0;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen }
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool = pool_alloconly_create("login client", 8*1024);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen set = login_settings_read(pool, &local_ip,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen &conn->remote_ip, NULL, &other_sets);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen if (!ssl_connections && !conn->ssl) {
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen client = client_create(conn->fd, FALSE, pool, set, other_sets,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen &local_ip, &conn->remote_ip);
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen } else {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, set,
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen &proxy);
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen if (fd_ssl == -1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen net_disconnect(conn->fd);
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen pool_unref(&pool);
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen master_service_client_connection_destroyed(master_service);
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen return;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen client = client_create(fd_ssl, TRUE, pool, set, other_sets,
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen &local_ip, &conn->remote_ip);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen client->ssl_proxy = proxy;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ssl_proxy_set_client(proxy, client);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ssl_proxy_start(proxy);
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen }
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen client->remote_port = conn->remote_port;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->local_port = local_port;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen if (auth_client_to != NULL)
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen timeout_remove(&auth_client_to);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen}
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainenstatic void login_access_lookup_free(struct login_access_lookup *lookup)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (lookup->io != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen io_remove(&lookup->io);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen if (lookup->access != NULL)
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen access_lookup_destroy(&lookup->access);
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen if (lookup->conn.fd != -1) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (close(lookup->conn.fd) < 0)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_error("close(client) failed: %m");
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen master_service_client_connection_destroyed(master_service);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen p_strsplit_free(default_pool, lookup->sockets);
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen i_free(lookup);
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen}
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainenstatic void login_access_callback(bool success, void *context)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen{
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen struct login_access_lookup *lookup = context;
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (!success) {
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen i_info("access(%s): Client refused (rip=%s)",
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen *lookup->next_socket,
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen net_ip2addr(&lookup->conn.remote_ip));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen login_access_lookup_free(lookup);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen } else {
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen lookup->next_socket++;
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen login_access_lookup_next(lookup);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen }
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen}
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup)
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen{
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen if (*lookup->next_socket == NULL) {
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen /* last one */
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen if (lookup->io != NULL)
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen io_remove(&lookup->io);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen client_connected_finish(&lookup->conn);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen lookup->conn.fd = -1;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen login_access_lookup_free(lookup);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen return;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen login_binary->protocol,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen login_access_callback, lookup);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen if (lookup->access == NULL)
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen login_access_lookup_free(lookup);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen}
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenstatic void client_input_error(struct login_access_lookup *lookup)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen{
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen char c;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen int ret;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (ret <= 0) {
4b41116563110d00330896a568eff1078c382827Timo Sirainen i_info("access(%s): Client disconnected during lookup (rip=%s)",
4b41116563110d00330896a568eff1078c382827Timo Sirainen *lookup->next_socket,
4b41116563110d00330896a568eff1078c382827Timo Sirainen net_ip2addr(&lookup->conn.remote_ip));
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen login_access_lookup_free(lookup);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen } else {
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen /* actual input. stop listening until lookup is done. */
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen io_remove(&lookup->io);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic void client_connected(struct master_service_connection *conn)
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen{
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen const char *access_sockets =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen global_login_settings->login_access_sockets;
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainen struct login_access_lookup *lookup;
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen master_service_client_connection_accept(conn);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (conn->remote_ip.family != 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* log the connection's IP address in case we crash. it's of
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen course possible that another earlier client causes the
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen crash, but this is better than nothing. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_set_failure_send_ip(&conn->remote_ip);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen /* make sure we're connected (or attempting to connect) to auth */
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen auth_client_connect(auth_client);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen if (*access_sockets == '\0') {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* no access checks */
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen client_connected_finish(conn);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen return;
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen }
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen lookup = i_new(struct login_access_lookup, 1);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen lookup->conn = *conn;
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen lookup->next_socket = lookup->sockets;
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen login_access_lookup_next(lookup);
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainenstatic void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen bool connected, void *context ATTR_UNUSED)
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen{
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen if (connected) {
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen auth_connected_once = TRUE;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen clients_notify_auth_connected();
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen } else if (shutting_down)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen clients_destroy_all();
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (!auth_connected_once) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* auth disconnected without having ever succeeded, so the
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen auth process is probably misconfigured. no point in
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen keeping the client connections hanging. */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen clients_destroy_all_reason("Disconnected: Auth process broken");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainenstatic bool anvil_reconnect_callback(void)
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen{
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen master_service_stop_new_connections(master_service);
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen return FALSE;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic void main_preinit(bool allow_core_dumps)
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen{
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen unsigned int max_fds;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen random_init();
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* Initialize SSL proxy so it can read certificate and private
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen key file. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ssl_proxy_init();
d938e9e4ec4c0f326dffd5ebe42c1ad893ce7e52Timo Sirainen
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen /* set the number of fds we want to use. it may get increased or
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen decreased. leave a couple of extra fds for auth sockets and such.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen worst case each connection can use:
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen - 1 for client
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen - 1 for login proxy
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen - 2 for client-side ssl proxy
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen - 2 for server-side ssl proxy (with login proxy)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen */
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen max_fds = MASTER_LISTEN_FD_FIRST + 16 +
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen master_service_get_socket_count(master_service) +
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen master_service_get_client_limit(master_service)*6;
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen restrict_fd_limit(max_fds);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen io_loop_set_max_fd_count(current_ioloop, max_fds);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen i_assert(strcmp(global_login_settings->ssl, "no") == 0 ||
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen ssl_initialized);
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen if (global_login_settings->mail_max_userip_connections > 0) {
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen if (anvil_client_connect(anvil, TRUE) < 0)
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen i_fatal("Couldn't connect to anvil");
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen }
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen restrict_access_by_env(NULL, TRUE);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen if (allow_core_dumps)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen restrict_access_allow_coredumps(TRUE);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen initial_service_count = master_service_get_service_count(master_service);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (restrict_access_get_current_chroot() == NULL) {
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen if (chdir("login") < 0)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_fatal("chdir(login) failed: %m");
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen }
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen if (login_rawlog_dir != NULL &&
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen access(login_rawlog_dir, W_OK | X_OK) < 0) {
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen i_error("access(%s, wx) failed: %m - disabling rawlog",
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen login_rawlog_dir);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen login_rawlog_dir = NULL;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen }
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen}
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainenstatic void main_init(const char *login_socket)
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen{
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen /* make sure we can't fork() */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen restrict_process_count(1);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen master_service_set_avail_overflow_callback(master_service,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen client_destroy_oldest);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen master_service_set_die_callback(master_service, login_die);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen auth_client = auth_client_init(login_socket, (unsigned int)getpid(),
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen FALSE);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen master_auth = master_auth_init(master_service, login_binary->protocol);
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen
7baab0b0b60df7ce9093d0881cd322dff1e79491Timo Sirainen login_binary->init();
7baab0b0b60df7ce9093d0881cd322dff1e79491Timo Sirainen login_proxy_init("proxy-notify");
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen}
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainenstatic void main_deinit(void)
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen{
33b469d1ca66dd2cc496d2d990b8b98e72952a29Timo Sirainen ssl_proxy_deinit();
33b469d1ca66dd2cc496d2d990b8b98e72952a29Timo Sirainen login_proxy_deinit();
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen login_binary->deinit();
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen auth_client_deinit(&auth_client);
6b0d8106ae51ffc6ce45636b34d2e21cbefca7fdTimo Sirainen master_auth_deinit(&master_auth);
6b0d8106ae51ffc6ce45636b34d2e21cbefca7fdTimo Sirainen
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen if (anvil != NULL)
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen anvil_client_deinit(&anvil);
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen if (auth_client_to != NULL)
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen timeout_remove(&auth_client_to);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen login_settings_deinit();
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen}
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainenint login_binary_run(const struct login_binary *binary,
b3484b5b1f47e4cf112f0e371478a2d7794b31bbTimo Sirainen int argc, char *argv[])
b3484b5b1f47e4cf112f0e371478a2d7794b31bbTimo Sirainen{
d81131d3bbb4f0befb62a661d1785cf8c84a17e2Timo Sirainen enum master_service_flags service_flags =
d81131d3bbb4f0befb62a661d1785cf8c84a17e2Timo Sirainen MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN |
9456a4a3e74929f9d3d5b00b93be6d8eb69bc52aTimo Sirainen MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE;
9456a4a3e74929f9d3d5b00b93be6d8eb69bc52aTimo Sirainen pool_t set_pool;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen bool allow_core_dumps = FALSE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const char *login_socket = DEFAULT_LOGIN_SOCKET;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int c;
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen login_binary = binary;
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen master_service = master_service_init(login_binary->process_name,
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen service_flags, &argc, &argv,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen "DR:S");
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen master_service_init_log(master_service, t_strconcat(
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen login_binary->process_name, ": ", NULL));
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen while ((c = master_getopt(master_service)) > 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen switch (c) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen case 'D':
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen allow_core_dumps = TRUE;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen break;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen case 'R':
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen login_rawlog_dir = optarg;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen break;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen case 'S':
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ssl_connections = TRUE;
c0225f7f6b43d34dc58c17d3304f0fd60ab89894Timo Sirainen break;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen default:
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return FATAL_DEFAULT;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (argv[optind] != NULL)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen login_socket = argv[optind];
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen login_binary->preinit();
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen set_pool = pool_alloconly_create("global login settings", 4096);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen global_login_settings =
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen login_settings_read(set_pool, NULL, NULL, NULL,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen &global_other_settings);
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen main_preinit(allow_core_dumps);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen master_service_init_finish(master_service);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen main_init(login_socket);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen master_service_run(master_service, client_connected);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen main_deinit();
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen pool_unref(&set_pool);
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen master_service_deinit(&master_service);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen}
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen