main.c revision 9e0f35dcc277e3f55da306519738e5ca3499a2b6
/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
#include "array.h"
#include "ioloop.h"
#include "net.h"
#include "lib-signals.h"
#include "restrict-access.h"
#include "child-wait.h"
#include "sql-api.h"
#include "module-dir.h"
#include "hostpid.h"
#include "randgen.h"
#include "process-title.h"
#include "settings-parser.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "master-interface.h"
#include "dict.h"
#include "password-scheme.h"
#include "passdb-cache.h"
#include "mech.h"
#include "auth.h"
#include "auth-penalty.h"
#include "auth-token.h"
#include "auth-request-handler.h"
#include "auth-request-stats.h"
#include "auth-worker-server.h"
#include "auth-worker-client.h"
#include "auth-master-connection.h"
#include "auth-client-connection.h"
#include "auth-postfix-connection.h"
#include "auth-policy.h"
#include <unistd.h>
#define AUTH_PENALTY_ANVIL_PATH "anvil-auth-penalty"
enum auth_socket_type {
AUTH_SOCKET_UNKNOWN = 0,
};
struct auth_socket_listener {
enum auth_socket_type type;
char *path;
};
struct auth_penalty *auth_penalty;
static pool_t auth_set_pool;
static struct mechanisms_register *mech_reg;
void auth_refresh_proctitle(void)
{
return;
"[%u wait, %u passdb, %u userdb]",
}
static const char *const *read_global_settings(void)
{
const char **services;
unsigned int i, count;
/* strdup() the service names, because they're allocated from
set parser pool, and we'll later clear it. */
for (i = 0; i < count; i++) {
}
return services;
}
static enum auth_socket_type
auth_socket_type_get(const char *path)
{
else
name++;
else
suffix++;
return AUTH_SOCKET_LOGIN_CLIENT;
return AUTH_SOCKET_MASTER;
return AUTH_SOCKET_USERDB;
return AUTH_SOCKET_POSTFIX;
return AUTH_SOCKET_TOKEN;
return AUTH_SOCKET_TOKEN_LOGIN;
else
return AUTH_SOCKET_CLIENT;
}
static void listeners_init(void)
{
unsigned int i, n;
const char *path;
for (i = 0; i < n; i++) {
int fd = MASTER_LISTEN_FD_FIRST + i;
struct auth_socket_listener *l;
/* not a unix socket, set its name and type lazily */
} else {
if (l->type == AUTH_SOCKET_USERDB) {
}
}
}
}
{
/* this is lazily loaded */
return FALSE;
}
return TRUE;
}
static void main_preinit(void)
{
struct module_dir_load_settings mod_set;
const char *const *services;
/* Load built-in SQL drivers (if any) */
/* Initialize databases so their configuration files can be readable
only by root. Also load all modules here. */
passdbs_init();
userdbs_init();
/* init schemes before plugins are loaded */
if (!worker)
if (!worker)
/* Password lookups etc. may require roots, allow it. */
}
void auth_module_load(const char *names)
{
struct module_dir_load_settings mod_set;
&mod_set);
}
static void main_init(void)
{
/* If auth caches aren't used, just ignore these signals */
/* set proctitles before init()s, since they may set them to error */
auths_init();
if (worker) {
/* workers have only a single connection from the master
auth process */
} else {
/* caching is handled only by the main auth process */
}
}
static void main_deinit(void)
{
struct auth_socket_listener *l;
if (auth_penalty != NULL) {
/* cancel all pending anvil penalty lookups */
}
/* deinit auth workers, which aborts pending requests */
/* deinit passdbs and userdbs. it aborts any pending async requests. */
auths_deinit();
/* flush pending requests */
/* there are no more auth requests */
auths_free();
if (auth_worker_client != NULL)
the whole data structures containing them. */
}
{
if (auth_worker_client != NULL) {
i_error("Auth workers can handle only a single client");
return;
}
}
{
struct auth_socket_listener *l;
if (l->type == AUTH_SOCKET_UNKNOWN) {
/* first connection from inet socket, figure out its type
from the listener name */
}
auth = auth_default_service();
switch (l->type) {
case AUTH_SOCKET_MASTER:
break;
case AUTH_SOCKET_USERDB:
break;
case AUTH_SOCKET_POSTFIX:
break;
case AUTH_SOCKET_LOGIN_CLIENT:
break;
case AUTH_SOCKET_CLIENT:
break;
case AUTH_SOCKET_TOKEN_LOGIN:
break;
case AUTH_SOCKET_TOKEN:
break;
default:
i_unreached();
}
}
static void auth_die(void)
{
if (!worker) {
/* do nothing. auth clients should disconnect soon. */
} else {
/* ask auth master to disconnect us */
}
}
{
int c;
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'w':
break;
default:
return FATAL_DEFAULT;
}
}
main_preinit();
main_init();
main_deinit();
return 0;
}