Skip to content

Add a new type of ACL to permit a fake empty mailbox #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
5 changes: 5 additions & 0 deletions src/plugins/acl/acl-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct acl_letter_map {
static const struct acl_letter_map acl_letter_map[] = {
{ 'l', MAIL_ACL_LOOKUP },
{ 'r', MAIL_ACL_READ },
{ 'f', MAIL_ACL_FAKE_EMPTY},
{ 'w', MAIL_ACL_WRITE },
{ 's', MAIL_ACL_WRITE_SEEN },
{ 't', MAIL_ACL_WRITE_DELETED },
Expand Down Expand Up @@ -78,6 +79,10 @@ int acl_object_have_right(struct acl_object *aclobj, unsigned int right_idx)
MAIL_ACL_READ);
if (acl_cache_mask_isset(have_mask, read_idx))
return 1;
read_idx = acl_backend_lookup_right(aclobj->backend,
MAIL_ACL_FAKE_EMPTY);
if (acl_cache_mask_isset(have_mask, read_idx))
return 1;
}
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/acl/acl-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct acl_object;
#define MAIL_ACL_LOOKUP "lookup"
/* Allow opening mailbox for reading */
#define MAIL_ACL_READ "read"
/* The mailbox is readable but no messages are returned */
#define MAIL_ACL_FAKE_EMPTY "fake-empty"
/* Allow permanent flag changes (except for seen/deleted).
If not set, doesn't allow save/copy to set any flags either. */
#define MAIL_ACL_WRITE "write"
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/acl/acl-attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ static int acl_have_attribute_rights(struct mailbox *box)
return 0;
if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_POST) > 0)
return 0;
if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_FAKE_EMPTY) > 0)
return 0;
return -1;
}

Expand Down
1 change: 1 addition & 0 deletions src/plugins/acl/acl-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extern struct acl_backend_vfuncs acl_backend_vfile;
const char *const all_mailbox_rights[] = {
MAIL_ACL_LOOKUP,
MAIL_ACL_READ,
MAIL_ACL_FAKE_EMPTY,
MAIL_ACL_WRITE,
MAIL_ACL_WRITE_SEEN,
MAIL_ACL_WRITE_DELETED,
Expand Down
1 change: 1 addition & 0 deletions src/plugins/acl/acl-mailbox-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct acl_mailbox_list_iterate_context {
static const char *acl_storage_right_names[ACL_STORAGE_RIGHT_COUNT] = {
MAIL_ACL_LOOKUP,
MAIL_ACL_READ,
MAIL_ACL_FAKE_EMPTY,
MAIL_ACL_WRITE,
MAIL_ACL_WRITE_SEEN,
MAIL_ACL_WRITE_DELETED,
Expand Down
15 changes: 15 additions & 0 deletions src/plugins/acl/acl-mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,16 @@ void acl_mail_allocated(struct mail *_mail)
MODULE_CONTEXT_SET_SELF(mail, acl_mail_module, amail);
}

bool acl_search_next_nonblock(struct mail_search_context *ctx,
struct mail **mail_r, bool *tryagain_r) {
struct acl_mailbox *abox = ACL_CONTEXT(ctx->transaction->box);

if (acl_mailbox_right_lookup(ctx->transaction->box, ACL_STORAGE_RIGHT_FAKE_EMPTY) > 0) {
return FALSE;
}
return abox->module_ctx.super.search_next_nonblock(ctx, mail_r, tryagain_r);
}

static int
acl_save_get_flags(struct mailbox *box, enum mail_flags *flags,
enum mail_flags *pvt_flags, struct mail_keywords **keywords)
Expand Down Expand Up @@ -484,6 +494,7 @@ static int acl_mailbox_exists(struct mailbox *box, bool auto_boxes,
for (i = 0; rights[i] != NULL; i++) {
if (strcmp(rights[i], MAIL_ACL_LOOKUP) == 0 ||
strcmp(rights[i], MAIL_ACL_READ) == 0 ||
strcmp(rights[i], MAIL_ACL_FAKE_EMPTY) == 0 ||
strcmp(rights[i], MAIL_ACL_INSERT) == 0)
return abox->module_ctx.super.exists(box, auto_boxes,
existence_r);
Expand Down Expand Up @@ -516,6 +527,9 @@ static int acl_mailbox_open_check_acl(struct mailbox *box)
}

ret = acl_object_have_right(abox->aclobj, idx_arr[open_right]);
if (ret == 0 && open_right == ACL_STORAGE_RIGHT_READ) {
ret = acl_object_have_right(abox->aclobj, idx_arr[ACL_STORAGE_RIGHT_FAKE_EMPTY]);
}
if (ret <= 0) {
if (ret == 0) {
/* no access. */
Expand Down Expand Up @@ -612,6 +626,7 @@ void acl_mailbox_allocated(struct mailbox *box)
v->attribute_iter_init = acl_attribute_iter_init;
v->attribute_iter_next = acl_attribute_iter_next;
v->attribute_iter_deinit = acl_attribute_iter_deinit;
v->search_next_nonblock = acl_search_next_nonblock;
}
MODULE_CONTEXT_SET(box, acl_storage_module, abox);
}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/acl/acl-storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct acl_rights_update;
enum acl_storage_rights {
ACL_STORAGE_RIGHT_LOOKUP,
ACL_STORAGE_RIGHT_READ,
ACL_STORAGE_RIGHT_FAKE_EMPTY,
ACL_STORAGE_RIGHT_WRITE,
ACL_STORAGE_RIGHT_WRITE_SEEN,
ACL_STORAGE_RIGHT_WRITE_DELETED,
Expand Down