Mercurial > dovecot > core-2.2
view src/auth/main.c @ 9844:4efd13c0f778 HEAD
auth: Use net_getunixname() instead of implementing it ourself.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 31 Aug 2009 17:04:37 -0400 |
parents | c9a111a50579 |
children | cf27080f3fcf |
line wrap: on
line source
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */ #include "auth-common.h" #include "array.h" #include "ioloop.h" #include "network.h" #include "lib-signals.h" #include "restrict-access.h" #include "child-wait.h" #include "sql-api.h" #include "module-dir.h" #include "randgen.h" #include "master-service.h" #include "password-scheme.h" #include "mech.h" #include "auth.h" #include "auth-request-handler.h" #include "auth-worker-server.h" #include "auth-worker-client.h" #include "auth-master-interface.h" #include "auth-master-connection.h" #include "auth-client-connection.h" #include <stdlib.h> #include <unistd.h> #include <sys/un.h> enum auth_socket_type { AUTH_SOCKET_UNKNOWN = 0, AUTH_SOCKET_CLIENT, AUTH_SOCKET_MASTER, AUTH_SOCKET_USERDB }; bool worker = FALSE, shutdown_request = FALSE; time_t process_start_time; static struct module *modules = NULL; static struct auth *auth; static struct auth_worker_client *worker_client; static ARRAY_DEFINE(listen_fd_types, enum auth_socket_type); static void main_preinit(struct auth_settings *set) { /* Open /dev/urandom before chrooting */ random_init(); /* Load built-in SQL drivers (if any) */ sql_drivers_init(); sql_drivers_register_all(); /* Initialize databases so their configuration files can be readable only by root. Also load all modules here. */ passdbs_init(); userdbs_init(); modules = module_dir_load(AUTH_MODULE_DIR, NULL, TRUE, master_service_get_version_string(master_service)); module_dir_init(modules); auth = auth_preinit(set); /* Password lookups etc. may require roots, allow it. */ restrict_access_by_env(NULL, FALSE); restrict_access_allow_coredumps(TRUE); } static void main_init(void) { i_array_init(&listen_fd_types, 8); process_start_time = ioloop_time; /* If auth caches aren't used, just ignore these signals */ lib_signals_ignore(SIGHUP, TRUE); lib_signals_ignore(SIGUSR2, TRUE); child_wait_init(); mech_init(auth->set); password_schemes_init(); auth_worker_server_init(); auth_init(auth); auth_request_handler_init(); auth_master_connections_init(); auth_client_connections_init(); if (worker) { /* workers have only a single connection from the master auth process */ master_service_set_client_limit(master_service, 1); } else if (getenv("MASTER_AUTH_FD") != NULL) { (void)auth_master_connection_create(auth, MASTER_AUTH_FD, FALSE); } } static void main_deinit(void) { if (worker_client != NULL) auth_worker_client_unref(&worker_client); else auth_request_handler_flush_failures(TRUE); auth_client_connections_deinit(); auth_master_connections_deinit(); auth_worker_server_deinit(); module_dir_unload(&modules); userdbs_deinit(); passdbs_deinit(); mech_deinit(auth->set); auth_deinit(&auth); password_schemes_deinit(); sql_drivers_deinit(); random_deinit(); array_free(&listen_fd_types); } static void worker_connected(const struct master_service_connection *conn) { auth_worker_client_create(auth, conn->fd); } static void client_connected(const struct master_service_connection *conn) { enum auth_socket_type *type; const char *name, *suffix; type = array_idx_modifiable(&listen_fd_types, conn->listen_fd); if (*type == AUTH_SOCKET_UNKNOWN) { /* figure out if this is a server or network socket by checking the socket path name. */ if (net_getunixname(conn->listen_fd, &name) < 0) i_fatal("getsockname(%d) failed: %m", conn->listen_fd); suffix = strrchr(name, '-'); if (suffix == NULL) *type = AUTH_SOCKET_CLIENT; else { suffix++; if (strcmp(suffix, "master") == 0) *type = AUTH_SOCKET_MASTER; else if (strcmp(suffix, "userdb") == 0) *type = AUTH_SOCKET_USERDB; else *type = AUTH_SOCKET_CLIENT; } } switch (*type) { case AUTH_SOCKET_MASTER: (void)auth_master_connection_create(auth, conn->fd, FALSE); break; case AUTH_SOCKET_USERDB: (void)auth_master_connection_create(auth, conn->fd, TRUE); break; case AUTH_SOCKET_CLIENT: (void)auth_client_connection_create(auth, conn->fd); break; default: i_unreached(); } } int main(int argc, char *argv[]) { const char *getopt_str, *auth_name = "default"; int c; master_service = master_service_init("auth", 0, argc, argv); master_service_init_log(master_service, "auth: ", 0); getopt_str = t_strconcat("w", master_service_getopt_string(), NULL); while ((c = getopt(argc, argv, getopt_str)) > 0) { switch (c) { case 'a': auth_name = optarg; break; case 'w': worker = TRUE; break; default: if (!master_service_parse_option(master_service, c, optarg)) exit(FATAL_DEFAULT); break; } } main_preinit(auth_settings_read(master_service, auth_name)); 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; }