Mercurial > dovecot > original-hg > dovecot-1.2
view src/login/main.c @ 925:2e649dec0f09 HEAD
Auth and login processes send an "we're ok" reply at the end of
initialization. If the process dies before master receives that reply, it
shutdowns itself. Usually this is because of some configuration error and
it's not nice to start spamming the log files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 08 Jan 2003 23:13:05 +0200 |
parents | fd8888f6f037 |
children | f782b3319553 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "common.h" #include "ioloop.h" #include "lib-signals.h" #include "restrict-access.h" #include "process-title.h" #include "fd-close-on-exec.h" #include "auth-connection.h" #include "master.h" #include "client.h" #include "ssl-proxy.h" #include <stdlib.h> #include <unistd.h> #include <syslog.h> int disable_plaintext_auth, process_per_connection, verbose_proctitle; unsigned int max_logging_users; unsigned int login_process_uid; static struct ioloop *ioloop; static struct io *io_imap, *io_imaps; static int main_refcount; static int closing_down; void main_ref(void) { main_refcount++; } void main_unref(void) { if (--main_refcount == 0) { /* nothing to do, quit */ io_loop_stop(ioloop); } else if (closing_down && clients_get_count() == 0) { /* last login finished, close all communications to master process */ master_close(); } } void main_close_listen(void) { if (closing_down) return; if (io_imap != NULL) { if (close(LOGIN_IMAP_LISTEN_FD) < 0) i_fatal("can't close() IMAP listen handle"); io_remove(io_imap); io_imap = NULL; } if (io_imaps != NULL) { if (close(LOGIN_IMAPS_LISTEN_FD) < 0) i_fatal("can't close() IMAPS listen handle"); io_remove(io_imaps); io_imaps = NULL; } closing_down = TRUE; master_notify_finished(); } static void sig_quit(int signo __attr_unused__) { io_loop_stop(ioloop); } static void login_accept(void *context __attr_unused__, int listen_fd, struct io *io __attr_unused__) { struct ip_addr ip; int fd; fd = net_accept(listen_fd, &ip, NULL); if (fd < 0) { if (fd < -1) i_fatal("accept() failed: %m"); return; } if (process_per_connection) main_close_listen(); (void)client_create(fd, &ip, FALSE); } static void login_accept_ssl(void *context __attr_unused__, int listen_fd, struct io *io __attr_unused__) { struct client *client; struct ip_addr addr; int fd, fd_ssl; fd = net_accept(listen_fd, &addr, NULL); if (fd < 0) { if (fd < -1) i_fatal("accept() failed: %m"); return; } if (process_per_connection) main_close_listen(); fd_ssl = ssl_proxy_new(fd); if (fd_ssl == -1) net_disconnect(fd); else { client = client_create(fd_ssl, &addr, TRUE); client->tls = TRUE; } } static void open_logfile(void) { if (getenv("IMAP_USE_SYSLOG") != NULL) i_set_failure_syslog("imap-login", LOG_NDELAY, LOG_MAIL); else { /* log to file or stderr */ i_set_failure_file(getenv("IMAP_LOGFILE"), "imap-login"); } if (getenv("IMAP_INFOLOGFILE") != NULL) i_set_info_file(getenv("IMAP_INFOLOGFILE")); i_set_failure_timestamp_format(getenv("IMAP_LOGSTAMP")); } static void drop_privileges(void) { /* Log file or syslog opening probably requires roots */ open_logfile(); /* Initialize SSL proxy so it can read certificate and private key file. */ ssl_proxy_init(); /* Refuse to run as root - we should never need it and it's dangerous with SSL. */ restrict_access_by_env(TRUE); } static void main_init(void) { const char *value; lib_init_signals(sig_quit); disable_plaintext_auth = getenv("DISABLE_PLAINTEXT_AUTH") != NULL; process_per_connection = getenv("PROCESS_PER_CONNECTION") != NULL; verbose_proctitle = getenv("VERBOSE_PROCTITLE") != NULL; value = getenv("MAX_LOGGING_USERS"); max_logging_users = value == NULL ? 0 : strtoul(value, NULL, 10); value = getenv("PROCESS_UID"); if (value == NULL) i_fatal("BUG: PROCESS_UID environment not given"); login_process_uid = strtoul(value, NULL, 10); if (login_process_uid == 0) i_fatal("BUG: PROCESS_UID environment is 0"); closing_down = FALSE; main_refcount = 0; auth_connection_init(); clients_init(); io_imap = io_imaps = NULL; if (net_getsockname(LOGIN_IMAP_LISTEN_FD, NULL, NULL) == 0) { /* we're listening for imap */ io_imap = io_add(LOGIN_IMAP_LISTEN_FD, IO_READ, login_accept, NULL); } if (net_getsockname(LOGIN_IMAPS_LISTEN_FD, NULL, NULL) == 0) { /* we're listening for imaps */ if (!ssl_initialized) { /* this shouldn't happen, master should have disabled the imaps socket.. */ i_fatal("BUG: SSL initialization parameters not given " "while they should have been"); } io_imaps = io_add(LOGIN_IMAPS_LISTEN_FD, IO_READ, login_accept_ssl, NULL); } /* initialize master last - it sends the "we're ok" notification */ master_init(); } static void main_deinit(void) { if (lib_signal_kill != 0) i_warning("Killed with signal %d", lib_signal_kill); if (io_imap != NULL) io_remove(io_imap); if (io_imaps != NULL) io_remove(io_imaps); clients_deinit(); master_deinit(); auth_connection_deinit(); ssl_proxy_deinit(); closelog(); } int main(int argc __attr_unused__, char *argv[], char *envp[]) { #ifdef DEBUG fd_debug_verify_leaks(3, 1024); #endif /* NOTE: we start rooted, so keep the code minimal until restrict_access_by_env() is called */ lib_init(); drop_privileges(); process_title_init(argv, envp); ioloop = io_loop_create(system_pool); main_init(); io_loop_run(ioloop); main_deinit(); io_loop_destroy(ioloop); lib_deinit(); return 0; }