* Augmented the access control model and API
authorArt Cancro <ajc@citadel.org>
Wed, 10 Jan 2007 22:22:51 +0000 (22:22 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 10 Jan 2007 22:22:51 +0000 (22:22 +0000)
* More work on IMAP ACL...

citadel/imap_acl.c
citadel/ipcdef.h
citadel/msgbase.c
citadel/room_ops.c

index 2f8bf24ee152125b9ef3a897dfcdb118aee52ab6..abdee0cea8ba2e11250a1f2a69b66696ad37471c 100644 (file)
@@ -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(" ");
index 85372f0ffd67c18735fbb48fdbef68cdd1d1237c..285ae75f0eac0237276db58b3fd3f0c024ec83c8 100644 (file)
@@ -78,6 +78,7 @@ extern "C" {
 #define UA_GOTOALLOWED          4
 #define UA_HASNEWMSGS           8
 #define UA_ZAPPED               16
+#define UA_POSTALLOWED         32
 
 #ifdef __cplusplus
 }
index 099af20dcd920054873b3340abe9ecbc40864355..9212602d4d8b699530d10f677897df566655201c 100644 (file)
@@ -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);
        }
 
index 285256807dd7fc05ffa0a46552f902dbac7735d1..66cc9789292a8216a41d2e1ab17bc9a03ae67d47 100644 (file)
@@ -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 */