#include <sys/stat.h>
struct auth_client *auth_client_new(unsigned int client_pid)
+{
+ return auth_client_new_external(client_pid, NULL, NULL, NULL);
+}
+
+struct auth_client *auth_client_new_external(unsigned int client_pid,
+ const char *socket_paths,
+ input_func_add_t *add_func,
+ input_func_remove_t *remove_func)
{
struct auth_client *client;
client = i_new(struct auth_client, 1);
client->pid = client_pid;
+ client->socket_paths = i_strdup(socket_paths);
client->available_auth_mechs =
buffer_create_dynamic(default_pool, 128, (size_t)-1);
+ client->ext_input_add = add_func;
+ client->ext_input_remove = remove_func;
+
auth_client_connect_missing_servers(client);
return client;
}
if (client->to_reconnect != NULL)
timeout_remove(client->to_reconnect);
+ i_free(client->socket_paths);
i_free(client);
}
int auth_client_is_connected(struct auth_client *client)
{
- return client->to_reconnect == NULL &&
+ return !client->reconnect &&
client->conn_waiting_handshake_count == 0;
}
auth_client_connect_missing_servers(client);
}
+static void auth_client_connect_missing_servers_list(struct auth_client *client,
+ const char *list)
+{
+ const char *const *path;
+
+ client->reconnect = FALSE;
+
+ t_push();
+ path = t_strsplit(list, ":");
+ for (; *path != NULL; path++) {
+ if (auth_server_connection_find_path(client, *path) == NULL) {
+ if (auth_server_connection_new(client, *path) == NULL)
+ client->reconnect = TRUE;
+ }
+ }
+ t_pop();
+}
+
void auth_client_connect_missing_servers(struct auth_client *client)
{
DIR *dirp;
struct dirent *dp;
struct stat st;
- int reconnect;
- /* we're chrooted into */
- dirp = opendir(".");
- if (dirp == NULL) {
- i_fatal("opendir(.) failed when trying to get list of "
- "authentication servers: %m");
- }
+ if (client->socket_paths != NULL) {
+ auth_client_connect_missing_servers_list(client,
+ client->socket_paths);
+ } else {
+ /* we're chrooted */
+ dirp = opendir(".");
+ if (dirp == NULL) {
+ i_fatal("opendir(.) failed when trying to get list of "
+ "authentication servers: %m");
+ }
- reconnect = FALSE;
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_name[0] == '.')
- continue;
+ client->reconnect = FALSE;
+ while ((dp = readdir(dirp)) != NULL) {
+ const char *name = dp->d_name;
- if (auth_server_connection_find_path(client, dp->d_name) != NULL) {
- /* already connected */
- continue;
- }
+ if (name[0] == '.')
+ continue;
+
+ if (auth_server_connection_find_path(client,
+ name) != NULL) {
+ /* already connected */
+ continue;
+ }
- if (stat(dp->d_name, &st) == 0 && S_ISSOCK(st.st_mode)) {
- if (auth_server_connection_new(client,
- dp->d_name) == NULL)
- reconnect = TRUE;
+ if (stat(name, &st) == 0 && S_ISSOCK(st.st_mode)) {
+ if (auth_server_connection_new(client,
+ name) == NULL)
+ client->reconnect = TRUE;
+ }
}
- }
- if (closedir(dirp) < 0)
- i_error("closedir() failed: %m");
+ if (closedir(dirp) < 0)
+ i_error("closedir() failed: %m");
+ }
- if (reconnect || client->connections == NULL) {
- if (client->to_reconnect == NULL) {
+ if (client->reconnect || client->connections == NULL) {
+ if (client->to_reconnect == NULL &&
+ client->ext_input_add == NULL) {
client->to_reconnect =
timeout_add(5000, reconnect_timeout, client);
}
const struct auth_mech_desc *
auth_client_find_mech(struct auth_client *client, const char *name);
-void auth_client_connect_missing_servers(struct auth_client *client);
-
/* Create a new authentication request. callback is called whenever something
happens for the request. */
struct auth_request *
/* Return the PID of the server that handled this request. */
unsigned int auth_client_request_get_server_pid(struct auth_request *request);
+/* -- Using lib-auth with external I/O loop -- */
+
+typedef void *input_func_add_t(int fd, void (*cb)(void *), void *context);
+typedef void *input_func_remove_t(void *io);
+
+struct auth_client *auth_client_new_external(unsigned int client_pid,
+ const char *socket_paths,
+ input_func_add_t *add_func,
+ input_func_remove_t *remove_func);
+/* Call every few seconds. */
+void auth_client_connect_missing_servers(struct auth_client *client);
+
#endif
buffer_t *buf;
unsigned int i;
- if (handshake->server_pid == 0) {
- i_error("BUG: Auth server said it's PID 0");
- auth_server_connection_destroy(conn, FALSE);
- return;
- }
-
if (handshake->data_size == 0 || data[handshake->data_size-1] != '\0' ||
handshake->mech_count * sizeof(handshake_mech_desc) >=
handshake->data_size) {
conn->client = client;
conn->path = p_strdup(pool, path);
conn->fd = fd;
- conn->io = io_add(fd, IO_READ, auth_client_input, conn);
+ if (client->ext_input_add == NULL)
+ conn->io = io_add(fd, IO_READ, auth_client_input, conn);
+ else {
+ conn->ext_input_io =
+ client->ext_input_add(fd, auth_client_input, conn);
+ }
conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE,
FALSE);
conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE,
if (!conn->handshake_received)
client->conn_waiting_handshake_count--;
- io_remove(conn->io);
- conn->io = NULL;
+ if (conn->ext_input_io != NULL) {
+ client->ext_input_remove(conn->ext_input_io);
+ conn->ext_input_io = NULL;
+ }
+ if (conn->io != NULL) {
+ io_remove(conn->io);
+ conn->io = NULL;
+ }
i_stream_close(conn->input);
o_stream_close(conn->output);
for (conn = client->connections; conn != NULL; conn = conn->next) {
mech = conn->available_auth_mechs;
for (i = 0; i < conn->available_auth_mechs_count; i++) {
- if (strcmp(mech[i].name, name) == 0)
+ if (strcasecmp(mech[i].name, name) == 0)
return conn;
}
}