main.c revision 5da4bfdce070b54ce8dfcd1bf6249798cda86bd6
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
#include "login-common.h"
#include "ioloop.h"
#include "randgen.h"
#include "process-title.h"
#include "restrict-access.h"
#include "restrict-process-size.h"
#include "master-auth.h"
#include "master-service.h"
#include "master-interface.h"
#include "client-common.h"
#include "access-lookup.h"
#include "anvil-client.h"
#include "auth-client.h"
#include "ssl-proxy.h"
#include "login-proxy.h"
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#define DEFAULT_LOGIN_SOCKET "login"
struct login_access_lookup {
struct master_service_connection conn;
char **sockets, **next_socket;
struct access_lookup *access;
};
const struct login_binary *login_binary;
struct auth_client *auth_client;
struct master_auth *master_auth;
bool closing_down;
struct anvil_client *anvil;
const char *login_rawlog_dir = NULL;
unsigned int initial_service_count;
const struct login_settings *global_login_settings;
void **global_other_settings;
static struct timeout *auth_client_to;
static bool shutting_down = FALSE;
static bool ssl_connections = FALSE;
static bool auth_connected_once = FALSE;
void login_refresh_proctitle(void)
{
const char *addr;
return;
if (clients_get_count() == 0) {
process_title_set("");
clients_get_count(), ssl_proxy_get_count()));
} else {
}
}
{
}
void login_client_destroyed(void)
{
}
}
static void login_die(void)
{
if (!auth_client_is_connected(auth_client)) {
/* we don't have auth client, and we might never get one */
}
}
static void
{
const struct login_settings *set;
unsigned int local_port;
int fd_ssl;
void **other_sets;
local_port = 0;
}
} else {
&proxy);
if (fd_ssl == -1) {
pool_unref(&pool);
return;
}
}
if (auth_client_to != NULL)
}
{
i_error("close(client) failed: %m");
}
}
{
if (!success) {
i_info("access(%s): Client refused (rip=%s)",
} else {
lookup->next_socket++;
}
}
{
/* last one */
return;
}
}
{
char c;
int ret;
if (ret <= 0) {
i_info("access(%s): Client disconnected during lookup (rip=%s)",
} else {
/* actual input. stop listening until lookup is done. */
}
}
{
const char *access_sockets =
struct login_access_lookup *lookup;
/* log the connection's IP address in case we crash. it's of
course possible that another earlier client causes the
crash, but this is better than nothing. */
}
/* make sure we're connected (or attempting to connect) to auth */
if (*access_sockets == '\0') {
/* no access checks */
return;
}
}
{
if (connected) {
} else if (shutting_down)
else if (!auth_connected_once) {
/* auth disconnected without having ever succeeded, so the
auth process is probably misconfigured. no point in
keeping the client connections hanging. */
clients_destroy_all_reason("Disconnected: Auth process broken");
}
}
static bool anvil_reconnect_callback(void)
{
/* we got disconnected from anvil. we can't reconnect to it since we're
chrooted, so just die after we've finished handling the current
connections. */
return FALSE;
}
static void main_preinit(bool allow_core_dumps)
{
unsigned int max_fds;
random_init();
/* Initialize SSL proxy so it can read certificate and private
key file. */
/* set the number of fds we want to use. it may get increased or
decreased. leave a couple of extra fds for auth sockets and such.
worst case each connection can use:
- 1 for client
- 1 for login proxy
- 2 for client-side ssl proxy
- 2 for server-side ssl proxy (with login proxy)
*/
if (global_login_settings->mail_max_userip_connections > 0) {
i_fatal("Couldn't connect to anvil");
}
if (allow_core_dumps)
if (restrict_access_get_current_chroot() == NULL) {
if (chdir("login") < 0)
i_fatal("chdir(login) failed: %m");
}
if (login_rawlog_dir != NULL &&
i_error("access(%s, wx) failed: %m - disabling rawlog",
}
}
static void main_init(const char *login_socket)
{
/* make sure we can't fork() */
FALSE);
login_binary->init();
login_proxy_init("proxy-notify");
}
static void main_deinit(void)
{
login_binary->deinit();
if (auth_client_to != NULL)
}
{
bool allow_core_dumps = FALSE;
const char *login_socket = DEFAULT_LOGIN_SOCKET;
int c;
"DR:S");
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'D':
break;
case 'R':
break;
case 'S':
break;
default:
return FATAL_DEFAULT;
}
}
login_binary->preinit();
main_deinit();
return 0;
}