From 06c07ce781d6cac85d840b2454d85b8cd5267c26 Mon Sep 17 00:00:00 2001 From: Nathan Dushman Date: Thu, 23 Jan 2003 22:03:12 +0000 Subject: [PATCH] The attached patch provides improved support for IMAP ACLs (on servers that support them). This means that mutt will now write the Seen flag in mailboxes that allow it, even if the mailbox doesn't allow other changes. --- curs_main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++- flags.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- imap/imap.c | 8 ++++++- pager.c | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 4 deletions(-) diff --git a/curs_main.c b/curs_main.c index 2cc2ada2..ed4a4140 100644 --- a/curs_main.c +++ b/curs_main.c @@ -30,7 +30,7 @@ #endif #ifdef USE_IMAP -#include "imap.h" +#include "imap_private.h" #endif #include "mutt_crypt.h" @@ -78,6 +78,17 @@ static const char *No_visible = N_("No visible messages."); break; \ } +#ifdef USE_IMAP +/* the error message returned here could be better. */ +#define CHECK_IMAP_ACL(aclbit) if (Context->magic == M_IMAP) \ + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,aclbit)){ \ + mutt_flushinp(); \ + mutt_error ("Operation not permitted by the IMAP ACL for this mailbox"); \ + break; \ + } +#endif + #define CHECK_ATTACH if(option(OPTATTACHMSG)) \ {\ mutt_flushinp (); \ @@ -744,6 +755,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + CHECK_ATTACH; mutt_pattern_func (M_DELETE, _("Delete messages matching: ")); menu->redraw = REDRAW_INDEX | REDRAW_STATUS; @@ -901,6 +917,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: ")) == 0) menu->redraw = REDRAW_INDEX | REDRAW_STATUS; break; @@ -1342,6 +1363,10 @@ int mutt_index_menu (void) } #endif +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_WRITE); +#endif + if (tag) { for (j = 0; j < Context->vcount; j++) @@ -1377,6 +1402,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_SEEN); +#endif + if (tag) { for (j = 0; j < Context->vcount; j++) @@ -1489,6 +1519,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +/* #ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_WRITE); +#endif */ + if (mutt_change_flag (tag ? NULL : CURHDR, (op == OP_MAIN_SET_FLAG)) == 0) { menu->redraw = REDRAW_STATUS; @@ -1627,6 +1662,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + if (tag) { mutt_tag_set_flag (M_DELETE, 1); @@ -1667,6 +1707,10 @@ int mutt_index_menu (void) CHECK_VISIBLE; CHECK_READONLY; +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + rc = mutt_thread_set_flag (CURHDR, M_DELETE, 1, op == OP_DELETE_THREAD ? 0 : 1); @@ -1716,6 +1760,10 @@ int mutt_index_menu (void) } #endif +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_INSERT); +#endif + mutt_edit_message (Context, tag ? NULL : CURHDR); menu->redraw = REDRAW_FULL; @@ -1814,6 +1862,10 @@ int mutt_index_menu (void) CHECK_VISIBLE; CHECK_READONLY; +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_SEEN); +#endif + rc = mutt_thread_set_flag (CURHDR, M_READ, 1, op == OP_MAIN_READ_THREAD ? 0 : 1); @@ -1896,6 +1948,11 @@ int mutt_index_menu (void) CHECK_MSGCOUNT; CHECK_VISIBLE; CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + if (tag) { mutt_tag_set_flag (M_DELETE, 0); @@ -1922,6 +1979,10 @@ int mutt_index_menu (void) CHECK_VISIBLE; CHECK_READONLY; +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0, op == OP_UNDELETE_THREAD ? 0 : 1); diff --git a/flags.c b/flags.c index 9eedbea3..cba37978 100644 --- a/flags.c +++ b/flags.c @@ -21,6 +21,10 @@ #include "sort.h" #include "mx.h" +#ifdef USE_IMAP +#include "imap_private.h" +#endif + void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) { int changed = h->changed; @@ -33,9 +37,17 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) switch (flag) { case M_DELETE: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_DELETE)) + return; +#endif + if (bf) { - if (!h->deleted) + if (!h->deleted && !ctx->readonly) { h->deleted = 1; if (upd_ctx) ctx->deleted++; @@ -76,6 +88,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) break; case M_NEW: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN)) + return; +#endif + if (bf) { if (h->read || h->old) @@ -103,6 +123,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) break; case M_OLD: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN)) + return; +#endif + if (bf) { if (!h->old) @@ -125,6 +153,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) break; case M_READ: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN)) + return; +#endif + if (bf) { if (!h->read) @@ -149,6 +185,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) break; case M_REPLIED: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_WRITE)) + return; +#endif + if (bf) { if (!h->replied) @@ -174,6 +218,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) break; case M_FLAG: + +#ifdef USE_IMAP + if (Context->magic == M_IMAP) + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_WRITE)) + return; +#endif + if (bf) { if (!h->flagged) diff --git a/imap/imap.c b/imap/imap.c index f9feccdf..18852aa1 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -611,7 +611,8 @@ int imap_open_mailbox (CONTEXT* ctx) goto fail; /* check for READ-ONLY notification */ - if (!ascii_strncasecmp (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11)) + if (!ascii_strncasecmp (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11) \ + && !mutt_bit_isset (idata->capabilities, ACL)) { dprint (2, (debugfile, "Mailbox is read-only.\n")); ctx->readonly = 1; @@ -644,6 +645,11 @@ int imap_open_mailbox (CONTEXT* ctx) { if (imap_check_acl (idata)) goto fail; + if (!(mutt_bit_isset(idata->rights, IMAP_ACL_DELETE) || + mutt_bit_isset(idata->rights, IMAP_ACL_SEEN) || + mutt_bit_isset(idata->rights, IMAP_ACL_WRITE) || + mutt_bit_isset(idata->rights, IMAP_ACL_INSERT))) + ctx->readonly = 1; } /* assume we have all rights if ACL is unavailable */ else diff --git a/pager.c b/pager.c index 4d7b9206..a9255719 100644 --- a/pager.c +++ b/pager.c @@ -30,7 +30,7 @@ #include "mx.h" #ifdef USE_IMAP -#include "imap.h" +#include "imap_private.h" #endif #include "mutt_crypt.h" @@ -75,6 +75,17 @@ static const char *Function_not_permitted_in_attach_message_mode = N_("Function break; \ } +#ifdef USE_IMAP +/* the error message returned here could be better. */ +#define CHECK_IMAP_ACL(aclbit) if (Context->magic == M_IMAP) \ + if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \ + && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,aclbit)){ \ + mutt_flushinp(); \ + mutt_error ("Operation not permitted by the IMAP ACL for this mailbox"); \ + break; \ + } +#endif + struct q_class_t { int length; @@ -2175,6 +2186,11 @@ search_next: case OP_DELETE: CHECK_MODE(IsHeader (extra)); CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + mutt_set_flag (Context, extra->hdr, M_DELETE, 1); if (option (OPTDELETEUNTAG)) mutt_set_flag (Context, extra->hdr, M_TAG, 0); @@ -2191,6 +2207,10 @@ search_next: CHECK_MODE(IsHeader (extra)); CHECK_READONLY; +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + r = mutt_thread_set_flag (extra->hdr, M_DELETE, 1, ch == OP_DELETE_THREAD ? 0 : 1); @@ -2319,6 +2339,10 @@ search_next: } #endif +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_WRITE); +#endif + mutt_set_flag (Context, extra->hdr, M_FLAG, !extra->hdr->flagged); redraw = REDRAW_STATUS | REDRAW_INDEX; if (option (OPTRESOLVE)) @@ -2468,6 +2492,11 @@ search_next: case OP_TOGGLE_NEW: CHECK_MODE(IsHeader (extra)); CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_SEEN); +#endif + if (extra->hdr->read || extra->hdr->old) mutt_set_flag (Context, extra->hdr, M_NEW, 1); else if (!first) @@ -2485,6 +2514,11 @@ search_next: case OP_UNDELETE: CHECK_MODE(IsHeader (extra)); CHECK_READONLY; + +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + mutt_set_flag (Context, extra->hdr, M_DELETE, 0); redraw = REDRAW_STATUS | REDRAW_INDEX; if (option (OPTRESOLVE)) @@ -2499,6 +2533,10 @@ search_next: CHECK_MODE(IsHeader (extra)); CHECK_READONLY; +#ifdef USE_IMAP +CHECK_IMAP_ACL(IMAP_ACL_DELETE); +#endif + r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0, ch == OP_UNDELETE_THREAD ? 0 : 1); -- 2.40.0