static bool acl_mailbox_update_removed_id(struct acl_object *aclobj, const struct acl_rights_update *update) { struct acl_object_list_iter *iter; struct acl_rights rights; int ret; if (update->modify_mode != ACL_MODIFY_MODE_CLEAR && update->neg_modify_mode != ACL_MODIFY_MODE_CLEAR) return FALSE; if (update->modify_mode == ACL_MODIFY_MODE_CLEAR && update->neg_modify_mode == ACL_MODIFY_MODE_CLEAR) return TRUE; /* mixed clear/non-clear. see if the identifier exists anymore */ iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (rights.id_type == update->rights.id_type && null_strcmp(rights.identifier, update->rights.identifier) == 0) break; } acl_object_list_deinit(&iter); return ret == 0; }
int acl_attribute_iter_deinit(struct mailbox_attribute_iter *iter) { struct acl_mailbox_attribute_iter *aiter = (struct acl_mailbox_attribute_iter *)iter; struct acl_mailbox *abox = ACL_CONTEXT(iter->box); int ret = aiter->failed ? -1 : 0; if (aiter->super != NULL) { if (abox->module_ctx.super.attribute_iter_deinit(aiter->super) < 0) ret = -1; } if (aiter->acl_iter != NULL) acl_object_list_deinit(&aiter->acl_iter); if (aiter->acl_name != NULL) str_free(&aiter->acl_name); i_free(aiter); return ret; }
static int acl_attribute_get_acl(struct mailbox *box, const char *key, struct mail_attribute_value *value_r) { struct acl_object *aclobj = acl_mailbox_get_aclobj(box); struct acl_object_list_iter *iter; struct acl_rights rights, wanted_rights; const char *id; int ret; memset(value_r, 0, sizeof(*value_r)); if (!box->storage->user->dsyncing) { mail_storage_set_error(box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); return -1; } /* set last_change for all ACL objects, even if they don't exist (because they could have been removed by the last change, and dsync can use this information) */ (void)acl_object_last_changed(aclobj, &value_r->last_change); memset(&wanted_rights, 0, sizeof(wanted_rights)); id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); if (acl_identifier_parse(id, &wanted_rights) < 0) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, t_strdup_printf("Invalid ID: %s", id)); return -1; } iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (!rights.global && rights.id_type == wanted_rights.id_type && null_strcmp(rights.identifier, wanted_rights.identifier) == 0) { value_r->value = acl_rights_export(&rights); break; } } if (ret < 0) mail_storage_set_internal_error(box->storage); acl_object_list_deinit(&iter); return ret; }
static const char * acl_attribute_iter_next_acl(struct acl_mailbox_attribute_iter *aiter) { struct acl_rights rights; int ret; while ((ret = acl_object_list_next(aiter->acl_iter, &rights)) > 0) { if (rights.global) continue; str_truncate(aiter->acl_name, strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL)); acl_rights_write_id(aiter->acl_name, &rights); return str_c(aiter->acl_name); } if (ret < 0) { mail_storage_set_internal_error(aiter->iter.box->storage); aiter->failed = TRUE; return NULL; } acl_object_list_deinit(&aiter->acl_iter); return NULL; }
static void cmd_acl_get_mailbox(struct doveadm_acl_cmd_context *ctx, struct mailbox *box) { struct acl_object *aclobj = acl_mailbox_get_aclobj(box); struct acl_backend *backend; struct acl_object_list_iter *iter; struct acl_rights rights; int ret; backend = acl_mailbox_list_get_backend(box->list); iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) T_BEGIN { if (!ctx->get_match_me || acl_backend_rights_match_me(backend, &rights)) cmd_acl_get_right(&rights); } T_END; acl_object_list_deinit(&iter); if (ret < 0) i_error("ACL iteration failed"); }
static void acl_mailbox_copy_acls_from_parent(struct mailbox *box) { struct acl_mailbox *abox = ACL_CONTEXT(box); struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list); struct acl_object *parent_aclobj; struct acl_object_list_iter *iter; struct acl_rights_update update; memset(&update, 0, sizeof(update)); update.modify_mode = ACL_MODIFY_MODE_REPLACE; update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; parent_aclobj = acl_object_init_from_parent(alist->rights.backend, box->name); iter = acl_object_list_init(parent_aclobj); while (acl_object_list_next(iter, &update.rights) > 0) { /* don't copy global ACL rights. */ if (!update.rights.global) (void)acl_object_update(abox->aclobj, &update); } acl_object_list_deinit(&iter); acl_object_deinit(&parent_aclobj); }
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; }
static int cmd_acl_get_mailbox(struct doveadm_acl_cmd_context *ctx, struct mailbox *box) { struct acl_object *aclobj = acl_mailbox_get_aclobj(box); struct acl_backend *backend; struct acl_object_list_iter *iter; struct acl_rights rights; int ret; backend = acl_mailbox_list_get_backend(box->list); iter = acl_object_list_init(aclobj); while (acl_object_list_next(iter, &rights)) T_BEGIN { if (!ctx->get_match_me || acl_backend_rights_match_me(backend, &rights)) cmd_acl_get_right(&rights); } T_END; if ((ret = acl_object_list_deinit(&iter))<0) { i_error("ACL iteration failed"); doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_TEMP); } return ret; }