static int traverse_range_index(_UNUSED_ struct ldb_kv_private *ldb_kv,
				_UNUSED_ struct ldb_val key,
				struct ldb_val data,
				void *state)
{

	struct ldb_context *ldb;
	struct ldb_kv_ordered_index_context *ctx =
	    (struct ldb_kv_ordered_index_context *)state;
	struct ldb_module *module = ctx->module;
	struct ldb_message_element *el = NULL;
	struct ldb_message *msg = NULL;
	int version;
	size_t dn_array_size, additional_length;
	unsigned int i;

	ldb = ldb_module_get_ctx(module);

	msg = ldb_msg_new(module);

	ctx->error = ldb_unpack_data_flags(ldb, &data, msg,
					   LDB_UNPACK_DATA_FLAG_NO_DN);

	if (ctx->error != LDB_SUCCESS) {
		talloc_free(msg);
		return ctx->error;
	}

	el = ldb_msg_find_element(msg, LDB_KV_IDX);
	if (!el) {
		talloc_free(msg);
		return LDB_SUCCESS;
	}

	version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0);

	/*
	 * we avoid copying the strings by stealing the list.  We have
	 * to steal msg onto el->values (which looks odd) because
	 * the memory is allocated on msg, not on each value.
	 */
	if (version != LDB_KV_GUID_INDEXING_VERSION) {
		/* This is quite likely during the DB startup
		   on first upgrade to using a GUID index */
		ldb_debug_set(ldb_module_get_ctx(module),
			      LDB_DEBUG_ERROR, __location__
			      ": Wrong GUID index version %d expected %d",
			      version, LDB_KV_GUID_INDEXING_VERSION);
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if (el->num_values == 0) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0
	    || el->values[0].length == 0) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	dn_array_size = talloc_array_length(ctx->dn_list->dn);

	additional_length = el->values[0].length / LDB_KV_GUID_SIZE;

	if (ctx->dn_list->count + additional_length < ctx->dn_list->count) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if ((ctx->dn_list->count + additional_length) >= dn_array_size) {
		size_t new_array_length;

		if (dn_array_size * 2 < dn_array_size) {
			talloc_free(msg);
			ctx->error = LDB_ERR_OPERATIONS_ERROR;
			return ctx->error;
		}

		new_array_length = MAX(ctx->dn_list->count + additional_length,
				       dn_array_size * 2);

		ctx->dn_list->dn = talloc_realloc(ctx->dn_list,
						  ctx->dn_list->dn,
						  struct ldb_val,
						  new_array_length);
	}

	if (ctx->dn_list->dn == NULL) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	/*
	 * The actual data is on msg.
	 */
	talloc_steal(ctx->dn_list->dn, msg);
	for (i = 0; i < additional_length; i++) {
		ctx->dn_list->dn[i + ctx->dn_list->count].data
			= &el->values[0].data[i * LDB_KV_GUID_SIZE];
		ctx->dn_list->dn[i + ctx->dn_list->count].length = LDB_KV_GUID_SIZE;

	}

	ctx->dn_list->count += additional_length;

	talloc_free(msg->elements);

	return LDB_SUCCESS;
}
static int traverse_range_index(_UNUSED_ struct ldb_kv_private *ldb_kv,
				_UNUSED_ struct ldb_val key,
				struct ldb_val data,
				void *state)
{

	struct ldb_context *ldb;
	struct ldb_kv_ordered_index_context *ctx =
	    (struct ldb_kv_ordered_index_context *)state;
	struct ldb_module *module = ctx->module;
	struct ldb_message_element *el = NULL;
	struct ldb_message *msg = NULL;
	int version;
	size_t dn_array_size, additional_length;
	unsigned int i;

	ldb = ldb_module_get_ctx(module);

	msg = ldb_msg_new(module);

	ctx->error = ldb_unpack_data_flags(ldb, &data, msg,
					   LDB_UNPACK_DATA_FLAG_NO_DN);

	if (ctx->error != LDB_SUCCESS) {
		talloc_free(msg);
		return ctx->error;
	}

	el = ldb_msg_find_element(msg, LDB_KV_IDX);
	if (!el) {
		talloc_free(msg);
		return LDB_SUCCESS;
	}

	version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0);

	 
	if (version != LDB_KV_GUID_INDEXING_VERSION) {
		 
		ldb_debug_set(ldb_module_get_ctx(module),
			      LDB_DEBUG_ERROR, __location__
			      ": Wrong GUID index version %d expected %d",
			      version, LDB_KV_GUID_INDEXING_VERSION);
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if (el->num_values == 0) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0
	    || el->values[0].length == 0) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	dn_array_size = talloc_array_length(ctx->dn_list->dn);

	additional_length = el->values[0].length / LDB_KV_GUID_SIZE;

	if (ctx->dn_list->count + additional_length < ctx->dn_list->count) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	if ((ctx->dn_list->count + additional_length) >= dn_array_size) {
		size_t new_array_length;

		if (dn_array_size * 2 < dn_array_size) {
			talloc_free(msg);
			ctx->error = LDB_ERR_OPERATIONS_ERROR;
			return ctx->error;
		}

		new_array_length = MAX(ctx->dn_list->count + additional_length,
				       dn_array_size * 2);

		ctx->dn_list->dn = talloc_realloc(ctx->dn_list,
						  ctx->dn_list->dn,
						  struct ldb_val,
						  new_array_length);
	}

	if (ctx->dn_list->dn == NULL) {
		talloc_free(msg);
		ctx->error = LDB_ERR_OPERATIONS_ERROR;
		return ctx->error;
	}

	 
	talloc_steal(ctx->dn_list->dn, msg);
	for (i = 0; i < additional_length; i++) {
		ctx->dn_list->dn[i + ctx->dn_list->count].data
			= &el->values[0].data[i * LDB_KV_GUID_SIZE];
		ctx->dn_list->dn[i + ctx->dn_list->count].length = LDB_KV_GUID_SIZE;

	}

	ctx->dn_list->count += additional_length;

	talloc_free(msg->elements);

	return LDB_SUCCESS;
}