4 * Functions which implement RFC2086/RFC4314 (IMAP ACL extension)
17 #include <sys/types.h>
19 #if TIME_WITH_SYS_TIME
20 # include <sys/time.h>
24 # include <sys/time.h>
36 #include "sysdep_decls.h"
37 #include "citserver.h"
40 #include "serv_extensions.h"
47 #include "internet_addressing.h"
48 #include "serv_imap.h"
49 #include "imap_tools.h"
50 #include "imap_fetch.h"
51 #include "imap_misc.h"
57 * Implements the SETACL command.
59 void imap_setacl(int num_parms, char *parms[]) {
61 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
67 * Implements the DELETEACL command.
69 void imap_deleteacl(int num_parms, char *parms[]) {
71 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
77 * Given the bits returned by CtdlRoomAccess(), populate a string buffer
78 * with IMAP ACL format flags. This code is common to GETACL and MYRIGHTS.
80 void imap_acl_flags(char *rights, int ra)
84 /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox)
85 * r - read (SELECT the mailbox, perform STATUS)
86 * s - keep seen/unseen information across sessions (set or clear \SEEN flag
87 * via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...])
88 * e - perform EXPUNGE and expunge as a part of CLOSE
90 if ( (ra & UA_KNOWN) /* known rooms */
91 || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED)) /* zapped rooms */
98 /* Only output the remaining flags if the room is known */
100 /* w - write (set or clear arbitrary flags; not supported in Citadel) */
102 /* i - insert (perform APPEND, COPY into mailbox) */
103 /* p - post (send mail to submission address for mailbox - not enforced) */
104 if (ra & UA_POSTALLOWED) {
109 /* k - create mailboxes in this hierarchy */
111 /* t - delete messages (set/clear \Deleted flag) */
112 if (ra & UA_DELETEALLOWED) {
116 /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
117 /* x - delete mailbox (DELETE mailbox, old mailbox name in RENAME) */
118 if (ra & UA_ADMINALLOWED) {
120 * This is the correct place to put the "a" flag. We are leaving
121 * it commented out for now, because it implies that we could
122 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS. Since these
123 * commands are not yet implemented, omitting the flag should
124 * theoretically prevent compliant clients from attempting to
127 /* strcat(rights, "a"); * commented out */
135 * Implements the GETACL command.
137 void imap_getacl(int num_parms, char *parms[]) {
138 char roomname[ROOMNAMELEN];
139 char savedroom[ROOMNAMELEN];
142 struct ctdluser temp;
143 struct cdbdata *cdbus;
147 if (num_parms != 3) {
148 cprintf("%s BAD usage error\r\n", parms[0]);
153 * Search for the specified room or folder
155 ret = imap_grabroom(roomname, parms[2], 0);
157 cprintf("%s NO Invalid mailbox name or access denied\r\n",
163 * usergoto() formally takes us to the desired room. (If another
164 * folder is selected, save its name so we can return there!!!!!)
166 if (IMAP->selected) {
167 strcpy(savedroom, CC->room.QRname);
169 usergoto(roomname, 0, 0, &msgs, &new);
173 imap_strout(parms[2]);
176 * Traverse the userlist
178 cdb_rewind(CDB_USERS);
179 while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
180 memset(&temp, 0, sizeof temp);
181 memcpy(&temp, cdbus->ptr, sizeof temp);
184 CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
185 if (strlen(temp.fullname) > 0) {
186 imap_acl_flags(rights, ra);
187 if (strlen(rights) > 0) {
189 imap_strout(temp.fullname);
190 cprintf(" %s", rights);
198 * If another folder is selected, go back to that room so we can resume
199 * our happy day without violent explosions.
201 if (IMAP->selected) {
202 usergoto(savedroom, 0, 0, &msgs, &new);
205 cprintf("%s OK GETACL completed\r\n", parms[0]);
210 * Implements the LISTRIGHTS command.
212 void imap_listrights(int num_parms, char *parms[]) {
213 char roomname[ROOMNAMELEN];
214 char savedroom[ROOMNAMELEN];
217 struct recptypes *valid;
218 struct ctdluser temp;
220 if (num_parms != 4) {
221 cprintf("%s BAD usage error\r\n", parms[0]);
226 * Search for the specified room/folder
228 ret = imap_grabroom(roomname, parms[2], 0);
230 cprintf("%s NO Invalid mailbox name or access denied\r\n",
236 * Search for the specified user
239 valid = validate_recipients(parms[3]);
241 if (valid->num_local == 1) {
242 ret = getuser(&temp, valid->recp_local);
247 cprintf("%s NO Invalid user name or access denied\r\n",
253 * usergoto() formally takes us to the desired room. (If another
254 * folder is selected, save its name so we can return there!!!!!)
256 if (IMAP->selected) {
257 strcpy(savedroom, CC->room.QRname);
259 usergoto(roomname, 0, 0, &msgs, &new);
263 * Now output the list of rights
265 cprintf("* LISTRIGHTS ");
266 imap_strout(parms[2]);
268 imap_strout(parms[3]);
270 imap_strout(""); /* FIXME ... do something here */
275 * If another folder is selected, go back to that room so we can resume
276 * our happy day without violent explosions.
278 if (IMAP->selected) {
279 usergoto(savedroom, 0, 0, &msgs, &new);
282 cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
288 * Implements the MYRIGHTS command.
290 void imap_myrights(int num_parms, char *parms[]) {
291 char roomname[ROOMNAMELEN];
292 char savedroom[ROOMNAMELEN];
298 if (num_parms != 3) {
299 cprintf("%s BAD usage error\r\n", parms[0]);
303 ret = imap_grabroom(roomname, parms[2], 0);
305 cprintf("%s NO Invalid mailbox name or access denied\r\n",
311 * usergoto() formally takes us to the desired room. (If another
312 * folder is selected, save its name so we can return there!!!!!)
314 if (IMAP->selected) {
315 strcpy(savedroom, CC->room.QRname);
317 usergoto(roomname, 0, 0, &msgs, &new);
319 CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
320 imap_acl_flags(rights, ra);
322 cprintf("* MYRIGHTS ");
323 imap_strout(parms[2]);
324 cprintf(" %s\r\n", rights);
327 * If a different folder was previously selected, return there now.
329 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
330 usergoto(savedroom, 0, 0, &msgs, &new);
333 cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);