dovecot-2.0: login proxy: If passdb returns proxy_refresh=<secs>...

dovecot at dovecot.org dovecot at dovecot.org
Wed May 19 13:23:40 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/c872378a8de6
changeset: 11324:c872378a8de6
user:      Timo Sirainen <tss at iki.fi>
date:      Wed May 19 12:20:36 2010 +0200
description:
login proxy: If passdb returns proxy_refresh=<secs>, send username to proxy-notify fifo every n secs.

diffstat:

 src/login-common/client-common-auth.c |   3 +
 src/login-common/client-common.c      |   5 +-
 src/login-common/client-common.h      |   1 +
 src/login-common/login-proxy-state.c  |  49 ++++++++++++++++++++++++-
 src/login-common/login-proxy-state.h  |   5 ++-
 src/login-common/login-proxy.c        |  21 +++++++++-
 src/login-common/login-proxy.h        |   5 ++-
 src/login-common/main.c               |   2 +-
 8 files changed, 81 insertions(+), 10 deletions(-)

diffs (269 lines):

diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/client-common-auth.c
--- 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) {
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/client-common.c
--- 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);
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/client-common.h
--- 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;
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/login-proxy-state.c
--- 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);
+		}
+	}
+}
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/login-proxy-state.h
--- 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
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/login-proxy.c
--- 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)
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/login-proxy.h
--- 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
diff -r 0fc0cc9e0952 -r c872378a8de6 src/login-common/main.c
--- 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)


More information about the dovecot-cvs mailing list