]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added %l, %r and %P variables and mail_log_prefix setting.
authorTimo Sirainen <tss@iki.fi>
Mon, 31 May 2004 18:04:46 +0000 (21:04 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 31 May 2004 18:04:46 +0000 (21:04 +0300)
--HG--
branch : HEAD

23 files changed:
doc/Makefile.am
doc/variables.txt [new file with mode: 0644]
dovecot-example.conf
src/auth/auth-client-interface.h
src/auth/mech.c
src/auth/mech.h
src/imap-login/client-authenticate.c
src/imap-login/client.c
src/imap-login/client.h
src/lib-auth/auth-client.h
src/lib-auth/auth-server-request.c
src/login-common/client-common.h
src/login-common/main.c
src/login-common/master.c
src/master/login-process.c
src/master/mail-process.c
src/master/mail-process.h
src/master/master-login-interface.h
src/master/master-settings.c
src/master/master-settings.h
src/pop3-login/client-authenticate.c
src/pop3-login/client.c
src/pop3-login/client.h

index 6a8e99d4acc2e95ba3fc2ba54cbff37edcffb54d..d14cbb163ee8f43bc8863e2d1197144922bc2a83 100644 (file)
@@ -8,7 +8,8 @@ doc_DATA = \
        mail-storages.txt \
        multiaccess.txt \
        nfs.txt \
-       securecoding.txt
+       securecoding.txt \
+       variables.txt
 
 EXTRA_DIST = \
        mkcert.sh \
diff --git a/doc/variables.txt b/doc/variables.txt
new file mode 100644 (file)
index 0000000..105e488
--- /dev/null
@@ -0,0 +1,27 @@
+You can use special variables in several places:
+ - default_mail_env setting
+ - namespace locations
+ - static userdb template string
+ - LDAP and SQL userdb query strings
+ - log prefix for imap/pop3 process
+
+The variables are:
+
+ %u - username
+ %n - user part in user@domain, same as %u if there's no domain
+ %d - domain part in user@domain, empty if user there's no domain
+ %h - home directory
+ %p - protocol (IMAP or POP3)
+ %P - PID of the current process (login or imap/pop3 process)
+ %l - local IP address
+ %r - remote IP address
+
+You can apply a modifiers for each variable (eg. %Lp = pop3):
+
+ %L - lowercase
+ %U - uppercase
+ %E - escape '"', "'" and '\' characters by inserting '\' before them.
+
+You can also limit a width of string by giving the number of max. characters
+after the '%' character. For example %1u gives the first character of
+username.
index f1e7921ad08540d4f03bbbf0f0aff910a001e9bb..466b263c559485b744eb8d907972aa9ebae9fe5d 100644 (file)
 
 # Default MAIL environment to use when it's not set. By leaving this empty
 # dovecot tries to do some automatic detection as described in
-# doc/mail-storages.txt. There's a few special variables you can use:
+# doc/mail-storages.txt. There's a few special variables you can use, eg.:
 #
 #   %u - username
 #   %n - user part in user@domain, same as %u if there's no domain
 #   %d - domain part in user@domain, empty if user there's no domain
 #   %h - home directory
-#   %p - protocol (IMAP or POP3)
 #
-# You can apply a modifiers for each variable (eg. %Lp = pop3):
-#   %L - lowercase
-#   %U - uppercase
-#   %E - escape '"', "'" and '\' characters by inserting '\' before them.
-#
-# You can also limit a width of string by giving the number of max. characters
-# after the '%' character. For example %1u gives the first character of
-# username. Some examples:
+# See doc/variables.txt for full list. Some examples:
 #
 #   default_mail_env = maildir:/var/mail/%1u/%u/Maildir
 #   default_mail_env = mbox:~/mail/:INBOX=/var/mail/%u
 # files, so it shouldn't harm much even if this limit is set pretty high.
 #mail_process_size = 256
 
+# Log prefix for mail processes. See doc/variables.txt for list of possible
+# variables you can use.
+#mail_log_prefix = "%Up(%u): "
+
 ##
 ## IMAP specific settings
 ##
index ac5a9f7cff30030ab4ba00fe707746bc7a3a4fa5..bd074d639cb66451952d79a5ebec68b7de70cf08 100644 (file)
@@ -50,6 +50,8 @@ struct auth_client_request_new {
 
        enum auth_client_request_new_flags flags;
 
+       uint32_t ip_family; /* if non-zero, data begins with local/remote IPs */
+
        uint32_t protocol_idx;
        uint32_t mech_idx;
        uint32_t initial_resp_idx;
index a29713ad4f5c57fbaa98079294fa999fe226d1cd..ca408b0cdb942801a832ee222bac687a966f5640 100644 (file)
@@ -77,9 +77,17 @@ void mech_request_new(struct auth_client_connection *conn,
 {
         struct mech_module *mech;
        struct auth_request *auth_request;
+       size_t ip_size = 1;
+
+       if (request->ip_family == AF_INET)
+               ip_size = 4;
+       else if (request->ip_family != 0)
+               ip_size = sizeof(auth_request->local_ip.ip);
+       else
+               ip_size = 0;
 
        /* make sure data is NUL-terminated */
-       if (request->data_size == 0 || request->initial_resp_idx == 0 ||
+       if (request->data_size <= ip_size*2 || request->initial_resp_idx == 0 ||
            request->mech_idx >= request->data_size ||
            request->protocol_idx >= request->data_size ||
            request->initial_resp_idx > request->data_size ||
@@ -127,6 +135,16 @@ void mech_request_new(struct auth_client_connection *conn,
                        p_strdup(auth_request->pool,
                                 (const char *)data + request->protocol_idx);
 
+               if (request->ip_family != 0) {
+                       auth_request->local_ip.family = request->ip_family;
+                       auth_request->remote_ip.family = request->ip_family;
+                               
+
+                       memcpy(&auth_request->local_ip, data, ip_size);
+                       memcpy(&auth_request->remote_ip, data + ip_size,
+                              ip_size);
+               }
+
                hash_insert(conn->auth_requests, POINTER_CAST(request->id),
                            auth_request);
 
@@ -265,6 +283,10 @@ auth_request_get_var_expand_table(const struct auth_request *auth_request,
                { 'n', NULL },
                { 'd', NULL },
                { 'p', NULL },
+               { 'h', NULL },
+               { 'l', NULL },
+               { 'r', NULL },
+               { 'P', NULL },
                { '\0', NULL }
        };
        struct var_expand_table *tab;
@@ -281,6 +303,12 @@ auth_request_get_var_expand_table(const struct auth_request *auth_request,
        if (tab[2].value != NULL)
                tab[2].value = escape_func(tab[2].value+1);
        tab[3].value = auth_request->protocol;
+       /* tab[4] = we have no home dir */
+       if (auth_request->local_ip.family != 0)
+               tab[5].value = net_ip2addr(&auth_request->local_ip);
+       if (auth_request->remote_ip.family != 0)
+               tab[6].value = net_ip2addr(&auth_request->remote_ip);
+       tab[7].value = dec2str(auth_request->conn->pid);
        return tab;
 }
 
index 981c933c20cf64f70e1a0704627e9980c5052c41..451ceb004c3b828f58aa69537c9d47d93f79f388 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __MECH_H
 #define __MECH_H
 
+#include "network.h"
 #include "auth-client-interface.h"
 
 struct auth_client_connection;
@@ -20,6 +21,7 @@ struct auth_request {
        time_t created;
 
        char *protocol;
+       struct ip_addr local_ip, remote_ip;
        mech_callback_t *callback;
 
        int (*auth_initial)(struct auth_request *auth_request,
index d1c3a8d3f6ea6ede95828ba7ddc79e542f562c69..9bdf789c04282bafaa79e0fcb92ae7708f2491e9 100644 (file)
@@ -107,8 +107,6 @@ static void login_callback(struct auth_request *request,
 {
        struct imap_client *client = context;
        const char *error;
-       const void *ptr;
-       size_t size;
 
        switch (auth_callback(request, reply, data, &client->common,
                              master_callback, &error)) {
@@ -141,7 +139,8 @@ client_get_auth_flags(struct imap_client *client)
 int cmd_login(struct imap_client *client, struct imap_arg *args)
 {
        const char *user, *pass, *error;
-       string_t *str;
+       struct auth_request_info info;
+       string_t *plain_login;
 
        /* two arguments: username and password */
        if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
@@ -165,20 +164,26 @@ int cmd_login(struct imap_client *client, struct imap_arg *args)
        }
 
        /* authorization ID \0 authentication ID \0 pass */
-       str = t_str_new(64);
-       str_append_c(str, '\0');
-       str_append(str, user);
-       str_append_c(str, '\0');
-       str_append(str, pass);
+       plain_login = t_str_new(64);
+       str_append_c(plain_login, '\0');
+       str_append(plain_login, user);
+       str_append_c(plain_login, '\0');
+       str_append(plain_login, pass);
+
+       memset(&info, 0, sizeof(info));
+       info.mech = "PLAIN";
+       info.protocol = "IMAP";
+       info.flags = client_get_auth_flags(client);
+       info.local_ip = client->common.local_ip;
+       info.remote_ip = client->common.ip;
+       info.initial_resp_data = str_data(plain_login);
+       info.initial_resp_size = str_len(plain_login);
 
        client_ref(client);
 
        client->common.auth_request =
-               auth_client_request_new(auth_client, "PLAIN", "IMAP",
-                                       client_get_auth_flags(client),
-                                       str_data(str), str_len(str),
-                                       login_callback,
-                                       client, &error);
+               auth_client_request_new(auth_client, &info,
+                                       login_callback, client, &error);
        if (client->common.auth_request == NULL) {
                client_send_tagline(client, t_strconcat(
                        "NO Login failed: ", error, NULL));
@@ -278,6 +283,7 @@ int cmd_authenticate(struct imap_client *client, struct imap_arg *args)
 {
        const struct auth_mech_desc *mech;
        const char *mech_name, *error;
+       struct auth_request_info info;
 
        /* we want only one argument: authentication mechanism name */
        if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
@@ -302,12 +308,17 @@ int cmd_authenticate(struct imap_client *client, struct imap_arg *args)
                return TRUE;
        }
 
+       memset(&info, 0, sizeof(info));
+       info.mech = mech->name;
+       info.protocol = "IMAP";
+       info.flags = client_get_auth_flags(client);
+       info.local_ip = client->common.local_ip;
+       info.remote_ip = client->common.ip;
+
        client_ref(client);
        client->common.auth_request =
-               auth_client_request_new(auth_client, mech->name, "IMAP",
-                                       client_get_auth_flags(client),
-                                       NULL, 0, authenticate_callback,
-                                       client, &error);
+               auth_client_request_new(auth_client, &info,
+                                       authenticate_callback, client, &error);
        if (client->common.auth_request != NULL) {
                /* following input data will go to authentication */
                if (client->common.io != NULL)
index 4ba1f667dd1a098ea9c8871448704f34ddbc7540..7b694c051874c2e65f8f008ef220db02117521a0 100644 (file)
@@ -348,7 +348,8 @@ static void client_destroy_oldest(void)
        }
 }
 
-struct client *client_create(int fd, struct ip_addr *ip, int ssl)
+struct client *client_create(int fd, int ssl, const struct ip_addr *local_ip,
+                            const struct ip_addr *ip)
 {
        struct imap_client *client;
        const char *addr;
@@ -373,6 +374,7 @@ struct client *client_create(int fd, struct ip_addr *ip, int ssl)
                (IPADDR_IS_V4(ip) && strncmp(addr, "127.", 4) == 0) ||
                (IPADDR_IS_V6(ip) && strcmp(addr, "::1") == 0);
 
+       client->common.local_ip = *local_ip;
        client->common.ip = *ip;
        client->common.fd = fd;
 
index 74148633cbd1e2873731a0e5a2e4e87e4a5565a5..149026f78d5f395b9c92970f5a385c9cb0b5de79 100644 (file)
@@ -29,7 +29,6 @@ struct imap_client {
        unsigned int destroyed:1;
 };
 
-struct client *client_create(int fd, struct ip_addr *ip, int ssl);
 void client_destroy(struct imap_client *client, const char *reason);
 
 void client_send_line(struct imap_client *client, const char *line);
index d75e2caef9c089e36e37b56f876eec235d1a5c79..7b359f2a63423802f3228fe47a1603a954ec4a8e 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __AUTH_CLIENT_H
 #define __AUTH_CLIENT_H
 
+#include "network.h"
 #include "../auth/auth-client-interface.h"
 
 struct auth_client;
@@ -12,6 +13,17 @@ struct auth_mech_desc {
        unsigned int advertise:1;
 };
 
+struct auth_request_info {
+       const char *mech;
+       const char *protocol;
+       enum auth_client_request_new_flags flags;
+
+       struct ip_addr local_ip, remote_ip;
+
+       const unsigned char *initial_resp_data;
+       size_t initial_resp_size;
+};
+
 /* reply is NULL if auth connection died */
 typedef void auth_request_callback_t(struct auth_request *request,
                                     struct auth_client_request_reply *reply,
@@ -38,10 +50,7 @@ auth_client_find_mech(struct auth_client *client, const char *name);
    happens for the request. */
 struct auth_request *
 auth_client_request_new(struct auth_client *client,
-                       const char *mech, const char *protocol,
-                       enum auth_client_request_new_flags flags,
-                       const unsigned char *initial_resp_data,
-                       size_t initial_resp_size,
+                       const struct auth_request_info *request_info,
                        auth_request_callback_t *callback, void *context,
                        const char **error_r);
 
index 86d404bc7388d437bda574a6cc45bc2f42ee0634..20dad41598d17bb5899baef890f70e9a8d9802b3 100644 (file)
 struct auth_request {
         struct auth_server_connection *conn;
 
+       unsigned int id;
+
        char *mech, *protocol;
        enum auth_client_request_new_flags flags;
-
-       unsigned int id;
+       struct ip_addr local_ip, remote_ip;
 
        unsigned char *initial_resp_data;
        size_t initial_resp_size;
@@ -73,6 +74,7 @@ static int auth_server_send_new_request(struct auth_server_connection *conn,
 {
        struct auth_client_request_new auth_request;
        buffer_t *buf;
+       size_t size;
        int ret;
 
        memset(&auth_request, 0, sizeof(auth_request));
@@ -80,10 +82,20 @@ static int auth_server_send_new_request(struct auth_server_connection *conn,
        auth_request.id = request->id;
        auth_request.flags = request->flags;
 
+       if (request->local_ip.family == request->remote_ip.family)
+               auth_request.ip_family = request->local_ip.family;
+
        t_push();
        buf = buffer_create_dynamic(pool_datastack_create(), 256, (size_t)-1);
        buffer_set_used_size(buf, sizeof(auth_request));
 
+       if (auth_request.ip_family != 0) {
+               size = IPADDR_IS_V4(&request->local_ip) ? 4 :
+                       sizeof(request->local_ip.ip);
+               buffer_append(buf, &request->local_ip.ip, size);
+               buffer_append(buf, &request->remote_ip.ip, size);
+       }
+
        auth_request.mech_idx =
                buffer_get_used_size(buf) - sizeof(auth_request);
        buffer_append(buf, request->mech, strlen(request->mech)+1);
@@ -236,32 +248,34 @@ void auth_server_requests_remove_all(struct auth_server_connection *conn)
 
 struct auth_request *
 auth_client_request_new(struct auth_client *client,
-                       const char *mech, const char *protocol,
-                       enum auth_client_request_new_flags flags,
-                       const unsigned char *initial_resp_data,
-                       size_t initial_resp_size,
+                       const struct auth_request_info *request_info,
                        auth_request_callback_t *callback, void *context,
                        const char **error_r)
 {
        struct auth_server_connection *conn;
        struct auth_request *request;
 
-       conn = auth_server_connection_find_mech(client, mech, error_r);
+       conn = auth_server_connection_find_mech(client, request_info->mech,
+                                               error_r);
        if (conn == NULL)
                return NULL;
 
        request = i_new(struct auth_request, 1);
        request->conn = conn;
-       request->mech = i_strdup(mech);
-       request->protocol = i_strdup(protocol);
-       request->flags = flags;
+       request->mech = i_strdup(request_info->mech);
+       request->protocol = i_strdup(request_info->protocol);
+       request->flags = request_info->flags;
+       request->local_ip = request_info->local_ip;
+       request->remote_ip = request_info->remote_ip;
        request->id = ++client->request_id_counter;
 
-       if (initial_resp_size != 0) {
-               request->initial_resp_size = initial_resp_size;
-               request->initial_resp_data = i_malloc(initial_resp_size);
-               memcpy(request->initial_resp_data, initial_resp_data,
-                      initial_resp_size);
+       if (request_info->initial_resp_size != 0) {
+               request->initial_resp_size = request_info->initial_resp_size;
+               request->initial_resp_data =
+                       i_malloc(request_info->initial_resp_size);
+               memcpy(request->initial_resp_data,
+                      request_info->initial_resp_data,
+                      request_info->initial_resp_size);
        }
        
        if (request->id == 0) {
index 97b738c0fa765112ae8dce33938008cb4926d30b..e981aff74e910846ace8a697630bbbbf694e03b5 100644 (file)
@@ -5,6 +5,7 @@
 #include "master.h"
 
 struct client {
+       struct ip_addr local_ip;
        struct ip_addr ip;
        struct ssl_proxy *proxy;
 
@@ -19,7 +20,8 @@ struct client {
        /* ... */
 };
 
-struct client *client_create(int fd, struct ip_addr *ip, int ssl);
+struct client *client_create(int fd, int ssl, const struct ip_addr *local_ip,
+                            const struct ip_addr *ip);
 
 unsigned int clients_get_count(void);
 void clients_notify_auth_connected(void);
index 7375d5a34d28013e2931ef92e6eddea95d2a0355..7ef35b0a78dbe002ef52d3672d90793a891e5471 100644 (file)
@@ -76,7 +76,7 @@ static void sig_quit(int signo __attr_unused__)
 
 static void login_accept(void *context __attr_unused__)
 {
-       struct ip_addr ip;
+       struct ip_addr ip, local_ip;
        int fd;
 
        fd = net_accept(LOGIN_LISTEN_FD, &ip, NULL);
@@ -89,12 +89,15 @@ static void login_accept(void *context __attr_unused__)
        if (process_per_connection)
                main_close_listen();
 
-       (void)client_create(fd, &ip, FALSE);
+       if (net_getsockname(fd, &local_ip, NULL) < 0)
+               memset(&local_ip, 0, sizeof(local_ip));
+
+       (void)client_create(fd, FALSE, &local_ip, &ip);
 }
 
 static void login_accept_ssl(void *context __attr_unused__)
 {
-       struct ip_addr ip;
+       struct ip_addr ip, local_ip;
        struct client *client;
        struct ssl_proxy *proxy;
        int fd, fd_ssl;
@@ -108,12 +111,14 @@ static void login_accept_ssl(void *context __attr_unused__)
 
        if (process_per_connection)
                main_close_listen();
+       if (net_getsockname(fd, &local_ip, NULL) < 0)
+               memset(&local_ip, 0, sizeof(local_ip));
 
        fd_ssl = ssl_proxy_new(fd, &ip, &proxy);
        if (fd_ssl == -1)
                net_disconnect(fd);
        else {
-               client = client_create(fd_ssl, &ip, TRUE);
+               client = client_create(fd_ssl, TRUE, &local_ip, &ip);
                client->proxy = proxy;
        }
 }
@@ -216,7 +221,7 @@ static void main_deinit(void)
 int main(int argc __attr_unused__, char *argv[], char *envp[])
 {
        const char *name, *group_name;
-       struct ip_addr ip;
+       struct ip_addr ip, local_ip;
        struct ssl_proxy *proxy = NULL;
        struct client *client;
        int i, fd = -1, master_fd = -1;
@@ -256,10 +261,12 @@ int main(int argc __attr_unused__, char *argv[], char *envp[])
        main_init();
 
        if (is_inetd) {
-               if (net_getsockname(1, &ip, NULL) < 0) {
+               if (net_getpeername(1, &ip, NULL) < 0) {
                        i_fatal("%s can be started only through dovecot "
                                "master process, inetd or equilevant", argv[0]);
                }
+               if (net_getsockname(1, &local_ip, NULL) < 0)
+                       memset(&local_ip, 0, sizeof(local_ip));
 
                fd = 1;
                for (i = 1; i < argc; i++) {
@@ -273,11 +280,11 @@ int main(int argc __attr_unused__, char *argv[], char *envp[])
 
                master_init(master_fd, FALSE);
                closing_down = TRUE;
-       }
 
-       if (fd != -1) {
-               client = client_create(fd, &ip, TRUE);
-               client->proxy = proxy;
+               if (fd != -1) {
+                       client = client_create(fd, TRUE, &local_ip, &ip);
+                       client->proxy = proxy;
+               }
        }
 
        io_loop_run(ioloop);
index 99d50fb1affbaad04b0a11209eded420ed9740eb..9f68449d6aac47d77607c5ebe7110ce0059ce46e 100644 (file)
@@ -49,7 +49,8 @@ void master_request_login(struct client *client, master_callback_t *callback,
                req.tag = ++master_tag_counter;
        req.auth_pid = auth_pid;
        req.auth_id = auth_id;
-       req.ip = client->ip;
+       req.local_ip = client->local_ip;
+       req.remote_ip = client->ip;
 
        if (fd_send(master_fd, client->fd, &req, sizeof(req)) != sizeof(req))
                i_fatal("fd_send(%d) failed: %m", client->fd);
index d89744e860cc8fc36e551ff40eef13f407794e81..f3a48bb35505936aee34a699e4edd77ead89dbbd 100644 (file)
@@ -39,7 +39,7 @@ struct login_auth_request {
        unsigned int login_tag;
        int fd;
 
-       struct ip_addr ip;
+       struct ip_addr local_ip, remote_ip;
 };
 
 static unsigned int auth_id_counter, login_pid_counter;
@@ -82,9 +82,13 @@ void auth_master_callback(struct auth_master_reply *reply,
        else {
                struct login_group *group = request->process->group;
 
+               t_push();
                master_reply.success =
-                       create_mail_process(group, request->fd, &request->ip,
+                       create_mail_process(group, request->fd,
+                                           &request->local_ip,
+                                           &request->remote_ip,
                                            reply, (const char *) data);
+               t_pop();
        }
 
        /* reply to login */
@@ -268,7 +272,8 @@ static void login_process_input(void *context)
        authreq->tag = ++auth_id_counter;
        authreq->login_tag = req.tag;
        authreq->fd = client_fd;
-       authreq->ip = req.ip;
+       authreq->local_ip = req.local_ip;
+       authreq->remote_ip = req.remote_ip;
 
        auth_process = auth_process_find(req.auth_pid);
        if (auth_process == NULL) {
index a2937a073b1d2e001539bf690f0466ca4df444f7..4b2b6a6a058d82cd79bb728265a6d70015cd0a7f 100644 (file)
@@ -75,8 +75,10 @@ static int validate_chroot(struct settings *set, const char *dir)
 }
 
 static const struct var_expand_table *
-get_var_expand_table(const char *user, const char *home,
-                    enum process_type process_type)
+get_var_expand_table(enum process_type process_type,
+                    const char *user, const char *home,
+                    const struct ip_addr *local_ip,
+                    const struct ip_addr *remote_ip, pid_t pid)
 {
        static struct var_expand_table static_tab[] = {
                { 'u', NULL },
@@ -84,6 +86,9 @@ get_var_expand_table(const char *user, const char *home,
                { 'd', NULL },
                { 'p', NULL },
                { 'h', NULL },
+               { 'l', NULL },
+               { 'r', NULL },
+               { 'P', NULL },
                { '\0', NULL }
        };
        struct var_expand_table *tab;
@@ -97,6 +102,9 @@ get_var_expand_table(const char *user, const char *home,
        if (tab[2].value != NULL) tab[2].value++;
        tab[3].value = t_str_ucase(process_names[process_type]);
        tab[4].value = home;
+       tab[5].value = net_ip2addr(local_ip);
+       tab[6].value = net_ip2addr(remote_ip);
+       tab[7].value = dec2str(pid);
 
        return tab;
 }
@@ -173,16 +181,18 @@ env_put_namespace(struct namespace_settings *ns, const char *default_location,
 }
 
 int create_mail_process(struct login_group *group, int socket,
-                       struct ip_addr *ip,
+                       const struct ip_addr *local_ip,
+                       const struct ip_addr *remote_ip,
                        struct auth_master_reply *reply, const char *data)
 {
        struct settings *set = group->set;
        const struct var_expand_table *var_expand_table;
        const char *argv[4];
        const char *addr, *mail, *user, *chroot_dir, *home_dir, *full_home_dir;
-       const char *executable, *p, *prefix;
+       const char *executable, *p;
        struct log_io *log;
        char title[1024];
+       string_t *str;
        pid_t pid;
        int i, err, ret, log_fd;
 
@@ -196,6 +206,8 @@ int create_mail_process(struct login_group *group, int socket,
                              data + reply->virtual_user_idx))
                return FALSE;
 
+       user = data + reply->virtual_user_idx;
+       mail = data + reply->mail_idx;
        home_dir = data + reply->home_idx;
        chroot_dir = data + reply->chroot_idx;
 
@@ -217,12 +229,16 @@ int create_mail_process(struct login_group *group, int socket,
                return FALSE;
        }
 
+       var_expand_table =
+               get_var_expand_table(group->process_type, user, home_dir,
+                                    local_ip, remote_ip,
+                                    pid != 0 ? pid : getpid());
+       str = t_str_new(128);
+
        if (pid != 0) {
                /* master */
-               prefix = t_strdup_printf("%s(%s): ",
-                                        process_names[group->process_type],
-                                        data + reply->virtual_user_idx);
-               log_set_prefix(log, prefix);
+               var_expand(str, set->mail_log_prefix, var_expand_table);
+               log_set_prefix(log, str_c(str));
 
                mail_process_count++;
                PID_ADD_PROCESS_TYPE(pid, group->process_type);
@@ -230,10 +246,9 @@ int create_mail_process(struct login_group *group, int socket,
                return TRUE;
        }
 
-       prefix = t_strdup_printf("master-%s(%s): ",
-                                process_names[group->process_type],
-                                data + reply->virtual_user_idx);
-       log_set_prefix(log, prefix);
+       str_append(str, "master-");
+       var_expand(str, set->mail_log_prefix, var_expand_table);
+       log_set_prefix(log, str_c(str));
 
        child_process_init_env();
 
@@ -345,12 +360,6 @@ int create_mail_process(struct login_group *group, int socket,
        /* user given environment - may be malicious. virtual_user comes from
           auth process, but don't trust that too much either. Some auth
           mechanism might allow leaving extra data there. */
-       mail = data + reply->mail_idx;
-       user = data + reply->virtual_user_idx;
-
-       var_expand_table =
-               get_var_expand_table(user, home_dir, group->process_type);
-
        if (*mail == '\0' && set->default_mail_env != NULL)
                mail = expand_mail_env(set->default_mail_env, var_expand_table);
 
@@ -362,7 +371,7 @@ int create_mail_process(struct login_group *group, int socket,
        env_put(t_strconcat("MAIL=", mail, NULL));
        env_put(t_strconcat("USER=", data + reply->virtual_user_idx, NULL));
 
-       addr = net_ip2addr(ip);
+       addr = net_ip2addr(remote_ip);
        env_put(t_strconcat("IP=", addr, NULL));
 
        if (!set->verbose_proctitle)
index 9d22b4a646ef26acbba9708c3631faeab60831d4..3f6a61b94f803ef37d1202c2d79e448dc182cac5 100644 (file)
@@ -5,7 +5,8 @@ struct login_group;
 struct auth_master_reply;
 
 int create_mail_process(struct login_group *group, int socket,
-                       struct ip_addr *ip,
+                       const struct ip_addr *local_ip,
+                       const struct ip_addr *remote_ip,
                        struct auth_master_reply *reply, const char *data);
 
 void mail_process_destroyed(pid_t pid);
index 552d3248930e53d8ab71c7b3835591c68e83e30a..b8197183546e5ef6e5c5c3c6038f4a0f40326136 100644 (file)
@@ -13,7 +13,7 @@ struct master_login_request {
        unsigned int auth_pid;
        unsigned int auth_id;
 
-       struct ip_addr ip;
+       struct ip_addr local_ip, remote_ip;
 };
 
 struct master_login_reply {
index 1be9b89568fac0ff2cd23f34ebf7c6462ba4d5a8..bf3eda9f87ea5648c86aada1e18a6dad202f1214 100644 (file)
@@ -107,6 +107,7 @@ static struct setting_def setting_defs[] = {
        DEF(SET_INT, mail_process_size),
        DEF(SET_BOOL, mail_use_modules),
        DEF(SET_STR, mail_modules),
+       DEF(SET_STR, mail_log_prefix),
 
        /* imap */
        DEF(SET_INT, imap_max_line_length),
@@ -241,6 +242,7 @@ struct settings default_settings = {
        MEMBER(mail_process_size) 256,
        MEMBER(mail_use_modules) FALSE,
        MEMBER(mail_modules) MODULEDIR"/imap",
+       MEMBER(mail_log_prefix) "%Up(%u): ",
 
        /* imap */
        MEMBER(imap_max_line_length) 65536,
index 588bf486e285c807b9d22dea9ffe209c13a865e5..ce5bb02d9e09f84db5b657e9080941f3342c3fcc 100644 (file)
@@ -82,6 +82,7 @@ struct settings {
        unsigned int mail_process_size;
        int mail_use_modules;
        const char *mail_modules;
+       const char *mail_log_prefix;
 
        /* imap */
        unsigned int imap_max_line_length;
index 77d802e66d0758b27c1115ec58e0c02eabedadcb..4e59d0ca8bafd498a6d33930d08b4d9c18e94e4c 100644 (file)
@@ -148,10 +148,8 @@ int cmd_user(struct pop3_client *client, const char *args)
                return TRUE;
        }
 
-       /* authorization ID \0 authentication ID \0 pass */
-       buffer_set_used_size(client->plain_login, 0);
-       buffer_append_c(client->plain_login, '\0');
-       buffer_append(client->plain_login, args, strlen(args));
+       i_free(client->last_user);
+       client->last_user = i_strdup(args);
 
        client_send_line(client, "+OK");
        return TRUE;
@@ -160,23 +158,34 @@ int cmd_user(struct pop3_client *client, const char *args)
 int cmd_pass(struct pop3_client *client, const char *args)
 {
        const char *error;
+       struct auth_request_info info;
+       string_t *plain_login;
 
-       if (buffer_get_used_size(client->plain_login) == 0) {
+       if (client->last_user == NULL) {
                client_send_line(client, "-ERR No username given.");
                return TRUE;
        }
 
-       buffer_append_c(client->plain_login, '\0');
-       buffer_append(client->plain_login, args, strlen(args));
+       /* authorization ID \0 authentication ID \0 pass */
+       plain_login = t_str_new(128);
+       str_append_c(plain_login, '\0');
+       str_append(plain_login, client->last_user);
+       str_append_c(plain_login, '\0');
+       str_append(plain_login, args);
+
+       memset(&info, 0, sizeof(info));
+       info.mech = "PLAIN";
+       info.protocol = "POP3";
+       info.flags = client_get_auth_flags(client);
+       info.local_ip = client->common.local_ip;
+       info.remote_ip = client->common.ip;
+       info.initial_resp_data = str_data(plain_login);
+       info.initial_resp_size = str_len(plain_login);
 
        client_ref(client);
        client->common.auth_request =
-               auth_client_request_new(auth_client, "PLAIN", "POP3",
-                                        client_get_auth_flags(client),
-                                       str_data(client->plain_login),
-                                       str_len(client->plain_login),
+               auth_client_request_new(auth_client, &info,
                                        login_callback, client, &error);
-       buffer_set_used_size(client->plain_login, 0);
 
        if (client->common.auth_request != NULL) {
                /* don't read any input from client until login is finished */
@@ -265,6 +274,7 @@ static void client_auth_input(void *context)
 
 int cmd_auth(struct pop3_client *client, const char *args)
 {
+       struct auth_request_info info;
        const struct auth_mech_desc *mech;
        const char *mech_name, *error, *p;
        string_t *buf;
@@ -303,11 +313,18 @@ int cmd_auth(struct pop3_client *client, const char *args)
                return TRUE;
        }
 
+       memset(&info, 0, sizeof(info));
+       info.mech = mech->name;
+       info.protocol = "POP3";
+       info.flags = client_get_auth_flags(client);
+       info.local_ip = client->common.local_ip;
+       info.remote_ip = client->common.ip;
+       info.initial_resp_data = str_data(buf);
+       info.initial_resp_size = str_len(buf);
+
        client_ref(client);
        client->common.auth_request =
-               auth_client_request_new(auth_client, mech->name, "POP3",
-                                        client_get_auth_flags(client),
-                                       str_data(buf), str_len(buf),
+               auth_client_request_new(auth_client, &info,
                                        authenticate_callback, client, &error);
        if (client->common.auth_request != NULL) {
                /* following input data will go to authentication */
index 44ed53ac7b188247b14738af898cd5d7bb0b5139..74a7fa6ec16ee346ae04d3d44c13e75e2720763f 100644 (file)
@@ -228,7 +228,8 @@ static void client_destroy_oldest(void)
        }
 }
 
-struct client *client_create(int fd, struct ip_addr *ip, int ssl)
+struct client *client_create(int fd, int ssl, const struct ip_addr *local_ip,
+                            const struct ip_addr *ip)
 {
        struct pop3_client *client;
        const char *addr;
@@ -253,11 +254,11 @@ struct client *client_create(int fd, struct ip_addr *ip, int ssl)
                (IPADDR_IS_V4(ip) && strncmp(addr, "127.", 4) == 0) ||
                (IPADDR_IS_V6(ip) && strcmp(addr, "::1") == 0);
 
+       client->common.local_ip = *local_ip;
        client->common.ip = *ip;
        client->common.fd = fd;
        client->common.io = io_add(fd, IO_READ, client_input, client);
        client_open_streams(client, fd);
-       client->plain_login = buffer_create_dynamic(system_pool, 128, 8192);
 
        client->last_input = ioloop_time;
        hash_insert(clients, client, client);
@@ -317,7 +318,6 @@ int client_unref(struct pop3_client *client)
        i_stream_unref(client->input);
        o_stream_unref(client->output);
 
-       buffer_free(client->plain_login);
        i_free(client->common.virtual_user);
        i_free(client);
 
index 2aa2c315b3f38855557834fff0dd67d2e74f205d..cd789339c0d552f592732aa7eab26d0d4ef4a0e9 100644 (file)
@@ -17,7 +17,7 @@ struct pop3_client {
        time_t last_input;
        unsigned int bad_counter;
 
-       buffer_t *plain_login;
+       char *last_user;
 
        unsigned int tls:1;
        unsigned int secured:1;
@@ -25,7 +25,6 @@ struct pop3_client {
        unsigned int destroyed:1;
 };
 
-struct client *client_create(int fd, struct ip_addr *ip, int ssl);
 void client_destroy(struct pop3_client *client, const char *reason);
 
 void client_send_line(struct pop3_client *client, const char *line);