# HG changeset patch # User Timo Sirainen # Date 1278092863 -3600 # Node ID 1683324ac6321db5225a34232705129ff27d0556 # Parent eaa42f37048105821a257a801344629a7533aa7b director: Added support for LMTP proxying. diff -r eaa42f370481 -r 1683324ac632 doc/example-config/conf.d/10-director.conf --- a/doc/example-config/conf.d/10-director.conf Fri Jul 02 17:00:21 2010 +0000 +++ b/doc/example-config/conf.d/10-director.conf Fri Jul 02 18:47:43 2010 +0100 @@ -29,6 +29,9 @@ fifo_listener login/proxy-notify { #mode = 0666 } + unix_listener director-userdb { + #mode = 0600 + } inet_listener { #port = } @@ -42,3 +45,8 @@ service pop3-login { #executable = pop3-login director } + +# Enable director for LMTP proxying: +protocol lmtp { + #auth_socket_path = director-userdb +} diff -r eaa42f370481 -r 1683324ac632 src/director/login-connection.c --- a/src/director/login-connection.c Fri Jul 02 17:00:21 2010 +0000 +++ b/src/director/login-connection.c Fri Jul 02 18:47:43 2010 +0100 @@ -25,6 +25,7 @@ struct director *dir; unsigned int destroyed:1; + unsigned int userdb:1; }; struct login_host_request { @@ -100,7 +101,7 @@ { struct login_connection *conn = context; struct login_host_request *request; - const char *const *args, *username = NULL; + const char *const *args, *line_params, *username = NULL; bool proxy = FALSE, host = FALSE; if (line == NULL) { @@ -108,13 +109,17 @@ login_connection_deinit(&conn); return; } - if (strncmp(line, "OK\t", 3) != 0) { + if (!conn->userdb && strncmp(line, "OK\t", 3) == 0) + line_params = line + 3; + else if (conn->userdb && strncmp(line, "PASS\t", 5) == 0) + line_params = line + 5; + else { login_connection_send_line(conn, line); return; } /* OK [] */ - args = t_strsplit(line + 3, "\t"); + args = t_strsplit(line_params, "\t"); if (*args != NULL) { /* we should always get here, but in case we don't just forward as-is and let login process handle the error. */ @@ -157,7 +162,7 @@ struct login_connection * login_connection_init(struct director *dir, int fd, - struct auth_connection *auth) + struct auth_connection *auth, bool userdb) { struct login_connection *conn; @@ -168,6 +173,7 @@ conn->dir = dir; conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); conn->io = io_add(conn->fd, IO_READ, login_connection_input, conn); + conn->userdb = userdb; auth_connection_set_callback(conn->auth, auth_input_line, conn); DLLIST_PREPEND(&login_connections, conn); diff -r eaa42f370481 -r 1683324ac632 src/director/login-connection.h --- a/src/director/login-connection.h Fri Jul 02 17:00:21 2010 +0000 +++ b/src/director/login-connection.h Fri Jul 02 18:47:43 2010 +0100 @@ -5,7 +5,7 @@ struct login_connection * login_connection_init(struct director *dir, int fd, - struct auth_connection *auth); + struct auth_connection *auth, bool userdb); void login_connection_deinit(struct login_connection **conn); void login_connections_deinit(void); diff -r eaa42f370481 -r 1683324ac632 src/director/main.c --- a/src/director/main.c Fri Jul 02 17:00:21 2010 +0000 +++ b/src/director/main.c Fri Jul 02 18:47:43 2010 +0100 @@ -21,10 +21,11 @@ #include #define AUTH_SOCKET_PATH "auth-login" +#define AUTH_USERDB_SOCKET_PATH "auth-userdb" static struct director *director; static struct notify_connection *notify_conn; -static char *auth_socket_path; +static char *auth_socket_path, *userdb_socket_path; static int director_client_connected(int fd, const struct ip_addr *ip) { @@ -41,9 +42,10 @@ static void client_connected(struct master_service_connection *conn) { struct auth_connection *auth; - const char *path, *name; + const char *path, *name, *socket_path; struct ip_addr ip; unsigned int port, len; + bool userdb; if (conn->fifo) { if (notify_conn != NULL) { @@ -77,15 +79,21 @@ /* doveadm connection */ master_service_client_connection_accept(conn); (void)doveadm_connection_init(director, conn->fd); + return; + } + + /* a) userdb connection, probably for lmtp proxy + b) login connection + Both of them are handled exactly the same, except for which + auth socket they connect to. */ + userdb = len > 7 && strcmp(name + len - 7, "-userdb") == 0; + socket_path = userdb ? userdb_socket_path : auth_socket_path; + auth = auth_connection_init(socket_path); + if (auth_connection_connect(auth) == 0) { + master_service_client_connection_accept(conn); + login_connection_init(director, conn->fd, auth, userdb); } else { - /* login connection */ - auth = auth_connection_init(auth_socket_path); - if (auth_connection_connect(auth) == 0) { - master_service_client_connection_accept(conn); - login_connection_init(director, conn->fd, auth); - } else { - auth_connection_deinit(&auth); - } + auth_connection_deinit(&auth); } } @@ -133,6 +141,8 @@ auth_socket_path = i_strconcat(set->base_dir, "/"AUTH_SOCKET_PATH, NULL); + userdb_socket_path = i_strconcat(set->base_dir, + "/"AUTH_USERDB_SOCKET_PATH, NULL); listen_port = find_inet_listener_port(&listen_ip); if (listen_port == 0 && *set->director_servers != '\0') { @@ -158,6 +168,7 @@ login_connections_deinit(); auth_connections_deinit(); i_free(auth_socket_path); + i_free(userdb_socket_path); } int main(int argc, char *argv[])