main.c revision 304eae229e1e3cc02044f94a8f3a057c6345030e
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#define AUTH_PENALTY_ANVIL_PATH "anvil-auth-penalty"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic ARRAY_DEFINE(listen_fd_types, enum auth_socket_type);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen "[%u wait, %u passdb, %u userdb]",
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_NEW] +
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] +
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_FINISHED],
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_PASSDB],
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_state_count[AUTH_REQUEST_STATE_USERDB]));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic const char *const *read_global_settings(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct master_service_settings_output set_output;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int i, count;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_set_pool = pool_alloconly_create("auth settings", 8192);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_settings_read(NULL, auth_set_pool, &set_output);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* strdup() the service names, because they're allocated from
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen set parser pool, and we'll later clear it. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen count = str_array_length(set_output.specific_services);
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen services = p_new(auth_set_pool, const char *, count + 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (i = 0; i < count; i++) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void main_preinit(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *const *services;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* Open /dev/urandom before chrooting */
740dfc753f1f087f0c41082e4c551053129e875dTimo Sirainen /* Load built-in SQL drivers (if any) */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* Initialize databases so their configuration files can be readable
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen only by root. Also load all modules here. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen mod_set.version = master_service_get_version_string(master_service);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen modules = module_dir_load(AUTH_MODULE_DIR, NULL, &mod_set);
7e459d4ba3add84f31a72992efc33bd53f2c655dTimo Sirainen auth_penalty = auth_penalty_init(AUTH_PENALTY_ANVIL_PATH);
7e459d4ba3add84f31a72992efc33bd53f2c655dTimo Sirainen mech_reg = mech_register_init(global_auth_settings);
7e459d4ba3add84f31a72992efc33bd53f2c655dTimo Sirainen auths_preinit(global_auth_settings, auth_set_pool,
7e459d4ba3add84f31a72992efc33bd53f2c655dTimo Sirainen /* Password lookups etc. may require roots, allow it. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void main_init(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* If auth caches aren't used, just ignore these signals */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* workers have only a single connection from the master
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth process */
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen master_service_set_client_limit(master_service, 1);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen /* caching is handled only by the main auth process */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void main_deinit(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_worker_client_destroy(&auth_worker_client);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* there may still be some async auth requests left, but above
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen functions should have marked all of them as destroyed. pass/userdb
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen deinits should abort the pending requests, which still triggers
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen callbacks, which should avoid crashes by checking the destroyed
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen /* allow modules to unregister their dbs/drivers/etc. before freeing
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen the whole data structures containing them. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void worker_connected(struct master_service_connection *conn)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_error("Auth workers can handle only a single client");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen master_service_client_connection_accept(conn);
5160580b0ec3f3288a320987abdf12a990f09df5Timo Sirainen (void)auth_worker_client_create(auth_find_service(NULL), conn->fd);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void client_connected(struct master_service_connection *conn)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen type = array_idx_modifiable(&listen_fd_types, conn->listen_fd);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen /* figure out if this is a server or network socket by
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen checking the socket path name. */
5160580b0ec3f3288a320987abdf12a990f09df5Timo Sirainen if (net_getunixname(conn->listen_fd, &path) < 0)
5160580b0ec3f3288a320987abdf12a990f09df5Timo Sirainen i_fatal("getsockname(%d) failed: %m", conn->listen_fd);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (void)auth_master_connection_create(auth, conn->fd, FALSE);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen (void)auth_master_connection_create(auth, conn->fd, TRUE);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (void)auth_client_connection_create(auth, conn->fd, TRUE);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (void)auth_client_connection_create(auth, conn->fd, FALSE);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen master_service_client_connection_accept(conn);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void auth_die(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* do nothing. auth clients should disconnect soon. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen master_service = master_service_init("auth", 0, &argc, &argv, "w");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen master_service_init_log(master_service, "auth: ");
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen while ((c = master_getopt(master_service)) > 0) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen master_service_set_die_callback(master_service, auth_die);