acl-api.c revision cc287b822b175619a853686b738ba673e370117b
/* Copyright (c) 2006-2013 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "hash.h"
#include "mail-user.h"
#include "mailbox-list.h"
#include "acl-cache.h"
#include "acl-api-private.h"
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 },
{ 'p', MAIL_ACL_POST },
{ 'e', MAIL_ACL_EXPUNGE },
{ 'k', MAIL_ACL_CREATE },
{ 'x', MAIL_ACL_DELETE },
{ 'a', MAIL_ACL_ADMIN },
{ '\0', NULL }
};
const char *name)
{
}
const char *child_name)
{
}
{
}
{
unsigned int read_idx;
return -1;
return -1;
}
return 1;
/* when dsync is running on a shared mailbox, it must be able
to do everything inside it. however, dsync shouldn't touch
mailboxes where user doesn't have any read access, because
that could make them readable on the replica. */
return 1;
}
return 0;
}
const char *const *
{
const char *const *names;
count = 0;
else {
continue;
/* @UNSAFE */
}
}
}
/* @UNSAFE */
return rights;
}
const char *const **rights_r)
{
return -1;
return -1;
}
return 0;
}
const char *const **rights_r)
{
int ret;
if (pool->datastack_pool)
T_BEGIN {
} T_END;
return ret;
}
{
}
{
}
const struct acl_rights_update *update)
{
}
{
}
struct acl_rights *rights_r)
{
return -1;
}
{
}
struct acl_mailbox_list_context *
{
}
const char **name_r)
{
}
void
{
}
{
}
{
case ACL_ID_ANYONE:
break;
case ACL_ID_AUTHENTICATED:
break;
case ACL_ID_OWNER:
break;
case ACL_ID_USER:
break;
case ACL_ID_GROUP:
break;
case ACL_ID_GROUP_OVERRIDE:
break;
case ACL_ID_TYPE_COUNT:
i_unreached();
}
}
{
}
static bool is_standard_right(const char *name)
{
unsigned int i;
for (i = 0; all_mailbox_rights[i] != NULL; i++) {
return TRUE;
}
return FALSE;
}
const char **error_r)
{
unsigned int i, j;
return -1;
}
return 0;
}
if (right[0] != '-')
dest = &dest_rights;
else {
right++;
dest = &dest_neg_rights;
}
if (*right == ':') {
/* non-standard right */
right++;
} else if (is_standard_right(right)) {
} else {
right);
return -1;
}
} else {
for (j = 0; all_mailbox_rights[j] != NULL; j++)
}
}
if (array_count(&dest_rights) > 0) {
}
if (array_count(&dest_neg_rights) > 0) {
}
return 0;
}
{
}
}
{
int ret;
/* globals have higher priority than locals */
}
if (ret != 0)
return ret;
}
{
const char *const *p;
/* ignore owner rights */
return FALSE;
}
return FALSE;
if (strcmp(*p, MAIL_ACL_LOOKUP) == 0)
return TRUE;
}
return FALSE;
}
{
strlen(ACL_ID_NAME_USER_PREFIX)) == 0) {
strlen(ACL_ID_NAME_GROUP_PREFIX)) == 0) {
strlen(ACL_ID_NAME_GROUP_OVERRIDE_PREFIX)) == 0) {
} else {
return -1;
}
return 0;
}
static const char *const *
bool dup_strings)
{
/* sort the rights first so we can easily drop duplicates */
/* @UNSAFE */
if (count > 0) {
}
if (dup_strings) {
for (i = 0; i < dest; i++)
}
}
return ret;
}
const char *const *
{
const char *const *names;
unsigned int i;
/* parse IMAP ACL list */
acl++;
break;
}
return NULL;
}
acl++;
}
if (*acl != '\0') {
/* parse our own extended ACLs */
if (*acl != ':') {
*error_r = "Missing ':' prefix in ACL extensions";
return NULL;
}
}
}
}
{
char c2[2];
unsigned int i, j, pos;
/* use letters if possible */
pos++;
break;
}
}
/* fallback to full name */
}
}
c2[0] = ':';
}
}
const char *const *src, bool dup_strings)
{
unsigned int i;
}
}
}
const char *const **rightsp,
const char *const *modify_rights,
enum acl_modify_mode modify_mode)
{
const char *const *old_rights = *rightsp;
const char *const *new_rights = NULL;
unsigned int i, j;
/* nothing to do here */
return FALSE;
}
switch (modify_mode) {
case ACL_MODIFY_MODE_REMOVE:
/* nothing to do */
return FALSE;
}
for (i = 0; old_rights[i] != NULL; i++) {
for (j = 0; modify_rights[j] != NULL; j++) {
break;
}
if (modify_rights[j] == NULL)
}
new_rights = &null;
break;
case ACL_MODIFY_MODE_ADD:
break;
case ACL_MODIFY_MODE_REPLACE:
new_rights = &null;
break;
case ACL_MODIFY_MODE_CLEAR:
/* ACL didn't exist before either */
return FALSE;
}
return TRUE;
}
*rightsp = new_rights;
if (old_rights == NULL)
return new_rights[0] != NULL;
/* see if anything changed */
return TRUE;
}
}