int acl_mailbox_list_have_right(struct mailbox_list *list, const char *name, bool parent, unsigned int acl_storage_right_idx, bool *can_see_r) { struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list); struct acl_backend *backend = alist->rights.backend; const unsigned int *idx_arr = alist->rights.acl_storage_right_idx; struct acl_object *aclobj; int ret, ret2; aclobj = !parent ? acl_object_init_from_name(backend, name) : acl_object_init_from_parent(backend, name); ret = acl_object_have_right(aclobj, idx_arr[acl_storage_right_idx]); if (can_see_r != NULL) { ret2 = acl_object_have_right(aclobj, idx_arr[ACL_STORAGE_RIGHT_LOOKUP]); if (ret2 < 0) ret = -1; *can_see_r = ret2 > 0; } acl_object_deinit(&aclobj); if (ret < 0) mailbox_list_set_internal_error(list); return ret; }
void acl_mailbox_allocated(struct mailbox *box) { struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list); struct mailbox_vfuncs *v = box->vlast; struct acl_mailbox *abox; if (alist == NULL) { /* ACLs disabled */ return; } if (box->list->ns->type == MAIL_NAMESPACE_TYPE_SHARED && (box->list->ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) { /* this is the root shared namespace, which itself doesn't have any existing mailboxes. */ return; } abox = p_new(box->pool, struct acl_mailbox, 1); abox->module_ctx.super = *v; box->vlast = &abox->module_ctx.super; /* aclobj can be used for setting ACLs, even when mailbox is opened with IGNORE_ACLS flag */ abox->aclobj = acl_object_init_from_name(alist->rights.backend, mailbox_get_name(box)); v->free = acl_mailbox_free; if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) == 0) { abox->acl_enabled = TRUE; v->is_readonly = acl_is_readonly; v->exists = acl_mailbox_exists; v->open = acl_mailbox_open; v->get_status = acl_mailbox_get_status; v->create_box = acl_mailbox_create; v->update_box = acl_mailbox_update; v->delete_box = acl_mailbox_delete; v->rename_box = acl_mailbox_rename; v->save_begin = acl_save_begin; v->copy = acl_copy; v->transaction_commit = acl_transaction_commit; v->attribute_set = acl_attribute_set; v->attribute_get = acl_attribute_get; v->attribute_iter_init = acl_attribute_iter_init; v->attribute_iter_next = acl_attribute_iter_next; v->attribute_iter_deinit = acl_attribute_iter_deinit; } MODULE_CONTEXT_SET(box, acl_storage_module, abox); }
static int acllist_append(struct acl_backend_vfile *backend, struct ostream *output, const char *vname) { struct acl_object *aclobj; struct acl_object_list_iter *iter; struct acl_rights rights; struct acl_backend_vfile_acllist acllist; const char *name; int ret; name = mail_namespace_get_storage_name(backend->backend.list->ns, vname); acl_cache_flush(backend->backend.cache, name); aclobj = acl_object_init_from_name(&backend->backend, name); iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (acl_rights_has_nonowner_lookup_changes(&rights)) break; } acl_object_list_deinit(&iter); if (acl_backend_vfile_object_get_mtime(aclobj, &acllist.mtime) < 0) ret = -1; if (ret > 0) { acllist.name = p_strdup(backend->acllist_pool, name); array_append(&backend->acllist, &acllist, 1); T_BEGIN { const char *line; line = t_strdup_printf("%s %s\n", dec2str(acllist.mtime), name); o_stream_send_str(output, line); } T_END; }