#endif
#ifdef USE_IMAP
-#include "imap.h"
+#include "imap_private.h"
#endif
#include "mutt_crypt.h"
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 (); \
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;
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;
}
#endif
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_WRITE);
+#endif
+
if (tag)
{
for (j = 0; j < Context->vcount; j++)
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++)
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;
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);
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);
}
#endif
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_INSERT);
+#endif
+
mutt_edit_message (Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
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);
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);
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);
#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;
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++;
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)
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)
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)
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)
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)
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;
{
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
#include "mx.h"
#ifdef USE_IMAP
-#include "imap.h"
+#include "imap_private.h"
#endif
#include "mutt_crypt.h"
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;
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);
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);
}
#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))
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)
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))
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);