# HG changeset patch # User Timo Sirainen # Date 1226841645 -7200 # Node ID 1b7c0a216663b2e0fdd2f7c12e8161db946a184b # Parent 47198d7a5f03297777aee528fad2c2d16ab96cda ACLs: Initial support for "post" right. diff -r 47198d7a5f03 -r 1b7c0a216663 src/deliver/deliver.c --- a/src/deliver/deliver.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/deliver/deliver.c Sun Nov 16 15:20:45 2008 +0200 @@ -149,6 +149,15 @@ struct mail_namespace *ns; struct mailbox *box; enum mail_error error; + enum mailbox_open_flags open_flags = MAILBOX_OPEN_FAST | + MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_SAVEONLY | + MAILBOX_OPEN_POST_SESSION; + + if (strcasecmp(name, "INBOX") == 0) { + /* deliveries to INBOX must always succeed, + regardless of ACLs */ + open_flags |= MAILBOX_OPEN_IGNORE_ACLS; + } ns = mail_namespace_find(namespaces, &name); if (ns == NULL) { @@ -163,8 +172,7 @@ return NULL; } - box = mailbox_open(ns->storage, name, NULL, MAILBOX_OPEN_FAST | - MAILBOX_OPEN_KEEP_RECENT); + box = mailbox_open(ns->storage, name, NULL, open_flags); if (box != NULL || !deliver_set->mailbox_autocreate) return box; @@ -181,8 +189,7 @@ } /* and try opening again */ - box = mailbox_open(ns->storage, name, NULL, MAILBOX_OPEN_FAST | - MAILBOX_OPEN_KEEP_RECENT); + box = mailbox_open(ns->storage, name, NULL, open_flags); if (box == NULL) return NULL; diff -r 47198d7a5f03 -r 1b7c0a216663 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/lib-storage/index/index-storage.c Sun Nov 16 15:20:45 2008 +0200 @@ -452,6 +452,7 @@ ibox->box.storage = storage; ibox->box.name = p_strdup(ibox->box.pool, name); + ibox->box.open_flags = flags; if (ibox->box.file_create_mode == 0) { ibox->box.file_create_mode = 0600; ibox->box.dir_create_mode = 0700; @@ -462,7 +463,6 @@ array_create(&ibox->box.module_contexts, ibox->box.pool, sizeof(void *), 5); - ibox->open_flags = flags; ibox->readonly = (flags & MAILBOX_OPEN_READONLY) != 0; ibox->keep_recent = (flags & MAILBOX_OPEN_KEEP_RECENT) != 0; ibox->keep_locked = (flags & MAILBOX_OPEN_KEEP_LOCKED) != 0; diff -r 47198d7a5f03 -r 1b7c0a216663 src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Sun Nov 16 15:02:57 2008 +0200 +++ b/src/lib-storage/index/index-storage.h Sun Nov 16 15:20:45 2008 +0200 @@ -26,7 +26,6 @@ union mail_index_view_module_context view_module_ctx; struct mail_storage *storage; - enum mailbox_open_flags open_flags; struct mail_index *index; struct mail_index_view *view; diff -r 47198d7a5f03 -r 1b7c0a216663 src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/lib-storage/index/maildir/maildir-mail.c Sun Nov 16 15:20:45 2008 +0200 @@ -220,7 +220,8 @@ /* either nothing is cached, or only vsize is cached. */ mail->pop3_state = 1; } else if (vsize_dec != MAIL_CACHE_DECISION_YES && - (mail->ibox->open_flags & MAILBOX_OPEN_POP3_SESSION) == 0) { + (mail->ibox->box.open_flags & + MAILBOX_OPEN_POP3_SESSION) == 0) { /* if virtual size isn't cached permanently, POP3 isn't being used */ mail->pop3_state = -1; diff -r 47198d7a5f03 -r 1b7c0a216663 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Sun Nov 16 15:02:57 2008 +0200 +++ b/src/lib-storage/mail-storage-private.h Sun Nov 16 15:20:45 2008 +0200 @@ -187,6 +187,7 @@ /* private: */ pool_t pool; + enum mailbox_open_flags open_flags; unsigned int transaction_count; enum mailbox_feature enabled_features; diff -r 47198d7a5f03 -r 1b7c0a216663 src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Sun Nov 16 15:02:57 2008 +0200 +++ b/src/lib-storage/mail-storage.h Sun Nov 16 15:20:45 2008 +0200 @@ -59,8 +59,11 @@ /* Enable if mailbox is used for serving POP3. This allows making better caching decisions. */ MAILBOX_OPEN_POP3_SESSION = 0x40, + /* Enable if mailbox is used for saving a mail delivery using MDA. + This causes ACL plugin to use POST right rather than INSERT. */ + MAILBOX_OPEN_POST_SESSION = 0x80, /* Force opening mailbox and ignoring any ACLs */ - MAILBOX_OPEN_IGNORE_ACLS = 0x80 + MAILBOX_OPEN_IGNORE_ACLS = 0x100 }; enum mailbox_feature { diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-api.h --- a/src/plugins/acl/acl-api.h Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-api.h Sun Nov 16 15:20:45 2008 +0200 @@ -19,6 +19,8 @@ #define MAIL_ACL_WRITE_DELETED "write-deleted" /* Allow saving and copying mails into the mailbox */ #define MAIL_ACL_INSERT "insert" +/* Allow posting mails to the mailbox (e.g. Sieve fileinto) */ +#define MAIL_ACL_POST "post" /* Allow expunging mails */ #define MAIL_ACL_EXPUNGE "expunge" /* Allow creating child mailboxes */ diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-backend-vfile.c Sun Nov 16 15:20:45 2008 +0200 @@ -50,6 +50,7 @@ { 's', MAIL_ACL_WRITE_SEEN }, { 't', MAIL_ACL_WRITE_DELETED }, { 'i', MAIL_ACL_INSERT }, + { 'p', MAIL_ACL_POST }, { 'e', MAIL_ACL_EXPUNGE }, { 'k', MAIL_ACL_CREATE }, { 'x', MAIL_ACL_DELETE }, diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-backend.c --- a/src/plugins/acl/acl-backend.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-backend.c Sun Nov 16 15:20:45 2008 +0200 @@ -16,6 +16,7 @@ MAIL_ACL_WRITE_SEEN, MAIL_ACL_WRITE_DELETED, MAIL_ACL_INSERT, + MAIL_ACL_POST, MAIL_ACL_EXPUNGE, MAIL_ACL_CREATE, MAIL_ACL_DELETE, diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-mailbox-list.c --- a/src/plugins/acl/acl-mailbox-list.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-mailbox-list.c Sun Nov 16 15:20:45 2008 +0200 @@ -401,6 +401,11 @@ const char *acl_env, *current_username, *owner_username; bool owner = TRUE; + if ((list->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) { + /* no ACL checks for internal namespaces (deliver) */ + return; + } + acl_env = getenv("ACL"); i_assert(acl_env != NULL); @@ -427,7 +432,7 @@ flags = mailbox_list_get_flags(list); if ((flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0) { - /* not necessarily, but safer to do this for now.. */ + /* not necessarily, but safer to do this for now. */ i_fatal("mail_full_filesystem_access=yes is " "incompatible with ACLs"); } diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-mailbox.c --- a/src/plugins/acl/acl-mailbox.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-mailbox.c Sun Nov 16 15:20:45 2008 +0200 @@ -67,11 +67,14 @@ static bool acl_is_readonly(struct mailbox *box) { struct acl_mailbox *abox = ACL_CONTEXT(box); + enum acl_storage_rights save_right; if (abox->module_ctx.super.is_readonly(box)) return TRUE; - if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_INSERT) > 0) + save_right = (box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ? + ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT; + if (acl_mailbox_right_lookup(box, save_right) > 0) return FALSE; if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_EXPUNGE) > 0) return FALSE; @@ -264,8 +267,11 @@ { struct mailbox *box = ctx->transaction->box; struct acl_mailbox *abox = ACL_CONTEXT(box); + enum acl_storage_rights save_right; - if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_INSERT) <= 0) + save_right = (box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ? + ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT; + if (acl_mailbox_right_lookup(box, save_right) <= 0) return -1; if (acl_save_get_flags(box, &ctx->flags, &ctx->keywords) < 0) return -1; @@ -279,8 +285,11 @@ struct mail *dest_mail) { struct acl_mailbox *abox = ACL_CONTEXT(t->box); + enum acl_storage_rights save_right; - if (acl_mailbox_right_lookup(t->box, ACL_STORAGE_RIGHT_INSERT) <= 0) + save_right = (t->box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ? + ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT; + if (acl_mailbox_right_lookup(t->box, save_right) <= 0) return -1; if (acl_save_get_flags(t->box, &flags, &keywords) < 0) return -1; diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-storage.c --- a/src/plugins/acl/acl-storage.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-storage.c Sun Nov 16 15:20:45 2008 +0200 @@ -18,6 +18,7 @@ MAIL_ACL_WRITE_SEEN, MAIL_ACL_WRITE_DELETED, MAIL_ACL_INSERT, + MAIL_ACL_POST, MAIL_ACL_EXPUNGE, MAIL_ACL_CREATE, MAIL_ACL_DELETE, @@ -95,19 +96,21 @@ { struct acl_mail_storage *astorage = ACL_CONTEXT(storage); struct mailbox *box; + enum acl_storage_rights save_right; bool can_see; int ret; /* mailbox can be opened either for reading or appending new messages */ if ((flags & MAILBOX_OPEN_IGNORE_ACLS) != 0) { ret = 1; - } else if ((flags & MAILBOX_OPEN_SAVEONLY) != 0) { + } else if ((flags & MAILBOX_OPEN_SAVEONLY) == 0) { ret = acl_storage_have_right(storage, name, - ACL_STORAGE_RIGHT_INSERT, + ACL_STORAGE_RIGHT_READ, &can_see); } else { - ret = acl_storage_have_right(storage, name, - ACL_STORAGE_RIGHT_READ, + save_right = (flags & MAILBOX_OPEN_POST_SESSION) != 0 ? + ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT; + ret = acl_storage_have_right(storage, name, save_right, &can_see); } if (ret <= 0) { @@ -128,6 +131,8 @@ if (box == NULL) return NULL; + if ((flags & MAILBOX_OPEN_IGNORE_ACLS) != 0) + return box; return acl_mailbox_open_box(box); } @@ -164,6 +169,11 @@ struct acl_mail_storage *astorage; struct acl_backend *backend; + if ((storage->ns->flags & NAMESPACE_FLAG_INTERNAL) != 0) { + /* no ACL checks for internal namespaces (deliver) */ + return; + } + astorage = p_new(storage->pool, struct acl_mail_storage, 1); astorage->module_ctx.super = storage->v; storage->v.destroy = acl_storage_destroy; diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/acl/acl-storage.h --- a/src/plugins/acl/acl-storage.h Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/acl/acl-storage.h Sun Nov 16 15:20:45 2008 +0200 @@ -8,6 +8,7 @@ ACL_STORAGE_RIGHT_WRITE_SEEN, ACL_STORAGE_RIGHT_WRITE_DELETED, ACL_STORAGE_RIGHT_INSERT, + ACL_STORAGE_RIGHT_POST, ACL_STORAGE_RIGHT_EXPUNGE, ACL_STORAGE_RIGHT_CREATE, ACL_STORAGE_RIGHT_DELETE, diff -r 47198d7a5f03 -r 1b7c0a216663 src/plugins/imap-acl/imap-acl-plugin.c --- a/src/plugins/imap-acl/imap-acl-plugin.c Sun Nov 16 15:02:57 2008 +0200 +++ b/src/plugins/imap-acl/imap-acl-plugin.c Sun Nov 16 15:20:45 2008 +0200 @@ -38,6 +38,7 @@ { 's', MAIL_ACL_WRITE_SEEN }, { 't', MAIL_ACL_WRITE_DELETED }, { 'i', MAIL_ACL_INSERT }, + { 'p', MAIL_ACL_POST }, { 'e', MAIL_ACL_EXPUNGE }, { 'k', MAIL_ACL_CREATE }, { 'x', MAIL_ACL_DELETE }, @@ -244,7 +245,10 @@ mailbox_close(&box); return TRUE; } - if (*rights == NULL) { + /* Post right alone doesn't give permissions to see if the mailbox + exists or not. Only mail deliveries care about that. */ + if (*rights == NULL || + (strcmp(*rights, MAIL_ACL_POST) == 0 && rights[1] == NULL)) { client_send_tagline(cmd, t_strdup_printf( "NO ["IMAP_RESP_CODE_NONEXISTENT"] " MAIL_ERRSTR_MAILBOX_NOT_FOUND, real_mailbox));