diff src/director/director-connection.c @ 13045:79f9dce5d5fd

director: Added support for moving user to another server with "doveadm director move".
author Timo Sirainen <tss@iki.fi>
date Mon, 23 May 2011 14:54:02 +0300
parents e9139f74c451
children 66e3cc789efb
line wrap: on
line diff
--- a/src/director/director-connection.c	Fri May 20 21:46:32 2011 +0300
+++ b/src/director/director-connection.c	Mon May 23 14:54:02 2011 +0300
@@ -348,8 +348,8 @@
 	    net_addr2ip(args[0], &ip) < 0 ||
 	    str_to_uint(args[1], &port) < 0 ||
 	    str_to_uint(args[2], &seq) < 0) {
-		i_error("director(%s): Command is missing parameters",
-			conn->name);
+		i_error("director(%s): Command is missing parameters: %s",
+			conn->name, t_strarray_join(args, " "));
 		return -1;
 	}
 	*_args = args + 3;
@@ -475,6 +475,74 @@
 	return TRUE;
 }
 
+static bool
+director_cmd_user_move(struct director_connection *conn,
+		       const char *const *args)
+{
+	struct director_host *dir_host;
+	struct mail_host *host;
+	struct ip_addr ip;
+	unsigned int username_hash;
+	int ret;
+
+	if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0)
+		return ret > 0;
+
+	if (str_array_length(args) != 2 ||
+	    str_to_uint(args[0], &username_hash) < 0 ||
+	    net_addr2ip(args[1], &ip) < 0) {
+		i_error("director(%s): Invalid USER-MOVE args", conn->name);
+		return FALSE;
+	}
+
+	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
+	if (host != NULL) {
+		director_move_user(conn->dir, conn->host, dir_host,
+				   username_hash, host);
+	}
+	return TRUE;
+}
+
+static bool
+director_cmd_user_killed(struct director_connection *conn,
+			 const char *const *args)
+{
+	struct director_host *dir_host;
+	unsigned int username_hash;
+
+	if (str_array_length(args) != 1 ||
+	    str_to_uint(args[0], &username_hash) < 0) {
+		i_error("director(%s): Invalid USER-KILLED args", conn->name);
+		return FALSE;
+	}
+
+	director_user_killed(conn->dir, username_hash);
+	return TRUE;
+}
+
+static bool
+director_cmd_user_killed_everywhere(struct director_connection *conn,
+				    const char *const *args)
+{
+	struct director_host *dir_host;
+	unsigned int username_hash;
+	int ret;
+
+	if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0)
+		return ret > 0;
+
+	if (str_array_length(args) != 1 ||
+	    str_to_uint(args[0], &username_hash) < 0) {
+		i_error("director(%s): Invalid USER-KILLED-EVERYWHERE args",
+			conn->name);
+		return FALSE;
+	}
+
+	director_user_killed_everywhere(conn->dir, conn->host,
+					dir_host, username_hash);
+	return TRUE;
+}
+
 static void director_handshake_cmd_done(struct director_connection *conn)
 {
 	struct director *dir = conn->dir;
@@ -766,6 +834,12 @@
 		return director_cmd_host_remove(conn, args);
 	if (strcmp(cmd, "HOST-FLUSH") == 0)
 		return director_cmd_host_flush(conn, args);
+	if (strcmp(cmd, "USER-MOVE") == 0)
+		return director_cmd_user_move(conn, args);
+	if (strcmp(cmd, "USER-KILLED") == 0)
+		return director_cmd_user_killed(conn, args);
+	if (strcmp(cmd, "USER-KILLED-EVERYWHERE") == 0)
+		return director_cmd_user_killed_everywhere(conn, args);
 	if (strcmp(cmd, "DIRECTOR") == 0)
 		return director_cmd_director(conn, args);
 	if (strcmp(cmd, "SYNC") == 0)