"Fossies" - the Fresh Open Source Software Archive 
Member "courier-1.2.2/libs/sqwebmail/acl.c" (19 Feb 2023, 12592 Bytes) of package /linux/misc/courier-1.2.2.tar.bz2:
The requested HTML page contains a <FORM> tag that is unusable on "Fossies" in "automatic" (rendered) mode so that page is shown as HTML source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file. For more information about "acl.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 ** Copyright 2004-2011 Double Precision, Inc. See COPYING for
3 ** distribution information.
4 */
5
6
7 /*
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <courierauth.h>
16 #include "config.h"
17 #include "sqwebmail.h"
18 #include "maildir.h"
19 #include "cgi/cgi.h"
20 #include "pref.h"
21 #include "sqconfig.h"
22 #include "auth.h"
23 #include "acl.h"
24 #include "maildir/maildirquota.h"
25 #include "maildir/maildirrequota.h"
26 #include "maildir/maildirgetquota.h"
27 #include "maildir/maildirmisc.h"
28 #include "maildir/maildircreate.h"
29 #include "maildir/maildirwatch.h"
30 #include "htmllibdir.h"
31
32 #if HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35
36 #if HAVE_DIRENT_H
37 #include <dirent.h>
38 #define NAMLEN(dirent) strlen(dirent->d_name)
39 #else
40 #define dirent direct
41 #define NAMLEN(dirent) ((dirent)->d_namlen)
42 #if HAVE_SYS_NDIR_H
43 #include <sys/ndir.h>
44 #endif
45 #if HAVE_SYS_DIR_H
46 #include <sys/dir.h>
47 #endif
48 #if HAVE_NDIR_H
49 #include <ndir.h>
50 #endif
51 #endif
52
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #if HAVE_UTIME_H
56 #include <utime.h>
57 #endif
58
59 #include <courier-unicode.h>
60
61 #include "strftime.h"
62
63
64 /* ACL support stuff */
65
66 extern const char *sqwebmail_folder;
67 extern void output_urlencoded(const char *p);
68 extern void output_attrencoded(const char *p);
69 extern void output_scriptptrget();
70 extern void output_scriptptr();
71 extern void output_scriptptrpostinfo();
72
73 extern dev_t sqwebmail_homedir_dev;
74 extern ino_t sqwebmail_homedir_ino;
75
76 extern const char *sqwebmail_content_charset;
77 int verify_shared_index_file=0;
78
79 int maildir_info_suppress(const char *maildir)
80 {
81 struct stat stat_buf;
82
83 if (stat(maildir, &stat_buf) < 0 ||
84
85 (stat_buf.st_dev == sqwebmail_homedir_dev &&
86 stat_buf.st_ino == sqwebmail_homedir_ino))
87 return 1;
88 return 0;
89 }
90
91 const char *maildir_shared_index_file()
92 {
93 static char *filenamep=NULL;
94
95 if (filenamep == NULL)
96 {
97 const char *p=getenv("SQWEBMAIL_SHAREDINDEXFILE");
98
99 if (!p || !*p)
100 p=SHAREDINDEXFILE;
101
102 if (p && *p)
103 {
104 const char *q=auth_getoptionenv("sharedgroup");
105
106 if (!q) q="";
107
108 filenamep=malloc(strlen(p)+strlen(q)+1);
109
110 if (!filenamep)
111 enomem();
112
113 strcat(strcpy(filenamep, p), q);
114 }
115 }
116
117 if (filenamep && verify_shared_index_file)
118 {
119 struct stat stat_buf;
120
121 if (stat(filenamep, &stat_buf))
122 {
123 fprintf(stderr, "ERR: ");
124 perror(filenamep);
125 }
126 }
127
128 return filenamep;
129 }
130
131 int acl_read(maildir_aclt_list *l, const char *folder,
132 char **owner)
133 {
134 struct maildir_info minfo;
135 int rc;
136
137 if (maildir_info_imap_find(&minfo, folder,
138 login_returnaddr())<0)
139 {
140 return -1;
141 }
142
143 rc=acl_read2(l, &minfo, owner);
144 maildir_info_destroy(&minfo);
145 return rc;
146 }
147
148 int acl_read2(maildir_aclt_list *l,
149 struct maildir_info *minfo,
150 char **owner)
151 {
152 int rc;
153 char *p;
154
155 if (minfo->mailbox_type == MAILBOXTYPE_OLDSHARED)
156 {
157 /* Legacy shared., punt. */
158
159 maildir_aclt_list_init(l);
160 if (maildir_aclt_list_add(l, "anyone",
161 ACL_LOOKUP ACL_READ
162 ACL_SEEN ACL_WRITE
163 ACL_INSERT
164 ACL_DELETEMSGS ACL_EXPUNGE, NULL) < 0
165 || (*owner=strdup("vendor=courier.internal")) == NULL)
166 {
167 maildir_aclt_list_destroy(l);
168 return -1;
169 }
170 return 0;
171 }
172
173 if (minfo->homedir == NULL || minfo->maildir == NULL)
174 return -1;
175
176 p=maildir_name2dir(".", minfo->maildir);
177
178 if (!p)
179 return -1;
180
181 rc=maildir_acl_read(l, minfo->homedir,
182 strncmp(p, "./", 2) == 0 ? p+2:p);
183 free(p);
184 if (owner && rc == 0)
185 {
186 *owner=minfo->owner;
187 minfo->owner=NULL;
188 }
189 return rc;
190 }
191
192 void acl_computeRightsOnFolder(const char *folder, char *rights)
193 {
194 maildir_aclt_list l;
195 char *owner;
196
197 if (acl_read(&l, folder, &owner) < 0)
198 {
199 *rights=0;
200 return;
201 }
202 acl_computeRights(&l, rights, owner);
203 if (owner)
204 free(owner);
205 maildir_aclt_list_destroy(&l);
206 }
207
208 void acl_computeRights(maildir_aclt_list *l, char *rights,
209 const char *owner)
210 {
211 char *p, *q;
212
213 maildir_aclt a;
214
215 if (maildir_acl_computerights(&a, l, login_returnaddr(), owner) < 0)
216 {
217 *rights=0;
218 return;
219 }
220
221 for (p=q=rights; *p; p++)
222 {
223 if (strchr(maildir_aclt_ascstr(&a), *p))
224 *q++ = *p;
225 }
226 *q=0;
227 maildir_aclt_destroy(&a);
228 }
229
230 static void showrights(const char *buf)
231 {
232 size_t i;
233 char buf2[40];
234
235 for (i=0; buf[i]; i++)
236 {
237 const char *p;
238
239 if (i)
240 printf(", ");
241
242 sprintf(buf2, "ACL_%c", buf[i]);
243
244 p=getarg(buf2);
245 if (p && *p)
246 printf("%s", p);
247 else
248 {
249 buf2[0]=buf[i];
250 buf2[1]=0;
251
252 printf(getarg("ACL_unknown"), buf2);
253 }
254 }
255 }
256
257 static void doupdate();
258
259 void listrights()
260 {
261 maildir_aclt_list l;
262 char buf[40];
263 char *owner;
264
265 if (*cgi("do.update") || *cgi("delentity"))
266 {
267 struct maildir_info minfo;
268
269 if (maildir_info_imap_find(&minfo, sqwebmail_folder,
270 login_returnaddr()) == 0)
271 {
272 if (minfo.homedir)
273 {
274 struct maildirwatch *w;
275 char *lock;
276 int tryanyway;
277
278 w=maildirwatch_alloc(minfo.homedir);
279
280 if (!w)
281 {
282 maildir_info_destroy(&minfo);
283 enomem();
284 return;
285 }
286
287 lock=maildir_lock(minfo.homedir, w,
288 &tryanyway);
289
290 maildir_info_destroy(&minfo);
291
292 if (lock == NULL)
293 {
294 if (!tryanyway)
295 {
296 printf("%s",
297 getarg("ACL_noaccess"));
298 return;
299 }
300 }
301 doupdate();
302 if (lock)
303 {
304 unlink(lock);
305 free(lock);
306 }
307 maildirwatch_free(w);
308 }
309 }
310 }
311
312 if (acl_read(&l, sqwebmail_folder, &owner) < 0)
313 {
314 printf("%s", getarg("ACL_cantread"));
315 return;
316 }
317 buf[0]=0;
318 strncat(buf, getarg("ACL_all"), sizeof(buf)-2);
319 acl_computeRights(&l, buf, owner);
320 maildir_aclt_list_destroy(&l);
321 if (owner)
322 free(owner);
323
324 if (!maildir_acl_canlistrights(buf))
325 {
326 printf("%s", getarg("ACL_cantread"));
327 return;
328 }
329
330 showrights(buf);
331 }
332
333 static void doupdate()
334 {
335 maildir_aclt_list l;
336 char *owner;
337 char buf[2];
338 char *p;
339 struct maildir_info minfo;
340
341 if (maildir_info_imap_find(&minfo, sqwebmail_folder,
342 login_returnaddr()) < 0)
343 return;
344
345 if (acl_read2(&l, &minfo, &owner) < 0)
346 {
347 maildir_info_destroy(&minfo);
348 return;
349 }
350
351 strcpy(buf, ACL_ADMINISTER);
352 acl_computeRights(&l, buf, owner);
353 if (!*buf)
354 {
355 if (owner)
356 free(owner);
357 maildir_aclt_list_destroy(&l);
358 maildir_info_destroy(&minfo);
359 return;
360 }
361
362 if (*cgi("delentity"))
363 {
364 if (maildir_aclt_list_del(&l, cgi("delentity")))
365 printf("%s", getarg("ACL_failed"));
366 }
367
368 if (*cgi("do.update"))
369 {
370 char *entity=NULL;
371 const char *p;
372 char new_acl[40];
373
374 p=cgi("entitytype");
375
376 if (strcmp(p, "anonymous") == 0 ||
377 strcmp(p, "owner") == 0)
378 entity=strdup(p);
379 else if (strcmp(p, "user") == 0)
380 {
381 p=cgi("entity");
382
383 if (*p)
384 {
385 entity=malloc(sizeof("user=")+strlen(p));
386 if (entity)
387 strcat(strcpy(entity, "user="), p);
388 }
389 }
390 else if (strcmp(p, "group") == 0)
391 {
392 p=cgi("entity");
393
394 if (*p)
395 {
396 entity=malloc(sizeof("group=")+strlen(p));
397 if (entity)
398 strcat(strcpy(entity, "group="), p);
399 }
400 }
401 else
402 {
403 entity=strdup(cgi("entity"));
404 }
405
406 if (*cgi("negate") == '-' && entity)
407 {
408 char *p=malloc(strlen(entity)+2);
409
410 if (p)
411 strcat(strcpy(p, "-"), entity);
412 free(entity);
413 entity=p;
414 }
415
416 if (entity)
417 {
418 char *val=
419 unicode_convert_toutf8(entity,
420 sqwebmail_content_charset,
421 NULL);
422
423
424 if (val)
425 {
426 free(entity);
427 entity=val;
428 }
429 }
430 p=getarg("ACL_all");
431
432 new_acl[0]=0;
433
434 while (*p && strlen(new_acl) < sizeof(new_acl)-2)
435 {
436 char b[40];
437
438 sprintf(b, "acl_%c", *p);
439
440 if (*cgi(b))
441 {
442 b[0]=*p;
443 b[1]=0;
444 strcat(new_acl, b);
445 }
446 ++p;
447 }
448
449 if (!entity || !*entity ||
450 maildir_aclt_list_add(&l, entity, new_acl, NULL) < 0)
451 printf("%s", getarg("ACL_failed"));
452
453 if (entity)
454 free(entity);
455 }
456
457 p=maildir_name2dir(".", minfo.maildir);
458
459 if (p)
460 {
461 const char *err_ident;
462
463 if (maildir_acl_write(&l, minfo.homedir,
464 strncmp(p, "./", 2) == 0 ? p+2:p,
465 owner, &err_ident))
466 printf("%s", getarg("ACL_failed"));
467 free(p);
468 }
469
470 if (owner)
471 free(owner);
472 maildir_aclt_list_destroy(&l);
473 maildir_info_destroy(&minfo);
474 }
475
476 static void p_ident_name(const char *identifier)
477 {
478 char *val=unicode_convert_fromutf8(identifier,
479 sqwebmail_content_charset,
480 NULL);
481
482 if (val)
483 {
484 output_attrencoded(val);
485 free(val);
486 return;
487 }
488
489 output_attrencoded(identifier);
490 }
491
492 static int getacl_cb(const char *identifier, const maildir_aclt *acl,
493 void *dummy)
494 {
495 printf("<tr><td>");
496 p_ident_name(identifier);
497 printf("</td><td>");
498 showrights(maildir_aclt_ascstr(acl));
499
500
501
502 printf("<span class=\"folder-acl-list-action\"> (<a href=\"");
503 output_scriptptrget();
504 printf("&form=acl&editentity=");
505 output_urlencoded(identifier);
506 printf("&editaccess=");
507 output_urlencoded(maildir_aclt_ascstr(acl));
508 printf("\">%s</a>) (<a href=\"", getarg("EDIT"));
509 output_scriptptrget();
510 printf("&form=acl&delentity=");
511 output_urlencoded(identifier);
512 printf("\">%s</a>)</td></tr>\n", getarg("DELETE"));
513 return 0;
514 }
515
516 void getacl()
517 {
518 maildir_aclt_list l;
519 char buf[2];
520 char *owner;
521 const char *a;
522 const char *editentity=cgi("editentity");
523 const char *editaccess=cgi("editaccess");
524
525 const char *entitytype="";
526 const char *entityval="";
527 int negate=0;
528
529 if (acl_read(&l, sqwebmail_folder, &owner) < 0)
530 {
531 printf("%s", getarg("ACL_noaccess"));
532 return;
533 }
534 strcpy(buf, ACL_ADMINISTER);
535 acl_computeRights(&l, buf, owner);
536 if (owner)
537 free(owner);
538
539 if (buf[0] == 0)
540 {
541 maildir_aclt_list_destroy(&l);
542 return;
543 }
544
545 printf("<form method=\"post\" name=\"form1\" action=\"");
546 output_scriptptr();
547 printf("\">");
548 output_scriptptrpostinfo();
549 printf("<input type=\"hidden\" name=\"update\" value=\"1\" />\n"
550 "<input type=\"hidden\" name=\"form\" value=\"acl\" />\n");
551 printf("<table class=\"folder-acl-list\"><tbody>"
552 "<tr><th align=\"left\">%s</th><th align=\"left\">%s</th></tr>\n",
553 getarg("ENTITY"),
554 getarg("ACCESSRIGHTS"));
555
556 maildir_aclt_list_enum(&l, getacl_cb, NULL);
557
558 if (*editentity == '-')
559 {
560 ++editentity;
561 negate=1;
562 }
563
564 if (*editentity)
565 {
566 if (strncmp(editentity, "user=", 5) == 0)
567 {
568 entitytype="user";
569 entityval=editentity+5;
570 }
571 else if (strncmp(editentity, "group=", 6) == 0)
572 {
573 entitytype="group";
574 entityval=editentity+6;
575 }
576 else if (strcmp(editentity, "owner") == 0 ||
577 strcmp(editentity, "anonymous") == 0)
578 {
579 entitytype=editentity;
580 }
581 else
582 {
583 entitytype="other";
584 entityval=editentity;
585 }
586 }
587
588 printf("<tr><td colspan=\"2\"><hr width=\"90%%\" />");
589 printf("<table><tbody>\n");
590 printf("<tr><th colspan=\"2\" align=\"left\">%s</th></tr>\n",
591 getarg("UPDATEHDR"));
592 printf("<tr align=\"top\"><td>"
593 "<select name=\"negate\" id=\"negate\">\n"
594 "<option value=\"\" > </option>\n"
595 "<option value=\"-\" %s>-</option>\n"
596 "</select>\n"
597 "<select name=\"entitytype\" id=\"entitytype\" "
598 "onchange=\"javascript:updent()\" >\n"
599 "<option value=\"user\" %s >%s</option>\n"
600 "<option value=\"group\" %s >%s</option>\n"
601 "<option value=\"owner\" %s >%s</option>\n"
602 "<option value=\"anonymous\" %s >%s</option>\n"
603 "<option value=\"administrators\" %s >%s</option>\n"
604 "<option value=\"other\" %s >%s</option>\n"
605 "</select><input type=\"text\" name=\"entity\" "
606 " id=\"entity\" value=\"",
607 negate ? "selected=\"selected\"":"",
608 strcmp(entitytype, "user") == 0 ? "selected=\"selected\"":"",
609 getarg("USER"),
610
611 strcmp(entitytype, "group") == 0 ? "selected=\"selected\"":"",
612 getarg("GROUP"),
613
614 strcmp(entitytype, "owner") == 0 ? "selected=\"selected\"":"",
615 getarg("OWNER"),
616
617 strcmp(entitytype, "anonymous") == 0 ? "selected=\"selected\"":"",
618 getarg("ANONYMOUS"),
619
620 strcmp(entitytype, "administrators") == 0 ? "selected=\"selected\"":"",
621 getarg("ADMINISTRATORS"),
622
623 strcmp(entitytype, "other") == 0 ? "selected=\"selected\"":"",
624 getarg("OTHER"));
625
626 p_ident_name(entityval);
627
628 printf("\"/></td><td><table><tbody>");
629
630 a=getarg("ACL_all");
631
632 while (*a)
633 {
634 char buf2[40];
635
636 sprintf(buf2, "ACL_%c", *a);
637
638 printf("<tr><td><input type=\"checkbox\" name=\"acl_%c\" "
639 "id=\"acl_%c\" %s />"
640 "</td><td>%s</td></tr>\n",
641 *a, *a,
642 strchr(editaccess, *a) ? "checked=\"checked\"":"",
643 getarg(buf2));
644 ++a;
645 }
646
647 printf("</tbody></table></td></tr>\n"
648 "<tr><td> </td>"
649 "<td><input type=\"submit\" name=\"do.update\" value=\"%s\" />"
650 "</td>"
651 "</table></tbody></td></tr>\n",
652 getarg("UPDATE"));
653
654 printf("</tbody></table></form>\n");
655 }
656