parent, false);
}
+static int construct_msDS_ReplValueMetaData(struct ldb_module *module,
+ struct ldb_message *msg,
+ enum ldb_scope scope,
+ struct ldb_request *parent,
+ bool xml)
+{
+ struct operational_context *ac =
+ talloc_get_type_abort(parent->context,
+ struct operational_context);
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ unsigned ei;
+ enum ndr_err_code ndr_err;
+ int ret;
+
+ if (ac->schema == NULL) {
+ ac->schema = dsdb_get_schema(ldb, ac);
+ if (ac->schema == NULL) {
+ /* We can't make up anything without a schema */
+ return LDB_SUCCESS;
+ }
+ }
+
+ for (ei=0; ei < msg->num_elements; ei++) {
+ struct ldb_message_element *el = &msg->elements[ei];
+ struct msDS_ReplValueMetaDataBlob _r;
+ struct msDS_ReplValueMetaData *r = &_r.stamp;
+ const struct dsdb_attribute *a = NULL;
+ const char *dsa_dn = NULL;
+ const char *attr_name = NULL;
+ struct ldb_val val = data_blob_null;
+
+ a = dsdb_attribute_by_lDAPDisplayName(ac->schema, el->name);
+ if (a == NULL) {
+ continue;
+ }
+
+ if (a->linkID == 0) {
+ continue;
+ }
+
+ if (a->linkID % 2) {
+ continue;
+ }
+
+ dsa_dn = operational_dsa_by_invocation_id(ac,
+ &m->originating_invocation_id);
+ if (dsa_dn == NULL) {
+ return ldb_module_operr(module);
+ }
+
+ r->attribute_name = a->lDAPDisplayName;
+ r->version = m->version;
+ r->originating_change_time = m->originating_change_time;
+ r->originating_invocation_id = m->originating_invocation_id;
+ r->originating_usn = m->originating_usn;
+ r->local_usn = m->local_usn;
+ r->originating_dsa_dn = dsa_dn;
+
+ if (xml) {
+ struct timeval_buf tv_buf;
+ struct timeval change_tv;
+ struct GUID_txt_buf iv_buf;
+ char *str = NULL;
+
+ nttime_to_timeval(&change_tv,
+ r->originating_change_time);
+
+ str = talloc_asprintf(msg,
+ "<DS_REPL_ATTR_META_DATA>\n"
+ "\t<pszAttributeName>%s"
+ "</pszAttributeName>\n"
+ "\t<dwVersion>%u</dwVersion>\n"
+ "\t<ftimeLastOriginatingChange>%s"
+ "</ftimeLastOriginatingChange>\n"
+ "\t<uuidLastOriginatingDsaInvocationID>%s"
+ "</uuidLastOriginatingDsaInvocationID>\n"
+ "\t<usnOriginatingChange>%llu"
+ "</usnOriginatingChange>\n"
+ "\t<usnLocalChange>%llu</usnLocalChange>\n"
+ "\t<pszLastOriginatingDsaDN>%s"
+ "</pszLastOriginatingDsaDN>\n"
+ "</DS_REPL_ATTR_META_DATA>\n",
+ r->attribute_name,
+ (unsigned)r->version,
+ timeval_str_utc_buf(&change_tv, false, &tv_buf),
+ GUID_buf_string(&r->originating_invocation_id,
+ &iv_buf),
+ (unsigned long long)r->originating_usn,
+ (unsigned long long)r->local_usn,
+ dsa_dn);
+ if (str == NULL) {
+ return ldb_module_oom(module);
+ }
+
+ attr_name = "msDS-ReplValueMetaData";
+ val.data = (uint8_t *)str;
+ val.length = strlen(str) + 1;
+ } else {
+
+ attr_name = "msDS-ReplValueMetaData;binary";
+ ndr_err = ndr_push_struct_blob(&val, msg, &_r,
+ (ndr_push_flags_fn_t)ndr_push_msDS_ReplValueMetaDataBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0,(__location__ ": Failed to marshall msDS_ReplValueMetaDataBlob for %s\n",
+ ldb_dn_get_linearized(msg->dn)));
+ return ldb_module_operr(module);
+ }
+ }
+
+ ret = ldb_msg_add_steal_value(msg, attr_name, &val);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ talloc_free(omd);
+ return LDB_SUCCESS;
+}
+
+static int construct_msDS_ReplValueMetaData_xml(struct ldb_module *module,
+ struct ldb_message *msg,
+ enum ldb_scope scope,
+ struct ldb_request *parent)
+{
+ return construct_msDS_ReplValueMetaData(module, msg, scope,
+ parent, true);
+}
+
+static int construct_msDS_ReplValueMetaData_blob(struct ldb_module *module,
+ struct ldb_message *msg,
+ enum ldb_scope scope,
+ struct ldb_request *parent)
+{
+ return construct_msDS_ReplValueMetaData(module, msg, scope,
+ parent, false);
+}
+
struct op_controls_flags {
bool sd;
bool bypassoperational;
construct_msDS_ReplAttributeMetaData_xml },
{ "msDS-ReplAttributeMetaData;binary", "replPropertyMetaData", NULL,
construct_msDS_ReplAttributeMetaData_blob },
+ { "msDS-ReplValueMetaData", "*", NULL,
+ construct_msDS_ReplValueMetaData_xml },
+ { "msDS-ReplValueMetaData;binary", "*", NULL,
+ construct_msDS_ReplValueMetaData_blob },
};