int mailbox_scan(const char *reference, const char *name, int list_options, int (*callback_func)(const char *hiersep, const char *mailbox, int flags, void *void_arg), void *void_arg) { char *pattern, *p; int nullname= *name == 0; int rc; pattern=malloc(strlen(reference)+strlen(name)+2); strcpy(pattern, reference); p=strrchr(pattern, HIERCH); if (p && p[1] == 0) *p=0; /* Strip trailing . for now */ if (*pattern) { struct maildir_info mi; if (maildir_info_imap_find(&mi, pattern, getenv("AUTHENTICATED"))) { free(pattern); return (0); /* Invalid reference */ } maildir_info_destroy(&mi); } /* Combine reference and name. */ if (*pattern && *name) strcat(pattern, hierchs); strcat(pattern, name); if (name && *name) { char *s=strrchr(pattern, HIERCH); if (s && s[1] == 0) *s=0; /* strip trailing . */ } /* Now, do the list */ rc=do_mailbox_list(list_options, pattern, nullname, callback_func, void_arg); free(pattern); return (rc); }
int acl_read(maildir_aclt_list *l, const char *folder, char **owner) { struct maildir_info minfo; int rc; if (maildir_info_imap_find(&minfo, folder, login_returnaddr())<0) { return -1; } rc=acl_read2(l, &minfo, owner); maildir_info_destroy(&minfo); return rc; }
static void doupdate() { maildir_aclt_list l; char *owner; char buf[2]; char *p; struct maildir_info minfo; if (maildir_info_imap_find(&minfo, sqwebmail_folder, login_returnaddr()) < 0) return; if (acl_read2(&l, &minfo, &owner) < 0) { maildir_info_destroy(&minfo); return; } strcpy(buf, ACL_ADMINISTER); acl_computeRights(&l, buf, owner); if (!*buf) { if (owner) free(owner); maildir_aclt_list_destroy(&l); maildir_info_destroy(&minfo); return; } if (*cgi("delentity")) { if (maildir_aclt_list_del(&l, cgi("delentity"))) printf("%s", getarg("ACL_failed")); } if (*cgi("do.update")) { char *entity=NULL; const char *p; char new_acl[40]; p=cgi("entitytype"); if (strcmp(p, "anonymous") == 0 || strcmp(p, "owner") == 0) entity=strdup(p); else if (strcmp(p, "user") == 0) { p=cgi("entity"); if (*p) { entity=malloc(sizeof("user="******"user="******"group") == 0) { p=cgi("entity"); if (*p) { entity=malloc(sizeof("group=")+strlen(p)); if (entity) strcat(strcpy(entity, "group="), p); } } else { entity=strdup(cgi("entity")); } if (*cgi("negate") == '-' && entity) { char *p=malloc(strlen(entity)+2); if (p) strcat(strcpy(p, "-"), entity); free(entity); entity=p; } if (entity) { char *val= unicode_convert_toutf8(entity, sqwebmail_content_charset, NULL); if (val) { free(entity); entity=val; } } p=getarg("ACL_all"); new_acl[0]=0; while (*p && strlen(new_acl) < sizeof(new_acl)-2) { char b[40]; sprintf(b, "acl_%c", *p); if (*cgi(b)) { b[0]=*p; b[1]=0; strcat(new_acl, b); } ++p; } if (!entity || !*entity || maildir_aclt_list_add(&l, entity, new_acl, NULL) < 0) printf("%s", getarg("ACL_failed")); if (entity) free(entity); } p=maildir_name2dir(".", minfo.maildir); if (p) { const char *err_ident; if (maildir_acl_write(&l, minfo.homedir, strncmp(p, "./", 2) == 0 ? p+2:p, owner, &err_ident)) printf("%s", getarg("ACL_failed")); free(p); } if (owner) free(owner); maildir_aclt_list_destroy(&l); maildir_info_destroy(&minfo); }
void listrights() { maildir_aclt_list l; char buf[40]; char *owner; if (*cgi("do.update") || *cgi("delentity")) { struct maildir_info minfo; if (maildir_info_imap_find(&minfo, sqwebmail_folder, login_returnaddr()) == 0) { if (minfo.homedir) { struct maildirwatch *w; char *lock; int tryanyway; w=maildirwatch_alloc(minfo.homedir); if (!w) { maildir_info_destroy(&minfo); enomem(); return; } lock=maildir_lock(minfo.homedir, w, &tryanyway); maildir_info_destroy(&minfo); if (lock == NULL) { if (!tryanyway) { printf("%s", getarg("ACL_noaccess")); return; } } doupdate(); if (lock) { unlink(lock); free(lock); } maildirwatch_free(w); } } } if (acl_read(&l, sqwebmail_folder, &owner) < 0) { printf("%s", getarg("ACL_cantread")); return; } buf[0]=0; strncat(buf, getarg("ACL_all"), sizeof(buf)-2); acl_computeRights(&l, buf, owner); maildir_aclt_list_destroy(&l); if (owner) free(owner); if (!maildir_acl_canlistrights(buf)) { printf("%s", getarg("ACL_cantread")); return; } showrights(buf); }
int maildir_info_imap_find(struct maildir_info *info, const char *path, const char *myId) { const char *p; struct imap_find_shared ifs; const char *indexfile; char *indexfile_cpy; struct maildir_shindex_cache *curcache; const char *subhierarchy; info->homedir=NULL; info->maildir=NULL; info->owner=NULL; if (strchr(path, '/')) { errno=EINVAL; return -1; } for (p=path; *p; p++) if (*p == '.' && p[1] == '.') { errno=EINVAL; return -1; } if (strncmp(path, SHARED, sizeof(SHARED)-1) == 0) { path += sizeof(SHARED)-1; info->homedir=strdup("."); if (!info->homedir) return -1; info->mailbox_type=MAILBOXTYPE_OLDSHARED; info->owner=strdup("anonymous"); if (!info->owner) { maildir_info_destroy(info); return -1; } /* We need to specialcase "shared" and "shared.name". ** maildir_shareddir will return NULL for these cases, because ** it will insist on "name.folder", but we need to return a ** non NULL value to indicate that this is a valid hierarchy ** name. We return a special value of an empty string, which ** is checked for in situations where a valid folder is ** required. */ if (*path && *path != '.') { maildir_info_destroy(info); errno=EINVAL; return -1; } return 0; } if (strncasecmp(path, INBOX, sizeof(INBOX)-1) == 0) { switch (path[sizeof(INBOX)-1]) { case 0: case '.': break; default: errno=EINVAL; return -1; } info->homedir=strdup("."); if (!info->homedir) return -1; info->maildir=strdup(path); if (!info->maildir) { maildir_info_destroy(info); return -1; } info->owner=malloc(strlen(myId)+sizeof("user="******"user="******"vendor=courier.internal"); if (!info->owner) return -1; ifs.homedir=NULL; ifs.maildir=NULL; indexfile=NULL; indexfile_cpy=NULL; curcache=NULL; subhierarchy=NULL; while (*ifs.path) { int rc, eof; size_t i; curcache=maildir_shared_cache_read(curcache, indexfile, subhierarchy); if (indexfile_cpy) { free(indexfile_cpy); indexfile_cpy=NULL; } if (!curcache) break; p=strchr(ifs.path, '.'); if (p) ifs.path_l=p-ifs.path; else ifs.path_l=strlen(ifs.path); if (ifs.homedir) free(ifs.homedir); if (ifs.maildir) free(ifs.maildir); ifs.homedir=NULL; ifs.maildir=NULL; for (i=0; i < curcache->nrecords; i++) { char *n=maildir_info_imapmunge(curcache-> records[i].name); if (n == NULL) { i=curcache->nrecords; break; } if (strlen(n) == ifs.path_l && strncmp(n, ifs.path, ifs.path_l) == 0) { free(n); break; } free(n); } if (i >= curcache->nrecords) break; curcache->indexfile.startingpos= curcache->records[i].offset; rc=maildir_newshared_nextAt(&curcache->indexfile, &eof, imap_find_cb, &ifs); if (rc || eof) { fprintf(stderr, "ERR: Internal error -" " maildir_newshared_nextAt: %s\n", strerror(errno)); fflush(stderr); break; } if (!ifs.homedir && !ifs.maildir) break; if (!ifs.homedir) { indexfile=indexfile_cpy=ifs.maildir; ifs.maildir=NULL; subhierarchy=curcache->records[i].name; ifs.path += ifs.path_l; if (*ifs.path) ++ifs.path; continue; } info->homedir=maildir_location(ifs.homedir, ifs.maildir); free(ifs.homedir); free(ifs.maildir); free(info->owner); if (!info->homedir) { info->maildir=NULL; info->owner=NULL; return -1; } if (!subhierarchy || !*subhierarchy) { info->owner=strdup("vendor=courier.internal"); if (!info->owner) { free(info->homedir); info->homedir=NULL; info->maildir=NULL; return -1; } } else { char *owner_utf8; info->owner=malloc(strlen(subhierarchy) +sizeof("user="******"user="******"utf-8", NULL); if (!owner_utf8) { free(info->homedir); info->homedir=NULL; return (0); } free(info->owner); info->owner=owner_utf8; } ifs.path += ifs.path_l; info->maildir=malloc(strlen(INBOX)+1+strlen(ifs.path)); if (!info->maildir) { free(info->owner); free(info->homedir); info->owner=NULL; info->homedir=NULL; return -1; } strcat(strcpy(info->maildir, INBOX), ifs.path); if (maildir_info_suppress(info->homedir)) { free(info->homedir); free(info->maildir); info->homedir=NULL; info->maildir=NULL; info->mailbox_type=MAILBOXTYPE_IGNORE; free(info->owner); info->owner=NULL; info->owner=strdup("vendor=courier.internal"); if (!info->owner) { return -1; } } return 0; } if (indexfile_cpy) free(indexfile_cpy); if (ifs.homedir) { free(ifs.homedir); ifs.homedir=NULL; } if (ifs.maildir) { free(ifs.maildir); ifs.maildir=NULL; } return 0; }
int maildir_info_smap_find(struct maildir_info *info, char **folder, const char *myId) { char *p; size_t n; const char *indexfile; struct maildir_shindex_cache *curcache; const char *subhierarchy; struct imap_find_shared ifs; int rc, eof; char *indexfile_cpy=NULL; info->homedir=NULL; info->maildir=NULL; info->owner=NULL; info->mailbox_type=MAILBOXTYPE_IGNORE; if (folder[0] == NULL) { errno=EINVAL; return -1; } if (strcmp(folder[0], PUBLIC)) { if (strcmp(folder[0], INBOX)) { errno=EINVAL; return -1; } info->maildir=smap_path(NULL, folder); if (info->maildir == NULL) return -1; info->homedir=strdup("."); if (!info->homedir) { maildir_info_destroy(info); return -1; } info->mailbox_type=MAILBOXTYPE_INBOX; info->owner=malloc(strlen(myId)+sizeof("user="******"user="******"ERR: Internal error -" " maildir_newshared_nextAt: %s\n", strerror(errno)); fflush(stderr); break; } if (!ifs.homedir && !ifs.maildir) break; if (!ifs.homedir) { if (indexfile_cpy) free(indexfile_cpy); indexfile=indexfile_cpy=ifs.maildir; ifs.maildir=NULL; subhierarchy=curcache->records[i].name; ++n; continue; } if (indexfile_cpy) free(indexfile_cpy); info->homedir=maildir_location(ifs.homedir, ifs.maildir); free(ifs.homedir); free(ifs.maildir); info->maildir=NULL; if (maildir_info_suppress(info->homedir)) { free(info->homedir); info->homedir=NULL; info->maildir=NULL; info->mailbox_type=MAILBOXTYPE_IGNORE; info->owner=NULL; info->owner=strdup("vendor=courier.internal"); if (!info->owner) { maildir_info_destroy(info); return -1; } return 0; } if (!subhierarchy || !*subhierarchy) { info->owner=strdup("vendor=courier.internal"); if (!info->owner) { maildir_info_destroy(info); return -1; } } else { info->owner=malloc(strlen(subhierarchy) +sizeof("user="******"user="******"vendor=courier.internal"); if (!info->owner) { maildir_info_destroy(info); return -1; } /* Intermediate shared namespce */ return 0; } return -1; }