From a6f259c6025fa6094d89e0db343f3c4b563482d6 Mon Sep 17 00:00:00 2001 From: Bron Gondwana Date: Wed, 24 Dec 2008 23:26:30 +1100 Subject: [PATCH] add "auditlog:" syslog statements All operations which change the UID's, messages or folders within a user's imap storage are logged with a prefix auditlog: and in a standardised format ( key= separated by spaces ) such that they're easy to parse into a database for cross linking with logs from other machines. The sessionid patch earlier gives a value which can be cross linked from these auditlog records to the precise login or lmtp delivery that caused the change, allowing reliable joining of logs from different machines and end-to-end tracking of all message changing actions. --- imap/append.c | 43 +++++++++++++++++++++++++++++++++++++++---- imap/append.h | 1 + imap/duplicate.c | 3 +++ imap/imapd.c | 6 ++++-- imap/index.c | 16 +++++++++++++++- imap/lmtp_sieve.c | 14 +++++++++++++- imap/mailbox.c | 38 +++++++++++++++++++++++++------------- imap/mboxlist.c | 34 +++++++++++++++++++++++++++++++++- imap/message.c | 7 ++++++- imap/message.h | 3 ++- imap/pop3d.c | 6 ++++-- imap/reconstruct.c | 33 +++++++++++++++++++++++++++++++-- imap/sync_commit.c | 17 +++++++++++++++++ imap/sync_support.c | 2 +- lib/imapoptions | 5 +++++ lib/libconfig.c | 4 ++++ lib/libconfig.h | 1 + 17 files changed, 204 insertions(+), 29 deletions(-) diff --git a/imap/append.c b/imap/append.c index 9904345..aa0b8d5 100644 --- a/imap/append.c +++ b/imap/append.c @@ -471,6 +471,7 @@ int append_fromstage(struct appendstate *as, struct body **body, struct mailbox *mailbox = &as->m; struct index_record message_index; char fname[MAX_MAILBOX_PATH+1]; + char *msgid = NULL; FILE *destfile; int i, r; int userflag, emptyflag; @@ -579,7 +580,7 @@ int append_fromstage(struct appendstate *as, struct body **body, if (!*body || (as->nummsg - 1)) r = message_parse_file(destfile, NULL, NULL, body); if (!r) r = message_create_record(mailbox->name, mailbox->cache_fd, - &message_index, *body); + &message_index, *body, &msgid); } if (destfile) { /* this will hopefully ensure that the link() actually happened @@ -588,6 +589,7 @@ int append_fromstage(struct appendstate *as, struct body **body, fclose(destfile); } if (r) { + if (msgid) free(msgid); append_abort(as); return r; } @@ -647,9 +649,15 @@ int append_fromstage(struct appendstate *as, struct body **body, r = mailbox_append_index(mailbox, &message_index, mailbox->exists + as->nummsg - 1, 1, 0); if (r) { + if (msgid) free(msgid); append_abort(as); return r; } + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: append sessionid=<%s> mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s> message-id=%s", + session_id(), mailbox->name, mailbox->uniqueid, message_index.uid, + message_guid_encode(&message_index.guid), msgid); + if (msgid) free(msgid); /* ok, we've successfully added a message */ as->quota_used += message_index.size; @@ -701,6 +709,7 @@ int append_fromstream(struct appendstate *as, struct body **body, struct mailbox *mailbox = &as->m; struct index_record message_index; char fname[MAX_MAILBOX_PATH+1]; + char *msgid = NULL; FILE *destfile; int i, r; int userflag, emptyflag; @@ -742,10 +751,11 @@ int append_fromstream(struct appendstate *as, struct body **body, if (!*body || (as->nummsg - 1)) r = message_parse_file(destfile, NULL, NULL, body); if (!r) r = message_create_record(mailbox->name, mailbox->cache_fd, - &message_index, *body); + &message_index, *body, &msgid); } fclose(destfile); if (r) { + if (msgid) free(msgid); append_abort(as); return r; } @@ -807,10 +817,17 @@ int append_fromstream(struct appendstate *as, struct body **body, r = mailbox_append_index(mailbox, &message_index, mailbox->exists + as->nummsg - 1, 1, 0); if (r) { + if (msgid) free(msgid); append_abort(as); return r; } - + + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: append sessionid=<%s> mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s> message-id=%s", + session_id(), mailbox->name, mailbox->uniqueid, message_index.uid, + message_guid_encode(&message_index.guid), msgid); + if (msgid) free(msgid); + /* ok, we've successfully added a message */ as->quota_used += message_index.size; @@ -834,6 +851,7 @@ int append_copy(struct mailbox *mailbox, int msg; struct index_record *message_index; char fname[MAX_MAILBOX_PATH+1]; + char **msgid; const char *src_base; unsigned long src_size; const char *startline, *endline; @@ -852,6 +870,7 @@ int append_copy(struct mailbox *mailbox, lseek(append_mailbox->cache_fd, 0L, SEEK_END); message_index = (struct index_record *) xmalloc(nummsg * sizeof(struct index_record)); + msgid = xzmalloc(nummsg * sizeof(char *)); /* Copy/link all files and cache info */ for (msg = 0; msg < nummsg; msg++) { @@ -904,6 +923,9 @@ int append_copy(struct mailbox *mailbox, r = IMAP_IOERROR; goto fail; } + + if (copymsg[msg].msgid) + msgid[msg] = xstrdup(copymsg[msg].msgid); } else { /* * Have to copy the message, possibly converting LF to CR LF @@ -950,7 +972,7 @@ int append_copy(struct mailbox *mailbox, if (!r) r = message_parse_file(destfile, NULL, NULL, &body); if (!r) r = message_create_record(append_mailbox->name, append_mailbox->cache_fd, - &message_index[msg], body); + &message_index[msg], body, &msgid[msg]); if (body) message_free_body(body); fclose(destfile); if (r) goto fail; @@ -1014,9 +1036,22 @@ int append_copy(struct mailbox *mailbox, append_mailbox->exists + as->nummsg - nummsg, nummsg, 0); + if (!r && config_auditlog) { + for (msg = 0; msg < nummsg; msg++) { + syslog(LOG_NOTICE, "auditlog: copy sessionid=<%s> srcmailbox=<%s> srcuniqueid=<%s> srcuid=<%d> mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s> message-id=%s", + session_id(), mailbox->name, mailbox->uniqueid, copymsg[msg].uid, + append_mailbox->name, append_mailbox->uniqueid, message_index[msg].uid, + message_guid_encode(&message_index[msg].guid), msgid[msg]); + } + } + fail: if (r) append_abort(as); free(message_index); + for (msg = 0; msg < nummsg; msg++) { + if (msgid[msg]) free (msgid[msg]); + } + free(msgid); return r; } diff --git a/imap/append.h b/imap/append.h index 9b13f71..afa908f 100644 --- a/imap/append.h +++ b/imap/append.h @@ -59,6 +59,7 @@ struct copymsg { unsigned long cache_version; const char *cache_begin; int cache_len; /* 0 if need to copy & parse message */ + char *msgid; /* you need to free this after use */ int seen; struct message_guid guid; bit32 system_flags; diff --git a/imap/duplicate.c b/imap/duplicate.c index e233bbb..8c00bd4 100644 --- a/imap/duplicate.c +++ b/imap/duplicate.c @@ -166,6 +166,9 @@ void duplicate_log(char *msgid, const char *name, char *action) { syslog(LOG_INFO, "dupelim: eliminated duplicate message to %s id %s (%s)", name, msgid, action); + if (config_auditlog) + syslog(LOG_NOTICE, "auditlog: duplicate sessionid=<%s> action=<%s> message-id=%s user=<%s>", + session_id(), action, msgid, name); } void duplicate_mark(char *id, int idlen, const char *to, int tolen, time_t mark, diff --git a/imap/imapd.c b/imap/imapd.c index 57462bb..7d294b5 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -564,7 +564,8 @@ static void imapd_reset(void) prot_free(imapd_out); } - syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + syslog(LOG_NOTICE, "auditlog: traffic sessionid=<%s> bytes_in=<%d> bytes_out=<%d>", + session_id(), bytes_in, bytes_out); imapd_in = imapd_out = NULL; @@ -916,7 +917,8 @@ void shut_down(int code) snmp_increment(ACTIVE_CONNECTIONS, -1); } - syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + syslog(LOG_NOTICE, "auditlog: traffic sessionid=<%s> bytes_in=<%d> bytes_out=<%d>", + session_id(), bytes_in, bytes_out); if (protin) protgroup_free(protin); diff --git a/imap/index.c b/imap/index.c index 089a1b7..556a130 100644 --- a/imap/index.c +++ b/imap/index.c @@ -1439,7 +1439,7 @@ index_copy(struct mailbox *mailbox, r = append_setup(&append_mailbox, name, MAILBOX_FORMAT_NORMAL, imapd_userid, imapd_authstate, ACL_INSERT, totalsize); - if (r) return r; + if (r) goto done; docopyuid = (append_mailbox.m.myrights & ACL_READ); @@ -1497,6 +1497,15 @@ index_copy(struct mailbox *mailbox, *copyuidp = copyuid; } + done: + /* free messageid copies */ + for (i = 0; i < copyargs.nummsg; i++) { + if (copyargs.copymsg[i].msgid) { + free(copyargs.copymsg[i].msgid); + copyargs.copymsg[i].msgid = NULL; + } + } + return r; } @@ -3597,6 +3606,11 @@ void *rock; } copyargs->copymsg[copyargs->nummsg].flag[flag] = 0; + if (copyargs->copymsg[copyargs->nummsg].cache_len) + copyargs->copymsg[copyargs->nummsg].msgid = index_get_msgid(mailbox, msgno); + else + copyargs->copymsg[copyargs->nummsg].msgid = NULL; + copyargs->nummsg++; return 0; diff --git a/imap/lmtp_sieve.c b/imap/lmtp_sieve.c index 46e6c4f..2128704 100644 --- a/imap/lmtp_sieve.c +++ b/imap/lmtp_sieve.c @@ -390,6 +390,9 @@ static int sieve_redirect(void *ac, snmp_increment(SIEVE_REDIRECT, 1); syslog(LOG_INFO, "sieve redirected: %s to: %s", m->id ? m->id : "", rc->addr); + if (config_auditlog) + syslog(LOG_NOTICE, "auditlog: redirect sessionid=<%s> message-id=%s target=<%s>", + session_id(), m->id ? m->id : "", rc->addr); return SIEVE_OK; } else { if (res == -1) { @@ -414,6 +417,9 @@ static int sieve_discard(void *ac __attribute__((unused)), /* ok, we won't file it, but log it */ syslog(LOG_INFO, "sieve discarded: %s", md->id ? md->id : ""); + if (config_auditlog) + syslog(LOG_NOTICE, "auditlog: discard sessionid=<%s> message-id=%s", + session_id(), md->id ? md->id : ""); return SIEVE_OK; } @@ -438,7 +444,10 @@ static int sieve_reject(void *ac, if (strlen(md->return_path) == 0) { syslog(LOG_INFO, "sieve: discarded reject to <> for %s id %s", sd->username, md->id ? md->id : ""); - return SIEVE_OK; + if (config_auditlog) + syslog(LOG_NOTICE, "auditlog: discard-reject sessionid=<%s> message-id=%s", + session_id(), md->id ? md->id : ""); + return SIEVE_OK; } body = msg_getheader(md, "original-recipient"); @@ -449,6 +458,9 @@ static int sieve_reject(void *ac, snmp_increment(SIEVE_REJECT, 1); syslog(LOG_INFO, "sieve rejected: %s to: %s", md->id ? md->id : "", md->return_path); + if (config_auditlog) + syslog(LOG_NOTICE, "auditlog: reject sessionid=<%s> message-id=%s target=<%s>", + session_id(), md->id ? md->id : "", md->return_path); return SIEVE_OK; } else { if (res == -1) { diff --git a/imap/mailbox.c b/imap/mailbox.c index 54bac98..7bce8e7 100644 --- a/imap/mailbox.c +++ b/imap/mailbox.c @@ -2569,20 +2569,32 @@ int mailbox_expunge(struct mailbox *mailbox, if (newcache) { fclose(newcache); - /* Delete message files */ - fname = &fpath.data; - *(fname->tail)++ = '/'; - fname->len++; - for (msgno = 0; msgno < numdeleted; msgno++) { - mailbox_message_get_fname(mailbox, deleted[msgno], - fname->tail, - sizeof(fname->buf) - fname->len); - unlink(fname->buf); + if (numdeleted > 0) { + /* Delete message files */ + fname = &fpath.data; + *(fname->tail)++ = '/'; + fname->len++; + for (msgno = 0; msgno < numdeleted; msgno++) { + mailbox_message_get_fname(mailbox, deleted[msgno], + fname->tail, + sizeof(fname->buf) - fname->len); + unlink(fname->buf); + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: unlink sessionid=<%s> mailbox=<%s> uniqueid=<%s> uid=<%d>", + session_id(), mailbox->name, mailbox->uniqueid, deleted[msgno]); + } + syslog(LOG_NOTICE, "Immediate Expunged %d messages from %s", + numdeleted, mailbox->name); } - } - - if (numdeleted > 0) { - syslog(LOG_NOTICE, "Expunged %d messages from %s", + } else if (numdeleted > 0) { + if (config_auditlog) { + for (msgno = 0; msgno < numdeleted; msgno++) { + syslog(LOG_NOTICE, + "auditlog: expunge sessionid=<%s> mailbox=<%s> uniqueid=<%s> uid=<%d>", + session_id(), mailbox->name, mailbox->uniqueid, deleted[msgno]); + } + } + syslog(LOG_NOTICE, "Delayed Expunged %d messages from %s", numdeleted, mailbox->name); } diff --git a/imap/mboxlist.c b/imap/mboxlist.c index b0a389a..b87ad7d 100644 --- a/imap/mboxlist.c +++ b/imap/mboxlist.c @@ -593,6 +593,7 @@ int mboxlist_createmailbox(char *name, int mbtype, char *partition, int localonly, int forceuser, int dbonly) { int r; + char *uniqueid = NULL; char *acl = NULL; char *newpartition = NULL; struct txn *tid = NULL; @@ -670,12 +671,18 @@ int mboxlist_createmailbox(char *name, int mbtype, char *partition, done: /* All checks compete. Time to fish or cut bait. */ if (!r && !dbonly && !(mbtype & MBTYPE_REMOTE)) { + struct mailbox mailbox; /* Filesystem Operations */ r = mailbox_create(name, newpartition, acl, NULL, ((mbtype & MBTYPE_NETNEWS) ? MAILBOX_FORMAT_NETNEWS : MAILBOX_FORMAT_NORMAL), - NULL); + &mailbox); + if (!r) { + if (mailbox.uniqueid) + uniqueid = xstrdup(mailbox.uniqueid); + mailbox_close(&mailbox); + } } if (r) { /* CREATE failed */ @@ -758,9 +765,14 @@ int mboxlist_createmailbox(char *name, int mbtype, char *partition, } } + if (!r && config_auditlog) syslog(LOG_NOTICE, + "auditlog: create sessionid=<%s> mailbox=<%s> uniqueid=<%s>", + session_id(), name, uniqueid); + if(config_mupdate_server && mupdate_h) mupdate_disconnect(&mupdate_h); if (acl) free(acl); + if (uniqueid) free (uniqueid); if (newpartition) free(newpartition); if (mboxent) free(mboxent); @@ -1001,6 +1013,7 @@ int mboxlist_deletemailbox(const char *name, int isadmin, char *userid, { int r; char *acl; + char *uniqueid = NULL; long access; struct mailbox mailbox; int deletequotaroot = 0; @@ -1122,6 +1135,9 @@ int mboxlist_deletemailbox(const char *name, int isadmin, char *userid, if ((r && !force) || isremote) goto done; + if (mailbox.uniqueid) + uniqueid = xstrdup(mailbox.uniqueid); + if (!r || force) r = mailbox_delete(&mailbox, deletequotaroot); /* @@ -1148,6 +1164,11 @@ int mboxlist_deletemailbox(const char *name, int isadmin, char *userid, } } + if (!r && config_auditlog) syslog(LOG_NOTICE, + "auditlog: delete sessionid=<%s> mailbox=<%s> uniqueid=<%s>", + session_id(), name, uniqueid); + if (uniqueid) free(uniqueid); + return r; } @@ -1169,6 +1190,7 @@ int mboxlist_renamemailbox(char *oldname, char *newname, char *partition, int oldopen = 0, newopen = 0, newreserved = 0; struct mailbox oldmailbox; struct mailbox newmailbox; + char *oldunqid = NULL, *newunqid = NULL; char *oldacl = NULL, *newacl = NULL; const char *root = NULL; struct txn *tid = NULL; @@ -1356,6 +1378,8 @@ int mboxlist_renamemailbox(char *oldname, char *newname, char *partition, goto done; } else { oldopen = 1; + if (oldmailbox.uniqueid) + oldunqid = xstrdup(oldmailbox.uniqueid); } } @@ -1369,6 +1393,8 @@ int mboxlist_renamemailbox(char *oldname, char *newname, char *partition, goto done; } else { newopen = 1; + if (newmailbox.uniqueid) + newunqid = xstrdup(newmailbox.uniqueid); } } @@ -1520,9 +1546,15 @@ int mboxlist_renamemailbox(char *oldname, char *newname, char *partition, mailbox_close(&oldmailbox); } + + if (!r && config_auditlog) syslog(LOG_NOTICE, + "auditlog: rename sessionid=<%s> oldmailbox=<%s> olduniqueid=<%s> mailbox=<%s> uniqueid=<%s>", + session_id(), oldname, oldunqid, newname, newunqid); /* free memory */ if (newacl) free(newacl); /* we're done with the new ACL */ + if (oldunqid) free (oldunqid); + if (newunqid) free (newunqid); if (newpartition) free(newpartition); if (mboxent) free(mboxent); diff --git a/imap/message.c b/imap/message.c index cf53504..4da6ad2 100644 --- a/imap/message.c +++ b/imap/message.c @@ -522,11 +522,12 @@ void message_fetch_part(struct message_content *msg, * by 'message_index'. */ int -message_create_record(cache_name, cache_fd, message_index, body) +message_create_record(cache_name, cache_fd, message_index, body, messageid) const char *cache_name; int cache_fd; struct index_record *message_index; struct body *body; +char **messageid; { int n; enum enum_value config_guidmode = config_getenum(IMAPOPT_GUID_MODE); @@ -555,6 +556,10 @@ struct body *body; message_guid_copy(&message_index->guid, &body->guid); } + if (messageid && body->message_id) { + *messageid = xstrdup(body->message_id); + } + return 0; } diff --git a/imap/message.h b/imap/message.h index c9b43fb..748fb11 100644 --- a/imap/message.h +++ b/imap/message.h @@ -96,7 +96,8 @@ extern void message_fetch_part P((struct message_content *msg, extern int message_create_record P((const char *cache_name, int cache_fd, struct index_record *message_index, - struct body *body)); + struct body *body, + char **messageid)); extern void message_free_body P((struct body *body)); #endif /* INCLUDED_MESSAGE_H */ diff --git a/imap/pop3d.c b/imap/pop3d.c index c1419c3..cd884ea 100644 --- a/imap/pop3d.c +++ b/imap/pop3d.c @@ -354,7 +354,8 @@ static void popd_reset(void) prot_free(popd_out); } - syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + syslog(LOG_NOTICE, "auditlog: traffic sessionid=<%s> bytes_in=<%d> bytes_out=<%d>", + session_id(), bytes_in, bytes_out); popd_in = popd_out = NULL; @@ -654,7 +655,8 @@ void shut_down(int code) prot_free(popd_out); } - syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + syslog(LOG_NOTICE, "auditlog: traffic sessionid=<%s> bytes_in=<%d> bytes_out=<%d>", + session_id(), bytes_in, bytes_out); #ifdef HAVE_SSL tls_shutdown_serverengine(); diff --git a/imap/reconstruct.c b/imap/reconstruct.c index 6a115e0..445cfc5 100644 --- a/imap/reconstruct.c +++ b/imap/reconstruct.c @@ -704,6 +704,9 @@ static void reconstruct_clear_expunged(struct mailbox *mailbox, if ((uid = expunge_uidmap[msgno-1].uid) > 0) { mailbox_message_get_fname(mailbox, uid, msgfname, sizeof(msgfname)); unlink(msgfname); + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: unlink-expunged mailbox=<%s> uniqueid=<%s> uid=<%d>", + mailbox->name, mailbox->uniqueid, uid); } } } @@ -832,11 +835,18 @@ int reconstruct(char *name, struct discovered *found) mympath : mypath; snprintf(mbpath, sizeof(mbpath), "%s%s", path, FNAME_HEADER); if(stat(mbpath, &sbuf) == -1) { + struct mailbox mailbox; /* Header doesn't exist, create it! */ r = mailbox_create(name, mypart, myacl, NULL, ((mytype & MBTYPE_NETNEWS) ? MAILBOX_FORMAT_NETNEWS : - MAILBOX_FORMAT_NORMAL), NULL); + MAILBOX_FORMAT_NORMAL), &mailbox); + if (!r) { + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: recreate mailbox=<%s> uniqueid=<%s>", + mailbox.name, mailbox.uniqueid); + mailbox_close(&mailbox); + } if(r) return r; } @@ -918,6 +928,10 @@ int reconstruct(char *name, struct discovered *found) mailbox.index_lock_count = 1; mailbox.pop3_last_login = 0; + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: reconstruct mailbox=<%s> uniqueid=<%s>", + mailbox.name, mailbox.uniqueid); + /* Open, lock and then map cyrus.expunge file if it exists */ r = reconstruct_open_expunge(&mailbox, &expunge_fd, &expunge_size); if (r) { @@ -1042,6 +1056,8 @@ int reconstruct(char *name, struct discovered *found) expmsg = 0; for (msg = 0; msg < uid_num; msg++) { char msgfname[MAILBOX_FNAME_LEN+1]; + int is_new = 0; + char *msgid = NULL; memset(&message_index, 0, sizeof(struct index_record)); message_index.uid = uid[msg]; @@ -1053,6 +1069,9 @@ int reconstruct(char *name, struct discovered *found) fprintf(stderr, ("reconstruct: fopen() failed for '%s' " "[error=%d] -- skipping.\n"), msgfname, errno); + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: missing mailbox=<%s> uniqueid=<%s> uid=<%d>", + mailbox.name, mailbox.uniqueid, uid[msg]); continue; } @@ -1063,6 +1082,9 @@ int reconstruct(char *name, struct discovered *found) if (sbuf.st_size == 0) { /* Zero-length message file--blow it away */ fclose(msgfile); + if (config_auditlog) syslog(LOG_NOTICE, + "auditlog: unlink-zerolength mailbox=<%s> uniqueid=<%s> uid=<%d>", + mailbox.name, mailbox.uniqueid, uid[msg]); unlink(msgfname); continue; } @@ -1128,6 +1150,7 @@ int reconstruct(char *name, struct discovered *found) message_guid_set_null(&message_index.guid); /* If we are recovering a message, reset MODSEQ */ message_index.modseq = 1; + is_new = 1; } if (message_index.modseq > highestmodseq) { @@ -1140,7 +1163,7 @@ int reconstruct(char *name, struct discovered *found) /* NB: message_create_record() will reconstruct GUID if NULL */ if (((r = message_parse_file(msgfile, NULL, NULL, &body)) != 0) || ((r = message_create_record(mailbox.name, newcache_fd, - &message_index, body)) != 0)) { + &message_index, body, &msgid)) != 0)) { r = IMAP_IOERROR; goto bail; } @@ -1164,8 +1187,14 @@ int reconstruct(char *name, struct discovered *found) if (n != INDEX_RECORD_SIZE) { r = IMAP_IOERROR; + if (msgid) free(msgid); goto bail; } + + if (is_new && config_auditlog) syslog(LOG_NOTICE, + "auditlog: found mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s> message-id=%s", + mailbox.name, mailbox.uniqueid, message_index.uid, message_guid_encode(&message_index.guid), msgid); + if (msgid) free(msgid); } /* Write out new index and expunge file headers */ diff --git a/imap/sync_commit.c b/imap/sync_commit.c index b7cf67b..969d496 100644 --- a/imap/sync_commit.c +++ b/imap/sync_commit.c @@ -671,6 +671,13 @@ static int sync_combine_commit(struct mailbox *mailbox, IMAP_ENUM_METAPARTITION_FILES_EXPUNGE, FNAME_EXPUNGE_INDEX); + if (!r && config_auditlog) { + for (item = upload_list->head ; item ; item = item->next) { + syslog(LOG_NOTICE, "auditlog: combine mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s>", + mailbox->name, mailbox->uniqueid, item->uid, message_guid_encode(&item->guid)); + } + } + bail: if (newexpunge) fclose(newexpunge); if (newcache) fclose(newcache); @@ -903,6 +910,12 @@ static int sync_append_commit(struct mailbox *mailbox, quota_add, mailbox->quota.root); } } + if (!r && config_auditlog) { + for (item = upload_list->head ; item ; item = item->next) { + syslog(LOG_NOTICE, "auditlog: append mailbox=<%s> uniqueid=<%s> uid=<%d> guid=<%s>", + mailbox->name, mailbox->uniqueid, item->uid, message_guid_encode(&item->guid)); + } + } free(index_chunk); free(cache_iovec); @@ -1325,6 +1338,10 @@ int sync_create_commit(char *name, char *partition, char *uniqueid, char *acl, } if (!r) mailbox_write_index_header(&m); + if (!r && config_auditlog) syslog(LOG_NOTICE, + "auditlog: create mailbox=<%s> uniqueid=<%s>", + name, uniqueid); + if (mboxopen) mailbox_close(&m); if (free_uniqueid) free(uniqueid); diff --git a/imap/sync_support.c b/imap/sync_support.c index 22e00e8..1147942 100644 --- a/imap/sync_support.c +++ b/imap/sync_support.c @@ -1414,7 +1414,7 @@ int sync_getsimple(struct protstream *input, struct protstream *output, r = message_parse_file(file, NULL, NULL, &body); if (!r) r = message_create_record(list->cache_name, list->cache_fd, - &record, body); + &record, body, NULL); if (body) message_free_body(body); message->hdr_size = record.header_size; diff --git a/lib/imapoptions b/lib/imapoptions index 7537331..88f8f0f 100644 --- a/lib/imapoptions +++ b/lib/imapoptions @@ -173,6 +173,11 @@ are listed with ``''. user on their mailboxes? In a large organization this can cause support problems, but it's enabled by default. */ +{ "auditlog", 0, SWITCH } +/* Should cyrus output log entries for every action taken on a message + file or mailboxes list entry? It's noisy so disabled by default, but + can be very useful for tracking down what happened if things look strange */ + { "auth_mech", "unix", STRINGLIST("unix", "pts", "krb", "krb5")} /* The authorization mechanism to use. */ diff --git a/lib/libconfig.c b/lib/libconfig.c index d863bda..fe6a79e 100644 --- a/lib/libconfig.c +++ b/lib/libconfig.c @@ -80,6 +80,7 @@ const char *config_ident = NULL; /* the service name */ int config_hashimapspool; /* f */ enum enum_value config_virtdomains; /* f */ enum enum_value config_mupdate_config; /* IMAP_ENUM_MUPDATE_CONFIG_STANDARD */ +int config_auditlog; int config_maxword; int config_maxquoted; @@ -307,6 +308,9 @@ void config_read(const char *alt_config) config_virtdomains = config_getenum(IMAPOPT_VIRTDOMAINS); config_defdomain = config_getstring(IMAPOPT_DEFAULTDOMAIN); + /* are we auditlogging */ + config_auditlog = config_getswitch(IMAPOPT_AUDITLOG); + /* look up the hostname and info we should present to the user */ config_servername = config_getstring(IMAPOPT_SERVERNAME); if (!config_servername) { diff --git a/lib/libconfig.h b/lib/libconfig.h index 7d4e441..6a8bb63 100644 --- a/lib/libconfig.h +++ b/lib/libconfig.h @@ -78,6 +78,7 @@ extern int config_hashimapspool; extern int config_implicitrights; extern enum enum_value config_virtdomains; extern enum enum_value config_mupdate_config; +extern int config_auditlog; extern int config_maxquoted; extern int config_maxword; -- 1.5.6.5