Back to index

courier  0.68.2
Classes | Defines | Functions | Variables
maildiraclt.c File Reference
#include "maildiraclt.h"
#include "maildirmisc.h"
#include "maildircreate.h"
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

Go to the source code of this file.

Classes

struct  maildir_acl_resetList

Defines

#define dirent   direct
#define NAMLEN(dirent)   (dirent)->d_namlen
#define ISIDENT(s)   (MAILDIR_ACL_ANYONE(s) ? 1: chk_admin(cb_func, (s), void_arg))

Functions

static int compar_aclt (const void *a, const void *b)
static void fixup (maildir_aclt *aclt)
static int validacl (const char *p)
int maildir_aclt_init (maildir_aclt *aclt, const char *initvalue_cstr, const maildir_aclt *initvalue_cpy)
void maildir_aclt_destroy (maildir_aclt *aclt)
int maildir_aclt_add (maildir_aclt *aclt, const char *add_strs, const maildir_aclt *add_aclt)
int maildir_aclt_del (maildir_aclt *aclt, const char *del_strs, const maildir_aclt *del_aclt)
void maildir_aclt_list_init (maildir_aclt_list *aclt_list)
void maildir_aclt_list_destroy (maildir_aclt_list *aclt_list)
int maildir_aclt_list_add (maildir_aclt_list *aclt_list, const char *identifier, const char *aclt_str, maildir_aclt *aclt_cpy)
int maildir_aclt_list_del (maildir_aclt_list *aclt_list, const char *identifier)
int maildir_aclt_list_enum (maildir_aclt_list *aclt_list, int(*cb_func)(const char *identifier, const maildir_aclt *acl, void *cb_arg), void *cb_arg)
const maildir_acltmaildir_aclt_list_find (maildir_aclt_list *aclt_list, const char *identifier)
static int maildir_acl_read_check (maildir_aclt_list *aclt_list, const char *maildir, const char *path)
int maildir_acl_read (maildir_aclt_list *aclt_list, const char *maildir, const char *path)
static int maildir_aclt_add_default_admin (maildir_aclt_list *aclt_list)
int maildir_acl_delete (const char *maildir, const char *path)
static int save_acl (const char *identifier, const maildir_aclt *acl, void *cb_arg)
static int is_owner (const char *isme, void *void_arg)
static int is_admin (const char *isme, void *void_arg)
static int check_adminrights (maildir_aclt *list)
static int check_allrights (maildir_aclt *list)
static int maildir_acl_compute_chkowner (maildir_aclt *aclt, maildir_aclt_list *aclt_list, int(*cb_func)(const char *isme, void *void_arg), void *void_arg, int chkowner)
int maildir_acl_write (maildir_aclt_list *aclt_list, const char *maildir, const char *path, const char *owner, const char **err_failedrights)
static void acl_check_cb (const char *mbox, void *voidarg)
int maildir_acl_reset (const char *maildir)
static int chk_admin (int(*cb_func)(const char *isme, void *void_arg), const char *identifier, void *void_arg)
int maildir_acl_compute (maildir_aclt *aclt, maildir_aclt_list *aclt_list, int(*cb_func)(const char *isme, void *void_arg), void *void_arg)
static int chk_array (const char *identifier, void *void_arg)
int maildir_acl_compute_array (maildir_aclt *aclt, maildir_aclt_list *aclt_list, const char *const *identifiers)
int maildir_acl_canlistrights (const char *myrights)
static int get_owner_list (int(*cb_func)(const char *, void *), const char *c, const char *mailbox_owner, void *arg)
static int count_owner_list (const char *o, void *arg)
static int save_owner_list (const char *o, void *arg)
int maildir_acl_computerights (maildir_aclt *rights, maildir_aclt_list *acl_list, const char *me, const char *folder_owner)

Variables

int maildir_acl_disabled = 0

Class Documentation

struct maildir_acl_resetList

Definition at line 893 of file maildiraclt.c.

Collaboration diagram for maildir_acl_resetList:
Class Members
char * mbox
struct maildir_acl_resetList * next

Define Documentation

#define dirent   direct

Definition at line 17 of file maildiraclt.c.

#define ISIDENT (   s)    (MAILDIR_ACL_ANYONE(s) ? 1: chk_admin(cb_func, (s), void_arg))

