acl-backend-vfile.c revision da9f6acdcb303d0fe5160b669668aedf39c8f45a
/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "istream.h"
#include "nfs-workarounds.h"
#include "mail-storage-private.h"
#include "acl-cache.h"
#include "acl-backend-vfile.h"
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define VALIDITY_MTIME_NOTFOUND 0
#define VALIDITY_MTIME_NOACCESS -1
struct acl_vfile_validity {
};
struct acl_backend_vfile_validity {
struct acl_vfile_validity mailbox_validity;
};
struct acl_letter_map {
char letter;
const char *name;
};
static const struct acl_letter_map acl_letter_map[] = {
{ 'l', MAIL_ACL_LOOKUP },
{ 'r', MAIL_ACL_READ },
{ 'w', MAIL_ACL_WRITE },
{ 's', MAIL_ACL_WRITE_SEEN },
{ 't', MAIL_ACL_WRITE_DELETED },
{ 'i', MAIL_ACL_INSERT },
{ 'e', MAIL_ACL_EXPUNGE },
{ 'k', MAIL_ACL_CREATE },
{ 'x', MAIL_ACL_DELETE },
{ 'a', MAIL_ACL_ADMIN },
{ '\0', NULL }
};
static struct acl_backend *acl_backend_vfile_alloc(void)
{
struct acl_backend_vfile *backend;
}
static int
{
struct acl_backend_vfile *backend =
(struct acl_backend_vfile *)_backend;
const char *const *tmp;
tmp++;
else {
return -1;
}
}
i_info("acl vfile: Global ACL directory: %s",
}
sizeof(struct acl_backend_vfile_validity));
return 0;
}
{
struct acl_backend_vfile *backend =
(struct acl_backend_vfile *)_backend;
}
}
static const char *
{
const char *dir;
bool is_file;
if (is_file) {
}
return dir;
}
static struct acl_object *
{
struct acl_backend_vfile *backend =
(struct acl_backend_vfile *)_backend;
struct acl_object_vfile *aclobj;
const char *dir;
/* the default ACL for mailbox list */
} else {
}
}
static const char *
{
const char *p;
char sep;
}
static int
struct acl_vfile_validity *validity)
{
/* use the cached value */
}
return 0;
}
return 1;
}
return -1;
}
return 1;
}
static bool
{
struct acl_backend_vfile *backend =
(struct acl_backend_vfile *)_backend;
int ret;
if (old_validity != NULL)
else
/* See if the mailbox exists. If we wanted recursive lookups we could
skip this, but at least for now we assume that if an existing
mailbox has no ACL it's equivalent to default ACLs. */
if (ret == 0) {
}
}
return ret > 0;
}
static struct acl_object *
struct mail_storage *storage,
const char *child_name)
{
const char *parent;
/* stop at the first parent that
a) has global ACL file
b) has local ACL file
c) exists */
break;
child_name = parent;
}
/* use the root */
parent = "";
}
}
{
}
static const char *const *
{
ARRAY_DEFINE(rights, const char *);
const char *const *names, **ret_rights;
unsigned int i, count;
/* parse IMAP ACL list */
acl++;
break;
}
return NULL;
}
acl++;
}
if (*acl != '\0') {
/* parse our own extended ACLs */
}
}
/* @UNSAFE */
if (count > 0) {
sizeof(const char *) * count);
}
return ret_rights;
}
static int
{
struct acl_rights_update rights;
return 0;
/* <id> [<imap acls>] [:<named acls>] */
if (p == NULL)
p = "";
else {
p++;
}
if (*line != '-') {
} else {
line++;
}
switch (*line) {
case 'u':
break;
}
case 'o':
break;
}
case 'g':
break;
break;
}
case 'a':
break;
break;
}
default:
break;
}
return -1;
}
return 0;
}
{
struct acl_rights_update rights;
}
static int
bool *is_dir_r)
{
const char *line;
unsigned int linenum;
if (fd == -1) {
} else {
return -1;
}
return 1;
}
return 0;
}
return -1;
}
/* we opened a directory. */
return 0;
}
pool_alloconly_create("acl rights",
} else {
}
linenum = 1;
T_BEGIN {
linenum++);
} T_END;
if (ret < 0)
break;
}
if (ret < 0) {
/* parsing failure */
} else if (input->stream_errno != 0) {
ret = 0;
else {
ret = -1;
}
} else {
ret = 0;
else {
ret = -1;
}
} else {
ret = 1;
}
}
return 0;
return -1;
}
return ret;
}
static int
const char *path,
struct acl_vfile_validity *validity)
{
unsigned int i;
int ret;
bool is_dir;
return 0;
for (i = 0;; i++) {
&is_dir);
if (ret != 0)
break;
if (is_dir) {
/* opened a directory. use dir/.DEFAULT instead */
} else {
/* ESTALE - try again */
}
}
return ret <= 0 ? -1 : 0;
}
static int
struct acl_vfile_validity *validity)
{
struct acl_backend_vfile *backend =
return 1;
return 0;
/* if the file used to exist, we have to re-read it */
}
return -1;
}
/* same timestamp, but if it was modified within the
same second we want to refresh it again later (but
do it only after a couple of seconds so we don't
keep re-reading it all the time within those
seconds) */
if (validity->last_read_time != 0 &&
return 0;
}
return 1;
}
{
struct acl_backend_vfile_validity *validity;
return -1;
else
*mtime_r = 0;
return 0;
}
{
struct acl_backend_vfile *backend =
struct acl_backend_vfile_validity *old_validity;
struct acl_backend_vfile_validity validity;
int ret;
if (ret == 0) {
}
if (ret <= 0)
return ret;
/* either global or local ACLs changed, need to re-read both */
&validity.global_validity) < 0)
return -1;
&validity.local_validity) < 0)
return -1;
return 0;
}
static int
const struct acl_rights_update *rights
{
/* FIXME */
return -1;
}
static struct acl_object_list_iter *
{
struct acl_object_list_iter *iter;
return iter;
}
static int
struct acl_rights *rights_r)
{
struct acl_object_vfile *aclobj =
const struct acl_rights *rights;
return 0;
return 1;
}
static void
{
}
struct acl_backend_vfuncs acl_backend_vfile = {
};