main.c revision 2f340bd8f8c4dfadad9c7577a0de8c0c5a7cb213
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (C) 2002 Timo Sirainen */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "common.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "buffer.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "ioloop.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "network.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "lib-signals.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "restrict-access.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "fd-close-on-exec.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "randgen.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "password-scheme.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "mech.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-request-handler.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-worker-server.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-worker-client.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-master-interface.h"
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch#include "auth-master-listener.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-master-connection.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include "auth-client-connection.h"
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <stdio.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <stdlib.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <unistd.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <syslog.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <pwd.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <grp.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen#include <sys/stat.h>
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
fe779565bda49a0ed0476724819c6e3c1340c94bTimo Sirainenstruct ioloop *ioloop;
fe779565bda49a0ed0476724819c6e3c1340c94bTimo Sirainenint standalone = FALSE, worker = FALSE;
fe779565bda49a0ed0476724819c6e3c1340c94bTimo Sirainentime_t process_start_time;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic struct auth *auth;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic struct auth_worker_client *worker_client;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschstatic void sig_die(int signo, void *context __attr_unused__)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen which is too common at least while testing :) */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (signo != SIGINT)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_warning("Killed with signal %d", signo);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen io_loop_stop(ioloop);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic void open_logfile(void)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen const char *env;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_set_failure_internal();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (getenv("USE_SYSLOG") != NULL) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen env = getenv("SYSLOG_FACILITY");
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_set_failure_syslog("dovecot-auth", LOG_NDELAY,
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen env == NULL ? LOG_MAIL : atoi(env));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen } else {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* log to file or stderr */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_set_failure_file(getenv("LOGFILE"), "dovecot-auth");
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (getenv("INFOLOGFILE") != NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic uid_t get_uid(const char *user)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen struct passwd *pw;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (user == NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return (uid_t)-1;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if ((pw = getpwnam(user)) == NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("User doesn't exist: %s", user);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return pw->pw_uid;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic gid_t get_gid(const char *group)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen struct group *gr;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (group == NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return (gid_t)-1;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if ((gr = getgrnam(group)) == NULL)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch i_fatal("Group doesn't exist: %s", group);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch return gr->gr_gid;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch}
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic int create_unix_listener(const char *env, int backlog)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen const char *path, *mode, *user, *group;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen mode_t old_umask;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen unsigned int mask;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen uid_t uid;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen gid_t gid;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen int fd, i;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen path = getenv(env);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (path == NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return -1;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen mode = getenv(t_strdup_printf("%s_MODE", env));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (mode == NULL)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen mask = 0177; /* default to 0600 */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen else {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (sscanf(mode, "%o", &mask) != 1)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("%s: Invalid mode %s", env, mode);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen mask = (mask ^ 0777) & 0777;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen old_umask = umask(mask);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen for (i = 0; i < 5; i++) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen fd = net_listen_unix(path, backlog);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (fd != -1)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen break;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (errno != EADDRINUSE)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("net_listen_unix(%s) failed: %m", path);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* see if it really exists */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (net_connect_unix(path) != -1 || errno != ECONNREFUSED)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("Socket already exists: %s", path);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* delete and try again */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (unlink(path) < 0)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("unlink(%s) failed: %m", path);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen umask(old_umask);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen user = getenv(t_strdup_printf("%s_USER", env));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen group = getenv(t_strdup_printf("%s_GROUP", env));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen uid = get_uid(user); gid = get_gid(group);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (chown(path, uid, gid) < 0) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen i_fatal("chown(%s, %s, %s) failed: %m",
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen path, dec2str(uid), dec2str(gid));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return fd;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic void add_extra_listeners(void)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen struct auth_master_listener *listener;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen const char *str, *client_path, *master_path;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen int client_fd, master_fd;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen unsigned int i;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen for (i = 1;; i++) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen t_push();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen client_path = getenv(t_strdup_printf("AUTH_%u", i));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen master_path = getenv(t_strdup_printf("AUTH_%u_MASTER", i));
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (client_path == NULL && master_path == NULL) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen t_pop();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen break;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen str = t_strdup_printf("AUTH_%u", i);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen client_fd = create_unix_listener(str, 64);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen str = t_strdup_printf("AUTH_%u_MASTER", i);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen master_fd = create_unix_listener(str, 64);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen listener = auth_master_listener_create(auth);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (master_fd != -1) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_master_listener_add(listener, master_fd,
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen master_path, LISTENER_MASTER);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (client_fd != -1) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_master_listener_add(listener, client_fd,
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen client_path, LISTENER_CLIENT);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen t_pop();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic void drop_privileges(void)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen open_logfile();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* Open /dev/urandom before chrooting */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen random_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* Initialize databases so their configuration files can be readable
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen only by root. Also load all modules here. */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth = auth_preinit();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen password_schemes_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_master_listeners_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (!worker)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen add_extra_listeners();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* Password lookups etc. may require roots, allow it. */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen restrict_access_by_env(FALSE);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainenstatic void main_init(int nodaemon)
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen{
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen struct auth_master_listener *listener;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen process_start_time = ioloop_time;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen lib_signals_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch lib_signals_set_handler(SIGPIPE, FALSE, NULL, NULL);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch lib_signals_set_handler(SIGALRM, FALSE, NULL, NULL);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* If auth caches aren't used, just ignore these signals */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen lib_signals_set_handler(SIGHUP, FALSE, NULL, NULL);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen lib_signals_set_handler(SIGUSR2, FALSE, NULL, NULL);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen mech_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_init(auth);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_request_handler_init();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (worker) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen worker_client =
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_worker_client_create(auth, WORKER_SERVER_FD);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen standalone = getenv("DOVECOT_MASTER") == NULL;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (standalone) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* starting standalone */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (getenv("AUTH_1") == NULL) {
8855b8b57050fe3b6dc3f19283488512fae98648Timo Sirainen i_fatal("dovecot-auth is usually started through "
8855b8b57050fe3b6dc3f19283488512fae98648Timo Sirainen "dovecot master process. If you wish to run "
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen "it standalone, you'll need to set AUTH_* "
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen "environment variables (AUTH_1 isn't set).");
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen if (!nodaemon) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen switch (fork()) {
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen case -1:
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch i_fatal("fork() failed: %m");
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen case 0:
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch break;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch default:
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch exit(0);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch }
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (setsid() < 0)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch i_fatal("setsid() failed: %m");
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (chdir("/") < 0)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch i_fatal("chdir(/) failed: %m");
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch }
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch } else {
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch listener = auth_master_listener_create(auth);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch (void)auth_master_connection_create(listener, MASTER_SOCKET_FD);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_master_listener_add(listener, CLIENT_LISTEN_FD,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch NULL, LISTENER_CLIENT);
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen }
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen /* everything initialized, notify masters that all is well */
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen auth_master_listeners_send_handshake();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch}
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschstatic void main_deinit(void)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch{
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_deinit(auth);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (worker_client != NULL)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_worker_client_unref(worker_client);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch else
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_request_handler_flush_failures();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_worker_server_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_master_listeners_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch auth_request_handler_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch mech_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch password_schemes_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch random_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch lib_signals_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch closelog();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch}
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint main(int argc __attr_unused__, char *argv[])
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch{
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch int foreground = FALSE;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch#ifdef DEBUG
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (getenv("GDB") == NULL)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch fd_debug_verify_leaks(WORKER_SERVER_FD + 1, 1024);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch#endif
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch /* NOTE: we start rooted, so keep the code minimal until
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch restrict_access_by_env() is called */
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch lib_init();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch ioloop = io_loop_create(system_pool);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch while (argv[1] != NULL) {
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (strcmp(argv[1], "-F") == 0)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch foreground = TRUE;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch else if (strcmp(argv[1], "-w") == 0)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch worker = TRUE;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch argv++;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch }
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch drop_privileges();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch main_init(foreground);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch io_loop_run(ioloop);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch main_deinit();
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch io_loop_destroy(ioloop);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch lib_deinit();
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen return 0;
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen}
02c75e04c6ff80726bb59e3ea34a7995ad1f6f7cTimo Sirainen