* es.po: the correct license for this file was supposed to be GPL v2-or-later, not...
[citadel.git] / citadel / modules / imap / imap_acl.c
blobc54340a497b5f18ec69daec59305c16ab86e48b2
1 /*
2 * $Id$
4 * Functions which implement RFC2086 (and maybe RFC4314) (IMAP ACL extension)
6 */
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <pwd.h>
16 #include <errno.h>
17 #include <sys/types.h>
19 #if TIME_WITH_SYS_TIME
20 # include <sys/time.h>
21 # include <time.h>
22 #else
23 # if HAVE_SYS_TIME_H
24 # include <sys/time.h>
25 # else
26 # include <time.h>
27 # endif
28 #endif
30 #include <sys/wait.h>
31 #include <ctype.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <libcitadel.h>
35 #include "citadel.h"
36 #include "server.h"
37 #include "sysdep_decls.h"
38 #include "citserver.h"
39 #include "support.h"
40 #include "config.h"
41 #include "room_ops.h"
42 #include "user_ops.h"
43 #include "policy.h"
44 #include "database.h"
45 #include "msgbase.h"
46 #include "internet_addressing.h"
47 #include "serv_imap.h"
48 #include "imap_tools.h"
49 #include "imap_fetch.h"
50 #include "imap_misc.h"
51 #include "genstamp.h"
56 * Implements the SETACL command.
58 void imap_setacl(int num_parms, char *parms[]) {
60 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
61 return;
66 * Implements the DELETEACL command.
68 void imap_deleteacl(int num_parms, char *parms[]) {
70 cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
71 return;
76 * Given the bits returned by CtdlRoomAccess(), populate a string buffer
77 * with IMAP ACL format flags. This code is common to GETACL and MYRIGHTS.
79 void imap_acl_flags(char *rights, int ra)
81 strcpy(rights, "");
83 /* l - lookup (mailbox is visible to LIST/LSUB commands)
84 * r - read (SELECT the mailbox, perform STATUS et al)
85 * s - keep seen/unseen information across sessions (STORE SEEN flag)
87 if ( (ra & UA_KNOWN) /* known rooms */
88 || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED)) /* zapped rooms */
89 ) {
90 strcat(rights, "l");
91 strcat(rights, "r");
92 strcat(rights, "s");
94 /* Only output the remaining flags if the room is known */
96 /* w - write (set or clear flags other than SEEN or DELETED, not supported in Citadel */
98 /* i - insert (perform APPEND, COPY into mailbox) */
99 /* p - post (send mail to submission address for mailbox - not enforced) */
100 /* c - create (CREATE new sub-mailboxes) */
101 if (ra & UA_POSTALLOWED) {
102 strcat(rights, "i");
103 strcat(rights, "p");
104 strcat(rights, "c");
107 /* d - delete messages (STORE DELETED flag, perform EXPUNGE) */
108 if (ra & UA_DELETEALLOWED) {
109 strcat(rights, "d");
112 /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
113 if (ra & UA_ADMINALLOWED) {
115 * This is the correct place to put the "a" flag. We are leaving
116 * it commented out for now, because it implies that we could
117 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS. Since these
118 * commands are not yet implemented, omitting the flag should
119 * theoretically prevent compliant clients from attempting to
120 * perform them.
122 /* strcat(rights, "a"); * commented out */
129 * Implements the GETACL command.
131 void imap_getacl(int num_parms, char *parms[]) {
132 char roomname[ROOMNAMELEN];
133 char savedroom[ROOMNAMELEN];
134 int msgs, new;
135 int ret;
136 struct ctdluser temp;
137 struct cdbdata *cdbus;
138 int ra;
139 char rights[32];
141 if (num_parms != 3) {
142 cprintf("%s BAD usage error\r\n", parms[0]);
143 return;
147 * Search for the specified room or folder
149 ret = imap_grabroom(roomname, parms[2], 0);
150 if (ret != 0) {
151 cprintf("%s NO Invalid mailbox name or access denied\r\n",
152 parms[0]);
153 return;
157 * usergoto() formally takes us to the desired room. (If another
158 * folder is selected, save its name so we can return there!!!!!)
160 if (IMAP->selected) {
161 strcpy(savedroom, CC->room.QRname);
163 usergoto(roomname, 0, 0, &msgs, &new);
165 cprintf("* ACL");
166 cprintf(" ");
167 imap_strout(parms[2]);
170 * Traverse the userlist
172 cdb_rewind(CDB_USERS);
173 while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
174 memset(&temp, 0, sizeof temp);
175 memcpy(&temp, cdbus->ptr, sizeof temp);
176 cdb_free(cdbus);
178 CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
179 if (!IsEmptyStr(temp.fullname)) {
180 imap_acl_flags(rights, ra);
181 if (!IsEmptyStr(rights)) {
182 cprintf(" ");
183 imap_strout(temp.fullname);
184 cprintf(" %s", rights);
189 cprintf("\r\n");
192 * If another folder is selected, go back to that room so we can resume
193 * our happy day without violent explosions.
195 if (IMAP->selected) {
196 usergoto(savedroom, 0, 0, &msgs, &new);
199 cprintf("%s OK GETACL completed\r\n", parms[0]);
204 * Implements the LISTRIGHTS command.
206 void imap_listrights(int num_parms, char *parms[]) {
207 char roomname[ROOMNAMELEN];
208 char savedroom[ROOMNAMELEN];
209 int msgs, new;
210 int ret;
211 struct recptypes *valid;
212 struct ctdluser temp;
214 if (num_parms != 4) {
215 cprintf("%s BAD usage error\r\n", parms[0]);
216 return;
220 * Search for the specified room/folder
222 ret = imap_grabroom(roomname, parms[2], 0);
223 if (ret != 0) {
224 cprintf("%s NO Invalid mailbox name or access denied\r\n",
225 parms[0]);
226 return;
230 * Search for the specified user
232 ret = (-1);
233 valid = validate_recipients(parms[3], NULL, 0);
234 if (valid != NULL) {
235 if (valid->num_local == 1) {
236 ret = getuser(&temp, valid->recp_local);
238 free_recipients(valid);
240 if (ret != 0) {
241 cprintf("%s NO Invalid user name or access denied\r\n",
242 parms[0]);
243 return;
247 * usergoto() formally takes us to the desired room. (If another
248 * folder is selected, save its name so we can return there!!!!!)
250 if (IMAP->selected) {
251 strcpy(savedroom, CC->room.QRname);
253 usergoto(roomname, 0, 0, &msgs, &new);
257 * Now output the list of rights
259 cprintf("* LISTRIGHTS ");
260 imap_strout(parms[2]);
261 cprintf(" ");
262 imap_strout(parms[3]);
263 cprintf(" ");
264 imap_strout(""); /* FIXME ... do something here */
265 cprintf("\r\n");
269 * If another folder is selected, go back to that room so we can resume
270 * our happy day without violent explosions.
272 if (IMAP->selected) {
273 usergoto(savedroom, 0, 0, &msgs, &new);
276 cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
277 return;
282 * Implements the MYRIGHTS command.
284 void imap_myrights(int num_parms, char *parms[]) {
285 char roomname[ROOMNAMELEN];
286 char savedroom[ROOMNAMELEN];
287 int msgs, new;
288 int ret;
289 int ra;
290 char rights[32];
292 if (num_parms != 3) {
293 cprintf("%s BAD usage error\r\n", parms[0]);
294 return;
297 ret = imap_grabroom(roomname, parms[2], 0);
298 if (ret != 0) {
299 cprintf("%s NO Invalid mailbox name or access denied\r\n",
300 parms[0]);
301 return;
305 * usergoto() formally takes us to the desired room. (If another
306 * folder is selected, save its name so we can return there!!!!!)
308 if (IMAP->selected) {
309 strcpy(savedroom, CC->room.QRname);
311 usergoto(roomname, 0, 0, &msgs, &new);
313 CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
314 imap_acl_flags(rights, ra);
316 cprintf("* MYRIGHTS ");
317 imap_strout(parms[2]);
318 cprintf(" %s\r\n", rights);
321 * If a different folder was previously selected, return there now.
323 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
324 usergoto(savedroom, 0, 0, &msgs, &new);
327 cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);
328 return;