+ def replicate_account_to_rodc(self, dn):
+ samdb = self.get_samdb()
+ rodc_samdb = self.get_rodc_samdb()
+
+ repl_val = f'{samdb.get_dsServiceName()}:{dn}:SECRETS_ONLY'
+
+ msg = ldb.Message()
+ msg.dn = ldb.Dn(rodc_samdb, '')
+ msg['replicateSingleObject'] = ldb.MessageElement(
+ repl_val,
+ ldb.FLAG_MOD_REPLACE,
+ 'replicateSingleObject')
+
+ try:
+ # Try replication using the replicateSingleObject rootDSE
+ # operation.
+ rodc_samdb.modify(msg)
+ except ldb.LdbError as err:
+ enum, estr = err.args
+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM)
+ self.assertIn('rootdse_modify: unknown attribute to change!',
+ estr)
+
+ # If that method wasn't supported, we may be in the rodc:local test
+ # environment, where we can try replicating to the local database.
+
+ lp = self.get_lp()
+
+ rodc_creds = Credentials()
+ rodc_creds.guess(lp)
+ rodc_creds.set_machine_account(lp)
+
+ local_samdb = SamDB(url=None, session_info=system_session(),
+ credentials=rodc_creds, lp=lp)
+
+ destination_dsa_guid = misc.GUID(local_samdb.get_ntds_GUID())
+
+ repl = drs_Replicate(f'ncacn_ip_tcp:{self.dc_host}[seal]',
+ lp, rodc_creds,
+ local_samdb, destination_dsa_guid)
+
+ source_dsa_invocation_id = misc.GUID(samdb.invocation_id)
+
+ repl.replicate(dn,
+ source_dsa_invocation_id,
+ destination_dsa_guid,
+ exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET,
+ rodc=True)
+
+ def check_revealed(self, dn, rodc_dn, revealed=True):
+ samdb = self.get_samdb()
+
+ res = samdb.search(base=rodc_dn,
+ scope=ldb.SCOPE_BASE,
+ attrs=['msDS-RevealedUsers'])
+
+ revealed_users = res[0].get('msDS-RevealedUsers')
+ if revealed_users is None:
+ self.assertFalse(revealed)
+ return
+
+ revealed_dns = set(str(dsdb_Dn(samdb, str(user),
+ syntax_oid=DSDB_SYNTAX_BINARY_DN).dn)
+ for user in revealed_users)
+
+ if revealed:
+ self.assertIn(str(dn), revealed_dns)
+ else:
+ self.assertNotIn(str(dn), revealed_dns)
+