"Fossies" - the Fresh Open Source Software Archive

Member "citadel/modules/imap/imap_acl.c" (5 Jun 2021, 8026 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ 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 "imap_acl.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 8.24_vs_9.01.

    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  */
   57 void 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  */
   67 void 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  */
   78 void 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  */
  131 void 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();
  171     cdb_rewind(CDB_USERS);
  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  */
  207 void 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  */
  281 void 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 }