Mercurial > dovecot > core-2.2
changeset 15814:e63d1cf19ec7
Merged changes from v2.1 tree.
line wrap: on
line diff
--- a/.hgsigs Sat Feb 16 18:24:28 2013 +0200 +++ b/.hgsigs Sat Feb 16 18:57:33 2013 +0200 @@ -55,3 +55,5 @@ 75bfda4a7c6c9aa04b6a6ef233fc527356171a06 0 iEYEABECAAYFAlC4WKwACgkQyUhSUUBViskaOACgmcwWV8hgsCOWvkbdh0OIw1ImSQYAn1RcTL0CG3M8+XG7QrrxSfQ7+V99 86bccdf46d172524ca19a1a8a16a50ac30a6743c 0 iEYEABECAAYFAlDqonoACgkQyUhSUUBVisnqqACfaqdR6GxUAJznotKT9WHIUVhVgcIAoJIEa0SBzlGIWThmLvtQByF9vXcc cf9d62fd0b143efa8e49fac998eb78a648cdd8a9 0 iEYEABECAAYFAlDqjXUACgkQyUhSUUBViskUEwCfYTWHeDmPr8HfxSBQN17SD5IwDygAnROhb3IVTm9niDun4gxPxbHLo/Pe +b314c97d4bbffd01b20f8492592aa422c13e3d55 0 iEYEABECAAYFAlEJlGMACgkQyUhSUUBVismNdQCgggPP/dt1duU1CMYfkpE4Kyc9Ju0An0kphokRqrtppkeqg7pF1JR01Mgq +fc75811f3c08d80ed339cbb4d37c66f549542ba7 0 iEYEABECAAYFAlEU+CEACgkQyUhSUUBViskh9QCgnqPHUkNvtOioWxo4W7fXjCFLVAwAnR9Z26jgBpoejXDkgwT07wdfYiL3
--- a/.hgtags Sat Feb 16 18:24:28 2013 +0200 +++ b/.hgtags Sat Feb 16 18:57:33 2013 +0200 @@ -92,3 +92,5 @@ 75bfda4a7c6c9aa04b6a6ef233fc527356171a06 2.1.12 cf9d62fd0b143efa8e49fac998eb78a648cdd8a9 2.1.13 86bccdf46d172524ca19a1a8a16a50ac30a6743c 2.2.beta1 +b314c97d4bbffd01b20f8492592aa422c13e3d55 2.1.14 +fc75811f3c08d80ed339cbb4d37c66f549542ba7 2.1.15
--- a/src/imap/imap-client.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/imap/imap-client.c Sat Feb 16 18:57:33 2013 +0200 @@ -83,6 +83,8 @@ set->imap_max_line_length, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); o_stream_set_no_error_handling(client->output, TRUE); + i_stream_set_name(client->input, "<imap client>"); + o_stream_set_name(client->output, "<imap client>"); o_stream_set_flush_callback(client->output, client_output, client);
--- a/src/lib-index/mail-cache-fields.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-index/mail-cache-fields.c Sat Feb 16 18:57:33 2013 +0200 @@ -280,6 +280,8 @@ file_cache_invalidate(cache->file_cache, offset, field_hdr_size); } + if (cache->read_buf != NULL) + buffer_set_used_size(cache->read_buf, 0); ret = mail_cache_map(cache, offset, field_hdr_size, &data); if (ret < 0) return -1;
--- a/src/lib-index/mail-cache-lookup.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-index/mail-cache-lookup.c Sat Feb 16 18:57:33 2013 +0200 @@ -15,6 +15,7 @@ { const struct mail_cache_record *rec; const void *data; + int ret; i_assert(offset != 0); @@ -41,17 +42,15 @@ } if (rec->size > CACHE_PREFETCH) { /* larger than we guessed. map the rest of the record. */ - if (mail_cache_map(cache, offset, rec->size, &data) < 0) + if ((ret = mail_cache_map(cache, offset, rec->size, &data)) < 0) return -1; + if (ret == 0) { + mail_cache_set_corrupted(cache, "record points outside file"); + return -1; + } rec = data; } - if (rec->size > cache->mmap_length || - offset + rec->size > cache->mmap_length) { - mail_cache_set_corrupted(cache, "record points outside file"); - return -1; - } - *rec_r = rec; return 0; }
--- a/src/lib-index/mail-cache.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-index/mail-cache.c Sat Feb 16 18:57:33 2013 +0200 @@ -370,12 +370,30 @@ int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size, const void **data_r) { + struct stat st; const void *data; ssize_t ret; if (size == 0) size = sizeof(struct mail_cache_header); + /* verify offset + size before trying to allocate a huge amount of + memory due to them. note that we may be prefetching more than we + actually need, so don't fail too early. */ + if ((size > cache->mmap_length || offset + size > cache->mmap_length) && + (offset > 0 || size > sizeof(struct mail_cache_header))) { + if (fstat(cache->fd, &st) < 0) { + i_error("fstat(%s) failed: %m", cache->filepath); + return -1; + } + if (offset >= (uoff_t)st.st_size) { + *data_r = NULL; + return 0; + } + if (offset + size > (uoff_t)st.st_size) + size = st.st_size - offset; + } + cache->remap_counter++; if (cache->map_with_read) return mail_cache_map_with_read(cache, offset, size, data_r); @@ -432,6 +450,7 @@ cache->mmap_base = mmap_ro_file(cache->fd, &cache->mmap_length); if (cache->mmap_base == MAP_FAILED) { cache->mmap_base = NULL; + cache->mmap_length = 0; mail_cache_set_syscall_error(cache, "mmap()"); return -1; } @@ -464,8 +483,7 @@ mail_cache_init_file_cache(cache); - if (mail_cache_map(cache, 0, sizeof(struct mail_cache_header), - &data) < 0) + if (mail_cache_map(cache, 0, 0, &data) < 0) return -1; return 1; } @@ -685,6 +703,8 @@ file_cache_invalidate(cache->file_cache, 0, sizeof(struct mail_cache_header)); } + if (cache->read_buf != NULL) + buffer_set_used_size(cache->read_buf, 0); if (mail_cache_map(cache, 0, 0, &data) > 0) cache->hdr_copy = *cache->hdr; else {
--- a/src/lib-storage/index/dbox-common/dbox-storage.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-storage.c Sat Feb 16 18:57:33 2013 +0200 @@ -270,6 +270,12 @@ if (mailbox_open(box) < 0) return -1; + if (mail_index_get_header(box->view)->uid_validity != 0) { + mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS, + "Mailbox already exists"); + return -1; + } + /* if alt path already exists and contains files, rebuild storage so that we don't start overwriting files. */ ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX, &alt_path);
--- a/src/lib-storage/index/index-mail-headers.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-storage/index/index-mail-headers.c Sat Feb 16 18:57:33 2013 +0200 @@ -374,6 +374,7 @@ input2 = tee_i_stream_create_child(mail->data.tee_stream); index_mail_parse_header_init(mail, NULL); + mail->data.parser_input = input; mail->data.parser_ctx = message_parser_init(mail->mail.data_pool, input, hdr_parser_flags, msg_parser_flags); @@ -386,10 +387,13 @@ struct index_mail_data *data = &mail->data; struct message_part *parts; - if (data->parser_ctx != NULL) + if (data->parser_ctx != NULL) { + data->parser_input = NULL; (void)message_parser_deinit(&data->parser_ctx, &parts); + } if (data->parts == NULL) { + data->parser_input = data->stream; data->parser_ctx = message_parser_init(mail->mail.data_pool, data->stream, hdr_parser_flags,
--- a/src/lib-storage/index/index-mail.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-storage/index/index-mail.c Sat Feb 16 18:57:33 2013 +0200 @@ -805,13 +805,43 @@ static int index_mail_parse_body_finish(struct index_mail *mail, enum index_cache_field field) { - if (message_parser_deinit(&mail->data.parser_ctx, - &mail->data.parts) < 0) { - mail_set_cache_corrupted(&mail->mail.mail, - MAIL_FETCH_MESSAGE_PARTS); + struct istream *parser_input = mail->data.parser_input; + int ret; + + if (parser_input == NULL) { + ret = message_parser_deinit(&mail->data.parser_ctx, + &mail->data.parts) < 0 ? 0 : 1; + } else { + mail->data.parser_input = NULL; + i_stream_ref(parser_input); + ret = message_parser_deinit(&mail->data.parser_ctx, + &mail->data.parts) < 0 ? 0 : 1; + if (parser_input->stream_errno == 0 || + parser_input->stream_errno == EPIPE) { + /* EPIPE = input already closed. allow the caller to + decide if that is an error or not. */ + i_assert(i_stream_read(parser_input) == -1 && + !i_stream_have_bytes_left(parser_input)); + } else { + errno = parser_input->stream_errno; + mail_storage_set_critical(mail->mail.mail.box->storage, + "mail parser: read(%s, box=%s) failed: %m", + i_stream_get_name(parser_input), + mail->mail.mail.box->vname); + ret = -1; + } + i_stream_unref(&parser_input); + } + if (ret <= 0) { + if (ret == 0) { + mail_set_cache_corrupted(&mail->mail.mail, + MAIL_FETCH_MESSAGE_PARTS); + } + mail->data.parts = NULL; mail->data.parsed_bodystructure = FALSE; return -1; } + if (mail->data.no_caching) { /* if we're here because we aborted parsing, don't get any further or we may crash while generating output from @@ -1221,6 +1251,7 @@ mail_set_cache_corrupted(&mail->mail.mail, MAIL_FETCH_MESSAGE_PARTS); } + mail->data.parser_input = NULL; } if (data->filter_stream != NULL) i_stream_unref(&data->filter_stream);
--- a/src/lib-storage/index/index-mail.h Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-storage/index/index-mail.h Sat Feb 16 18:57:33 2013 +0200 @@ -98,6 +98,7 @@ struct istream *stream, *filter_stream; struct tee_istream *tee_stream; struct message_size hdr_size, body_size; + struct istream *parser_input; struct message_parser_ctx *parser_ctx; int parsing_count; ARRAY_TYPE(keywords) keywords;
--- a/src/lib-storage/mail-storage.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib-storage/mail-storage.c Sat Feb 16 18:57:33 2013 +0200 @@ -641,10 +641,12 @@ i_assert(uni_utf8_str_is_valid(vname)); - if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && - strncasecmp(vname, "INBOX", 5) == 0 && + if (strncasecmp(vname, "INBOX", 5) == 0 && strncmp(vname, "INBOX", 5) != 0) { - /* make sure INBOX shows up in uppercase everywhere */ + /* make sure INBOX shows up in uppercase everywhere. do this + regardless of whether we're in inbox=yes namespace, because + clients expect INBOX to be case insensitive regardless of + server's internal configuration. */ if (vname[5] == '\0') vname = "INBOX"; else if (vname[5] == mail_namespace_get_sep(list->ns))
--- a/src/lib/Makefile.am Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/Makefile.am Sat Feb 16 18:57:33 2013 +0200 @@ -286,6 +286,7 @@ test-primes.c \ test-priorityq.c \ test-seq-range-array.c \ + test-str.c \ test-strescape.c \ test-strfuncs.c \ test-str-find.c \
--- a/src/lib/buffer.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/buffer.c Sat Feb 16 18:57:33 2013 +0200 @@ -39,6 +39,7 @@ static inline void buffer_check_limits(struct real_buffer *buf, size_t pos, size_t data_size) { + unsigned int extra; size_t new_size; if (unlikely((size_t)-1 - pos < data_size)) { @@ -53,7 +54,13 @@ memset(buf->w_buffer + buf->used, 0, max - buf->used); } - if (new_size > buf->alloc) { + + /* always keep +1 byte allocated available in case str_c() is called + for this buffer. this is mainly for cases where the buffer is + allocated from data stack, and str_c() is called in a separate stack + frame. */ + extra = buf->dynamic ? 1 : 0; + if (new_size + extra > buf->alloc) { if (unlikely(!buf->dynamic)) { i_panic("Buffer full (%"PRIuSIZE_T" > %"PRIuSIZE_T", " "pool %s)", pos + data_size, buf->alloc, @@ -62,7 +69,7 @@ } buffer_alloc(buf, pool_get_exp_grown_size(buf->pool, buf->alloc, - new_size)); + new_size + extra)); } #if 0 else if (new_size > buf->used && buf->alloced &&
--- a/src/lib/istream-tee.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/istream-tee.c Sat Feb 16 18:57:33 2013 +0200 @@ -225,6 +225,7 @@ tee->children = tstream; ret = i_stream_create(&tstream->istream, input, i_stream_get_fd(input)); + i_stream_set_name(&tstream->istream.istream, i_stream_get_name(input)); /* we keep the reference in tee stream, no need for extra references */ i_stream_unref(&input); return ret;
--- a/src/lib/str.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/str.c Sat Feb 16 18:57:33 2013 +0200 @@ -45,9 +45,6 @@ size_t len = str_len(str); size_t alloc = buffer_get_size(str); -#ifdef DEBUG - buffer_verify_pool(str); -#endif if (len == alloc || data[len] != '\0') { buffer_write(str, len, "", 1); /* remove the \0 - we don't want to keep it */
--- a/src/lib/test-lib.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/test-lib.c Sat Feb 16 18:57:33 2013 +0200 @@ -29,6 +29,7 @@ test_primes, test_priorityq, test_seq_range_array, + test_str, test_strescape, test_strfuncs, test_str_find,
--- a/src/lib/test-lib.h Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lib/test-lib.h Sat Feb 16 18:57:33 2013 +0200 @@ -28,6 +28,7 @@ void test_primes(void); void test_priorityq(void); void test_seq_range_array(void); +void test_str(void); void test_strescape(void); void test_strfuncs(void); void test_str_find(void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-str.c Sat Feb 16 18:57:33 2013 +0200 @@ -0,0 +1,26 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "str.h" + +static void test_str_c(void) +{ + string_t *str; + unsigned int i, j; + + test_begin("str_c()"); + for (i = 0; i < 32; i++) T_BEGIN { + str = t_str_new(15); + for (j = 0; j < i; j++) + str_append_c(str, 'x'); + T_BEGIN { + (void)str_c(str); + } T_END; + } T_END; + test_end(); +} + +void test_str(void) +{ + test_str_c(); +}
--- a/src/lmtp/client.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lmtp/client.c Sat Feb 16 18:57:33 2013 +0200 @@ -8,6 +8,7 @@ #include "istream.h" #include "ostream.h" #include "hostpid.h" +#include "process-title.h" #include "var-expand.h" #include "settings-parser.h" #include "master-service.h" @@ -31,6 +32,20 @@ static struct client *clients = NULL; unsigned int clients_count = 0; +void client_state_set(struct client *client, const char *name) +{ + client->state.name = name; + + if (!client->service_set->verbose_proctitle) + return; + if (clients_count == 0) + process_title_set("[idling]"); + else if (clients_count > 1) + process_title_set(t_strdup_printf("[%u clients]", clients_count)); + else + process_title_set(t_strdup_printf("[%s]", client->state.name)); +} + static void client_idle_timeout(struct client *client) { client_destroy(client, @@ -158,6 +173,7 @@ lmtp_settings_dup(set_parser, client->pool, &lmtp_set, &lda_set); settings_var_expand(&lmtp_setting_parser_info, lmtp_set, client->pool, mail_storage_service_get_var_expand_table(storage_service, &input)); + client->service_set = master_service_settings_get(master_service); client->lmtp_set = lmtp_set; client->set = lda_set; } @@ -222,7 +238,6 @@ client_io_reset(client); client->state_pool = pool_alloconly_create("client state", 4096); client->state.mail_data_fd = -1; - client->state.name = "banner"; client_read_settings(client); client_raw_user_create(client); client_generate_session_id(client); @@ -233,6 +248,7 @@ DLLIST_PREPEND(&clients, client); clients_count++; + client_state_set(client, "banner"); client_send_line(client, "220 %s %s", client->my_domain, client->lmtp_set->login_greeting); i_info("Connect from %s", client_remote_id(client)); @@ -247,6 +263,8 @@ clients_count--; DLLIST_REMOVE(&clients, client); + client_state_set(client, "destroyed"); + if (client->raw_mail_user != NULL) mail_user_unref(&client->raw_mail_user); if (client->proxy != NULL) @@ -330,7 +348,7 @@ client->state.mail_data_fd = -1; client_generate_session_id(client); - client->state.name = "reset"; + client_state_set(client, "reset"); } void client_send_line(struct client *client, const char *fmt, ...)
--- a/src/lmtp/client.h Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lmtp/client.h Sat Feb 16 18:57:33 2013 +0200 @@ -43,6 +43,7 @@ const struct setting_parser_info *user_set_info; const struct lda_settings *set; const struct lmtp_settings *lmtp_set; + const struct master_service_settings *service_set; int fd_in, fd_out; struct io *io; struct istream *input; @@ -78,6 +79,7 @@ const char *reason); void client_io_reset(struct client *client); void client_state_reset(struct client *client); +void client_state_set(struct client *client, const char *name); void client_input_handle(struct client *client); int client_input_read(struct client *client);
--- a/src/lmtp/commands.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/lmtp/commands.c Sat Feb 16 18:57:33 2013 +0200 @@ -77,7 +77,7 @@ i_free(client->lhlo); client->lhlo = i_strdup(str_c(domain)); - client->state.name = "LHLO"; + client_state_set(client, "LHLO"); return 0; } @@ -146,7 +146,7 @@ client->state.mail_from = p_strdup(client->state_pool, addr); p_array_init(&client->state.rcpt_to, client->state_pool, 64); client_send_line(client, "250 2.1.0 OK"); - client->state.name = "MAIL FROM"; + client_state_set(client, "MAIL FROM"); return 0; } @@ -507,7 +507,7 @@ const char *error = NULL; int ret = 0; - client->state.name = "RCPT TO"; + client_state_set(client, "RCPT TO"); if (client->state.mail_from == NULL) { client_send_line(client, "503 5.5.1 MAIL needed first"); @@ -1050,7 +1050,7 @@ client_send_line(client, "354 OK"); io_remove(&client->io); - client->state.name = "DATA"; + client_state_set(client, "DATA"); client->io = io_add(client->fd_in, IO_READ, client_input_data, client); client_input_data_handle(client); return -1;
--- a/src/plugins/acl/doveadm-acl.c Sat Feb 16 18:24:28 2013 +0200 +++ b/src/plugins/acl/doveadm-acl.c Sat Feb 16 18:57:33 2013 +0200 @@ -394,6 +394,34 @@ } static int +cmd_acl_recalc_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) +{ + struct acl_user *auser = ACL_USER_CONTEXT(user); + + if (auser == NULL) { + i_error("ACL not enabled for %s", user->username); + doveadm_mail_failed_error(ctx, MAIL_ERROR_NOTFOUND); + return -1; + } + if (acl_lookup_dict_rebuild(auser->acl_lookup_dict) < 0) { + i_error("Failed to recalculate ACL dicts"); + doveadm_mail_failed_error(ctx, MAIL_ERROR_TEMP); + return -1; + } + return 0; +} + +static struct doveadm_mail_cmd_context * +cmd_acl_recalc_alloc(void) +{ + struct doveadm_mail_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context); + ctx->v.run = cmd_acl_recalc_run; + return ctx; +} + +static int cmd_acl_debug_mailbox_open(struct doveadm_mail_cmd_context *ctx, struct mail_user *user, const char *mailbox, struct mailbox **box_r) @@ -582,6 +610,7 @@ { cmd_acl_add_alloc, "acl add", "<mailbox> <id> <right> [<right> ...]" }, { cmd_acl_remove_alloc, "acl remove", "<mailbox> <id> <right> [<right> ...]" }, { cmd_acl_delete_alloc, "acl delete", "<mailbox> <id>" }, + { cmd_acl_recalc_alloc, "acl recalc", "" }, { cmd_acl_debug_alloc, "acl debug", "<mailbox>" } };