main.c revision 4e65040b019c061d242c8bc19bf76009679b8a15
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "auth-common.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "array.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "ioloop.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "network.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "lib-signals.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "restrict-access.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "child-wait.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sql-api.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "module-dir.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "randgen.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "master-service.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "master-interface.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "password-scheme.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "mech.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "auth.h"
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen#include "auth-request-handler.h"
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen#include "auth-worker-server.h"
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen#include "auth-worker-client.h"
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen#include "auth-master-connection.h"
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen#include "auth-client-connection.h"
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi#include <unistd.h>
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenenum auth_socket_type {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen AUTH_SOCKET_UNKNOWN = 0,
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen AUTH_SOCKET_CLIENT,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen AUTH_SOCKET_MASTER,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen AUTH_SOCKET_USERDB
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipek};
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainenbool worker = FALSE, shutdown_request = FALSE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainentime_t process_start_time;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct module *modules = NULL;
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenstatic struct auth *auth;
fc40a9a002458e372ff4b9f6f4e15239520c0bcdTimo Sirainenstatic struct auth_worker_client *worker_client;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic ARRAY_DEFINE(listen_fd_types, enum auth_socket_type);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void main_preinit(struct auth_settings *set)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Open /dev/urandom before chrooting */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen random_init();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Load built-in SQL drivers (if any) */
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen sql_drivers_init();
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen sql_drivers_register_all();
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen /* Initialize databases so their configuration files can be readable
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi only by root. Also load all modules here. */
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi passdbs_init();
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen userdbs_init();
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen modules = module_dir_load(AUTH_MODULE_DIR, NULL, TRUE,
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen master_service_get_version_string(master_service));
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen module_dir_init(modules);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen auth = auth_preinit(set);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Password lookups etc. may require roots, allow it. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen restrict_access_by_env(NULL, FALSE);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen restrict_access_allow_coredumps(TRUE);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen}
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipekstatic void main_init(void)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek{
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen i_array_init(&listen_fd_types, 8);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen process_start_time = ioloop_time;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen /* If auth caches aren't used, just ignore these signals */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen lib_signals_ignore(SIGHUP, TRUE);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen lib_signals_ignore(SIGUSR2, TRUE);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen child_wait_init();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen mech_init(auth->set);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen password_schemes_init();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_worker_server_init();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_init(auth);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_request_handler_init();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_master_connections_init();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_client_connections_init();
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (worker) {
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen /* workers have only a single connection from the master
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen auth process */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen master_service_set_client_limit(master_service, 1);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen }
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen}
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenstatic void main_deinit(void)
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen{
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (worker_client != NULL)
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen auth_worker_client_destroy(&worker_client);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen else
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen auth_request_handler_flush_failures(TRUE);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen auth_client_connections_deinit();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen auth_master_connections_deinit();
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen auth_worker_server_deinit();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen module_dir_unload(&modules);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen userdbs_deinit();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen passdbs_deinit();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mech_deinit(auth->set);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen auth_deinit(&auth);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen password_schemes_deinit();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sql_drivers_deinit();
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen random_deinit();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_free(&listen_fd_types);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void worker_connected(const struct master_service_connection *conn)
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (worker_client != NULL) {
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen i_error("Auth workers can handle only a single client");
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen (void)close(conn->fd);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return;
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen worker_client = auth_worker_client_create(auth, conn->fd);
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen}
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void client_connected(const struct master_service_connection *conn)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen enum auth_socket_type *type;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *name, *suffix;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen type = array_idx_modifiable(&listen_fd_types, conn->listen_fd);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*type == AUTH_SOCKET_UNKNOWN) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* figure out if this is a server or network socket by
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen checking the socket path name. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (net_getunixname(conn->listen_fd, &name) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("getsockname(%d) failed: %m", conn->listen_fd);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen suffix = strrchr(name, '-');
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (suffix == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *type = AUTH_SOCKET_CLIENT;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen suffix++;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (strcmp(suffix, "master") == 0)
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen *type = AUTH_SOCKET_MASTER;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen else if (strcmp(suffix, "userdb") == 0)
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen *type = AUTH_SOCKET_USERDB;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *type = AUTH_SOCKET_CLIENT;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen switch (*type) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen case AUTH_SOCKET_MASTER:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (void)auth_master_connection_create(auth, conn->fd, FALSE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen case AUTH_SOCKET_USERDB:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (void)auth_master_connection_create(auth, conn->fd, TRUE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen case AUTH_SOCKET_CLIENT:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (void)auth_client_connection_create(auth, conn->fd);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen default:
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen i_unreached();
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen }
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint main(int argc, char *argv[])
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen int c;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen master_service = master_service_init("auth", 0, &argc, &argv, "w");
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen master_service_init_log(master_service, "auth: ");
6de6ec228a41275ddda972d4a554699ea75cd06dTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'w':
worker = TRUE;
break;
default:
return FATAL_DEFAULT;
}
}
main_preinit(auth_settings_read(master_service));
master_service_init_finish(master_service);
main_init();
master_service_run(master_service, worker ? worker_connected :
client_connected);
main_deinit();
master_service_deinit(&master_service);
return 0;
}