static int ldb_kv_msg_delete_attribute(struct ldb_module *module,
				       struct ldb_kv_private *ldb_kv,
				       struct ldb_message *msg,
				       const char *name)
{
	unsigned int i;
	int ret;
	struct ldb_message_element *el;
	bool is_special = ldb_dn_is_special(msg->dn);

	if (!is_special && ldb_kv->cache->GUID_index_attribute != NULL &&
	    ldb_attr_cmp(name, ldb_kv->cache->GUID_index_attribute) == 0) {
		struct ldb_context *ldb = ldb_module_get_ctx(module);
		ldb_asprintf_errstring(ldb,
				       "Must not modify GUID "
				       "attribute %s (used as DB index)",
				       ldb_kv->cache->GUID_index_attribute);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	el = ldb_msg_find_element(msg, name);
	if (el == NULL) {
		return LDB_ERR_NO_SUCH_ATTRIBUTE;
	}
	i = el - msg->elements;

	ret = ldb_kv_index_del_element(module, ldb_kv, msg, el);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	talloc_free(el->values);
	if (msg->num_elements > (i+1)) {
		memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1)));
	}
	msg->num_elements--;
	msg->elements = talloc_realloc(msg, msg->elements,
				       struct ldb_message_element,
				       msg->num_elements);
	return LDB_SUCCESS;
}
static int ldb_kv_msg_delete_attribute(struct ldb_module *module,
				       struct ldb_kv_private *ldb_kv,
				       struct ldb_message *msg,
				       const char *name)
{
	unsigned int i;
	int ret;
	struct ldb_message_element *el;
	bool is_special = ldb_dn_is_special(msg->dn);

	if (!is_special && ldb_kv->cache->GUID_index_attribute != NULL &&
	    ldb_attr_cmp(name, ldb_kv->cache->GUID_index_attribute) == 0) {
		struct ldb_context *ldb = ldb_module_get_ctx(module);
		ldb_asprintf_errstring(ldb,
				       "Must not modify GUID "
				       "attribute %s (used as DB index)",
				       ldb_kv->cache->GUID_index_attribute);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	el = ldb_msg_find_element(msg, name);
	if (el == NULL) {
		return LDB_ERR_NO_SUCH_ATTRIBUTE;
	}
	i = el - msg->elements;

	ret = ldb_kv_index_del_element(module, ldb_kv, msg, el);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	talloc_free(el->values);
	if (msg->num_elements > (i+1)) {
		memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1)));
	}
	msg->num_elements--;
	msg->elements = talloc_realloc(msg, msg->elements,
				       struct ldb_message_element,
				       msg->num_elements);
	return LDB_SUCCESS;
}