TODO msDS-ReplValueMetaData
authorStefan Metzmacher <metze@samba.org>
Tue, 9 Jan 2018 07:55:11 +0000 (08:55 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 29 Oct 2019 13:33:03 +0000 (14:33 +0100)
source4/dsdb/samdb/ldb_modules/operational.c

index 9f2d09cee0f409febee911b5795712c9b1a9daaa..46c9fc0c524137e7f4b664d517e2ae4305de18ca 100644 (file)
@@ -1580,6 +1580,143 @@ static int construct_msDS_ReplAttributeMetaData_blob(struct ldb_module *module,
                                                    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;
@@ -1691,6 +1828,10 @@ static const struct op_attributes_replace search_sub[] = {
          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 },
 };