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 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 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; }
int acl_mailbox_update_acl(struct mailbox_transaction_context *t, const struct acl_rights_update *update) { struct acl_object *aclobj; const char *key; time_t ts = update->last_change != 0 ? update->last_change : ioloop_time; key = t_strdup_printf(MAILBOX_ATTRIBUTE_PREFIX_ACL"%s", acl_rights_get_id(&update->rights)); aclobj = acl_mailbox_get_aclobj(t->box); if (acl_object_update(aclobj, update) < 0) { mail_storage_set_critical(t->box->storage, "Failed to set ACL"); return -1; } /* FIXME: figure out some value lengths, so maybe some day quota could apply to ACLs as well. */ if (acl_mailbox_update_removed_id(aclobj, update)) mail_index_attribute_unset(t->itrans, FALSE, key, ts); else mail_index_attribute_set(t->itrans, FALSE, key, ts, 0); return 0; }