Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-auth/auth-client.c @ 9532:00cd9aacd03c HEAD
Updated copyright notices to include year 2010.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 25 Jan 2010 01:18:58 +0200 |
parents | b9faf4db2a9f |
children |
line wrap: on
line source
/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "buffer.h" #include "ioloop.h" #include "hash.h" #include "auth-client.h" #include "auth-server-connection.h" #include <dirent.h> #include <sys/stat.h> #define AUTH_CLIENT_SOCKET_MAX_WAIT_TIME 10 struct auth_client *auth_client_new(unsigned int client_pid) { struct auth_client *client; client = i_new(struct auth_client, 1); client->pid = client_pid; client->available_auth_mechs = buffer_create_dynamic(default_pool, 128); auth_client_connect_missing_servers(client); return client; } void auth_client_free(struct auth_client **_client) { struct auth_client *client = *_client; struct auth_server_connection *next; struct auth_mech_desc *mech; size_t i, size; *_client = NULL; mech = buffer_get_modifiable_data(client->available_auth_mechs, &size); size /= sizeof(*mech); for (i = 0; i < size; i++) i_free(mech[i].name); buffer_free(&client->available_auth_mechs); while (client->connections != NULL) { next = client->connections->next; auth_server_connection_destroy(&client->connections, FALSE); client->connections = next; } if (client->to_reconnect != NULL) timeout_remove(&client->to_reconnect); i_free(client); } void auth_client_reconnect(struct auth_client *client) { struct auth_server_connection *next; while (client->connections != NULL) { next = client->connections->next; auth_server_connection_destroy(&client->connections, FALSE); client->connections = next; } auth_client_connect_missing_servers(client); } const struct auth_mech_desc * auth_client_get_available_mechs(struct auth_client *client, unsigned int *mech_count) { const struct auth_mech_desc *mechs; size_t size; mechs = buffer_get_data(client->available_auth_mechs, &size); *mech_count = size / sizeof(*mechs); return mechs; } const struct auth_mech_desc * auth_client_find_mech(struct auth_client *client, const char *name) { const struct auth_mech_desc *mech; size_t i, size; mech = buffer_get_data(client->available_auth_mechs, &size); size /= sizeof(*mech); for (i = 0; i < size; i++) { if (strcasecmp(mech[i].name, name) == 0) return &mech[i]; } return NULL; } bool auth_client_reserve_connection(struct auth_client *client, const char *mech, struct auth_connect_id *id_r) { struct auth_server_connection *conn; const char *error; conn = auth_server_connection_find_mech(client, mech, &error); if (conn == NULL) return FALSE; id_r->server_pid = conn->server_pid; id_r->connect_uid = conn->connect_uid; return TRUE; } bool auth_client_is_connected(struct auth_client *client) { return !client->reconnect && client->conn_waiting_handshake_count == 0 && client->connections != NULL; } void auth_client_set_connect_notify(struct auth_client *client, auth_connect_notify_callback_t *callback, void *context) { client->connect_notify_callback = callback; client->connect_notify_context = context; } static void reconnect_timeout(struct auth_client *client) { auth_client_connect_missing_servers(client); } void auth_client_connect_missing_servers(struct auth_client *client) { DIR *dirp; struct dirent *dp; struct stat st; /* we're chrooted */ dirp = opendir("."); if (dirp == NULL) { i_fatal("opendir(.) failed when trying to get list of " "authentication servers: %m"); } client->reconnect = FALSE; while ((dp = readdir(dirp)) != NULL) { const char *name = dp->d_name; if (name[0] == '.') continue; if (auth_server_connection_find_path(client, name) != NULL) { /* already connected */ continue; } /* Normally they're sockets, but in UnixWare they're created as fifos. */ if (stat(name, &st) == 0 && (S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode))) { if (auth_server_connection_new(client, name) == NULL) client->reconnect = TRUE; } } if (client->connections == NULL && !client->reconnect) { if (client->missing_sockets_start_time == 0) client->missing_sockets_start_time = ioloop_time; else if (ioloop_time - client->missing_sockets_start_time > AUTH_CLIENT_SOCKET_MAX_WAIT_TIME) i_fatal("No authentication sockets found"); } if (closedir(dirp) < 0) i_error("closedir() failed: %m"); if (client->reconnect || client->connections == NULL) { if (client->to_reconnect == NULL) { client->to_reconnect = timeout_add(1000, reconnect_timeout, client); } } else if (client->to_reconnect != NULL) timeout_remove(&client->to_reconnect); if (client->connect_notify_callback != NULL) { client->connect_notify_callback(client, auth_client_is_connected(client), client->connect_notify_context); } }