+/*
+ get metadata for specified object
+*/
+static WERROR kccdrs_replica_get_info_obj_metadata(TALLOC_CTX *mem_ctx,
+ struct ldb_context *samdb,
+ struct drsuapi_DsReplicaGetInfo *r,
+ union drsuapi_DsReplicaInfo *reply,
+ struct ldb_dn *dn)
+{
+ int ret, i;
+ const struct ldb_val *md_value;
+ struct ldb_result *result;
+ enum ndr_err_code ndr_err;
+ struct replPropertyMetaDataBlob md;
+ const struct dsdb_schema *schema;
+ const char *attrs[] = { "replPropertyMetaData", NULL };
+
+ ret = dsdb_search_dn(samdb, mem_ctx, &result, dn, attrs, DSDB_SEARCH_SHOW_DELETED);
+ if (ret != LDB_SUCCESS) {
+ return WERR_INTERNAL_ERROR;
+ } else if (result->count < 1) {
+ DEBUG(1, (__location__": Failed to find replPropertyMetaData for: %s\n", r->in.req->req1.object_dn));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ md_value = ldb_msg_find_ldb_val(result->msgs[0], "replPropertyMetaData");
+ if (!md_value) {
+ return WERR_INTERNAL_ERROR;
+ }
+
+ ndr_err = ndr_pull_struct_blob(md_value, mem_ctx,
+ lp_iconv_convenience(ldb_get_opaque(samdb, "loadparm")),
+ &md,
+ (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_INTERNAL_ERROR;
+ }
+
+ if (md.version != 1) {
+ return WERR_INTERNAL_ERROR;
+ }
+
+ schema = dsdb_get_schema(samdb);
+ if (!schema) {
+ DEBUG(0,(__location__": Failed to get the schema\n"));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ reply->objmetadata = talloc(mem_ctx, struct drsuapi_DsReplicaObjMetaDataCtr);
+ W_ERROR_HAVE_NO_MEMORY(reply->objmetadata);
+
+ reply->objmetadata->reserved = 0;
+ reply->objmetadata->count = md.ctr.ctr1.count;
+ reply->objmetadata->array = talloc_array(mem_ctx, struct drsuapi_DsReplicaObjMetaData, reply->objmetadata->count);
+ for (i=0; i<md.ctr.ctr1.count; i++) {
+ const struct dsdb_attribute *attr = dsdb_attribute_by_attributeID_id(schema, md.ctr.ctr1.array[i].attid);
+ char const* attribute_name = NULL;
+ if (!attr) {
+ DEBUG(0, (__location__": Failed to find attribute with id: %d", md.ctr.ctr1.array[i].attid));
+ } else {
+ attribute_name = attr->lDAPDisplayName;
+ }
+ reply->objmetadata->array[i].originating_change_time = md.ctr.ctr1.array[i].originating_change_time;
+ reply->objmetadata->array[i].version = md.ctr.ctr1.array[i].version;
+ reply->objmetadata->array[i].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id;
+ reply->objmetadata->array[i].originating_usn = md.ctr.ctr1.array[i].originating_usn;
+ reply->objmetadata->array[i].local_usn = md.ctr.ctr1.array[i].local_usn;
+ reply->objmetadata->array[i].attribute_name = attribute_name;
+ }
+
+ return WERR_OK;
+}