citadel
About: Citadel is an advanced messaging and collaboration system for groupware and BBS applications (preferred OS: Linux).
  Fossies Dox: citadel.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

imap_acl.c
Go to the documentation of this file.
1/*
2 * Functions which implement RFC2086 (and maybe RFC4314) (IMAP ACL extension)
3 *
4 * Copyright (c) 2007-2017 by the citadel.org team
5 *
6 * This program is open source software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "sysdep.h"
22#include <stdlib.h>
23#include <unistd.h>
24#include <stdio.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <pwd.h>
28#include <errno.h>
29#include <sys/types.h>
30#include <time.h>
31#include <sys/wait.h>
32#include <ctype.h>
33#include <string.h>
34#include <limits.h>
35#include <libcitadel.h>
36#include "citadel.h"
37#include "server.h"
38#include "sysdep_decls.h"
39#include "citserver.h"
40#include "support.h"
41#include "config.h"
42#include "user_ops.h"
43#include "database.h"
44#include "msgbase.h"
45#include "internet_addressing.h"
46#include "serv_imap.h"
47#include "imap_tools.h"
48#include "imap_fetch.h"
49#include "imap_misc.h"
50#include "genstamp.h"
51#include "ctdl_module.h"
52
53
54/*
55 * Implements the SETACL command.
56 */
57void imap_setacl(int num_parms, ConstStr *Params) {
58
59 IReply("BAD not yet implemented FIXME");
60 return;
61}
62
63
64/*
65 * Implements the DELETEACL command.
66 */
67void imap_deleteacl(int num_parms, ConstStr *Params) {
68
69 IReply("BAD not yet implemented FIXME");
70 return;
71}
72
73
74/*
75 * Given the bits returned by CtdlRoomAccess(), populate a string buffer
76 * with IMAP ACL format flags. This code is common to GETACL and MYRIGHTS.
77 */
78void imap_acl_flags(StrBuf *rights, int ra)
79{
80 FlushStrBuf(rights);
81
82 /* l - lookup (mailbox is visible to LIST/LSUB commands)
83 * r - read (SELECT the mailbox, perform STATUS et al)
84 * s - keep seen/unseen information across sessions (STORE SEEN flag)
85 */
86 if ( (ra & UA_KNOWN) /* known rooms */
87 || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED)) /* zapped rooms */
88 ) {
89 StrBufAppendBufPlain(rights, HKEY("l"), 0);
90 StrBufAppendBufPlain(rights, HKEY("r"), 0);
91 StrBufAppendBufPlain(rights, HKEY("s"), 0);
92
93 /* Only output the remaining flags if the room is known */
94
95 /* w - write (set or clear flags other than SEEN or DELETED, not supported in Citadel */
96
97 /* i - insert (perform APPEND, COPY into mailbox) */
98 /* p - post (send mail to submission address for mailbox - not enforced) */
99 /* c - create (CREATE new sub-mailboxes) */
100 if (ra & UA_POSTALLOWED) {
101 StrBufAppendBufPlain(rights, HKEY("i"), 0);
102 StrBufAppendBufPlain(rights, HKEY("p"), 0);
103 StrBufAppendBufPlain(rights, HKEY("c"), 0);
104 }
105
106 /* d - delete messages (STORE DELETED flag, perform EXPUNGE) */
107 if (ra & UA_DELETEALLOWED) {
108 StrBufAppendBufPlain(rights, HKEY("d"), 0);
109 }
110
111 /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
112 if (ra & UA_ADMINALLOWED) {
113 /*
114 * This is the correct place to put the "a" flag. We are leaving
115 * it commented out for now, because it implies that we could
116 * perform any of SETACL/DELETEACL/GETACL/LISTRIGHTS. Since these
117 * commands are not yet implemented, omitting the flag should
118 * theoretically prevent compliant clients from attempting to
119 * perform them.
120 *
121 * StrBufAppendBufPlain(rights, HKEY("a"), 0);
122 */
123 }
124 }
125}
126
127
128/*
129 * Implements the GETACL command.
130 */
131void imap_getacl(int num_parms, ConstStr *Params) {
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 StrBuf *rights;
140
141 if (num_parms != 3) {
142 IReply("BAD usage error");
143 return;
144 }
145
146 /*
147 * Search for the specified room or folder
148 */
149 ret = imap_grabroom(roomname, Params[2].Key, 1);
150 if (ret != 0) {
151 IReply("NO Invalid mailbox name or access denied");
152 return;
153 }
154
155 /*
156 * CtdlUserGoto() formally takes us to the desired room. (If another
157 * folder is selected, save its name so we can return there!!!!!)
158 */
159 if (IMAP->selected) {
160 strcpy(savedroom, CC->room.QRname);
161 }
162 CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL);
163
164 IAPuts("* ACL ");
165 IPutCParamStr(2);
166
167 /*
168 * Traverse the userlist
169 */
170 rights = NewStrBuf();
172 while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL)
173 {
174 memset(&temp, 0, sizeof temp);
175 memcpy(&temp, cdbus->ptr, sizeof temp);
176 cdb_free(cdbus);
177
178 CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
179 if (!IsEmptyStr(temp.fullname)) {
180 imap_acl_flags(rights, ra);
181 if (StrLength(rights) > 0) {
182 IAPuts(" ");
183 IPutStr(temp.fullname, strlen(temp.fullname));
184 IAPuts(" ");
185 iaputs(SKEY( rights));
186 }
187 }
188 }
189 FreeStrBuf(&rights);
190 IAPuts("\r\n");
191
192 /*
193 * If another folder is selected, go back to that room so we can resume
194 * our happy day without violent explosions.
195 */
196 if (IMAP->selected) {
197 CtdlUserGoto(savedroom, 0, 0, &msgs, &new, NULL, NULL);
198 }
199
200 IReply("OK GETACL completed");
201}
202
203
204/*
205 * Implements the LISTRIGHTS command.
206 */
207void imap_listrights(int num_parms, ConstStr *Params) {
208 char roomname[ROOMNAMELEN];
209 char savedroom[ROOMNAMELEN];
210 int msgs, new;
211 int ret;
212 struct recptypes *valid;
213 struct ctdluser temp;
214
215 if (num_parms != 4) {
216 IReply("BAD usage error");
217 return;
218 }
219
220 /*
221 * Search for the specified room/folder
222 */
223 ret = imap_grabroom(roomname, Params[2].Key, 1);
224 if (ret != 0) {
225 IReply("NO Invalid mailbox name or access denied");
226 return;
227 }
228
229 /*
230 * Search for the specified user
231 */
232 ret = (-1);
233 valid = validate_recipients(Params[3].Key, NULL, 0);
234 if (valid != NULL) {
235 if (valid->num_local == 1) {
236 ret = CtdlGetUser(&temp, valid->recp_local);
237 }
238 free_recipients(valid);
239 }
240 if (ret != 0) {
241 IReply("NO Invalid user name or access denied");
242 return;
243 }
244
245 /*
246 * CtdlUserGoto() formally takes us to the desired room. (If another
247 * folder is selected, save its name so we can return there!!!!!)
248 */
249 if (IMAP->selected) {
250 strcpy(savedroom, CC->room.QRname);
251 }
252 CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL);
253
254 /*
255 * Now output the list of rights
256 */
257 IAPuts("* LISTRIGHTS ");
258 IPutCParamStr(2);
259 IAPuts(" ");
260 IPutCParamStr(3);
261 IAPuts(" ");
262 IPutStr(HKEY("")); /* FIXME ... do something here */
263 IAPuts("\r\n");
264
265 /*
266 * If another folder is selected, go back to that room so we can resume
267 * our happy day without violent explosions.
268 */
269 if (IMAP->selected) {
270 CtdlUserGoto(savedroom, 0, 0, &msgs, &new, NULL, NULL);
271 }
272
273 IReply("OK LISTRIGHTS completed");
274 return;
275}
276
277
278/*
279 * Implements the MYRIGHTS command.
280 */
281void imap_myrights(int num_parms, ConstStr *Params) {
282 char roomname[ROOMNAMELEN];
283 char savedroom[ROOMNAMELEN];
284 int msgs, new;
285 int ret;
286 int ra;
287 StrBuf *rights;
288
289 if (num_parms != 3) {
290 IReply("BAD usage error");
291 return;
292 }
293
294 ret = imap_grabroom(roomname, Params[2].Key, 1);
295 if (ret != 0) {
296 IReply("NO Invalid mailbox name or access denied");
297 return;
298 }
299
300 /*
301 * CtdlUserGoto() formally takes us to the desired room. (If another
302 * folder is selected, save its name so we can return there!!!!!)
303 */
304 if (IMAP->selected) {
305 strcpy(savedroom, CC->room.QRname);
306 }
307 CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL);
308
309 CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
310 rights = NewStrBuf();
311 imap_acl_flags(rights, ra);
312
313 IAPuts("* MYRIGHTS ");
314 IPutCParamStr(2);
315 IAPuts(" ");
316 IPutStr(SKEY(rights));
317 IAPuts("\r\n");
318
319 FreeStrBuf(&rights);
320
321 /*
322 * If a different folder was previously selected, return there now.
323 */
324 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
325 CtdlUserGoto(savedroom, 0, 0, &msgs, &new, NULL, NULL);
326 }
327
328 IReply("OK MYRIGHTS completed");
329 return;
330}
#define ROOMNAMELEN
Definition: citadel.h:56
#define CC
Definition: context.h:140
void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *result, int *view)
Definition: room_ops.c:121
void CtdlUserGoto(char *where, int display_result, int transiently, int *msgs, int *new, long *oldest, long *newest)
Definition: room_ops.c:702
int CtdlGetUser(struct ctdluser *usbuf, char *name)
Definition: user_ops.c:75
void cdb_free(struct cdbdata *cdb)
Definition: database.c:609
struct cdbdata * cdb_next_item(int cdb)
Definition: database.c:655
void cdb_rewind(int cdb)
Definition: database.c:631
void imap_listrights(int num_parms, ConstStr *Params)
Definition: imap_acl.c:207
void imap_deleteacl(int num_parms, ConstStr *Params)
Definition: imap_acl.c:67
void imap_myrights(int num_parms, ConstStr *Params)
Definition: imap_acl.c:281
void imap_setacl(int num_parms, ConstStr *Params)
Definition: imap_acl.c:57
void imap_getacl(int num_parms, ConstStr *Params)
Definition: imap_acl.c:131
void imap_acl_flags(StrBuf *rights, int ra)
Definition: imap_acl.c:78
void iaputs(const char *Str, long Len)
Definition: imap_tools.c:908
void IPutStr(const char *Msg, long Len)
Definition: imap_tools.c:955
#define IAPuts(Msg)
Definition: imap_tools.h:39
#define IPutCParamStr(n)
Definition: imap_tools.h:53
#define IReply(msg)
Definition: imap_tools.h:45
struct recptypes * validate_recipients(char *supplied_recipients, const char *RemoteIdentifier, int Flags)
void free_recipients(struct recptypes *valid)
#define UA_ZAPPED
Definition: ipcdef.h:82
#define UA_ADMINALLOWED
Definition: ipcdef.h:84
#define UA_DELETEALLOWED
Definition: ipcdef.h:85
#define UA_GOTOALLOWED
Definition: ipcdef.h:80
#define UA_KNOWN
Definition: ipcdef.h:79
#define UA_POSTALLOWED
Definition: ipcdef.h:83
int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok)
Definition: serv_imap.c:1109
#define IMAP
Definition: serv_imap.h:104
@ CDB_USERS
Definition: server.h:186
char * ptr
Definition: server.h:204
char fullname[64]
Definition: citadel.h:90
char * recp_local
Definition: server.h:55
int num_local
Definition: server.h:49