4 * Functions which implement RFC2086 (and maybe RFC4314) (IMAP ACL extension)
7 * Copyright (c) 2007-2009 by the citadel.org team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <sys/types.h>
35 #if TIME_WITH_SYS_TIME
36 # include <sys/time.h>
40 # include <sys/time.h>
50 #include <libcitadel.h>
53 #include "sysdep_decls.h"
54 #include "citserver.h"
61 #include "internet_addressing.h"
62 #include "serv_imap.h"
63 #include "imap_tools.h"
64 #include "imap_fetch.h"
65 #include "imap_misc.h"
69 #include "ctdl_module.h"
72 * Implements the SETACL command.
74 void imap_setacl(int num_parms, char *parms[]) {
76 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
82 * Implements the DELETEACL command.
84 void imap_deleteacl(int num_parms, char *parms[]) {
86 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
92 * Given the bits returned by CtdlRoomAccess(), populate a string buffer
93 * with IMAP ACL format flags. This code is common to GETACL and MYRIGHTS.
95 void imap_acl_flags(char *rights, int ra)
99 /* l - lookup (mailbox is visible to LIST/LSUB commands)
100 * r - read (SELECT the mailbox, perform STATUS et al)
101 * s - keep seen/unseen information across sessions (STORE SEEN flag)
103 if ( (ra & UA_KNOWN) /* known rooms */
104 || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED)) /* zapped rooms */
110 /* Only output the remaining flags if the room is known */
112 /* w - write (set or clear flags other than SEEN or DELETED, not supported in Citadel */
114 /* i - insert (perform APPEND, COPY into mailbox) */
115 /* p - post (send mail to submission address for mailbox - not enforced) */
116 /* c - create (CREATE new sub-mailboxes) */
117 if (ra & UA_POSTALLOWED) {
123 /* d - delete messages (STORE DELETED flag, perform EXPUNGE) */
124 if (ra & UA_DELETEALLOWED) {
128 /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
129 if (ra & UA_ADMINALLOWED) {
131 * This is the correct place to put the "a" flag. We are leaving
132 * it commented out for now, because it implies that we could
133 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS. Since these
134 * commands are not yet implemented, omitting the flag should
135 * theoretically prevent compliant clients from attempting to
138 /* strcat(rights, "a"); * commented out */
145 * Implements the GETACL command.
147 void imap_getacl(int num_parms, char *parms[]) {
148 char roomname[ROOMNAMELEN];
149 char savedroom[ROOMNAMELEN];
152 struct ctdluser temp;
153 struct cdbdata *cdbus;
157 if (num_parms != 3) {
158 cprintf("%s BAD usage error\r\n", parms[0]);
163 * Search for the specified room or folder
165 ret = imap_grabroom(roomname, parms[2], 1);
167 cprintf("%s NO Invalid mailbox name or access denied\r\n",
173 * CtdlUserGoto() formally takes us to the desired room. (If another
174 * folder is selected, save its name so we can return there!!!!!)
176 if (IMAP->selected) {
177 strcpy(savedroom, CC->room.QRname);
179 CtdlUserGoto(roomname, 0, 0, &msgs, &new);
183 imap_strout(parms[2]);
186 * Traverse the userlist
188 cdb_rewind(CDB_USERS);
189 while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
190 memset(&temp, 0, sizeof temp);
191 memcpy(&temp, cdbus->ptr, sizeof temp);
194 CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
195 if (!IsEmptyStr(temp.fullname)) {
196 imap_acl_flags(rights, ra);
197 if (!IsEmptyStr(rights)) {
199 imap_strout(temp.fullname);
200 cprintf(" %s", rights);
208 * If another folder is selected, go back to that room so we can resume
209 * our happy day without violent explosions.
211 if (IMAP->selected) {
212 CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
215 cprintf("%s OK GETACL completed\r\n", parms[0]);
220 * Implements the LISTRIGHTS command.
222 void imap_listrights(int num_parms, char *parms[]) {
223 char roomname[ROOMNAMELEN];
224 char savedroom[ROOMNAMELEN];
227 struct recptypes *valid;
228 struct ctdluser temp;
230 if (num_parms != 4) {
231 cprintf("%s BAD usage error\r\n", parms[0]);
236 * Search for the specified room/folder
238 ret = imap_grabroom(roomname, parms[2], 1);
240 cprintf("%s NO Invalid mailbox name or access denied\r\n",
246 * Search for the specified user
249 valid = validate_recipients(parms[3], NULL, 0);
251 if (valid->num_local == 1) {
252 ret = getuser(&temp, valid->recp_local);
254 free_recipients(valid);
257 cprintf("%s NO Invalid user name or access denied\r\n",
263 * CtdlUserGoto() formally takes us to the desired room. (If another
264 * folder is selected, save its name so we can return there!!!!!)
266 if (IMAP->selected) {
267 strcpy(savedroom, CC->room.QRname);
269 CtdlUserGoto(roomname, 0, 0, &msgs, &new);
273 * Now output the list of rights
275 cprintf("* LISTRIGHTS ");
276 imap_strout(parms[2]);
278 imap_strout(parms[3]);
280 imap_strout(""); /* FIXME ... do something here */
285 * If another folder is selected, go back to that room so we can resume
286 * our happy day without violent explosions.
288 if (IMAP->selected) {
289 CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
292 cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
298 * Implements the MYRIGHTS command.
300 void imap_myrights(int num_parms, char *parms[]) {
301 char roomname[ROOMNAMELEN];
302 char savedroom[ROOMNAMELEN];
308 if (num_parms != 3) {
309 cprintf("%s BAD usage error\r\n", parms[0]);
313 ret = imap_grabroom(roomname, parms[2], 1);
315 cprintf("%s NO Invalid mailbox name or access denied\r\n",
321 * CtdlUserGoto() formally takes us to the desired room. (If another
322 * folder is selected, save its name so we can return there!!!!!)
324 if (IMAP->selected) {
325 strcpy(savedroom, CC->room.QRname);
327 CtdlUserGoto(roomname, 0, 0, &msgs, &new);
329 CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
330 imap_acl_flags(rights, ra);
332 cprintf("* MYRIGHTS ");
333 imap_strout(parms[2]);
334 cprintf(" %s\r\n", rights);
337 * If a different folder was previously selected, return there now.
339 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
340 CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
343 cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);