Mercurial > dovecot > core-2.2
changeset 11324:c872378a8de6 HEAD
login proxy: If passdb returns proxy_refresh=<secs>, send username to proxy-notify fifo every n secs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 19 May 2010 12:20:36 +0200 |
parents | 0fc0cc9e0952 |
children | 2a5336ad86cd |
files | src/login-common/client-common-auth.c src/login-common/client-common.c src/login-common/client-common.h src/login-common/login-proxy-state.c src/login-common/login-proxy-state.h src/login-common/login-proxy.c src/login-common/login-proxy.h src/login-common/main.c |
diffstat | 8 files changed, 81 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/client-common-auth.c Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/client-common-auth.c Wed May 19 12:20:36 2010 +0200 @@ -87,6 +87,8 @@ reply_r->password = value; else if (strcmp(key, "proxy_timeout") == 0) reply_r->proxy_timeout_msecs = 1000*atoi(value); + else if (strcmp(key, "proxy_refresh") == 0) + reply_r->proxy_refresh_secs = atoi(value); else if (strcmp(key, "master") == 0) reply_r->master_user = value; else if (strcmp(key, "ssl") == 0) { @@ -261,6 +263,7 @@ proxy_set.port = reply->port; proxy_set.dns_client_socket_path = LOGIN_DNS_CLIENT_SOCKET_PATH; proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs; + proxy_set.notify_refresh_secs = reply->proxy_refresh_secs; proxy_set.ssl_flags = reply->ssl_flags; if (login_proxy_new(client, &proxy_set, proxy_input) < 0) {
--- a/src/login-common/client-common.c Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/client-common.c Wed May 19 12:20:36 2010 +0200 @@ -144,9 +144,6 @@ i_free_and_null(client->proxy_password); } - i_free_and_null(client->proxy_user); - i_free_and_null(client->proxy_master_user); - if (client->login_proxy != NULL) login_proxy_free(&client->login_proxy); if (client->ssl_proxy != NULL) @@ -201,6 +198,8 @@ if (client->output != NULL) o_stream_unref(&client->output); + i_free(client->proxy_user); + i_free(client->proxy_master_user); i_free(client->virtual_user); i_free(client->auth_mech_name); pool_unref(&client->pool);
--- a/src/login-common/client-common.h Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/client-common.h Wed May 19 12:20:36 2010 +0200 @@ -43,6 +43,7 @@ const char *host, *destuser, *password; unsigned int port; unsigned int proxy_timeout_msecs; + unsigned int proxy_refresh_secs; enum login_proxy_ssl_flags ssl_flags; unsigned int proxy:1;
--- a/src/login-common/login-proxy-state.c Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/login-proxy-state.c Wed May 19 12:20:36 2010 +0200 @@ -3,11 +3,18 @@ #include "lib.h" #include "network.h" #include "hash.h" +#include "strescape.h" #include "login-proxy-state.h" +#include <unistd.h> +#include <fcntl.h> + struct login_proxy_state { struct hash_table *hash; pool_t pool; + + const char *notify_path; + int notify_fd; }; static unsigned int login_proxy_record_hash(const void *p) @@ -27,15 +34,23 @@ return (int)rec1->port - (int)rec2->port; } -struct login_proxy_state *login_proxy_state_init(void) +struct login_proxy_state *login_proxy_state_init(const char *notify_path) { struct login_proxy_state *state; state = i_new(struct login_proxy_state, 1); state->pool = pool_alloconly_create("login proxy state", 1024); + state->notify_path = p_strdup(state->pool, notify_path); state->hash = hash_table_create(default_pool, state->pool, 0, login_proxy_record_hash, login_proxy_record_cmp); + if (state->notify_path == NULL) + state->notify_fd = -1; + else { + state->notify_fd = open(state->notify_path, O_WRONLY); + if (state->notify_fd == -1) + i_error("open(%s) failed: %m", state->notify_path); + } return state; } @@ -44,6 +59,11 @@ struct login_proxy_state *state = *_state; *_state = NULL; + + if (state->notify_fd != -1) { + if (close(state->notify_fd) < 0) + i_error("close(%s) failed: %m", state->notify_path); + } hash_table_destroy(&state->hash); pool_unref(&state->pool); i_free(state); @@ -68,3 +88,30 @@ } return rec; } + +void login_proxy_state_notify(struct login_proxy_state *state, + const char *user) +{ + unsigned int len; + ssize_t ret; + + if (state->notify_fd == -1) + return; + + T_BEGIN { + const char *cmd; + + cmd = t_strconcat(str_tabescape(user), "\n", NULL); + len = strlen(cmd); + ret = write(state->notify_fd, cmd, len); + } T_END; + + if (ret != len) { + if (ret < 0) + i_error("write(%s) failed: %m", state->notify_path); + else { + i_error("write(%s) wrote partial update", + state->notify_path); + } + } +}
--- a/src/login-common/login-proxy-state.h Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/login-proxy-state.h Wed May 19 12:20:36 2010 +0200 @@ -12,11 +12,14 @@ struct timeval last_success; }; -struct login_proxy_state *login_proxy_state_init(void); +struct login_proxy_state *login_proxy_state_init(const char *notify_path); void login_proxy_state_deinit(struct login_proxy_state **state); struct login_proxy_record * login_proxy_state_get(struct login_proxy_state *state, const struct ip_addr *ip, unsigned int port); +void login_proxy_state_notify(struct login_proxy_state *state, + const char *user); + #endif
--- a/src/login-common/login-proxy.c Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/login-proxy.c Wed May 19 12:20:36 2010 +0200 @@ -31,13 +31,14 @@ time_t last_io; struct timeval created; - struct timeout *to; + struct timeout *to, *to_notify; struct login_proxy_record *state_rec; struct ip_addr ip; char *host; unsigned int port; unsigned int connect_timeout_msecs; + unsigned int notify_refresh_secs; enum login_proxy_ssl_flags ssl_flags; proxy_callback_t *callback; @@ -266,6 +267,7 @@ proxy->host = i_strdup(set->host); proxy->port = set->port; proxy->connect_timeout_msecs = set->connect_timeout_msecs; + proxy->notify_refresh_secs = set->notify_refresh_secs; proxy->ssl_flags = set->ssl_flags; client_ref(client); @@ -301,6 +303,8 @@ if (proxy->to != NULL) timeout_remove(&proxy->to); + if (proxy->to_notify != NULL) + timeout_remove(&proxy->to_notify); if (proxy->state_rec != NULL) proxy->state_rec->num_waiting_connections--; @@ -390,6 +394,11 @@ return proxy->ssl_flags; } +static void login_proxy_notify(struct login_proxy *proxy) +{ + login_proxy_state_notify(proxy_state, proxy->client->proxy_user); +} + void login_proxy_detach(struct login_proxy *proxy) { struct client *client = proxy->client; @@ -420,6 +429,12 @@ o_stream_set_flush_callback(proxy->server_output, server_output, proxy); i_stream_destroy(&proxy->server_input); + if (proxy->notify_refresh_secs != 0) { + proxy->to_notify = + timeout_add(proxy->notify_refresh_secs * 1000, + login_proxy_notify, proxy); + } + proxy->callback = NULL; DLLIST_PREPEND(&login_proxies, proxy); @@ -503,9 +518,9 @@ } } -void login_proxy_init(void) +void login_proxy_init(const char *proxy_notify_pipe_path) { - proxy_state = login_proxy_state_init(); + proxy_state = login_proxy_state_init(proxy_notify_pipe_path); } void login_proxy_deinit(void)
--- a/src/login-common/login-proxy.h Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/login-proxy.h Wed May 19 12:20:36 2010 +0200 @@ -18,6 +18,9 @@ const char *dns_client_socket_path; unsigned int port; unsigned int connect_timeout_msecs; + /* send a notification about proxy connection to proxy-notify pipe + every n seconds */ + unsigned int notify_refresh_secs; enum login_proxy_ssl_flags ssl_flags; }; @@ -54,7 +57,7 @@ void login_proxy_kill_idle(void); -void login_proxy_init(void); +void login_proxy_init(const char *proxy_notify_pipe_path); void login_proxy_deinit(void); #endif
--- a/src/login-common/main.c Wed May 19 12:17:53 2010 +0200 +++ b/src/login-common/main.c Wed May 19 12:20:36 2010 +0200 @@ -304,7 +304,7 @@ master_auth = master_auth_init(master_service, login_binary.protocol); clients_init(); - login_proxy_init(); + login_proxy_init("proxy-notify"); } static void main_deinit(void)