main.c revision 726e5e80865853b31ce51f9977f1fb339a43f301
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth-common.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "array.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "ioloop.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "network.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "lib-signals.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "restrict-access.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "child-wait.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "sql-api.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "module-dir.h"
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen#include "hostpid.h"
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen#include "randgen.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "process-title.h"
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#include "settings-parser.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "master-service.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "master-service-settings.h"
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen#include "master-interface.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "password-scheme.h"
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#include "passdb-cache.h"
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen#include "mech.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth-penalty.h"
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen#include "auth-request-handler.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth-worker-server.h"
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#include "auth-worker-client.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth-master-connection.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "auth-client-connection.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen#include <unistd.h>
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#include <sys/stat.h>
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen#define AUTH_PENALTY_ANVIL_PATH "anvil-auth-penalty"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenenum auth_socket_type {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen AUTH_SOCKET_UNKNOWN = 0,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen AUTH_SOCKET_CLIENT,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen AUTH_SOCKET_LOGIN_CLIENT,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen AUTH_SOCKET_MASTER,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen AUTH_SOCKET_USERDB
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen};
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstruct auth_socket_listener {
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen enum auth_socket_type type;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen struct stat st;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen char *path;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen};
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenbool worker = FALSE, shutdown_request = FALSE;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainentime_t process_start_time;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstruct auth_penalty *auth_penalty;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic pool_t auth_set_pool;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic struct module *modules = NULL;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic struct mechanisms_register *mech_reg;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic ARRAY_DEFINE(listeners, struct auth_socket_listener);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenvoid auth_refresh_proctitle(void)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (!global_auth_settings->verbose_proctitle)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen return;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen process_title_set(t_strdup_printf(
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen "[%u wait, %u passdb, %u userdb]",
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_NEW] +
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] +
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_FINISHED],
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_PASSDB],
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_USERDB]));
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen}
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstatic const char *const *read_global_settings(void)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen struct master_service_settings_output set_output;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char **services;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen unsigned int i, count;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen auth_set_pool = pool_alloconly_create("auth settings", 8192);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen global_auth_settings =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen auth_settings_read(NULL, auth_set_pool, &set_output);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* strdup() the service names, because they're allocated from
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen set parser pool, and we'll later clear it. */
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen count = str_array_length(set_output.specific_services);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen services = p_new(auth_set_pool, const char *, count + 1);
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen for (i = 0; i < count; i++) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen services[i] = p_strdup(auth_set_pool,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen set_output.specific_services[i]);
53cd46dd843c22f21f7e6efcc52a3e0f76cd1e52Timo Sirainen }
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen return services;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen}
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic enum auth_socket_type
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenauth_socket_type_get(int listen_fd, const char **path_r)
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen{
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen const char *path, *name, *suffix;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* figure out if this is a server or network socket by
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen checking the socket path name. */
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen if (net_getunixname(listen_fd, &path) < 0) {
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen if (errno != ENOTSOCK)
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen i_fatal("getunixname(%d) failed: %m", listen_fd);
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen /* not UNIX socket. let's just assume it's an
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen auth client. */
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen *path_r = NULL;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen return AUTH_SOCKET_CLIENT;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen }
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen *path_r = path;
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen name = strrchr(path, '/');
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (name == NULL)
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen name = path;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen else
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen name++;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen suffix = strrchr(name, '-');
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (suffix == NULL)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen suffix = name;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen else
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen suffix++;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen if (strcmp(suffix, "login") == 0)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return AUTH_SOCKET_LOGIN_CLIENT;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen else if (strcmp(suffix, "master") == 0)
53cd46dd843c22f21f7e6efcc52a3e0f76cd1e52Timo Sirainen return AUTH_SOCKET_MASTER;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen else if (strcmp(suffix, "userdb") == 0)
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen return AUTH_SOCKET_USERDB;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen else
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen return AUTH_SOCKET_CLIENT;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen}
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainenstatic void listeners_init(void)
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen{
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen unsigned int i, n;
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen const char *path;
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_array_init(&listeners, 8);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen n = master_service_get_socket_count(master_service);
b92e979748a22925b0770d3004eaab043ed69574Timo Sirainen for (i = 0; i < n; i++) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen int fd = MASTER_LISTEN_FD_FIRST + i;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct auth_socket_listener *l;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen l = array_idx_modifiable(&listeners, fd);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen l->type = auth_socket_type_get(fd, &path);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen l->path = i_strdup(path);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (l->type == AUTH_SOCKET_USERDB) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (stat(path, &l->st) < 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen i_error("stat(%s) failed: %m", path);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen}
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainenstatic bool auth_module_filter(const char *name, void *context ATTR_UNUSED)
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen{
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen if (strncmp(name, "authdb_", 7) == 0 ||
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen strncmp(name, "mech_", 5) == 0) {
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen /* this is lazily loaded */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return FALSE;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
53cd46dd843c22f21f7e6efcc52a3e0f76cd1e52Timo Sirainen return TRUE;
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen}
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen
0dbcf4026ff8471b4d6d2e14f7e52321396bf087Timo Sirainenstatic void main_preinit(void)
0dbcf4026ff8471b4d6d2e14f7e52321396bf087Timo Sirainen{
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen struct module_dir_load_settings mod_set;
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen const char *const *services;
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen /* Open /dev/urandom before chrooting */
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen random_init();
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen /* Load built-in SQL drivers (if any) */
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen sql_drivers_init();
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen sql_drivers_register_all();
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen /* Initialize databases so their configuration files can be readable
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen only by root. Also load all modules here. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen passdbs_init();
b92e979748a22925b0770d3004eaab043ed69574Timo Sirainen userdbs_init();
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainen /* init schemes before plugins are loaded */
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainen password_schemes_init();
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainen
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainen services = read_global_settings();
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen memset(&mod_set, 0, sizeof(mod_set));
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mod_set.version = master_service_get_version_string(master_service);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen mod_set.require_init_funcs = TRUE;
989cafb9d84d8c98d6441fc1ab45b4c37762a98aTimo Sirainen mod_set.debug = global_auth_settings->debug;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mod_set.filter_callback = auth_module_filter;
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen modules = module_dir_load(AUTH_MODULE_DIR, NULL, &mod_set);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen module_dir_init(modules);
53cd46dd843c22f21f7e6efcc52a3e0f76cd1e52Timo Sirainen
989cafb9d84d8c98d6441fc1ab45b4c37762a98aTimo Sirainen if (!worker)
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen auth_penalty = auth_penalty_init(AUTH_PENALTY_ANVIL_PATH);
989cafb9d84d8c98d6441fc1ab45b4c37762a98aTimo Sirainen mech_init(global_auth_settings);
989cafb9d84d8c98d6441fc1ab45b4c37762a98aTimo Sirainen mech_reg = mech_register_init(global_auth_settings);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen auths_preinit(global_auth_settings, auth_set_pool,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mech_reg, services);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen listeners_init();
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen /* Password lookups etc. may require roots, allow it. */
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen restrict_access_by_env(NULL, FALSE);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen restrict_access_allow_coredumps(TRUE);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen}
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainenvoid auth_module_load(const char *names)
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen{
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen struct module_dir_load_settings mod_set;
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen memset(&mod_set, 0, sizeof(mod_set));
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen mod_set.version = master_service_get_version_string(master_service);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen mod_set.require_init_funcs = TRUE;
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen mod_set.debug = global_auth_settings->debug;
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen mod_set.ignore_missing = TRUE;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen modules = module_dir_load_missing(modules, AUTH_MODULE_DIR, names,
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen &mod_set);
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen module_dir_init(modules);
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen}
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainenstatic void main_init(void)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen{
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen process_start_time = ioloop_time;
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen
8f32e59200da904613506f5649ffa4d9f5989cebTimo Sirainen /* If auth caches aren't used, just ignore these signals */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen lib_signals_ignore(SIGHUP, TRUE);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen lib_signals_ignore(SIGUSR2, TRUE);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen child_wait_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_worker_server_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auths_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_request_handler_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_master_connections_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_client_connections_init();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen if (worker) {
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* workers have only a single connection from the master
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth process */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen master_service_set_client_limit(master_service, 1);
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen } else {
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* caching is handled only by the main auth process */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen passdb_cache_init(global_auth_settings);
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen }
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_refresh_proctitle();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen}
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainenstatic void main_deinit(void)
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen{
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen struct auth_socket_listener *l;
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen if (auth_penalty != NULL) {
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* cancel all pending anvil penalty lookups */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_penalty_deinit(&auth_penalty);
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen }
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* deinit auth workers, which aborts pending requests */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_worker_server_deinit();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* deinit passdbs and userdbs. it aborts any pending async requests. */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auths_deinit();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* flush pending requests */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auth_request_handler_deinit();
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen /* there are no more auth requests */
8ab3d88c56dff2f567193f80cc29821a64e576d1Timo Sirainen auths_free();
auth_client_connections_deinit();
auth_master_connections_deinit();
if (auth_worker_client != NULL)
auth_worker_client_destroy(&auth_worker_client);
mech_register_deinit(&mech_reg);
mech_deinit(global_auth_settings);
/* allow modules to unregister their dbs/drivers/etc. before freeing
the whole data structures containing them. */
module_dir_unload(&modules);
userdbs_deinit();
passdbs_deinit();
passdb_cache_deinit();
password_schemes_deinit();
sql_drivers_deinit();
random_deinit();
child_wait_deinit();
array_foreach_modifiable(&listeners, l)
i_free(l->path);
array_free(&listeners);
pool_unref(&auth_set_pool);
}
static void worker_connected(struct master_service_connection *conn)
{
if (auth_worker_client != NULL) {
i_error("Auth workers can handle only a single client");
return;
}
master_service_client_connection_accept(conn);
(void)auth_worker_client_create(auth_find_service(NULL), conn->fd);
}
static void client_connected(struct master_service_connection *conn)
{
struct auth_socket_listener *l;
struct auth *auth;
l = array_idx_modifiable(&listeners, conn->listen_fd);
auth = auth_find_service(NULL);
switch (l->type) {
case AUTH_SOCKET_MASTER:
(void)auth_master_connection_create(auth, conn->fd,
l->path, NULL, FALSE);
break;
case AUTH_SOCKET_USERDB:
(void)auth_master_connection_create(auth, conn->fd,
l->path, &l->st, TRUE);
break;
case AUTH_SOCKET_LOGIN_CLIENT:
(void)auth_client_connection_create(auth, conn->fd, TRUE);
break;
case AUTH_SOCKET_CLIENT:
(void)auth_client_connection_create(auth, conn->fd, FALSE);
break;
default:
i_unreached();
}
master_service_client_connection_accept(conn);
}
static void auth_die(void)
{
/* do nothing. auth clients should disconnect soon. */
}
int main(int argc, char *argv[])
{
int c;
master_service = master_service_init("auth", 0, &argc, &argv, "w");
master_service_init_log(master_service, "auth: ");
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'w':
master_service_init_log(master_service,
t_strdup_printf("auth-worker(%s): ", my_pid));
worker = TRUE;
break;
default:
return FATAL_DEFAULT;
}
}
main_preinit();
master_service_init_finish(master_service);
master_service_set_die_callback(master_service, auth_die);
main_init();
master_service_run(master_service, worker ? worker_connected :
client_connected);
main_deinit();
master_service_deinit(&master_service);
return 0;
}