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_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Deletion"));
CHECK_ATTACH;
mutt_pattern_func (M_DELETE, _("Delete messages matching: "));
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Undeletion"));
if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: ")) ==
0)
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_POP
- if (Context->magic == M_POP) {
- mutt_flushinp ();
- mutt_error (_("Can't change 'important' flag on POP server."));
-
- break;
- }
-#endif
-
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_WRITE);
-#endif
-
-#ifdef USE_NNTP
- if (Context->magic == M_NNTP) {
- mutt_flushinp ();
- mutt_error (_("Can't change 'important' flag on NNTP server."));
-
- break;
- }
-#endif
+ CHECK_MX_ACL (Context, ACL_WRITE, _("Flagging"));
if (tag) {
for (j = 0; j < Context->vcount; j++) {
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_SEEN);
-#endif
+ CHECK_MX_ACL (Context, ACL_SEEN, _("Toggling"));
if (tag) {
for (j = 0; j < Context->vcount; j++) {
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_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Deletion"));
if (tag) {
mutt_tag_set_flag (M_DELETE, 1);
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Deletion"));
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 1,
op == OP_DELETE_THREAD ? 0 : 1);
CHECK_READONLY;
CHECK_ATTACH;
-#ifdef USE_POP
- if (Context->magic == M_POP) {
- mutt_flushinp ();
- mutt_error (_("Can't edit message on POP server."));
-
- break;
- }
-#endif
-
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_INSERT);
-#endif
-
-#ifdef USE_NNTP
- if (Context->magic == M_NNTP) {
- mutt_flushinp ();
- mutt_error (_("Can't edit message on newsserver."));
-
- break;
- }
-#endif
+ CHECK_MX_ACL (Context, ACL_INSERT, _("Editing"));
if (option (OPTPGPAUTODEC)
&& (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_SEEN);
-#endif
+ CHECK_MX_ACL (Context, ACL_SEEN, _("Marking as read"));
rc = mutt_thread_set_flag (CURHDR, M_READ, 1,
op == OP_MAIN_READ_THREAD ? 0 : 1);
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Undeletion"));
if (tag) {
mutt_tag_set_flag (M_DELETE, 0);
CHECK_VISIBLE;
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Undeletion"));
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
op == OP_UNDELETE_THREAD ? 0 : 1)
switch (flag) {
case M_DELETE:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_DELETE))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_DELETE))
+ return;
if (bf) {
if (!h->deleted && !ctx->readonly) {
case M_NEW:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_SEEN))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_SEEN))
+ return;
if (bf) {
if (h->read || h->old) {
case M_OLD:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_SEEN))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_SEEN))
+ return;
if (bf) {
if (!h->old) {
case M_READ:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_SEEN))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_SEEN))
+ return;
if (bf) {
if (!h->read) {
case M_REPLIED:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_WRITE))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_WRITE))
+ return;
if (bf) {
if (!h->replied) {
case M_FLAG:
-#ifdef USE_IMAP
- if (ctx && ctx->magic == M_IMAP)
- if (mutt_bit_isset (((IMAP_DATA *) ctx->data)->capabilities, ACL)
- && !mutt_bit_isset (((IMAP_DATA *) ctx->data)->rights,
- IMAP_ACL_WRITE))
- return;
-#endif
+ if (!mx_acl_check (ctx, ACL_WRITE))
+ return;
if (bf) {
if (!h->flagged) {
while (*s && !isspace ((unsigned char) *s)) {
switch (*s) {
case 'l':
- mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
+ mutt_bit_set (idata->rights, ACL_LOOKUP);
break;
case 'r':
- mutt_bit_set (idata->rights, IMAP_ACL_READ);
+ mutt_bit_set (idata->rights, ACL_READ);
break;
case 's':
- mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
+ mutt_bit_set (idata->rights, ACL_SEEN);
break;
case 'w':
- mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
+ mutt_bit_set (idata->rights, ACL_WRITE);
break;
case 'i':
- mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
+ mutt_bit_set (idata->rights, ACL_INSERT);
break;
case 'p':
- mutt_bit_set (idata->rights, IMAP_ACL_POST);
+ mutt_bit_set (idata->rights, ACL_POST);
break;
case 'c':
- mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
+ mutt_bit_set (idata->rights, ACL_CREATE);
break;
case 'd':
- mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
+ mutt_bit_set (idata->rights, ACL_DELETE);
break;
case 'a':
- mutt_bit_set (idata->rights, IMAP_ACL_ADMIN);
+ mutt_bit_set (idata->rights, ACL_ADMIN);
break;
}
s++;
if (mutt_bit_isset (idata->capabilities, ACL)) {
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)))
+ if (!(mutt_bit_isset (idata->rights, ACL_DELETE) ||
+ mutt_bit_isset (idata->rights, ACL_SEEN) ||
+ mutt_bit_isset (idata->rights, ACL_WRITE) ||
+ mutt_bit_isset (idata->rights, ACL_INSERT)))
ctx->readonly = 1;
}
/* assume we have all rights if ACL is unavailable */
else {
- mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
- mutt_bit_set (idata->rights, IMAP_ACL_READ);
- mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
- mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
- mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
- mutt_bit_set (idata->rights, IMAP_ACL_POST);
- mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
- mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
+ mutt_bit_set (idata->rights, ACL_LOOKUP);
+ mutt_bit_set (idata->rights, ACL_READ);
+ mutt_bit_set (idata->rights, ACL_SEEN);
+ mutt_bit_set (idata->rights, ACL_WRITE);
+ mutt_bit_set (idata->rights, ACL_INSERT);
+ mutt_bit_set (idata->rights, ACL_POST);
+ mutt_bit_set (idata->rights, ACL_CREATE);
+ mutt_bit_set (idata->rights, ACL_DELETE);
}
ctx->hdrmax = count;
flags[0] = '\0';
- imap_set_flag (idata, IMAP_ACL_SEEN, hdr->read, "\\Seen ",
+ imap_set_flag (idata, ACL_SEEN, hdr->read, "\\Seen ",
flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, hdr->flagged,
+ imap_set_flag (idata, ACL_WRITE, hdr->flagged,
"\\Flagged ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, hdr->replied,
+ imap_set_flag (idata, ACL_WRITE, hdr->replied,
"\\Answered ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_DELETE, hdr->deleted,
+ imap_set_flag (idata, ACL_DELETE, hdr->deleted,
"\\Deleted ", flags, sizeof (flags));
/* now make sure we don't lose custom tags */
- if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE))
+ if (mutt_bit_isset (idata->rights, ACL_WRITE))
imap_add_keywords (flags, hdr, idata->flags, sizeof (flags));
mutt_remove_trailing_ws (flags);
* explicitly revoke all system flags (if we have permission) */
if (!*flags)
{
- imap_set_flag (idata, IMAP_ACL_SEEN, 1, "\\Seen ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Flagged ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Answered ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_DELETE, 1, "\\Deleted ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_SEEN, 1, "\\Seen ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, 1, "\\Flagged ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, 1, "\\Answered ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_DELETE, 1, "\\Deleted ", flags, sizeof (flags));
mutt_remove_trailing_ws (flags);
memset (&cmd, 0, sizeof (cmd));
/* if we are expunging anyway, we can do deleted messages very quickly... */
- if (expunge && mutt_bit_isset (idata->rights, IMAP_ACL_DELETE)) {
+ if (expunge && mutt_bit_isset (idata->rights, ACL_DELETE)) {
mutt_buffer_addstr (&cmd, "UID STORE ");
deleted = imap_make_msg_set (idata, &cmd, M_DELETE, 1);
/* We must send an EXPUNGE command if we're not closing. */
if (expunge && !(ctx->closing) &&
- mutt_bit_isset (idata->rights, IMAP_ACL_DELETE)) {
+ mutt_bit_isset (idata->rights, ACL_DELETE)) {
mutt_message _("Expunging messages from server...");
/* Set expunge bit so we don't get spurious reopened messages */
IMAP_NS_SHARED
};
-/* ACL Rights */
-enum {
- IMAP_ACL_LOOKUP = 0,
- IMAP_ACL_READ,
- IMAP_ACL_SEEN,
- IMAP_ACL_WRITE,
- IMAP_ACL_INSERT,
- IMAP_ACL_POST,
- IMAP_ACL_CREATE,
- IMAP_ACL_DELETE,
- IMAP_ACL_ADMIN,
-
- RIGHTSMAX
-};
+/* ACL Rights are moved to ../mx.h */
/* Capabilities we are interested in */
enum {
-
-
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
return ((s == U_IMAP || s == U_IMAPS) ? M_IMAP : -1);
}
+static int acl_check_imap (CONTEXT* ctx, int bit) {
+ return (!mutt_bit_isset (((IMAP_DATA*) ctx->data)->capabilities, ACL) ||
+ mutt_bit_isset (((IMAP_DATA*) ctx->data)->rights, bit));
+}
+
mx_t* imap_reg_mx (void) {
mx_t* fmt = safe_calloc (1, sizeof (mx_t));
fmt->mx_is_magic = imap_is_magic;
fmt->mx_access = imap_access;
fmt->mx_open_mailbox = imap_open_mailbox;
+ fmt->mx_acl_check = acl_check_imap;
return (fmt);
}
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
/*
* interface of mx_t implementation for IMAP
return (-1);
}
+int mx_acl_check (CONTEXT* ctx, int flag) {
+ if (!ctx || ctx->magic <= 0 || ctx->magic >= MailboxFormats->length)
+ return (0);
+ /* if no acl_check defined for module, assume permission is granted */
+ if (!MX_COMMAND(ctx->magic-1,mx_acl_check))
+ return (1);
+ return (MX_COMMAND(ctx->magic-1,mx_acl_check)(ctx,flag));
+}
+
void mx_init (void) {
#ifdef DEBUG
int i = 0;
#endif
};
+enum {
+ ACL_LOOKUP = 0,
+ ACL_READ,
+ ACL_SEEN,
+ ACL_WRITE,
+ ACL_INSERT,
+ ACL_POST,
+ ACL_CREATE,
+ ACL_DELETE,
+ ACL_ADMIN,
+
+ RIGHTSMAX
+};
+
+/* ugly hack to define macro once (for pager+index) */
+#define CHECK_MX_ACL(c,f,s) if(!mx_acl_check(c,f)) \
+ {\
+ mutt_flushinp (); \
+ mutt_error(_("%s not permitted by ACL."), s); \
+ break; \
+ }
+
typedef struct {
/* folder magic */
int type;
int (*mx_access) (const char*, int);
/* read mailbox into ctx structure */
int (*mx_open_mailbox) (CONTEXT*);
+ /* check ACL flags; if not implemented, always assume granted
+ * permissions */
+ int (*mx_acl_check) (CONTEXT*, int);
} mx_t;
/* called from main: init all folder types */
WHERE short DefaultMagic INITVAL (M_MBOX);
+/*
+ * please use the following _ONLY_ when doing "something"
+ * with folders
+ */
+
CONTEXT *mx_open_mailbox (const char *, int, CONTEXT *);
MESSAGE *mx_open_message (CONTEXT *, int);
int mx_access (const char *, int);
int mx_check_empty (const char *);
+int mx_acl_check (CONTEXT*, int);
+
void mx_alloc_memory (CONTEXT *);
void mx_update_context (CONTEXT *, int);
void mx_update_tables (CONTEXT *, int);
-
-
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
return ((s == U_NNTP || s == U_NNTPS) ? M_NNTP : -1);
}
+static int acl_check_nntp (CONTEXT* ctx, int bit) {
+ switch (bit) {
+ case ACL_INSERT: /* editing messages */
+ case ACL_WRITE: /* change importance */
+ return (0);
+ case ACL_DELETE: /* (un)deletion */
+ case ACL_SEEN: /* mark as read */
+ return (1);
+ default:
+ return (0);
+ }
+}
+
/* called by nntp_init(); don't call elsewhere */
mx_t* nntp_reg_mx (void) {
mx_t* fmt = safe_calloc (1, sizeof (mx_t));
fmt->type = M_NNTP;
fmt->mx_is_magic = nntp_is_magic;
fmt->mx_open_mailbox = nntp_open_mailbox;
+ fmt->mx_acl_check = acl_check_nntp;
return (fmt);
}
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
/*
* interface of mx_t implementation for NNTP
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;
int index;
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Deletion"));
mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
mutt_set_flag (Context, extra->hdr, M_PURGED,
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Deletion"));
r = mutt_thread_set_flag (extra->hdr, M_DELETE, 1,
ch == OP_DELETE_THREAD ? 0 : 1);
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_POP
- if (Context->magic == M_POP) {
- mutt_flushinp ();
- mutt_error _("Can't change 'important' flag on POP server.");
-
- break;
- }
-#endif
-
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_WRITE);
-#endif
-
-#ifdef USE_NNTP
- if (Context->magic == M_NNTP) {
- mutt_flushinp ();
- mutt_error _("Can't change 'important' flag on NNTP server.");
-
- break;
- }
-#endif
+ CHECK_MX_ACL (Context, ACL_WRITE, _("Flagging"));
mutt_set_flag (Context, extra->hdr, M_FLAG, !extra->hdr->flagged);
redraw = REDRAW_STATUS | REDRAW_INDEX;
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_SEEN);
-#endif
+ CHECK_MX_ACL (Context, ACL_SEEN, _("Toggling"));
if (extra->hdr->read || extra->hdr->old)
mutt_set_flag (Context, extra->hdr, M_NEW, 1);
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Undeletion"));
mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
mutt_set_flag (Context, extra->hdr, M_PURGED, 0);
CHECK_MODE (IsHeader (extra));
CHECK_READONLY;
-#ifdef USE_IMAP
- CHECK_IMAP_ACL (IMAP_ACL_DELETE);
-#endif
+ CHECK_MX_ACL (Context, ACL_DELETE, _("Undeletion"));
r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
ch == OP_UNDELETE_THREAD ? 0 : 1)
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
return ((s == U_POP || s == U_POPS) ? M_POP : -1);
}
+static int acl_check_pop (CONTEXT* ctx, int bit) {
+ switch (bit) {
+ case ACL_INSERT: /* editing messages */
+ case ACL_WRITE: /* change importance */
+ return (0);
+ case ACL_DELETE: /* (un)deletion */
+ case ACL_SEEN: /* mark as read */
+ return (1);
+ default:
+ return (0);
+ }
+}
+
mx_t* pop_reg_mx (void) {
mx_t* fmt = safe_calloc (1, sizeof (mx_t));
fmt->type = M_POP;
fmt->mx_is_magic = pop_is_magic;
fmt->mx_open_mailbox = pop_open_mailbox;
+ fmt->mx_acl_check = acl_check_pop;
return (fmt);
}
+/*
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
/*
* interface of mx_t implementation for POP