4 * Functions which implement RFC2086 (and maybe 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)
85 * r - read (SELECT the mailbox, perform STATUS et al)
86 * s - keep seen/unseen information across sessions (STORE SEEN flag)
88 if ( (ra & UA_KNOWN) /* known rooms */
89 || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED)) /* zapped rooms */
95 /* Only output the remaining flags if the room is known */
97 /* w - write (set or clear flags other than SEEN or DELETED, not supported in Citadel */
99 /* i - insert (perform APPEND, COPY into mailbox) */
100 /* p - post (send mail to submission address for mailbox - not enforced) */
101 /* c - create (CREATE new sub-mailboxes) */
102 if (ra & UA_POSTALLOWED) {
108 /* d - delete messages (STORE DELETED flag, perform EXPUNGE) */
109 if (ra & UA_DELETEALLOWED) {
113 /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
114 if (ra & UA_ADMINALLOWED) {
116 * This is the correct place to put the "a" flag. We are leaving
117 * it commented out for now, because it implies that we could
118 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS. Since these
119 * commands are not yet implemented, omitting the flag should
120 * theoretically prevent compliant clients from attempting to
123 /* strcat(rights, "a"); * commented out */
130 * Implements the GETACL command.
132 void imap_getacl(int num_parms, char *parms[]) {
133 char roomname[ROOMNAMELEN];
134 char savedroom[ROOMNAMELEN];
137 struct ctdluser temp;
138 struct cdbdata *cdbus;
142 if (num_parms != 3) {
143 cprintf("%s BAD usage error\r\n", parms[0]);
148 * Search for the specified room or folder
150 ret = imap_grabroom(roomname, parms[2], 0);
152 cprintf("%s NO Invalid mailbox name or access denied\r\n",
158 * usergoto() formally takes us to the desired room. (If another
159 * folder is selected, save its name so we can return there!!!!!)
161 if (IMAP->selected) {
162 strcpy(savedroom, CC->room.QRname);
164 usergoto(roomname, 0, 0, &msgs, &new);
168 imap_strout(parms[2]);
171 * Traverse the userlist
173 cdb_rewind(CDB_USERS);
174 while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
175 memset(&temp, 0, sizeof temp);
176 memcpy(&temp, cdbus->ptr, sizeof temp);
179 CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
180 if (strlen(temp.fullname) > 0) {
181 imap_acl_flags(rights, ra);
182 if (strlen(rights) > 0) {
184 imap_strout(temp.fullname);
185 cprintf(" %s", rights);
193 * If another folder is selected, go back to that room so we can resume
194 * our happy day without violent explosions.
196 if (IMAP->selected) {
197 usergoto(savedroom, 0, 0, &msgs, &new);
200 cprintf("%s OK GETACL completed\r\n", parms[0]);
205 * Implements the LISTRIGHTS command.
207 void imap_listrights(int num_parms, char *parms[]) {
208 char roomname[ROOMNAMELEN];
209 char savedroom[ROOMNAMELEN];
212 struct recptypes *valid;
213 struct ctdluser temp;
215 if (num_parms != 4) {
216 cprintf("%s BAD usage error\r\n", parms[0]);
221 * Search for the specified room/folder
223 ret = imap_grabroom(roomname, parms[2], 0);
225 cprintf("%s NO Invalid mailbox name or access denied\r\n",
231 * Search for the specified user
234 valid = validate_recipients(parms[3]);
236 if (valid->num_local == 1) {
237 ret = getuser(&temp, valid->recp_local);
239 free_recipients(valid);
242 cprintf("%s NO Invalid user name or access denied\r\n",
248 * usergoto() formally takes us to the desired room. (If another
249 * folder is selected, save its name so we can return there!!!!!)
251 if (IMAP->selected) {
252 strcpy(savedroom, CC->room.QRname);
254 usergoto(roomname, 0, 0, &msgs, &new);
258 * Now output the list of rights
260 cprintf("* LISTRIGHTS ");
261 imap_strout(parms[2]);
263 imap_strout(parms[3]);
265 imap_strout(""); /* FIXME ... do something here */
270 * If another folder is selected, go back to that room so we can resume
271 * our happy day without violent explosions.
273 if (IMAP->selected) {
274 usergoto(savedroom, 0, 0, &msgs, &new);
277 cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
283 * Implements the MYRIGHTS command.
285 void imap_myrights(int num_parms, char *parms[]) {
286 char roomname[ROOMNAMELEN];
287 char savedroom[ROOMNAMELEN];
293 if (num_parms != 3) {
294 cprintf("%s BAD usage error\r\n", parms[0]);
298 ret = imap_grabroom(roomname, parms[2], 0);
300 cprintf("%s NO Invalid mailbox name or access denied\r\n",
306 * usergoto() formally takes us to the desired room. (If another
307 * folder is selected, save its name so we can return there!!!!!)
309 if (IMAP->selected) {
310 strcpy(savedroom, CC->room.QRname);
312 usergoto(roomname, 0, 0, &msgs, &new);
314 CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
315 imap_acl_flags(rights, ra);
317 cprintf("* MYRIGHTS ");
318 imap_strout(parms[2]);
319 cprintf(" %s\r\n", rights);
322 * If a different folder was previously selected, return there now.
324 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
325 usergoto(savedroom, 0, 0, &msgs, &new);
328 cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);