int acl_object_have_right(struct acl_object *aclobj, unsigned int right_idx) { struct acl_backend *backend = aclobj->backend; const struct acl_mask *have_mask; unsigned int read_idx; if (backend->v.object_refresh_cache(aclobj) < 0) return -1; have_mask = acl_cache_get_my_rights(backend->cache, aclobj->name); if (have_mask == NULL) { if (acl_backend_get_default_rights(backend, &have_mask) < 0) return -1; } if (acl_cache_mask_isset(have_mask, right_idx)) return 1; if (mailbox_list_get_user(aclobj->backend->list)->dsyncing) { /* 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. */ read_idx = acl_backend_lookup_right(aclobj->backend, MAIL_ACL_READ); if (acl_cache_mask_isset(have_mask, read_idx)) return 1; } return 0; }
struct acl_backend * acl_backend_init(const char *data, struct mailbox_list *list, const char *acl_username, const char *const *groups, bool owner) { struct mail_user *user = mailbox_list_get_user(list); struct acl_backend *backend; unsigned int i, group_count; if (user->mail_debug) { i_debug("acl: initializing backend with data: %s", data); i_debug("acl: acl username = %s", acl_username); i_debug("acl: owner = %d", owner ? 1 : 0); } group_count = str_array_length(groups); if (strncmp(data, "vfile:", 6) == 0) data += 6; else if (strcmp(data, "vfile") == 0) data = ""; else i_fatal("Unknown ACL backend: %s", t_strcut(data, ':')); backend = acl_backend_vfile.alloc(); backend->debug = user->mail_debug; backend->v = acl_backend_vfile; backend->list = list; backend->username = p_strdup(backend->pool, acl_username); backend->owner = owner; backend->globals_only = mail_user_plugin_getenv_bool(user, "acl_globals_only"); if (group_count > 0) { backend->group_count = group_count; backend->groups = p_new(backend->pool, const char *, group_count); for (i = 0; i < group_count; i++) { backend->groups[i] = p_strdup(backend->pool, groups[i]); if (user->mail_debug) i_debug("acl: group added: %s", groups[i]); } i_qsort(backend->groups, group_count, sizeof(const char *), i_strcmp_p); }
int acl_object_have_right(struct acl_object *aclobj, unsigned int right_idx) { struct acl_backend *backend = aclobj->backend; const struct acl_mask *have_mask; if (mailbox_list_get_user(aclobj->backend->list)->admin) { /* admin user (especially dsync) can do anything regardless of ACLs */ return 1; } if (backend->v.object_refresh_cache(aclobj) < 0) return -1; have_mask = acl_cache_get_my_rights(backend->cache, aclobj->name); if (have_mask == NULL) { if (acl_backend_get_default_rights(backend, &have_mask) < 0) return -1; } return acl_cache_mask_isset(have_mask, right_idx); }