dovecot-2.2: Added director_username_hash setting to specify wha...

dovecot at dovecot.org dovecot at dovecot.org
Sun May 20 03:26:25 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/817ef4c9f1f3
changeset: 14292:817ef4c9f1f3
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 05 17:28:06 2012 +0200
description:
Added director_username_hash setting to specify what part of the username is hashed.
The default is "%u" meaning the full username. Another potentially useful
value is "%d" for hashing only the domain (i.e. redirect users from the same
domain always to same server so they can safely access each others'
shared mailboxes).

diffstat:

 src/director/Makefile.am          |   3 +-
 src/director/director-request.c   |   3 +-
 src/director/director-settings.c  |   2 +
 src/director/director-settings.h  |   1 +
 src/director/director.c           |   3 +-
 src/director/doveadm-connection.c |   4 +-
 src/director/notify-connection.c  |   2 +-
 src/director/user-directory.c     |  21 ++++++++-----------
 src/director/user-directory.h     |   6 +++-
 src/lib-mail/Makefile.am          |   2 +
 src/lib-mail/mail-user-hash.c     |  41 +++++++++++++++++++++++++++++++++++++++
 src/lib-mail/mail-user-hash.h     |   8 +++++++
 src/login-common/Makefile.am      |   1 +
 src/login-common/login-proxy.c    |  19 +++++------------
 src/login-common/login-settings.c |   2 +
 src/login-common/login-settings.h |   1 +
 16 files changed, 86 insertions(+), 33 deletions(-)

diffs (truncated from 365 to 300 lines):

diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/Makefile.am
--- a/src/director/Makefile.am	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/Makefile.am	Mon Mar 05 17:28:06 2012 +0200
@@ -7,7 +7,8 @@
 	-I$(top_srcdir)/src/lib-auth \
 	-I$(top_srcdir)/src/lib-imap \
 	-I$(top_srcdir)/src/lib-settings \
-	-I$(top_srcdir)/src/lib-master
+	-I$(top_srcdir)/src/lib-master \
+	-I$(top_srcdir)/src/lib-mail
 
 director_LDADD = $(LIBDOVECOT)
 director_DEPENDENCIES = $(LIBDOVECOT_DEPS)
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/director-request.c
--- a/src/director/director-request.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/director-request.c	Mon Mar 05 17:28:06 2012 +0200
@@ -73,7 +73,8 @@
 		      director_request_callback *callback, void *context)
 {
 	struct director_request *request;
-	unsigned int username_hash = user_directory_get_username_hash(username);
+	unsigned int username_hash =
+		user_directory_get_username_hash(dir->users, username);
 
 	request = i_new(struct director_request, 1);
 	request->dir = dir;
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/director-settings.c
--- a/src/director/director-settings.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/director-settings.c	Mon Mar 05 17:28:06 2012 +0200
@@ -68,6 +68,7 @@
 
 	DEF(SET_STR, director_servers),
 	DEF(SET_STR, director_mail_servers),
+	DEF(SET_STR, director_username_hash),
 	DEF(SET_TIME, director_user_expire),
 	DEF(SET_UINT, director_doveadm_port),
 
@@ -79,6 +80,7 @@
 
 	.director_servers = "",
 	.director_mail_servers = "",
+	.director_username_hash = "%u",
 	.director_user_expire = 60*15,
 	.director_doveadm_port = 0
 };
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/director-settings.h
--- a/src/director/director-settings.h	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/director-settings.h	Mon Mar 05 17:28:06 2012 +0200
@@ -6,6 +6,7 @@
 
 	const char *director_servers;
 	const char *director_mail_servers;
+	const char *director_username_hash;
 	unsigned int director_user_expire;
 	unsigned int director_doveadm_port;
 };
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/director.c
--- a/src/director/director.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/director.c	Mon Mar 05 17:28:06 2012 +0200
@@ -625,7 +625,8 @@
 	dir->state_change_callback = callback;
 	i_array_init(&dir->dir_hosts, 16);
 	i_array_init(&dir->pending_requests, 16);
-	dir->users = user_directory_init(set->director_user_expire);
+	dir->users = user_directory_init(set->director_user_expire,
+					 set->director_username_hash);
 	dir->mail_hosts = mail_hosts_init();
 
 	dir->ipc_proxy = ipc_client_init(DIRECTOR_IPC_PROXY_PATH);
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/doveadm-connection.c
--- a/src/director/doveadm-connection.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/doveadm-connection.c	Mon Mar 05 17:28:06 2012 +0200
@@ -223,7 +223,7 @@
 	string_t *str = t_str_new(256);
 
 	if (str_to_uint(line, &username_hash) < 0)