Definition at line 1046 of file maildiraclt.c.

#define NAMLEN (   dirent)    (dirent)->d_namlen

Definition at line 18 of file maildiraclt.c.


Function Documentation

static void acl_check_cb ( const char *  mbox,
void *  voidarg 
) [static]

Definition at line 913 of file maildiraclt.c.

{
       struct maildir_acl_resetList **l=
              (struct maildir_acl_resetList **)voidarg;

       if (strncmp(mbox, INBOX ".", sizeof(INBOX ".")-1))
              return; /* Huh? */

       mbox += sizeof(INBOX ".")-1;

       while (*l)
       {
              int cl= strlen( (*l)->mbox );

              if (strncmp(mbox, (*l)->mbox, cl) == 0 &&
                  mbox[cl] == '.')
              {
                     struct maildir_acl_resetList *p= *l;

                     *l= p->next;
                     free(p->mbox);
                     free(p);
                     continue;
              }

              l= &(*l)->next;
       }
}

Here is the caller graph for this function:

static int check_adminrights ( maildir_aclt list) [static]

Definition at line 662 of file maildiraclt.c.

{
       if (strchr(maildir_aclt_ascstr(list), ACL_LOOKUP[0]) == NULL ||
           strchr(maildir_aclt_ascstr(list), ACL_ADMINISTER[0]) == NULL)
       {
              maildir_aclt_destroy(list);
              return -1;
       }

       maildir_aclt_destroy(list);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_allrights ( maildir_aclt list) [static]

Definition at line 675 of file maildiraclt.c.

{
       const char *all=ACL_ALL;

       while (*all)
       {
              if (strchr(maildir_aclt_ascstr(list), *all) == NULL)
              {
                     maildir_aclt_destroy(list);
                     return -1;
              }
              ++all;
       }

       maildir_aclt_destroy(list);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int chk_admin ( int(*)(const char *isme, void *void_arg)  cb_func,
const char *  identifier,
void *  void_arg 
) [static]

Definition at line 1028 of file maildiraclt.c.

{
       if (strcmp(identifier, "administrators") == 0 ||
           strcmp(identifier, "group=administrators") == 0)
       {
              int rc=(*cb_func)("administrators", void_arg);

              if (rc == 0)
                     rc=(*cb_func)("group=administrators", void_arg);
              return rc;
       }

       return (*cb_func)(identifier, void_arg);
}
static int chk_array ( const char *  identifier,
void *  void_arg 
) [static]

Definition at line 1152 of file maildiraclt.c.

{
       const char * const *p=(const char * const *)void_arg;
       size_t i;

       for (i=0; p[i]; i++)
              if (strcmp(identifier, p[i]) == 0)
                     return 1;
       return 0;
}

Here is the caller graph for this function:

static int compar_aclt ( const void *  a,
const void *  b 
) [static]

Definition at line 38 of file maildiraclt.c.

{
       char ca=*(const char *)a;
       char cb=*(const char *)b;

       return (int)(unsigned char)ca - (int)(unsigned char)cb;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int count_owner_list ( const char *  o,
void *  arg 
) [static]

Definition at line 1237 of file maildiraclt.c.

{
       ++*(size_t *)arg;

       return 0;
}

Here is the caller graph for this function:

static void fixup ( maildir_aclt aclt) [static]

Definition at line 48 of file maildiraclt.c.

{
       char *a, *b;

       qsort(*aclt, strlen(*aclt), 1, compar_aclt);

       for (a=b=*aclt; *a; a++)
       {
              if (*a == a[1])
                     continue;
              if ((int)(unsigned char)*a <= ' ')
                     continue; /* Silently drop bad access rights */

              *b++= *a;
       }
       *b=0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_owner_list ( int(*)(const char *, void *)  cb_func,
const char *  c,
const char *  mailbox_owner,
void *  arg 
) [static]

Definition at line 1183 of file maildiraclt.c.

{
       char *a;
       int rc;
       const char *p, *q;

       a=malloc(sizeof("user=")+strlen(c));
       if (!a)
              return -1;

       strcat(strcpy(a, "user="), c);

       rc=(*cb_func)(a, arg);

       if (rc == 0 && strcmp(a, mailbox_owner) == 0)
              rc=(*cb_func)("owner", arg);
       free(a);

       if (rc)
              return rc;

       c=getenv("OPTIONS");

       for (p=c; p && *p; )
       {
              if (*p == ',')
              {
                     ++p;
                     continue;
              }

              q=p;
              while (*p && *p != ',')
                     ++p;

              if (strncmp(q, "group=", 6) == 0)
              {
                     a=malloc(p-q+1);
                     if (!a)
                            return -1;

                     memcpy(a, q, p-q);
                     a[p-q]=0;
                     rc=(*cb_func)(a, arg);
                     free(a);
                     if (rc)
                            return rc;
              }
       }
       return 0;
}

Here is the caller graph for this function:

static int is_admin ( const char *  isme,
void *  void_arg 
) [static]

Definition at line 655 of file maildiraclt.c.

{
       return strcmp(isme, "administrators") == 0;

       /* We don't need to check for group=administrators, see chk_admin() */
}

Here is the caller graph for this function:

static int is_owner ( const char *  isme,
void *  void_arg 
) [static]

Definition at line 647 of file maildiraclt.c.

{
       if (void_arg && strcmp(isme, (const char *)void_arg) == 0)
              return 1;

       return strcmp(isme, "owner") == 0;
}

Here is the caller graph for this function:

int maildir_acl_canlistrights ( const char *  myrights)

Definition at line 1165 of file maildiraclt.c.

{
       return (strchr(myrights, ACL_LOOKUP[0]) ||
              strchr(myrights, ACL_READ[0]) ||
              strchr(myrights, ACL_INSERT[0]) ||
              strchr(myrights, ACL_CREATE[0]) ||
              strchr(myrights, ACL_DELETEFOLDER[0]) ||
              strchr(myrights, ACL_EXPUNGE[0]) ||
              strchr(myrights, ACL_ADMINISTER[0]));
}

Here is the caller graph for this function:

int maildir_acl_compute ( maildir_aclt aclt,
maildir_aclt_list aclt_list,
int(*)(const char *isme, void *void_arg)  cb_func,
void *  void_arg 
)

Definition at line 1134 of file maildiraclt.c.

{
       return maildir_acl_compute_chkowner(aclt, aclt_list, cb_func, void_arg,
                                       1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_acl_compute_array ( maildir_aclt aclt,
maildir_aclt_list aclt_list,
const char *const *  identifiers 
)

Definition at line 1144 of file maildiraclt.c.

{
       return maildir_acl_compute(aclt, aclt_list, chk_array,
                               (void *)identifiers);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maildir_acl_compute_chkowner ( maildir_aclt aclt,
maildir_aclt_list aclt_list,
int(*)(const char *isme, void *void_arg)  cb_func,
void *  void_arg,
int  chkowner 
) [static]

Definition at line 1049 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;
       int rc;

       if (maildir_aclt_init(aclt, "", NULL) < 0)
              return -1;

       for (p=aclt_list->head; p; p=p->next)
       {
              if (p->identifier[0] == '-')
                     continue;

              rc= ISIDENT(p->identifier);

              if (rc < 0)
              {
                     maildir_aclt_destroy(aclt);
                     return rc;
              }

              if (rc == 0)
                     continue;

              if (maildir_aclt_add(aclt, NULL, &p->acl) < 0)
              {
                     maildir_aclt_destroy(aclt);
                     return rc;
              }
       }

       for (p=aclt_list->head; p; p=p->next)
       {
              if (p->identifier[0] != '-')
                     continue;

              rc= ISIDENT(p->identifier+1);

              if (rc < 0)
              {
                     maildir_aclt_destroy(aclt);
                     return rc;
              }

              if (rc == 0)
                     continue;

              if (maildir_aclt_del(aclt, NULL, &p->acl) < 0)
              {
                     maildir_aclt_destroy(aclt);
                     return rc;
              }
       }

       /*
       ** In our scheme, the owner always gets admin rights.
       */

       rc=chkowner ? (*cb_func)("owner", void_arg):0;

       if (maildir_acl_disabled)
              rc=0;  /* Except when ACLs are disabled */

       if (rc < 0)
       {
              maildir_aclt_destroy(aclt);
              return rc;
       }

       if (rc)
       {
              if (maildir_aclt_add(aclt, ACL_ADMINISTER, NULL) < 0)
              {
                     maildir_aclt_destroy(aclt);
                     return rc;
              }
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_acl_computerights ( maildir_aclt rights,
maildir_aclt_list acl_list,
const char *  me,
const char *  folder_owner 
)

Definition at line 1257 of file maildiraclt.c.

{
       char **owner_array;
       size_t owner_cnt;
       char **p;
       int rc;

       owner_cnt=1;

       if (get_owner_list(count_owner_list, me, folder_owner,
                        (void *)&owner_cnt) ||
           (owner_array=calloc(owner_cnt, sizeof(char *))) == NULL)
              return -1;

       p=owner_array;

       if (get_owner_list(save_owner_list, me, folder_owner, (void *)&p))
       {
              for (owner_cnt=0; owner_array[owner_cnt]; ++owner_cnt)
                     free(owner_array[owner_cnt]);
              free(owner_array);
              return -1;
       }

       rc=maildir_acl_compute_array(rights, acl_list,
                                 (const char * const *)owner_array);

       for (owner_cnt=0; owner_array[owner_cnt]; ++owner_cnt)
              free(owner_array[owner_cnt]);
       free(owner_array);
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_acl_delete ( const char *  maildir,
const char *  path 
)

Definition at line 580 of file maildiraclt.c.

{
       char *p, *q;

#if 0
       if (strcmp(path, SHARED) == 0)
              return 0;

       if (strncmp(path, SHARED ".", sizeof(SHARED)) == 0)
              return 0;
#endif
       if (!maildir || !*maildir)
              maildir=".";
       if (!path || !*path)
              path=".";

       if (strchr(path, '/') || *path != '.')
       {
              errno=EINVAL;
              return -1;
       }

       p=malloc(strlen(maildir)+strlen(path)+2);

       if (!p)
              return -1;

       strcat(strcat(strcpy(p, maildir), "/"), path);

       q=malloc(strlen(p)+sizeof("/" ACLFILE));
       if (!q)
       {
              free(p);
              return -1;
       }

       unlink(strcat(strcpy(q, p), "/" ACLFILE));
       free(p);
       free(q);

       if (strcmp(path, ".") == 0)
       {
              /* INBOX ACL default */

              return 0;
       }

       q=malloc(strlen(maildir)+sizeof("/" ACLHIERDIR "/") +
               strlen(path));
       if (!q)
       {
              free(p);
              return -1;
       }
       strcat(strcat(strcpy(q, maildir), "/" ACLHIERDIR "/"),
              path+1);

       unlink(q);
       free(q);
       return 0;
}

Here is the caller graph for this function:

int maildir_acl_read ( maildir_aclt_list aclt_list,
const char *  maildir,
const char *  path 
)

Definition at line 332 of file maildiraclt.c.

{
       int rc=maildir_acl_read_check(aclt_list, maildir, path);
       char *p, *q;

       if (rc)
              maildir_aclt_list_destroy(aclt_list);

       if (rc <= 0)
              return rc;

       /*
       ** If the ACL config file for this folder was not found,
       ** check for the ACL config file for its parent folder.
       */

       if ((p=strdup(path)) == NULL)
              return -1;

       strcpy(p, path);

       q=strrchr(p, '.');

       if (!q)
       {
              free(p);
              errno=EIO; /* Should not happen */
              return -1;
       }

       *q=0;

       rc=maildir_acl_read(aclt_list, maildir, p);
       if (rc == 0)
       {
              /* Make sure to save the default acl list */

              rc=maildir_acl_write(aclt_list, maildir, path, NULL, NULL);
              if (rc >= 0) /* Ok if rc=1 */
                     rc=0;
              if (rc)
                     maildir_aclt_list_destroy(aclt_list);
       }
       free(p);
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maildir_acl_read_check ( maildir_aclt_list aclt_list,
const char *  maildir,
const char *  path 
) [static]

Definition at line 391 of file maildiraclt.c.

{
       char *p, *q;
       FILE *fp;
       char buffer[BUFSIZ];

       maildir_aclt_list_init(aclt_list);

       if (!maildir || !*maildir)
              maildir=".";
       if (!path || !*path)
              path=".";

       if (strchr(path, '/') || *path != '.')
       {
              errno=EINVAL;
              return -1;
       }

       if (maildir_acl_disabled)
       {
              if (maildir_aclt_list_add(aclt_list, "owner",
                                     ACL_LOOKUP ACL_READ
                                     ACL_SEEN ACL_WRITE ACL_INSERT
                                     ACL_CREATE
                                     ACL_DELETEFOLDER
                                     ACL_DELETEMSGS ACL_EXPUNGE,
                                     NULL) < 0 ||
                  maildir_aclt_add_default_admin(aclt_list))
              {
                     maildir_aclt_list_destroy(aclt_list);
                     return -1;
              }
              return 0;
       }

       p=malloc(strlen(maildir)+strlen(path)+2);

       if (!p)
              return -1;

       strcat(strcat(strcpy(p, maildir), "/"), path);

       q=malloc(strlen(p)+sizeof("/" ACLFILE));
       if (!q)
       {
              free(p);
              return -1;
       }
       fp=fopen(strcat(strcpy(q, p), "/" ACLFILE), "r");
       free(p);
       free(q);

       if (fp == NULL)
       {
              if (strcmp(path, ".") == 0)
              {
                     /* INBOX ACL default */

                     if (maildir_aclt_list_add(aclt_list, "owner",
                                            ACL_ALL, NULL) < 0 ||
                         maildir_aclt_add_default_admin(aclt_list))
                     {
                            return -1;
                     }
                     return 0;
              }

              q=malloc(strlen(maildir)+sizeof("/" ACLHIERDIR "/") +
                      strlen(path));
              if (!q)
                     return -1;

              strcat(strcat(strcpy(q, maildir), "/" ACLHIERDIR "/"),
                     path+1);

              fp=fopen(q, "r");
              free(q);
       }

       if (!fp && errno != ENOENT)
              return -1;

       if (!fp)
              return 1;

       errno=0;

       while (fgets(buffer, sizeof(buffer), fp) != NULL)
       {
              char *p=strchr(buffer, '\n');

              if (p) *p=0;

              for (p=buffer; *p; p++)
                     if (*p == ' ')
                     {
                            *p=0;
                            do
                            {
                                   ++p;
                            } while (*p && *p == ' ');
                            break;
                     }

              if (maildir_aclt_list_add(aclt_list, buffer, p, NULL) < 0)
              {
                     if (errno != EINVAL)
                            return -1;
                     /* Sweep crap in the ACL file under the carpet */
              }
       }
       if (ferror(fp))
       {
              fclose(fp);
              return -1;
       }
       fclose(fp);
       if (maildir_aclt_add_default_admin(aclt_list))
              return -1;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_acl_reset ( const char *  maildir)

Definition at line 942 of file maildiraclt.c.

{
       DIR *dirp;
       struct dirent *de;
       char *p;
       struct maildir_acl_resetList *rl=NULL;
       struct maildir_acl_resetList *r;
       time_t now;
       struct stat stat_buf;

       p=malloc(strlen(maildir) + sizeof("/" ACLHIERDIR));
       if (!p)
              return -1;

       strcat(strcpy(p, maildir), "/" ACLHIERDIR);

       dirp=opendir(p);

       if (!dirp)
       {
              mkdir(p, 0755);
              dirp=opendir(p);
       }
       free(p);

       while (dirp && (de=readdir(dirp)) != NULL)
       {
              if (de->d_name[0] == '.')
                     continue;

              if ((r=malloc(sizeof(struct maildir_acl_resetList))) == NULL
                  || (r->mbox=strdup(de->d_name)) == NULL)
              {
                     if (r)
                            free(r);

                     while (rl)
                     {
                            r=rl;
                            rl=r->next;
                            free(r->mbox);
                            free(r);
                     }
                     closedir(dirp);
                     return -1;
              }

              r->next=rl;
              rl=r;
       }
       if (dirp) closedir(dirp);

       maildir_list(maildir, acl_check_cb, &rl);

       time(&now);

       while (rl)
       {
              r=rl;
              rl=r->next;

              p=malloc(strlen(maildir)+strlen(r->mbox) +
                      sizeof("/" ACLHIERDIR "/"));
              if (p)
              {
                     strcat(strcat(strcpy(p, maildir),
                                  "/" ACLHIERDIR "/"), r->mbox);

                     /* Only unlink stale entries after 1 hour (race) */

                     if (stat(p, &stat_buf) == 0 &&
                         stat_buf.st_mtime < now - 60*60)
                            unlink(p);
                     free(p);
              }
              free(r->mbox);
              free(r);
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_acl_write ( maildir_aclt_list aclt_list,
const char *  maildir,
const char *  path,
const char *  owner,
const char **  err_failedrights 
)

Definition at line 700 of file maildiraclt.c.

{
       int trycreate;
       struct maildir_tmpcreate_info tci;
       FILE *fp;
       char *p, *q;
       const char *dummy_string;
       maildir_aclt chkacls;

       if (!err_failedrights)
              err_failedrights= &dummy_string;

       if (!maildir || !*maildir)
              maildir=".";
       if (!path || !*path)
              path=".";

       if (strchr(path, '/') || *path != '.')
       {
              errno=EINVAL;
              return -1;
       }

       if (strcmp(path, ".")) /* Sanity check */
              for (dummy_string=path; *dummy_string; dummy_string++)
                     if (*dummy_string == '.' &&
                         (dummy_string[1] == '.' ||
                          dummy_string[1] == 0))
                     {
                            errno=EINVAL;
                            return -1;
                     }


       if (maildir_acl_compute_chkowner(&chkacls, aclt_list, is_owner, NULL,
                                    0))
       {
              maildir_aclt_destroy(&chkacls);
              errno=EINVAL;
              return -1;
       }

       if (check_adminrights(&chkacls))
       {
              *err_failedrights="owner";
              errno=EINVAL;
              return -1;
       }

       if (owner)
       {
              if (maildir_acl_compute_chkowner(&chkacls, aclt_list, is_owner,
                                           (void *)owner, 0))
              {
                     maildir_aclt_destroy(&chkacls);
                     errno=EINVAL;
                     return -1;
              }
              if (check_adminrights(&chkacls))
              {
                     *err_failedrights=owner;
                     errno=EINVAL;
                     return -1;
              }
       }

       if (maildir_acl_compute(&chkacls, aclt_list, is_admin, NULL))
       {
              maildir_aclt_destroy(&chkacls);
              errno=EINVAL;
              return -1;
       }
       if (check_allrights(&chkacls))
       {
              errno=EINVAL;
              return -1;
       }

       p=malloc(strlen(maildir)+strlen(path)+2);

       if (!p)
              return -1;

       strcat(strcat(strcpy(p, maildir), "/"), path);

       maildir_tmpcreate_init(&tci);

       tci.maildir=p;
       tci.uniq="acl";
       tci.doordie=1;

       fp=maildir_tmpcreate_fp(&tci);

       trycreate=0;

       if (fp)
       {
              q=malloc(strlen(p) + sizeof("/" ACLFILE));
              if (!q)
              {
                     fclose(fp);
                     unlink(tci.tmpname);
                     maildir_tmpcreate_free(&tci);
                     free(p);
                     return -1;
              }
              strcat(strcpy(q, p), "/" ACLFILE);
              free(tci.newname);
              tci.newname=q;
              free(p);
       }
       else
       {
              free(p);

              q=malloc(strlen(maildir)+sizeof("/" ACLHIERDIR "/") +
                      strlen(path));
              if (!q)
              {
                     maildir_tmpcreate_free(&tci);
                     return -1;
              }
              strcat(strcat(strcpy(q, maildir), "/" ACLHIERDIR "/"), path+1);

              tci.maildir=maildir;
              tci.uniq="acl";
              tci.doordie=1;

              fp=maildir_tmpcreate_fp(&tci);

              if (!fp)
              {
                     free(q);
                     maildir_tmpcreate_free(&tci);
                     return -1;
              }
              free(tci.newname);
              tci.newname=q;
              trycreate=1;
       }

       if (maildir_aclt_list_enum(aclt_list, save_acl, fp) < 0 ||
           ferror(fp) || fflush(fp) < 0)
       {
              fclose(fp);
              unlink(tci.tmpname);
              maildir_tmpcreate_free(&tci);
              return -1;
       }
       fclose(fp);

       if (rename(tci.tmpname, tci.newname) < 0)
       {
              /* Perhaps ACLHIERDIR needs to be created? */

              if (!trycreate)
              {
                     unlink(tci.tmpname);
                     maildir_tmpcreate_free(&tci);
                     return -1;
              }

              p=strrchr(tci.newname, '/');
              *p=0;
              mkdir(tci.newname, 0755);
              *p='/';

              if (rename(tci.tmpname, tci.newname) < 0)
              {
                     unlink(tci.tmpname);
                     maildir_tmpcreate_free(&tci);
                     return -1;
              }
       }
       maildir_tmpcreate_free(&tci);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_aclt_add ( maildir_aclt aclt,
const char *  add_strs,
const maildir_aclt add_aclt 
)

Definition at line 113 of file maildiraclt.c.

{
       if (add_aclt)
              add_strs= *add_aclt;

       if (!add_strs || !*add_strs)
              return 0;

       if (validacl(add_strs) < 0)
              return -1;

       if (*aclt)
       {
              char *p=realloc(*aclt, strlen(*aclt)+strlen(add_strs)+1);

              if (!p)
                     return -1;
              strcat(p, add_strs);
              *aclt=p;

       }
       else if ( ((*aclt)=strdup(add_strs)) == NULL)
              return -1;

       fixup(aclt);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maildir_aclt_add_default_admin ( maildir_aclt_list aclt_list) [static]

Definition at line 526 of file maildiraclt.c.

{
       const maildir_aclt *old_acl;

       static const char * const drop_acls[]={"-administrators",
                                          "-group=administrators"};
       size_t i;

       if ((old_acl=maildir_aclt_list_find(aclt_list, "group=administrators"))
           != NULL)
       {
              maildir_aclt new_acl;

              if (maildir_aclt_init(&new_acl, ACL_ALL, NULL))
                     return -1;

              if (maildir_aclt_add(&new_acl, NULL, old_acl) ||
                  maildir_aclt_list_add(aclt_list, "group=administrators",
                                     NULL, &new_acl))
              {
                     maildir_aclt_destroy(&new_acl);
                     return -1;
              }
              maildir_aclt_destroy(&new_acl);
       }
       else
       {
              maildir_aclt new_acl;

              old_acl=maildir_aclt_list_find(aclt_list, "administrators");

              if (maildir_aclt_init(&new_acl, ACL_ALL, NULL))
                     return -1;

              if (maildir_aclt_add(&new_acl, NULL, old_acl) ||
                  maildir_aclt_list_add(aclt_list, "administrators",
                                     NULL, &new_acl))
              {
                     maildir_aclt_destroy(&new_acl);
                     return -1;
              }
              maildir_aclt_destroy(&new_acl);
       }

       for (i=0; i<2; i++)
       {
              const char *n=drop_acls[i];
              if (maildir_aclt_list_del(aclt_list, n) < 0)
                     return -1;
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_aclt_del ( maildir_aclt aclt,
const char *  del_strs,
const maildir_aclt del_aclt 
)

Definition at line 143 of file maildiraclt.c.

{
       char *a, *b;

       if (del_aclt)
              del_strs= *del_aclt;

       if (!del_strs)
              return 0;

       if (!*aclt)
              return 0;

       for (a=b=*aclt; *a; a++)
       {
              if (strchr(del_strs, *a))
                     continue;
              *b++= *a;
       }
       *b=0;

       if (**aclt == 0)
       {
              free(*aclt);
              *aclt=NULL;
       }
       return 0;
}

Here is the caller graph for this function:

Definition at line 104 of file maildiraclt.c.

{
       if (*aclt)
              free(*aclt);
}

Here is the caller graph for this function:

int maildir_aclt_init ( maildir_aclt aclt,
const char *  initvalue_cstr,
const maildir_aclt initvalue_cpy 
)

Definition at line 81 of file maildiraclt.c.

{
       if (initvalue_cpy)
              initvalue_cstr= *initvalue_cpy;

       *aclt=NULL;

       if (!initvalue_cstr || !*initvalue_cstr)
              return 0;

       if (validacl(initvalue_cstr) < 0)
              return -1;

       if ( (*aclt=strdup(initvalue_cstr)) == NULL)
              return -1;
       fixup(aclt);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_aclt_list_add ( maildir_aclt_list aclt_list,
const char *  identifier,
const char *  aclt_str,
maildir_aclt aclt_cpy 
)

Definition at line 202 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;
       const char *q;

       /* Check for valid identifiers */

       for (q=identifier; *q; q++)
              if ( (int)(unsigned char)*q <= ' ')
              {
                     errno=EINVAL;
                     return -1;
              }

       if (*identifier == 0)
       {
              errno=EINVAL;
              return -1;
       }

       if (aclt_cpy && *aclt_cpy)
              aclt_str= *aclt_cpy;

       for (p=aclt_list->head; p; p=p->next)
       {
              if (strcmp(p->identifier, identifier) == 0)
              {
                     maildir_aclt_destroy(&p->acl);
                     return maildir_aclt_init(&p->acl, aclt_str, NULL);
              }
       }

       if ((p=malloc(sizeof(*p))) == NULL ||
           (p->identifier=strdup(identifier)) == NULL)
       {
              if (p) free(p);
              return -1;
       }

       if (maildir_aclt_init(&p->acl, aclt_str, NULL) < 0)
       {
              free(p->identifier);
              free(p);
              return -1;
       }

       p->next=NULL;
       if ((p->prev=aclt_list->tail) != NULL)
              p->prev->next=p;
       else
              aclt_list->head=p;
       aclt_list->tail=p;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_aclt_list_del ( maildir_aclt_list aclt_list,
const char *  identifier 
)

Definition at line 264 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;

       for (p=aclt_list->head; p; p=p->next)
       {
              if (strcmp(p->identifier, identifier) == 0)
              {
                     if (p->prev)
                            p->prev->next=p->next;
                     else aclt_list->head=p->next;

                     if (p->next)
                            p->next->prev=p->prev;
                     else aclt_list->tail=p->prev;

                     maildir_aclt_destroy(&p->acl);
                     free(p->identifier);
                     free(p);
                     return 0;
              }
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 183 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;

       for (p=aclt_list->head; p; )
       {
              struct maildir_aclt_node *q=p->next;

              free(p->identifier);
              maildir_aclt_destroy(&p->acl);
              free(p);
              p=q;
       }
       maildir_aclt_list_init(aclt_list);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_aclt_list_enum ( maildir_aclt_list aclt_list,
int(*)(const char *identifier, const maildir_aclt *acl, void *cb_arg)  cb_func,
void *  cb_arg 
)

Definition at line 294 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;
       int rc;

       for (p=aclt_list->head; p; p=p->next)
       {
              rc= (*cb_func)(p->identifier, &p->acl, cb_arg);

              if (rc)
                     return rc;
       }
       return 0;
}

Here is the caller graph for this function:

const maildir_aclt* maildir_aclt_list_find ( maildir_aclt_list aclt_list,
const char *  identifier 
)

Definition at line 313 of file maildiraclt.c.

{
       struct maildir_aclt_node *p;

       for (p=aclt_list->head; p; p=p->next)
       {
              if (strcmp(p->identifier, identifier) == 0)
                     return &p->acl;
       }
       return NULL;
}

Here is the caller graph for this function:

Definition at line 177 of file maildiraclt.c.

{
       aclt_list->head=NULL;
       aclt_list->tail=NULL;
}

Here is the caller graph for this function:

static int save_acl ( const char *  identifier,
const maildir_aclt acl,
void *  cb_arg 
) [static]

Definition at line 883 of file maildiraclt.c.

{
       if (fprintf((FILE *)cb_arg, "%s %s\n",
                  identifier,
                  maildir_aclt_ascstr(acl)) < 0)
              return -1;
       return 0;
}

Here is the caller graph for this function:

static int save_owner_list ( const char *  o,
void *  arg 
) [static]

Definition at line 1244 of file maildiraclt.c.

{
       char ***p=(char ***)arg;

       **p=strdup(o);

       if (**p == NULL)
              return -1;

       ++*p;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int validacl ( const char *  p) [static]

Definition at line 66 of file maildiraclt.c.

{
       while (*p)
       {
              if ((int)(unsigned char)*p <= ' ')
              {
                     errno=EINVAL;
                     return -1;
              }
              ++p;
       }

       return 0;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 36 of file maildiraclt.c.