]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Verify that msg-get and msg-copy reply has the correct UID.
authorTimo Sirainen <tss@iki.fi>
Sun, 4 Apr 2010 21:18:41 +0000 (00:18 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 4 Apr 2010 21:18:41 +0000 (00:18 +0300)
--HG--
branch : HEAD

src/dsync/dsync-proxy-client.c
src/dsync/dsync-proxy-server-cmd.c
src/dsync/dsync-proxy-server.h
src/dsync/dsync-worker-local.c

index 249748d6423dd3efa5dc18cddbeeb1a6d9a1371a..591981392c8809581c62c60c4221d1e63c686ff7 100644 (file)
@@ -27,6 +27,7 @@ enum proxy_client_request_type {
 
 struct proxy_client_request {
        enum proxy_client_request_type type;
+       uint32_t uid;
        union {
                dsync_worker_msg_callback_t *get;
                dsync_worker_copy_callback_t *copy;
@@ -137,10 +138,31 @@ proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker)
 }
 
 static bool
-proxy_client_worker_next_copy(const struct proxy_client_request *request,
+proxy_client_worker_next_copy(struct proxy_client_dsync_worker *worker,
+                             const struct proxy_client_request *request,
                              const char *line)
 {
-       request->callback.copy(*line == '1', request->context);
+       uint32_t uid;
+       bool success;
+
+       if (line[0] == '1' && line[1] == '\t')
+               success = TRUE;
+       else if (line[0] == '0' && line[1] == '\t')
+               success = FALSE;
+       else {
+               i_error("msg-copy returned invalid input: %s", line);
+               proxy_client_fail(worker);
+               return FALSE;
+       }
+       uid = strtoul(line + 2, NULL, 10);
+       if (uid != request->uid) {
+               i_error("msg-copy returned invalid uid: %u != %u",
+                       uid, request->uid);
+               proxy_client_fail(worker);
+               return FALSE;
+       }
+
+       request->callback.copy(success, request->context);
        return TRUE;
 }
 
@@ -167,6 +189,13 @@ proxy_client_worker_next_msg_get(struct proxy_client_dsync_worker *worker,
                uid = strtoul(t_strcut(line, '\t'), NULL, 10);
                line = p + 1;
 
+               if (uid != request->uid) {
+                       i_error("msg-get returned invalid uid: %u != %u",
+                               uid, request->uid);
+                       proxy_client_fail(worker);
+                       return FALSE;
+               }
+
                if (dsync_proxy_msg_static_import(worker->msg_get_pool,
                                                  line, &worker->msg_get_data,
                                                  &error) < 0) {
@@ -230,7 +259,7 @@ proxy_client_worker_next_reply(struct proxy_client_dsync_worker *worker,
 
        switch (request.type) {
        case PROXY_CLIENT_REQUEST_TYPE_COPY:
-               ret = proxy_client_worker_next_copy(&request, line);
+               ret = proxy_client_worker_next_copy(worker, &request, line);
                break;
        case PROXY_CLIENT_REQUEST_TYPE_GET:
                ret = proxy_client_worker_next_msg_get(worker, &request, line);
@@ -847,6 +876,7 @@ proxy_client_worker_msg_copy(struct dsync_worker *_worker,
        request.type = PROXY_CLIENT_REQUEST_TYPE_COPY;
        request.callback.copy = callback;
        request.context = context;
+       request.uid = src_uid;
        aqueue_append(worker->request_queue, &request);
 }
 
@@ -960,6 +990,7 @@ proxy_client_worker_msg_get(struct dsync_worker *_worker,
        request.type = PROXY_CLIENT_REQUEST_TYPE_GET;
        request.callback.get = callback;
        request.context = context;
+       request.uid = uid;
        aqueue_append(worker->request_queue, &request);
 }
 
index 88755e5f0b61b9629ce804442cab67b1429cade4..7df73e56c81f478cc93ec914ffbb58a0ea88f57a 100644 (file)
@@ -364,8 +364,12 @@ cmd_msg_expunge(struct dsync_proxy_server *server, const char *const *args)
 static void copy_callback(bool success, void *context)
 {
        struct dsync_proxy_server *server = context;
+       const char *reply;
+
+       i_assert(server->copy_uid != 0);
 
-       o_stream_send(server->output, success ? "1\n" : "0\n", 2);
+       reply = t_strdup_printf("%d\t%u\n", success ? 1 : 0, server->copy_uid);
+       o_stream_send_str(server->output, reply);
 }
 
 static int
@@ -390,8 +394,10 @@ cmd_msg_copy(struct dsync_proxy_server *server, const char *const *args)
                                             args + 2, &msg, &error) < 0)
                i_error("Invalid message input: %s", error);
 
+       server->copy_uid = src_uid;
        dsync_worker_msg_copy(server->worker, &src_mailbox_guid, src_uid, &msg,
                              copy_callback, server);
+       server->copy_uid = 0;
        return 1;
 }
 
@@ -459,6 +465,8 @@ cmd_msg_get_callback(enum dsync_msg_get_result result,
        struct dsync_proxy_server *server = context;
        string_t *str;
 
+       i_assert(server->get_uid != 0);
+
        switch (result) {
        case DSYNC_MSG_GET_RESULT_SUCCESS:
                break;
@@ -507,7 +515,10 @@ cmd_msg_get(struct dsync_proxy_server *server, const char *const *args)
                dsync_worker_msg_get(server->worker, &mailbox_guid, uid,
                                     cmd_msg_get_callback, server);
        }
-       return server->get_input == NULL ? 1 : 0;
+       if (server->get_input != NULL)
+               return 0;
+       server->get_uid = 0;
+       return 1;
 }
 
 static void cmd_finish_callback(bool success, void *context)
index 727ca33532df0108c8b989e8a4fd05360748d9f1..44a48b00f6f35fca519abd9b720388054cec8a96 100644 (file)
@@ -28,7 +28,7 @@ struct dsync_proxy_server {
 
        struct istream *get_input;
        bool get_input_last_lf;
-       uint32_t get_uid;
+       uint32_t get_uid, copy_uid;
 
        unsigned int handshake_received:1;
        unsigned int subs_sending_unsubscriptions:1;
index f120b58eecc86ed99e51abfd2247cb9ecaa375ea..3a51b7da6cf882c490b9ad0b3c9c6a069ffa6e32 100644 (file)
@@ -485,7 +485,6 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
        if (info == NULL)
                return iter_next_deleted(iter, worker, dsync_box_r);
 
-       storage_name = mail_namespace_get_storage_name(info->ns, info->name);
        dsync_box_r->name = info->name;
        dsync_box_r->name_sep = info->ns->sep;