-		username_hash = user_directory_get_username_hash(line);
+		username_hash = user_directory_get_username_hash(conn->dir->users, line);
 
 	/* get user's current host */
 	user = user_directory_lookup(conn->dir->users, username_hash);
@@ -309,7 +309,7 @@
 	}
 
 	if (str_to_uint(args[0], &username_hash) < 0)
-		username_hash = user_directory_get_username_hash(line);
+		username_hash = user_directory_get_username_hash(conn->dir->users, line);
 	user = user_directory_lookup(conn->dir->users, username_hash);
 	if (user != NULL && user->kill_state != USER_KILL_STATE_NONE) {
 		o_stream_send_str(conn->output, "TRYAGAIN\n");
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/notify-connection.c
--- a/src/director/notify-connection.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/notify-connection.c	Mon Mar 05 17:28:06 2012 +0200
@@ -24,7 +24,7 @@
 	unsigned int hash;
 
 	while ((line = i_stream_read_next_line(conn->input)) != NULL) {
-		hash = user_directory_get_username_hash(line);
+		hash = user_directory_get_username_hash(conn->dir->users, line);
 		user = user_directory_lookup(conn->dir->users, hash);
 		if (user != NULL) {
 			user_directory_refresh(conn->dir->users, user);
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/user-directory.c
--- a/src/director/user-directory.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/user-directory.c	Mon Mar 05 17:28:06 2012 +0200
@@ -3,9 +3,9 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "array.h"
-#include "md5.h"
 #include "hash.h"
 #include "llist.h"
+#include "mail-user-hash.h"
 #include "mail-host.h"
 #include "user-directory.h"
 
@@ -24,6 +24,7 @@
 
 	ARRAY_DEFINE(iters, struct user_directory_iter *);
 
+	char *username_hash_fmt;
 	unsigned int timeout_secs;
 };
 
@@ -120,17 +121,10 @@
 	}
 }
 
-unsigned int user_directory_get_username_hash(const char *username)
+unsigned int user_directory_get_username_hash(struct user_directory *dir,
+					      const char *username)
 {
-	/* NOTE: If you modify this, modify also
-	   director_username_hash() in login-common/login-proxy.c */
-	unsigned char md5[MD5_RESULTLEN];
-	unsigned int i, hash = 0;
-
-	md5_get_digest(username, strlen(username), md5);
-	for (i = 0; i < sizeof(hash); i++)
-		hash = (hash << CHAR_BIT) | md5[i];
-	return hash;
+	return mail_user_hash(username, dir->username_hash_fmt);
 }
 
 bool user_directory_user_has_connections(struct user_directory *dir,
@@ -141,12 +135,14 @@
 	return expire_timestamp - MAX_CLOCK_DRIFT_SECS >= ioloop_time;
 }
 
-struct user_directory *user_directory_init(unsigned int timeout_secs)
+struct user_directory *
+user_directory_init(unsigned int timeout_secs, const char *username_hash_fmt)
 {
 	struct user_directory *dir;
 
 	dir = i_new(struct user_directory, 1);
 	dir->timeout_secs = timeout_secs;
+	dir->username_hash_fmt = i_strdup(username_hash_fmt);
 	dir->hash = hash_table_create(default_pool, default_pool,
 				      0, NULL, NULL);
 	i_array_init(&dir->iters, 8);
@@ -165,6 +161,7 @@
 		user_free(dir, dir->head);
 	hash_table_destroy(&dir->hash);
 	array_free(&dir->iters);
+	i_free(dir->username_hash_fmt);
 	i_free(dir);
 }
 
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/director/user-directory.h
--- a/src/director/user-directory.h	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/director/user-directory.h	Mon Mar 05 17:28:06 2012 +0200
@@ -42,7 +42,8 @@
 
 /* Create a new directory. Users are dropped if their time gets older
    than timeout_secs. */
-struct user_directory *user_directory_init(unsigned int timeout_secs);
+struct user_directory *
+user_directory_init(unsigned int timeout_secs, const char *username_hash_fmt);
 void user_directory_deinit(struct user_directory **dir);
 
 /* Look up username from directory. Returns NULL if not found. */
@@ -59,7 +60,8 @@
 void user_directory_remove_host(struct user_directory *dir,
 				struct mail_host *host);
 
