From b3b2bf006fa6a5bed69bc50275d3096868178ca8 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 10 Jan 2007 22:22:51 +0000 Subject: [PATCH] * Augmented the access control model and API * More work on IMAP ACL... --- citadel/imap_acl.c | 36 ++++++++++++++++++++++++++++++++---- citadel/ipcdef.h | 1 + citadel/msgbase.c | 13 ++++--------- citadel/room_ops.c | 36 +++++++++++++++++++++++++++--------- 4 files changed, 64 insertions(+), 22 deletions(-) diff --git a/citadel/imap_acl.c b/citadel/imap_acl.c index 2f8bf24ee..abdee0cea 100644 --- a/citadel/imap_acl.c +++ b/citadel/imap_acl.c @@ -125,14 +125,42 @@ void imap_getacl(int num_parms, char *parms[]) { if (strlen(temp.fullname) > 0) { strcpy(rights, ""); - /* Known, zapped, etc. mailboxes can probably be LIST-ed */ - /* FIXME don't give away hidden rooms */ + /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox) + * FIXME don't give away hidden rooms + */ if (ra & UA_GOTOALLOWED) strcat(rights, "l"); - /* Known rooms can be LSUB-ed */ + /* r - read (SELECT the mailbox, perform STATUS) */ if (ra & UA_KNOWN) strcat(rights, "r"); - /* FIXME do the rest */ + /* s - keep seen/unseen information across sessions (set or clear \SEEN flag + * via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...]) + */ + strcat(rights, "s"); /* Always granted */ + + /* w - write (set or clear flags other than \SEEN and \DELETED via + * STORE, also set them during APPEND/COPY) + */ + /* Never granted in Citadel because our store doesn't support other flags */ + + /* i - insert (perform APPEND, COPY into mailbox) */ + if (ra & UA_POSTALLOWED) strcat(rights, "i"); + + /* p - post (send mail to submission address for mailbox, not enforced by IMAP) */ + if (ra & UA_POSTALLOWED) strcat(rights, "p"); + + /* k - create mailboxes (CREATE new sub-mailboxes in any + * implementation-defined hierarchy, parent mailbox for the new + * mailbox name in RENAME) */ + + /* x - delete mailbox (DELETE mailbox, old mailbox name in RENAME) */ + + /* t - delete messages (set or clear \DELETED flag via STORE, set + * \DELETED flag during APPEND/COPY) */ + + /* e - perform EXPUNGE and expunge as a part of CLOSE */ + + /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */ if (strlen(rights) > 0) { cprintf(" "); diff --git a/citadel/ipcdef.h b/citadel/ipcdef.h index 85372f0ff..285ae75f0 100644 --- a/citadel/ipcdef.h +++ b/citadel/ipcdef.h @@ -78,6 +78,7 @@ extern "C" { #define UA_GOTOALLOWED 4 #define UA_HASNEWMSGS 8 #define UA_ZAPPED 16 +#define UA_POSTALLOWED 32 #ifdef __cplusplus } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 099af20dc..9212602d4 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -2986,6 +2986,7 @@ struct CtdlMessage *CtdlMakeMessage( * returns 0 on success. */ int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf, size_t n) { + int ra; if (!(CC->logged_in)) { snprintf(errmsgbuf, n, "Not logged in."); @@ -2999,15 +3000,9 @@ int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf, size_t n) { return (ERROR + HIGHER_ACCESS_REQUIRED); } - if ((CC->user.axlevel < 4) - && (CC->room.QRflags & QR_NETWORK)) { - snprintf(errmsgbuf, n, "Need net privileges to enter here."); - return (ERROR + HIGHER_ACCESS_REQUIRED); - } - - if ((CC->user.axlevel < 6) - && (CC->room.QRflags & QR_READONLY)) { - snprintf(errmsgbuf, n, "Sorry, this is a read-only room."); + CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL); + if (!(ra & UA_POSTALLOWED)) { + snprintf(errmsgbuf, n, "Higher access is required to post in this room."); return (ERROR + HIGHER_ACCESS_REQUIRED); } diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 285256807..66cc97892 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -54,7 +54,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, /* for internal programs, always do everything */ if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) { - retval = (UA_KNOWN | UA_GOTOALLOWED); + retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED); vbuf.v_view = 0; goto SKIP_EVERYTHING; } @@ -65,7 +65,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, /* Force the properties of the Aide room */ if (!strcasecmp(roombuf->QRname, config.c_aideroom)) { if (userbuf->axlevel >= 6) { - retval = UA_KNOWN | UA_GOTOALLOWED; + retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED; } else { retval = 0; } @@ -103,17 +103,35 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, } } - /* For mailbox rooms, also check the generation number matchups */ + /* For mailbox rooms, also check the namespace */ if (roombuf->QRflags & QR_MAILBOX) { if (userbuf->usernum == atol(roombuf->QRname)) { - retval = retval | UA_KNOWN | UA_GOTOALLOWED; + retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED; } /* An explicit match means the user belongs in this room */ if (vbuf.v_flags & V_ACCESS) { - retval = retval | UA_KNOWN | UA_GOTOALLOWED; + retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED; } } + /* For non-mailbox rooms... */ + else { + + /* User is allowed to post in the room unless: + * - User is not validated + * - User has no net privileges and it is a shared network room + * - It is a read-only room + */ + int post_allowed = 1; + if (CC->user.axlevel < 2) post_allowed = 0; + if ((CC->user.axlevel < 4) && (CC->room.QRflags & QR_NETWORK)) post_allowed = 0; + if (roombuf->QRflags & QR_READONLY) post_allowed = 0; + if (post_allowed) { + retval = retval | UA_POSTALLOWED; + } + + } + /* Check to see if the user has forgotten this room */ if (vbuf.v_flags & V_FORGET) { retval = retval & ~UA_KNOWN; @@ -126,17 +144,17 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, } /* If user is explicitly locked out of this room, deny everything */ if (vbuf.v_flags & V_LOCKOUT) { - retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED; + retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED; } /* Aides get access to all private rooms */ if ( (userbuf->axlevel >= 6) && ((roombuf->QRflags & QR_MAILBOX) == 0) ) { if (vbuf.v_flags & V_FORGET) { - retval = retval | UA_GOTOALLOWED; + retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED; } else { - retval = retval | UA_KNOWN | UA_GOTOALLOWED; + retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED; } } @@ -145,7 +163,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, */ if ( (userbuf->axlevel >= 6) && (roombuf->QRflags & QR_MAILBOX) ) { - retval = retval | UA_GOTOALLOWED; + retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED; } NEWMSG: /* By the way, we also check for the presence of new messages */ -- 2.39.2