}
+/*
+ * 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.
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",
CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
if (strlen(temp.fullname) > 0) {
- strcpy(rights, "");
-
- /* 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");
-
- /* r - read (SELECT the mailbox, perform STATUS) */
- if (ra & UA_KNOWN) strcat(rights, "r");
-
- /* 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) */
-
+ imap_acl_flags(rights, ra);
if (strlen(rights) > 0) {
cprintf(" ");
imap_strout(temp.fullname);
* 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;
}
* 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;
}