]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Added support for LMTP proxying.
authorTimo Sirainen <tss@iki.fi>
Fri, 2 Jul 2010 17:47:43 +0000 (18:47 +0100)
committerTimo Sirainen <tss@iki.fi>
Fri, 2 Jul 2010 17:47:43 +0000 (18:47 +0100)
--HG--
branch : HEAD

doc/example-config/conf.d/10-director.conf
src/director/login-connection.c
src/director/login-connection.h
src/director/main.c

index dceaa46a64d94275d8331398478de676bccffff5..cd750a556a33f8d187d7568670794c8f2c64e939 100644 (file)
@@ -29,6 +29,9 @@ service director {
   fifo_listener login/proxy-notify {
     #mode = 0666
   }
+  unix_listener director-userdb {
+    #mode = 0600
+  }
   inet_listener {
     #port = 
   }
@@ -42,3 +45,8 @@ service imap-login {
 service pop3-login {
   #executable = pop3-login director
 }
+
+# Enable director for LMTP proxying:
+protocol lmtp {
+  #auth_socket_path = director-userdb
+}
index fb5507f1bafd875ae293352e8822b99de827d2d0..644169245028a92aff2ae9b03f0cf0723d9beed9 100644 (file)
@@ -25,6 +25,7 @@ struct login_connection {
        struct director *dir;
 
        unsigned int destroyed:1;
+       unsigned int userdb:1;
 };
 
 struct login_host_request {
@@ -100,7 +101,7 @@ static void auth_input_line(const char *line, void *context)
 {
        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 @@ static void auth_input_line(const char *line, void *context)
                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 <id> [<parameters>] */
-       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 @@ static void auth_input_line(const char *line, void *context)
 
 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 @@ login_connection_init(struct director *dir, int fd,
        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);
index dbd9bef9cde902874231ba8e13ccf5c17b43f63f..b7936e2c00f9f596cc0cd76907d591e0b850d4bc 100644 (file)
@@ -5,7 +5,7 @@ struct director;
 
 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);
index d0c108464ca670fc8b920316c8fb0cd89fae6bfa..aa43fed2a8aaa99a2c948a052ff5e2d836656f1c 100644 (file)
 #include <unistd.h>
 
 #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 int director_client_connected(int fd, const struct ip_addr *ip)
 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 @@ static void client_connected(struct master_service_connection *conn)
                /* 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 @@ static void main_init(void)
 
        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 @@ static void main_deinit(void)
        login_connections_deinit();
        auth_connections_deinit();
        i_free(auth_socket_path);
+       i_free(userdb_socket_path);
 }
 
 int main(int argc, char *argv[])