int dsdb_load_udv_v2(struct ldb_context *samdb, struct ldb_dn *dn, TALLOC_CTX *mem_ctx,
		     struct drsuapi_DsReplicaCursor2 **cursors, uint32_t *count)
{
	static const char *attrs[] = { "replUpToDateVector", NULL };
	struct ldb_result *r = NULL;
	const struct ldb_val *ouv_value;
	unsigned int i;
	int ret;
	uint64_t highest_usn = 0;
	const struct GUID *our_invocation_id;
	static const struct timeval tv1970;
	NTTIME nt1970 = timeval_to_nttime(&tv1970);

	ret = dsdb_search_dn(samdb, mem_ctx, &r, dn, attrs, DSDB_SEARCH_SHOW_RECYCLED|DSDB_SEARCH_SHOW_DELETED);
	if (ret != LDB_SUCCESS) {
		return ret;
	}
	/* fix clang warning */
	if (r == NULL) {
		return LDB_ERR_OTHER;
	}
	ouv_value = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector");
	if (ouv_value) {
		enum ndr_err_code ndr_err;
		struct replUpToDateVectorBlob ouv;

		ndr_err = ndr_pull_struct_blob(ouv_value, r, &ouv,
					       (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			talloc_free(r);
			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
		}
		if (ouv.version != 2) {
			/* we always store as version 2, and
			 * replUpToDateVector is not replicated
			 */
			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
		}

		*count = ouv.ctr.ctr2.count;
		*cursors = talloc_steal(mem_ctx, ouv.ctr.ctr2.cursors);
	} else {
		*count = 0;
		*cursors = NULL;
	}

	talloc_free(r);

	our_invocation_id = samdb_ntds_invocation_id(samdb);
	if (!our_invocation_id) {
		DEBUG(0,(__location__ ": No invocationID on samdb - %s\n", ldb_errstring(samdb)));
		talloc_free(*cursors);
		return ldb_operr(samdb);
	}

	ret = ldb_sequence_number(samdb, LDB_SEQ_HIGHEST_SEQ, &highest_usn);
	if (ret != LDB_SUCCESS) {
		/* nothing to add - this can happen after a vampire */
		TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
		return LDB_SUCCESS;
	}

	for (i=0; i<*count; i++) {
		if (GUID_equal(our_invocation_id, &(*cursors)[i].source_dsa_invocation_id)) {
			(*cursors)[i].highest_usn = highest_usn;
			(*cursors)[i].last_sync_success = nt1970;
			TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
			return LDB_SUCCESS;
		}
	}

	(*cursors) = talloc_realloc(mem_ctx, *cursors, struct drsuapi_DsReplicaCursor2, (*count)+1);
	if (! *cursors) {
		return ldb_oom(samdb);
	}

	(*cursors)[*count].source_dsa_invocation_id = *our_invocation_id;
	(*cursors)[*count].highest_usn = highest_usn;
	(*cursors)[*count].last_sync_success = nt1970;
	(*count)++;

	TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);

	return LDB_SUCCESS;
}
int dsdb_load_udv_v2(struct ldb_context *samdb, struct ldb_dn *dn, TALLOC_CTX *mem_ctx,
		     struct drsuapi_DsReplicaCursor2 **cursors, uint32_t *count)
{
	static const char *attrs[] = { "replUpToDateVector", NULL };
	struct ldb_result *r = NULL;
	const struct ldb_val *ouv_value;
	unsigned int i;
	int ret;
	uint64_t highest_usn = 0;
	const struct GUID *our_invocation_id;
	static const struct timeval tv1970;
	NTTIME nt1970 = timeval_to_nttime(&tv1970);

	ret = dsdb_search_dn(samdb, mem_ctx, &r, dn, attrs, DSDB_SEARCH_SHOW_RECYCLED|DSDB_SEARCH_SHOW_DELETED);
	if (ret != LDB_SUCCESS) {
		return ret;
	}
	 
	if (r == NULL) {
		return LDB_ERR_OTHER;
	}
	ouv_value = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector");
	if (ouv_value) {
		enum ndr_err_code ndr_err;
		struct replUpToDateVectorBlob ouv;

		ndr_err = ndr_pull_struct_blob(ouv_value, r, &ouv,
					       (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			talloc_free(r);
			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
		}
		if (ouv.version != 2) {
			 
			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
		}

		*count = ouv.ctr.ctr2.count;
		*cursors = talloc_steal(mem_ctx, ouv.ctr.ctr2.cursors);
	} else {
		*count = 0;
		*cursors = NULL;
	}

	talloc_free(r);

	our_invocation_id = samdb_ntds_invocation_id(samdb);
	if (!our_invocation_id) {
		DEBUG(0,(__location__ ": No invocationID on samdb - %s\n", ldb_errstring(samdb)));
		talloc_free(*cursors);
		return ldb_operr(samdb);
	}

	ret = ldb_sequence_number(samdb, LDB_SEQ_HIGHEST_SEQ, &highest_usn);
	if (ret != LDB_SUCCESS) {
		 
		TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
		return LDB_SUCCESS;
	}

	for (i=0; i<*count; i++) {
		if (GUID_equal(our_invocation_id, &(*cursors)[i].source_dsa_invocation_id)) {
			(*cursors)[i].highest_usn = highest_usn;
			(*cursors)[i].last_sync_success = nt1970;
			TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
			return LDB_SUCCESS;
		}
	}

	(*cursors) = talloc_realloc(mem_ctx, *cursors, struct drsuapi_DsReplicaCursor2, (*count)+1);
	if (! *cursors) {
		return ldb_oom(samdb);
	}

	(*cursors)[*count].source_dsa_invocation_id = *our_invocation_id;
	(*cursors)[*count].highest_usn = highest_usn;
	(*cursors)[*count].last_sync_success = nt1970;
	(*count)++;

	TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);

	return LDB_SUCCESS;
}