"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\">&nbsp;(<a href=\"");
  503     output_scriptptrget();
  504     printf("&amp;form=acl&amp;editentity=");
  505     output_urlencoded(identifier);
  506     printf("&amp;editaccess=");
  507     output_urlencoded(maildir_aclt_ascstr(acl));
  508     printf("\">%s</a>)&nbsp;(<a href=\"", getarg("EDIT"));
  509     output_scriptptrget();
  510     printf("&amp;form=acl&amp;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>&nbsp;</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