bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "lib.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "array.h"
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen#include "llist.h"
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#include "str.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "str-sanitize.h"
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen#include "imap-util.h"
994bb1a8a80da664083691d41dd9aec5d6fba2bfTimo Sirainen#include "mail-user.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "mail-storage-private.h"
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen#include "notify-plugin.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "mail-log-plugin.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#define MAILBOX_NAME_LOG_LEN 64
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen#define HEADER_LOG_LEN 80
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen#define MAIL_LOG_USER_CONTEXT(obj) \
6deb39ab9145dd6b01d7ecb99f2526b53b3172bfAki Tuomi MODULE_CONTEXT_REQUIRE(obj, mail_log_user_module)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenenum mail_log_field {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_FIELD_UID = 0x01,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_FIELD_BOX = 0x02,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_FIELD_MSGID = 0x04,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_FIELD_PSIZE = 0x08,
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen MAIL_LOG_FIELD_VSIZE = 0x10,
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen MAIL_LOG_FIELD_FLAGS = 0x20,
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen MAIL_LOG_FIELD_FROM = 0x40,
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen MAIL_LOG_FIELD_SUBJECT = 0x80
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#define MAIL_LOG_DEFAULT_FIELDS \
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_FIELD_MSGID | MAIL_LOG_FIELD_PSIZE)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenenum mail_log_event {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_EVENT_DELETE = 0x01,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_EVENT_UNDELETE = 0x02,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MAIL_LOG_EVENT_EXPUNGE = 0x04,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen MAIL_LOG_EVENT_SAVE = 0x08,
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen MAIL_LOG_EVENT_COPY = 0x10,
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen MAIL_LOG_EVENT_MAILBOX_CREATE = 0x20,
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE = 0x40,
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen MAIL_LOG_EVENT_MAILBOX_RENAME = 0x80,
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE = 0x100
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen#define MAIL_LOG_DEFAULT_EVENTS \
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen (MAIL_LOG_EVENT_DELETE | MAIL_LOG_EVENT_UNDELETE | \
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_SAVE | MAIL_LOG_EVENT_COPY | \
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen MAIL_LOG_EVENT_MAILBOX_DELETE | MAIL_LOG_EVENT_MAILBOX_RENAME)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic const char *field_names[] = {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "uid",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "box",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "msgid",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "size",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "vsize",
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen "flags",
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen "from",
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen "subject",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic const char *event_names[] = {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "delete",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "undelete",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "expunge",
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen "save",
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen "copy",
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen "mailbox_create",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "mailbox_delete",
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen "mailbox_rename",
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen "flag_change",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenstruct mail_log_user {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen union mail_user_module_context module_ctx;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen enum mail_log_field fields;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen enum mail_log_event events;
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen bool cached_only;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct mail_log_message {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_message *prev, *next;
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen enum mail_log_event event;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen bool ignore;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *pretext, *text;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct mail_log_mail_txn_context {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen pool_t pool;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_message *messages, *messages_tail;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_log_user_module,
b66412da78711db8423288847ecfb08469609a03Timo Sirainen &mail_user_module_register);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic enum mail_log_field mail_log_field_find(const char *name)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen unsigned int i;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (i = 0; field_names[i] != NULL; i++) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (strcmp(name, field_names[i]) == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return 1 << i;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic enum mail_log_event mail_log_event_find(const char *name)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen unsigned int i;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if (strcmp(name, "append") == 0) {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen /* v1.x backwards compatibility */
b66412da78711db8423288847ecfb08469609a03Timo Sirainen name = "save";
b66412da78711db8423288847ecfb08469609a03Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (i = 0; event_names[i] != NULL; i++) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (strcmp(name, event_names[i]) == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return 1 << i;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic enum mail_log_field mail_log_parse_fields(const char *str)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *const *tmp;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen static enum mail_log_field field, fields = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen field = mail_log_field_find(*tmp);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (field == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_fatal("Unknown field in mail_log_fields: '%s'", *tmp);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen fields |= field;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return fields;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic enum mail_log_event mail_log_parse_events(const char *str)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *const *tmp;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen static enum mail_log_event event, events = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen for (tmp = t_strsplit_spaces(str, ", "); *tmp != NULL; tmp++) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen event = mail_log_event_find(*tmp);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (event == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_fatal("Unknown event in mail_log_events: '%s'", *tmp);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen events |= event;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return events;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenstatic void mail_log_mail_user_created(struct mail_user *user)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_log_user *muser;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *str;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen muser = p_new(user->pool, struct mail_log_user, 1);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen MODULE_CONTEXT_SET(user, mail_log_user_module, muser);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_fields");
b66412da78711db8423288847ecfb08469609a03Timo Sirainen muser->fields = str == NULL ? MAIL_LOG_DEFAULT_FIELDS :
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_parse_fields(str);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen str = mail_user_plugin_getenv(user, "mail_log_events");
b66412da78711db8423288847ecfb08469609a03Timo Sirainen muser->events = str == NULL ? MAIL_LOG_DEFAULT_EVENTS :
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_parse_events(str);
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen muser->cached_only =
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen mail_user_plugin_getenv_bool(user, "mail_log_cached_only");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_append_mailbox_name(string_t *str, struct mail *mail)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const char *mailbox_str;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
5bd2cf0f30371cb0374b026322a6f52fdb20755fTimo Sirainen mailbox_str = mailbox_get_vname(mail->box);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(str, "box=%s",
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_sanitize(mailbox_str, MAILBOX_NAME_LOG_LEN));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_append_mail_header(string_t *str, struct mail *mail,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *name, const char *header)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *value;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
fe219d44d016a40771117bdcb112828cdfad36a4Martti Rannanjärvi if (mail_get_first_header_utf8(mail, header, &value) <= 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen value = "";
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(str, "%s=%s", name, str_sanitize(value, HEADER_LOG_LEN));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_append_uid(struct mail_log_mail_txn_context *ctx,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_message *msg, string_t *str, uint32_t uid)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (uid != 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(str, "uid=%u", uid);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen else {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen /* we don't know the uid yet, assign it later */
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(str, "uid=");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen msg->pretext = p_strdup(ctx->pool, str_c(str));
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_truncate(str, 0);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainenstatic void
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainenmail_log_update_wanted_fields(struct mail *mail, enum mail_log_field fields)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen{
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen enum mail_fetch_field wanted_fields = 0;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers = NULL;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen const char *headers[4];
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen unsigned int hdr_idx = 0;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if ((fields & MAIL_LOG_FIELD_MSGID) != 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen headers[hdr_idx++] = "Message-ID";
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if ((fields & MAIL_LOG_FIELD_FROM) != 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen headers[hdr_idx++] = "From";
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if ((fields & MAIL_LOG_FIELD_SUBJECT) != 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen headers[hdr_idx++] = "Subject";
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if (hdr_idx > 0) {
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen i_assert(hdr_idx < N_ELEMENTS(headers));
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen headers[hdr_idx] = NULL;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen wanted_headers = mailbox_header_lookup_init(mail->box, headers);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen }
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if ((fields & MAIL_LOG_FIELD_PSIZE) != 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen wanted_fields |= MAIL_FETCH_PHYSICAL_SIZE;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if ((fields & MAIL_LOG_FIELD_VSIZE) != 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen wanted_fields |= MAIL_FETCH_VIRTUAL_SIZE;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mail_add_temp_wanted_fields(mail, wanted_fields, wanted_headers);
ceb8c97c6c9fe0ee7eb544645c6bdb74dfcb519dJosef 'Jeff' Sipek mailbox_header_lookup_unref(&wanted_headers);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen}
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_append_mail_message_real(struct mail_log_mail_txn_context *ctx,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail *mail, enum mail_log_event event,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *desc)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_log_user *muser =
b66412da78711db8423288847ecfb08469609a03Timo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_message *msg;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen string_t *text;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen uoff_t size;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen /* avoid parsing through the message multiple times */
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mail_log_update_wanted_fields(mail, muser->fields);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen text = t_str_new(128);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, desc);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ": ");
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mailbox_name(text, mail);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_UID) != 0) {
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen if (event != MAIL_LOG_EVENT_SAVE &&
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen event != MAIL_LOG_EVENT_COPY)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_uid(ctx, msg, text, mail->uid);
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen else {
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen /* with mbox mail->uid contains the uid, but handle
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen this consistently with all mailbox formats */
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen mail_log_append_uid(ctx, msg, text, 0);
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen }
5b79409cf50bf77dcb23083e69e04afc310c7f64Timo Sirainen /* make sure UID is assigned to this mail */
5b79409cf50bf77dcb23083e69e04afc310c7f64Timo Sirainen mail->transaction->flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_header(text, mail, "msgid", "Message-ID");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (mail_get_physical_size(mail, &size) == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(text, "size=%"PRIuUOFF_T, size);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen else
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(text, "size=error");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(text, "vsize=%"PRIuUOFF_T, size);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen else
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(text, "vsize=error");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FROM) != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_header(text, mail, "from", "From");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_SUBJECT) != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_header(text, mail, "subject", "Subject");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, ", ");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->fields & MAIL_LOG_FIELD_FLAGS) != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_printfa(text, "flags=(");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen imap_write_flags(text, mail_get_flags(mail),
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_get_keywords(mail));
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_append(text, "), ");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen str_truncate(text, str_len(text)-2);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen msg->event = event;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen msg->text = p_strdup(ctx->pool, str_c(text));
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainenstatic void mail_log_add_dummy_msg(struct mail_log_mail_txn_context *ctx,
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen enum mail_log_event event)
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen{
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen struct mail_log_message *msg;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen msg = p_new(ctx->pool, struct mail_log_message, 1);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen msg->event = event;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen msg->ignore = TRUE;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen}
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_append_mail_message(struct mail_log_mail_txn_context *ctx,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail *mail, enum mail_log_event event,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *desc)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_log_user *muser =
b66412da78711db8423288847ecfb08469609a03Timo Sirainen MAIL_LOG_USER_CONTEXT(mail->box->storage->user);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen if ((muser->events & event) == 0) {
daccffdfe982210ab0c020e394818c20972c6b63Timo Sirainen if (event == MAIL_LOG_EVENT_SAVE ||
daccffdfe982210ab0c020e394818c20972c6b63Timo Sirainen event == MAIL_LOG_EVENT_COPY)
daccffdfe982210ab0c020e394818c20972c6b63Timo Sirainen mail_log_add_dummy_msg(ctx, event);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen }
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen T_BEGIN {
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen enum mail_lookup_abort orig_lookup_abort = mail->lookup_abort;
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen if (event != MAIL_LOG_EVENT_SAVE && muser->cached_only)
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message_real(ctx, mail, event, desc);
86448bdb60ed69566bc1093dda824133448ed7a0Timo Sirainen mail->lookup_abort = orig_lookup_abort;
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen } T_END;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void *
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_mail_transaction_begin(struct mailbox_transaction_context *t ATTR_UNUSED)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen pool_t pool;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
901d0f036826476cf75799a0fdda5777e51301e4Timo Sirainen pool = pool_alloconly_create("mail-log", 2048);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen ctx = p_new(pool, struct mail_log_mail_txn_context, 1);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen ctx->pool = pool;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return ctx;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_mail_save(void *txn, struct mail *mail)
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_SAVE, "save");
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_mail_copy(void *txn, struct mail *src, struct mail *dst)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen struct mail_private *src_pmail = (struct mail_private *)src;
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen struct mailbox *src_box = src->box;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *desc;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen if (src_pmail->vmail != NULL) {
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen /* copying a mail from virtual storage. src points to the
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen backend mail, but we want to log the virtual mailbox name. */
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen src_box = src_pmail->vmail->box;
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen }
ac8693e6a363204da30fdbc8c2fb47bb46a5d87aTimo Sirainen desc = t_strdup_printf("copy from %s",
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen str_sanitize(mailbox_get_vname(src_box),
ac8693e6a363204da30fdbc8c2fb47bb46a5d87aTimo Sirainen MAILBOX_NAME_LOG_LEN));
ac8693e6a363204da30fdbc8c2fb47bb46a5d87aTimo Sirainen mail_log_append_mail_message(ctx, dst,
ac8693e6a363204da30fdbc8c2fb47bb46a5d87aTimo Sirainen MAIL_LOG_EVENT_COPY, desc);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_mail_expunge(void *txn, struct mail *mail)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
7f3fe26555d38209e4072eaee4ac56e912733c25Aki Tuomi struct mail_private *p = (struct mail_private*)mail;
7f3fe26555d38209e4072eaee4ac56e912733c25Aki Tuomi
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_EXPUNGE,
7f3fe26555d38209e4072eaee4ac56e912733c25Aki Tuomi p->autoexpunged ? "autoexpunge" : "expunge");
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_mail_update_flags(void *txn, struct mail *mail,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen enum mail_flags old_flags)
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen enum mail_flags new_flags = mail_get_flags(mail);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (((old_flags ^ new_flags) & MAIL_DELETED) == 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen MAIL_LOG_EVENT_FLAG_CHANGE,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen "flag_change");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen } else if ((old_flags & MAIL_DELETED) == 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_DELETE,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen "delete");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen } else {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_UNDELETE,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen "undelete");
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen }
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen}
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_mail_update_keywords(void *txn, struct mail *mail,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen const char *const *old_keywords ATTR_UNUSED)
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_append_mail_message(ctx, mail, MAIL_LOG_EVENT_FLAG_CHANGE,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen "flag_change");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainenstatic void mail_log_save(const struct mail_log_message *msg, uint32_t uid)
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen{
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen if (msg->ignore) {
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen /* not logging this save/copy */
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen } else if (msg->pretext == NULL)
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen i_info("%s", msg->text);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen else if (uid != 0)
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen i_info("%s%u%s", msg->pretext, uid, msg->text);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen else
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen i_info("%serror%s", msg->pretext, msg->text);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen}
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenmail_log_mail_transaction_commit(void *txn,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_transaction_commit_changes *changes)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_message *msg;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct seq_range_iter iter;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen unsigned int n = 0;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen uint32_t uid;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen seq_range_array_iter_init(&iter, &changes->saved_uids);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen for (msg = ctx->messages; msg != NULL; msg = msg->next) {
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen if (msg->event == MAIL_LOG_EVENT_SAVE ||
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen msg->event == MAIL_LOG_EVENT_COPY) {
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen if (!seq_range_array_iter_nth(&iter, n++, &uid))
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen uid = 0;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen mail_log_save(msg, uid);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen } else {
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen i_assert(msg->pretext == NULL);
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen i_info("%s", msg->text);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen pool_unref(&ctx->pool);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void mail_log_mail_transaction_rollback(void *txn)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mail_log_mail_txn_context *ctx =
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (struct mail_log_mail_txn_context *)txn;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen pool_unref(&ctx->pool);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainenstatic void
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainenmail_log_mailbox_create(struct mailbox *box)
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen{
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_CREATE) == 0)
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen return;
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen i_info("Mailbox created: %s",
bfe4a97ad6731012202b830c1219a4c10f91d72cTimo Sirainen str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN));
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen}
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenmail_log_mailbox_delete_commit(void *txn ATTR_UNUSED, struct mailbox *box)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(box->storage->user);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_DELETE) == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen i_info("Mailbox deleted: %s",
bfe4a97ad6731012202b830c1219a4c10f91d72cTimo Sirainen str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN));
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void
71e88fae3be360e9a93b3398e743f99a6f05d2edTimo Sirainenmail_log_mailbox_rename(struct mailbox *src, struct mailbox *dest)
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(src->storage->user);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if ((muser->events & MAIL_LOG_EVENT_MAILBOX_RENAME) == 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return;
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen i_info("Mailbox renamed: %s -> %s",
bfe4a97ad6731012202b830c1219a4c10f91d72cTimo Sirainen str_sanitize(mailbox_get_vname(src), MAILBOX_NAME_LOG_LEN),
bfe4a97ad6731012202b830c1219a4c10f91d72cTimo Sirainen str_sanitize(mailbox_get_vname(dest), MAILBOX_NAME_LOG_LEN));
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen}
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic const struct notify_vfuncs mail_log_vfuncs = {
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_transaction_begin = mail_log_mail_transaction_begin,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_save = mail_log_mail_save,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_copy = mail_log_mail_copy,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_expunge = mail_log_mail_expunge,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_update_flags = mail_log_mail_update_flags,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_update_keywords = mail_log_mail_update_keywords,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_transaction_commit = mail_log_mail_transaction_commit,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mail_transaction_rollback = mail_log_mail_transaction_rollback,
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen .mailbox_create = mail_log_mailbox_create,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mailbox_delete_commit = mail_log_mailbox_delete_commit,
f60ed9d5330a6167693b047d8138769fb596d41cTimo Sirainen .mailbox_rename = mail_log_mailbox_rename
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen};
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic struct notify_context *mail_log_ctx;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenstatic struct mail_storage_hooks mail_log_mail_storage_hooks = {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen .mail_user_created = mail_log_mail_user_created
b66412da78711db8423288847ecfb08469609a03Timo Sirainen};
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenvoid mail_log_plugin_init(struct module *module)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mail_log_ctx = notify_register(&mail_log_vfuncs);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen mail_storage_hooks_add(module, &mail_log_mail_storage_hooks);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainenvoid mail_log_plugin_deinit(void)
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen mail_storage_hooks_remove(&mail_log_mail_storage_hooks);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen notify_unregister(mail_log_ctx);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen}
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainen
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainenconst char *mail_log_plugin_dependencies[] = { "notify", NULL };