]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
pop3: initialize namespaces explicitly
authorJosef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
Tue, 23 May 2017 10:01:48 +0000 (13:01 +0300)
committerGitLab <gitlab@git.dovecot.net>
Sun, 4 Jun 2017 17:25:24 +0000 (20:25 +0300)
(instead of relying on mail user initialization to instantiate them for
us)

src/pop3/main.c
src/pop3/pop3-client.c

index 6c8b68ad15c13a9876194fdfe10a971876456be5..ea496edd1d71c5b1d4f9f42036ab260ee3bfc8e0 100644 (file)
@@ -16,6 +16,7 @@
 #include "var-expand.h"
 #include "mail-error.h"
 #include "mail-user.h"
+#include "mail-namespace.h"
 #include "mail-storage-service.h"
 
 #include <stdio.h>
@@ -126,6 +127,8 @@ static int lock_session(struct client *client)
 {
        int ret;
 
+       i_assert(client->user->namespaces != NULL);
+
        if (client->set->pop3_lock_session &&
            (ret = pop3_lock_session(client)) <= 0) {
                client_send_line(client, ret < 0 ?
@@ -138,11 +141,36 @@ static int lock_session(struct client *client)
        return 0;
 }
 
+#define MSG_BYE_INTERNAL_ERROR "-ERR "MAIL_ERRSTR_CRITICAL_MSG
+static int init_namespaces(struct client *client, bool already_logged_in)
+{
+       const char *error;
+
+       /* finish initializing the user (see comment in main()) */
+       if (mail_namespaces_init(client->user, &error) < 0) {
+               if (!already_logged_in)
+                       client_send_line(client, MSG_BYE_INTERNAL_ERROR);
+
+               i_error("%s", error);
+               client_destroy(client, error);
+               return -1;
+       }
+
+       i_assert(client->inbox_ns == NULL);
+       client->inbox_ns = mail_namespace_find_inbox(client->user->namespaces);
+       i_assert(client->inbox_ns != NULL);
+
+       return 0;
+}
+
 static void add_input(struct client *client,
                      const buffer_t *input_buf)
 {
        const char *error;
 
+       if (init_namespaces(client, FALSE) < 0)
+               return; /* no need to propagate an error */
+
        if (lock_session(client) < 0)
                return; /* no need to propagate an error */
 
@@ -271,6 +299,14 @@ int main(int argc, char *argv[])
                        MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
        }
 
+       /*
+        * We include MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES so that the
+        * mail_user initialization is fast and we can quickly send back the
+        * OK response to LOGIN/AUTHENTICATE.  Otherwise we risk a very slow
+        * namespace initialization to cause client timeouts on login.
+        */
+       storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES;
+
        master_service = master_service_init("pop3", service_flags,
                                             &argc, &argv, "a:t:u:");
        while ((c = master_getopt(master_service)) > 0) {
index b21bf5a24472b65f60f7dac80509fa49932576b8..96d7c6cfbf3ca16770887321c80e38fd204e0e8a 100644 (file)
@@ -434,9 +434,6 @@ struct client *client_create(int fd_in, int fd_out, const char *session_id,
        pop3_client_count++;
        DLLIST_PREPEND(&pop3_clients, client);
 
-       client->inbox_ns = mail_namespace_find_inbox(user->namespaces);
-       i_assert(client->inbox_ns != NULL);
-
        if (hook_client_created != NULL)
                hook_client_created(&client);