+static WERROR getncchanges_update_revealed_list(struct ldb_context *sam_ctx,
+ TALLOC_CTX *mem_ctx,
+ struct GUID *destination_dsa_guid,
+ struct ldb_message **msg,
+ struct ldb_dn *object_dn,
+ const struct dsdb_attribute *sa,
+ struct replPropertyMetaData1 *meta_data,
+ struct ldb_message *revealed_users)
+{
+ enum ndr_err_code ndr_err;
+ int ldb_err;
+ unsigned i;
+ char *attr_str = NULL;
+ char *attr_hex = NULL;
+ DATA_BLOB attr_blob;
+ struct ldb_message_element *existing = NULL, *el_add = NULL, *el_del = NULL;
+ const char * const * secret_attributes = ldb_get_opaque(sam_ctx, "LDB_SECRET_ATTRIBUTE_LIST");
+
+ if (!ldb_attr_in_list(secret_attributes,
+ sa->lDAPDisplayName)) {
+ return WERR_OK;
+ }
+
+
+ ndr_err = ndr_push_struct_blob(&attr_blob, mem_ctx, meta_data, (ndr_push_flags_fn_t)ndr_push_replPropertyMetaData1);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ attr_hex = hex_encode_talloc(mem_ctx, attr_blob.data, attr_blob.length);
+ if (attr_hex == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ attr_str = talloc_asprintf(mem_ctx, "B:%zd:%s:%s", attr_blob.length*2, attr_hex, ldb_dn_get_linearized(object_dn));
+ if (attr_str == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ existing = ldb_msg_find_element(revealed_users, "msDS-RevealedUsers");
+ if (existing != NULL) {
+ /* Replace the old value (if one exists) with the current one */
+ for (i = 0; i < existing->num_values; i++) {
+ struct dsdb_dn *existing_dn = dsdb_dn_parse_trusted(mem_ctx, sam_ctx, &existing->values[i], DSDB_SYNTAX_BINARY_DN);
+ if (ldb_dn_compare(object_dn, existing_dn->dn) == 0) {
+ struct replPropertyMetaData1 existing_meta_data;
+ ndr_err = ndr_pull_struct_blob_all_noalloc(&existing_dn->extra_part,
+ &existing_meta_data,
+ (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaData1);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ if (existing_meta_data.attid == sa->attributeID_id) {
+ ldb_err = ldb_msg_add_empty(*msg, "msDS-RevealedUsers", LDB_FLAG_MOD_DELETE, &el_del);
+ if (ldb_err != LDB_SUCCESS) {
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ el_del->values = talloc_array((*msg)->elements, struct ldb_val, 1);
+ if (el_del->values == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ el_del->values[0] = existing->values[i];
+ el_del->num_values = 1;
+ }
+ }
+ }
+ }
+
+ ldb_err = ldb_msg_add_empty(*msg, "msDS-RevealedUsers", LDB_FLAG_MOD_ADD, &el_add);
+ if (ldb_err != LDB_SUCCESS) {
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ el_add->values = talloc_array((*msg)->elements, struct ldb_val, 1);
+ if (el_add->values == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+
+ }
+
+ el_add->values[0] = data_blob_string_const(attr_str);
+ el_add->num_values = 1;
+
+ return WERR_OK;
+}
+