-unsigned int user_directory_get_username_hash(const char *username);
+unsigned int user_directory_get_username_hash(struct user_directory *dir,
+					      const char *username);
 
 /* Returns TRUE if user still potentially has connections. */
 bool user_directory_user_has_connections(struct user_directory *dir,
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/lib-mail/Makefile.am
--- a/src/lib-mail/Makefile.am	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/lib-mail/Makefile.am	Mon Mar 05 17:28:06 2012 +0200
@@ -8,6 +8,7 @@
 libmail_la_SOURCES = \
 	istream-dot.c \
 	istream-header-filter.c \
+	mail-user-hash.c \
 	mbox-from.c \
 	message-address.c \
 	message-date.c \
@@ -28,6 +29,7 @@
 headers = \
 	istream-dot.h \
 	istream-header-filter.h \
+	mail-user-hash.h \
 	mbox-from.h \
 	mail-types.h \
 	message-address.h \
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/lib-mail/mail-user-hash.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-mail/mail-user-hash.c	Mon Mar 05 17:28:06 2012 +0200
@@ -0,0 +1,41 @@
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "md5.h"
+#include "str.h"
+#include "var-expand.h"
+#include "mail-user-hash.h"
+
+unsigned int mail_user_hash(const char *username, const char *format)
+{
+	static struct var_expand_table static_tab[] = {
+		{ 'u', NULL, "user" },
+		{ 'n', NULL, "username" },
+		{ 'd', NULL, "domain" },
+		{ '\0', NULL, NULL }
+	};
+	struct var_expand_table *tab;
+	unsigned char md5[MD5_RESULTLEN];
+	unsigned int i, hash = 0;
+
+	if (strcmp(format, "%u") == 0) {
+		/* fast path */
+		md5_get_digest(username, strlen(username), md5);
+	} else T_BEGIN {
+		string_t *str = t_str_new(128);
+
+		tab = t_malloc(sizeof(static_tab));
+		memcpy(tab, static_tab, sizeof(static_tab));
+		tab[0].value = username;
+		tab[1].value = t_strcut(username, '@');
+		tab[2].value = strchr(username, '@');
+		if (tab[2].value != NULL) tab[2].value++;
+
+		var_expand(str, format, tab);
+		md5_get_digest(str_data(str), str_len(str), md5);
+	} T_END;
+	for (i = 0; i < sizeof(hash); i++)
+		hash = (hash << CHAR_BIT) | md5[i];
+	return hash;
+}
+
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/lib-mail/mail-user-hash.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-mail/mail-user-hash.h	Mon Mar 05 17:28:06 2012 +0200
@@ -0,0 +1,8 @@
+#ifndef MAIL_USER_HASH
+#define MAIL_USER_HASH
+
+/* Return a hash for username, based on given format. The format can use
+   %n, %d and %u variables. */
+unsigned int mail_user_hash(const char *username, const char *format);
+
+#endif
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/login-common/Makefile.am
--- a/src/login-common/Makefile.am	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/login-common/Makefile.am	Mon Mar 05 17:28:06 2012 +0200
@@ -7,6 +7,7 @@
 	-I$(top_srcdir)/src/lib-dns \
 	-I$(top_srcdir)/src/lib-master \
 	-I$(top_srcdir)/src/lib-ssl-iostream \
+	-I$(top_srcdir)/src/lib-mail \
 	-DPKG_STATEDIR=\""$(statedir)"\"
 
 liblogin_la_SOURCES = \
diff -r 005bcb8d8d02 -r 817ef4c9f1f3 src/login-common/login-proxy.c
--- a/src/login-common/login-proxy.c	Mon Mar 05 14:27:02 2012 +0200
+++ b/src/login-common/login-proxy.c	Mon Mar 05 17:28:06 2012 +0200
@@ -5,12 +5,12 @@
 #include "istream.h"
 #include "ostream.h"
 #include "llist.h"
-#include "md5.h"
 #include "str-sanitize.h"
 #include "time-util.h"
 #include "master-service.h"
 #include "ipc-server.h"
 #include "dns-lookup.h"
+#include "mail-user-hash.h"
 #include "client-common.h"
 #include "ssl-proxy.h"
 #include "login-proxy-state.h"
@@ -617,17 +617,10 @@
 	ipc_cmd_success_reply(&cmd, t_strdup_printf("%u", count));
 }
 


More information about the dovecot-cvs mailing list