]> 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)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 16 Jun 2017 06:17:25 +0000 (09:17 +0300)
(instead of relying on mail user initialization to instantiate them for
us)

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

index ed1a4c6145bd6048ef95c8b3cdf5fa1c2ad86d95..fd03edccdb77c5fb36473a7e1dedc596f97376a3 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 2aa09800b88b55c95f8c6fd5fa67cadfbbf7c44f..78d35396cf09d10b0c824a0993633bdc60e606dc 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);