]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
ACLs: Initial support for "post" right.
authorTimo Sirainen <tss@iki.fi>
Sun, 16 Nov 2008 13:20:45 +0000 (15:20 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 16 Nov 2008 13:20:45 +0000 (15:20 +0200)
--HG--
branch : HEAD

14 files changed:
src/deliver/deliver.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.h
src/plugins/acl/acl-api.h
src/plugins/acl/acl-backend-vfile.c
src/plugins/acl/acl-backend.c
src/plugins/acl/acl-mailbox-list.c
src/plugins/acl/acl-mailbox.c
src/plugins/acl/acl-storage.c
src/plugins/acl/acl-storage.h
src/plugins/imap-acl/imap-acl-plugin.c

index 216eb64010c63f78d08ef4aa8ea3e0321a2787ed..87a74241fe97b5440827216341e8d417bb1f0765 100644 (file)
@@ -149,6 +149,15 @@ mailbox_open_or_create_synced(struct mail_namespace *namespaces,
        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 @@ mailbox_open_or_create_synced(struct mail_namespace *namespaces,
                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 @@ mailbox_open_or_create_synced(struct mail_namespace *namespaces,
        }
 
        /* 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;
 
index 969d51bfca5f5dd48a80215ee22bef0bd86351c2..a2127bf32e00e5414e52b3e80592e71d9057bc79 100644 (file)
@@ -452,6 +452,7 @@ void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
 
        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 @@ void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
        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;
index 3b7bc7938a584286e2ea209e7e2f8ffed62bf3c6..db3906b4f6fa9616ed734526961b0e3f4b8616cd 100644 (file)
@@ -26,7 +26,6 @@ struct index_mailbox {
        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;
index a29b06a48fe6d413514744c2d8c6b47a3c4fbdbc..c6449bbc20f2288c5e043f9ede6b4ed4d644f6b8 100644 (file)
@@ -220,7 +220,8 @@ static int maildir_get_pop3_state(struct index_mail *mail)
                /* 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;
index 2bd036da0673251ef99ceb80087e9dd741a1ab3c..ba8ed012135d2283e2355864fc038114f4dbeec8 100644 (file)
@@ -187,6 +187,7 @@ struct mailbox {
 /* private: */
        pool_t pool;
 
+       enum mailbox_open_flags open_flags;
        unsigned int transaction_count;
        enum mailbox_feature enabled_features;
 
index 21cedd44cde440b719489e076406f00fe8a6fd07..63acc91c290e849e623d2b24a336b1f104f4e44d 100644 (file)
@@ -59,8 +59,11 @@ enum mailbox_open_flags {
        /* 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 {
index b56e75b50b13b759dcc72d45aeb5c973d4bceb93..785420684fdd4913cf6491715e15d922f6750ad0 100644 (file)
@@ -19,6 +19,8 @@ struct acl_object;
 #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 */
index 0f9b11efc4ccf1f780b1029a2288759dd3f4b7b9..27d18f8d58fefc363a1b060b6fedfaf94c497066 100644 (file)
@@ -50,6 +50,7 @@ static const struct acl_letter_map acl_letter_map[] = {
        { '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 },
index 62cefe17b977f99c9223cc8cf92ca182fbef76f2..9bdd49335b858551dd0bc79b6a29a90016d49716 100644 (file)
@@ -16,6 +16,7 @@ static const char *const owner_mailbox_rights[] = {
        MAIL_ACL_WRITE_SEEN,
        MAIL_ACL_WRITE_DELETED,
        MAIL_ACL_INSERT,
+       MAIL_ACL_POST,
        MAIL_ACL_EXPUNGE,
        MAIL_ACL_CREATE,
        MAIL_ACL_DELETE,
index b6f65d572406c20aebf9b14537f652d54717ea0e..f3d90c9a2c72873767ddbe0c28e4d52077dfcf03 100644 (file)
@@ -401,6 +401,11 @@ void acl_mailbox_list_created(struct mailbox_list *list)
        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 @@ void acl_mailbox_list_created(struct mailbox_list *list)
 
        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");
        }
index b994c39735930a397a3cbef9050820900e2d72b3..eec68fa3620096a9ebd7d559fde5a0d2a226ded9 100644 (file)
@@ -67,11 +67,14 @@ int acl_mailbox_right_lookup(struct mailbox *box, unsigned int right_idx)
 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 @@ acl_save_begin(struct mail_save_context *ctx, struct istream *input)
 {
        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 @@ acl_copy(struct mailbox_transaction_context *t, struct mail *mail,
         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;
index 2474535ab6e1e5d62dc2ba7abd26fae7944ab758..a5bd51a4add946e768bf0a7b7a777cae09adb608 100644 (file)
@@ -18,6 +18,7 @@ static const char *acl_storage_right_names[ACL_STORAGE_RIGHT_COUNT] = {
        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 @@ acl_mailbox_open(struct mail_storage *storage, const char *name,
 {
        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 @@ acl_mailbox_open(struct mail_storage *storage, const char *name,
        if (box == NULL)
                return NULL;
 
+       if ((flags & MAILBOX_OPEN_IGNORE_ACLS) != 0)
+               return box;
        return acl_mailbox_open_box(box);
 }
 
@@ -164,6 +169,11 @@ void acl_mail_storage_created(struct mail_storage *storage)
        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;
index 761eb8619118a3edb2e9d8fcbdeac3496b0bbe14..b2db1924741571c96524e0dff4600c86205a3eee 100644 (file)
@@ -8,6 +8,7 @@ enum acl_storage_rights {
        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,
index 6dc4b261b64e8bf5843d2941f79c3af4776afcc8..3c4ba38ee8b8b8582a7ae559a02774ebe4724572 100644 (file)
@@ -38,6 +38,7 @@ static const struct imap_acl_letter_map imap_acl_letter_map[] = {
        { '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 @@ static bool cmd_myrights(struct client_command_context *cmd)
                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));