]> code.citadel.org Git - citadel.git/blobdiff - citadel/imap_acl.c
struct recptypes now uses dynamically allocated
[citadel.git] / citadel / imap_acl.c
index 2f8bf24ee152125b9ef3a897dfcdb118aee52ab6..204b5473977ffd381c8104d605359460bbe98a1b 100644 (file)
@@ -73,6 +73,64 @@ void imap_deleteacl(int num_parms, char *parms[]) {
 }
 
 
+/*
+ * Given the bits returned by CtdlRoomAccess(), populate a string buffer
+ * with IMAP ACL format flags.   This code is common to GETACL and MYRIGHTS.
+ */
+void imap_acl_flags(char *rights, int ra)
+{
+       strcpy(rights, "");
+
+       /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox)
+        * r - read (SELECT the mailbox, perform STATUS)
+        * s - keep seen/unseen information across sessions (set or clear \SEEN flag
+        *     via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...])
+        * e - perform EXPUNGE and expunge as a part of CLOSE
+        */
+       if (    (ra & UA_KNOWN)                                 /* known rooms */
+          ||   ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED))     /* zapped rooms */
+          ) {
+               strcat(rights, "l");
+               strcat(rights, "r");
+               strcat(rights, "s");
+               strcat(rights, "e");
+
+               /* Only output the remaining flags if the room is known */
+
+               /* w - write (set or clear arbitrary flags; not supported in Citadel) */
+
+               /* i - insert (perform APPEND, COPY into mailbox) */
+               /* p - post (send mail to submission address for mailbox - not enforced) */
+               if (ra & UA_POSTALLOWED) {
+                       strcat(rights, "i");
+                       strcat(rights, "p");
+               }
+
+               /* k - create mailboxes in this hierarchy */
+
+               /* t - delete messages (set/clear \Deleted flag) */
+               if (ra & UA_DELETEALLOWED) {
+                       strcat(rights, "t");
+                       strcat(rights, "d");
+               }
+
+               /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
+               /* x - delete mailbox (DELETE mailbox, old mailbox name in RENAME) */
+               if (ra & UA_ADMINALLOWED) {
+                       /*
+                        * This is the correct place to put the "a" flag.  We are leaving
+                        * it commented out for now, because it implies that we could
+                        * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS.  Since these
+                        * commands are not yet implemented, omitting the flag should
+                        * theoretically prevent compliant clients from attempting to
+                        * perform them.
+                        */
+                       /* strcat(rights, "a"); * commented out */
+                       strcat(rights, "x");
+               }
+       }
+}
+
 
 /*
  * Implements the GETACL command.
@@ -92,6 +150,9 @@ void imap_getacl(int num_parms, char *parms[]) {
                return;
        }
 
+       /*
+        * Search for the specified room or folder
+        */
        ret = imap_grabroom(roomname, parms[2], 0);
        if (ret != 0) {
                cprintf("%s NO Invalid mailbox name or access denied\r\n",
@@ -123,17 +184,7 @@ void imap_getacl(int num_parms, char *parms[]) {
 
                CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
                if (strlen(temp.fullname) > 0) {
-                       strcpy(rights, "");
-
-                       /* Known, zapped, etc. mailboxes can probably be LIST-ed */
-                       /* FIXME don't give away hidden rooms */
-                       if (ra & UA_GOTOALLOWED)        strcat(rights, "l");
-
-                       /* Known rooms can be LSUB-ed */
-                       if (ra & UA_KNOWN)              strcat(rights, "r");
-
-                       /* FIXME do the rest */
-
+                       imap_acl_flags(rights, ra);
                        if (strlen(rights) > 0) {
                                cprintf(" ");
                                imap_strout(temp.fullname);
@@ -160,8 +211,76 @@ void imap_getacl(int num_parms, char *parms[]) {
  * Implements the LISTRIGHTS command.
  */
 void imap_listrights(int num_parms, char *parms[]) {
+       char roomname[ROOMNAMELEN];
+       char savedroom[ROOMNAMELEN];
+       int msgs, new;
+       int ret;
+       struct recptypes *valid;
+       struct ctdluser temp;
 
-       cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+       if (num_parms != 4) {
+               cprintf("%s BAD usage error\r\n", parms[0]);
+               return;
+       }
+
+       /*
+        * Search for the specified room/folder
+        */
+       ret = imap_grabroom(roomname, parms[2], 0);
+       if (ret != 0) {
+               cprintf("%s NO Invalid mailbox name or access denied\r\n",
+                       parms[0]);
+               return;
+       }
+
+       /*
+        * Search for the specified user
+        */
+       ret = (-1);
+       valid = validate_recipients(parms[3]);
+       if (valid != NULL) {
+               if (valid->num_local == 1) {
+                       ret = getuser(&temp, valid->recp_local);
+               }
+               free_recipients(valid);
+       }
+       if (ret != 0) {
+               cprintf("%s NO Invalid user name or access denied\r\n",
+                       parms[0]);
+               return;
+       }
+
+       /*
+        * usergoto() formally takes us to the desired room.  (If another
+        * folder is selected, save its name so we can return there!!!!!)
+        */
+       if (IMAP->selected) {
+               strcpy(savedroom, CC->room.QRname);
+       }
+       usergoto(roomname, 0, 0, &msgs, &new);
+
+
+       /*
+        * Now output the list of rights
+        */
+       cprintf("* LISTRIGHTS ");
+       imap_strout(parms[2]);
+       cprintf(" ");
+       imap_strout(parms[3]);
+       cprintf(" ");
+       imap_strout("");                /* FIXME ... do something here */
+       cprintf("\r\n");
+
+
+       /*
+        * If another folder is selected, go back to that room so we can resume
+        * our happy day without violent explosions.
+        */
+       if (IMAP->selected) {
+               usergoto(savedroom, 0, 0, &msgs, &new);
+       }
+
+       cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
        return;
 }
 
@@ -170,8 +289,49 @@ void imap_listrights(int num_parms, char *parms[]) {
  * Implements the MYRIGHTS command.
  */
 void imap_myrights(int num_parms, char *parms[]) {
+       char roomname[ROOMNAMELEN];
+       char savedroom[ROOMNAMELEN];
+       int msgs, new;
+       int ret;
+       int ra;
+       char rights[32];
 
-       cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+       if (num_parms != 3) {
+               cprintf("%s BAD usage error\r\n", parms[0]);
+               return;
+       }
+
+       ret = imap_grabroom(roomname, parms[2], 0);
+       if (ret != 0) {
+               cprintf("%s NO Invalid mailbox name or access denied\r\n",
+                       parms[0]);
+               return;
+       }
+
+       /*
+        * usergoto() formally takes us to the desired room.  (If another
+        * folder is selected, save its name so we can return there!!!!!)
+        */
+       if (IMAP->selected) {
+               strcpy(savedroom, CC->room.QRname);
+       }
+       usergoto(roomname, 0, 0, &msgs, &new);
+
+       CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
+       imap_acl_flags(rights, ra);
+
+       cprintf("* MYRIGHTS ");
+       imap_strout(parms[2]);
+       cprintf(" %s\r\n", rights);
+
+       /*
+        * If a different folder was previously selected, return there now.
+        */
+       if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
+               usergoto(savedroom, 0, 0, &msgs, &new);
+       }
+
+       cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);
        return;
 }