diff options
Diffstat (limited to 'source4')
| -rw-r--r-- | source4/dsdb/common/util.c | 82 | 
1 files changed, 82 insertions, 0 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 5dcbbd8d03..0aad315801 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -3237,3 +3237,85 @@ int samdb_ldb_val_case_cmp(const char *s, struct ldb_val *v)  	}  	return 0;  } + + +/* +  load the UDV for a partition in v2 format + */ +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; +	const struct ldb_val *ouv_value; +	enum ndr_err_code ndr_err; +	struct replUpToDateVectorBlob ouv; +	int ret; + +	ret = ldb_search(samdb, mem_ctx, &r, dn, LDB_SCOPE_BASE, attrs, NULL); +	if (ret != LDB_SUCCESS) { +		return ret; +	} + +	ouv_value = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector"); +	if (!ouv_value) { +		talloc_free(r); +		*count = 0; +		*cursors = NULL; +		return LDB_SUCCESS; +	} + +	ndr_err = ndr_pull_struct_blob(ouv_value, r, +				       lp_iconv_convenience(ldb_get_opaque(samdb, "loadparm")), &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); +	talloc_free(r); + +	return LDB_SUCCESS; +} + +/* +  load the UDV for a partition in version 1 format + */ +int dsdb_load_udv_v1(struct ldb_context *samdb, struct ldb_dn *dn, TALLOC_CTX *mem_ctx, +		     struct drsuapi_DsReplicaCursor **cursors, uint32_t *count) +{ +	struct drsuapi_DsReplicaCursor2 *v2; +	int ret, i; + +	ret = dsdb_load_udv_v2(samdb, dn, mem_ctx, &v2, count); +	if (ret != LDB_SUCCESS) { +		return ret; +	} + +	if (*count == 0) { +		talloc_free(v2); +		*cursors = NULL; +		return LDB_SUCCESS; +	} + +	*cursors = talloc_array(mem_ctx, struct drsuapi_DsReplicaCursor, *count); +	if (*cursors == NULL) { +		talloc_free(v2); +		return LDB_ERR_OPERATIONS_ERROR; +	} + +	for (i=0; i<*count; i++) { +		(*cursors)[i].source_dsa_invocation_id = v2[i].source_dsa_invocation_id; +		(*cursors)[i].highest_usn = v2[i].highest_usn; +	} +	talloc_free(v2); +	return LDB_SUCCESS; +}  | 
