main.c revision 0fe87c6c4972ab53eb4827814950d039fbcd5935
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "common.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "buffer.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "ioloop.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "network.h"
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen#include "lib-signals.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "restrict-access.h"
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen#include "fd-close-on-exec.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "randgen.h"
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen#include "mech.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "userdb.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "passdb.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "password-scheme.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "auth-master-connection.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "auth-client-connection.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <stdio.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <stdlib.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <unistd.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <syslog.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <pwd.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <grp.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <sys/stat.h>
9955f6cba7652469b1d600a3674e8d27dd4e61bdTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct ioloop *ioloop;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint verbose = FALSE, verbose_debug = FALSE;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenint standalone = FALSE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic buffer_t *masters_buf;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sig_quit(int signo __attr_unused__)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen io_loop_stop(ioloop);
03010dbaa74ec70f062994dfe3cd39bedc99a28bTimo Sirainen}
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenstatic void open_logfile(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_set_failure_internal();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen }
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen if (getenv("USE_SYSLOG") != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_set_failure_syslog("dovecot-auth", LOG_NDELAY, LOG_MAIL);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* log to file or stderr */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_set_failure_file(getenv("LOGFILE"), "dovecot-auth");
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (getenv("INFOLOGFILE") != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic uid_t get_uid(const char *user)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct passwd *pw;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (user == NULL)
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen return (uid_t)-1;
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((pw = getpwnam(user)) == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("User doesn't exist: %s", user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return pw->pw_uid;
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic gid_t get_gid(const char *group)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct group *gr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (group == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return (gid_t)-1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((gr = getgrnam(group)) == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("Group doesn't exist: %s", group);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return gr->gr_gid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int create_unix_listener(const char *env)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *path, *mode, *user, *group;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mode_t old_umask;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int mask;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_t uid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen gid_t gid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int fd, i;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen path = getenv(env);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen if (path == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen mode = getenv(t_strdup_printf("%s_MODE", env));
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (mode == NULL)
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen mask = 0177; /* default to 0600 */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sscanf(mode, "%o", &mask) != 1)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("%s: Invalid mode %s", env, mode);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mask = (mask ^ 0777) & 0777;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen old_umask = umask(mask);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen for (i = 0; i < 5; i++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen fd = net_listen_unix(path);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (fd != -1)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
03010dbaa74ec70f062994dfe3cd39bedc99a28bTimo Sirainen if (errno != EADDRINUSE)
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen i_fatal("net_listen_unix(%s) failed: %m", path);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen /* see if it really exists */
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen if (net_connect_unix(path) != -1 || errno != ECONNREFUSED)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("Socket already exists: %s", path);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen /* delete and try again */
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen if (unlink(path) < 0)
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen i_fatal("unlink(%s) failed: %m", path);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen umask(old_umask);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen user = getenv(t_strdup_printf("%s_USER", env));
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen group = getenv(t_strdup_printf("%s_GROUP", env));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen uid = get_uid(user); gid = get_gid(group);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (chown(path, uid, gid) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("chown(%s, %s, %s) failed: %m",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen path, dec2str(uid), dec2str(gid));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return fd;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void add_extra_listeners(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct auth_master_connection *master;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *str, *client_path, *master_path;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int client_fd, master_fd;
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen unsigned int i;
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen for (i = 1;; i++) {
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen t_push();
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen client_path = getenv(t_strdup_printf("AUTH_%u", i));
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen master_path = getenv(t_strdup_printf("AUTH_%u_MASTER", i));
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen if (client_path == NULL && master_path == NULL) {
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen t_pop();
e790c9b1fc56bca7ebd59dc289cb5035e3afcee5Timo Sirainen break;
f605df8a4c15cc7a11e16fdde994d51473700890Timo Sirainen }
e790c9b1fc56bca7ebd59dc289cb5035e3afcee5Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str = t_strdup_printf("AUTH_%u", i);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen client_fd = create_unix_listener(str);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str = t_strdup_printf("AUTH_%u_MASTER", i);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen master_fd = create_unix_listener(str);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen master = auth_master_connection_create(-1, getpid());
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen if (master_fd != -1) {
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen auth_master_connection_add_listener(master, master_fd,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen master_path, FALSE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen if (client_fd != -1) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen auth_master_connection_add_listener(master, client_fd,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen client_path, TRUE);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen auth_client_connections_init(master);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen buffer_append(masters_buf, &master, sizeof(master));
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen t_pop();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenstatic void drop_privileges(void)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen verbose = getenv("VERBOSE") != NULL;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen verbose_debug = getenv("VERBOSE_DEBUG") != NULL;
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen open_logfile();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* Open /dev/urandom before chrooting */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen random_init();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* Initialize databases so their configuration files can be readable
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen only by root. Also load all modules here. */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen userdb_preinit();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen passdb_preinit();
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen password_schemes_init();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen masters_buf = buffer_create_dynamic(default_pool, 64);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen add_extra_listeners();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Password lookups etc. may require roots, allow it. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen restrict_access_by_env(FALSE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void main_init(int nodaemon)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen struct auth_master_connection *master, **master_p;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen size_t i, size;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *env;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen unsigned int pid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen userdb_init();
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen passdb_init();
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
d0b2bd9e2246eb68ed952c7f2e13d1969d657c8fTimo Sirainen lib_init_signals(sig_quit);
d0b2bd9e2246eb68ed952c7f2e13d1969d657c8fTimo Sirainen mech_init();
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen env = getenv("AUTH_PROCESS");
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen standalone = env == NULL;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (standalone) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* starting standalone */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (getenv("AUTH_1") == NULL) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen i_fatal("dovecot-auth is usually started through "
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen "dovecot master process. If you wish to run "
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen "it standalone, you'll need to set AUTH_* "
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen "environment variables (AUTH_1 isn't set).");
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (!nodaemon) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen switch (fork()) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen case -1:
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen i_fatal("fork() failed: %m");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen case 0:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen default:
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen exit(0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (setsid() < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("setsid() failed: %m");
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen if (chdir("/") < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_fatal("chdir(/) failed: %m");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen pid = atoi(env);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (pid == 0)
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen i_fatal("AUTH_PROCESS can't be 0");
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen master = auth_master_connection_create(MASTER_SOCKET_FD, pid);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen auth_master_connection_add_listener(master, LOGIN_LISTEN_FD,
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainen NULL, TRUE);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen auth_client_connections_init(master);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen buffer_append(masters_buf, &master, sizeof(master));
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* everything initialized, notify masters that all is well */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen master_p = buffer_get_modifyable_data(masters_buf, &size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size /= sizeof(*master_p);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < size; i++)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen auth_master_connection_send_handshake(master_p[i]);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainenstatic void main_deinit(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct auth_master_connection **master;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t i, size;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (lib_signal_kill != 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_warning("Killed with signal %d", lib_signal_kill);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen auth_failure_buf_flush();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen master = buffer_get_modifyable_data(masters_buf, &size);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen size /= sizeof(*master);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen for (i = 0; i < size; i++)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen auth_master_connection_destroy(master[i]);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen password_schemes_deinit();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen passdb_deinit();
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen userdb_deinit();
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen mech_deinit();
62958c5eefcd7dd84717b487ca36ec3a86949eb9Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen random_deinit();
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen closelog();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenint main(int argc, char *argv[])
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen#ifdef DEBUG
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (getenv("GDB") == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen fd_debug_verify_leaks(4, 1024);
ddb018bc886680f462463b2c87f983fdedbf6cf0Timo Sirainen#endif
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen /* NOTE: we start rooted, so keep the code minimal until
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen restrict_access_by_env() is called */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen lib_init();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ioloop = io_loop_create(system_pool);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen drop_privileges();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen main_init(argc > 1 && strcmp(argv[1], "-F") == 0);
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen io_loop_run(ioloop);
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen main_deinit();
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen io_loop_destroy(ioloop);
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen lib_deinit();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen