1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

selftest: Make sure single-link conflict retains the deleted link

There should only ever be one active value for a single-valued link
attribute. When a conflict occurs the 'losing' value should still be
present, but should be marked as deleted.

This change is just making the test criteria stricter to make sure that
we fix the bug correctly.

Note that the only way to query the deleted link attributes present
is to send a DRS request.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Tim Beale 2017-09-19 13:41:02 +12:00 committed by Andrew Bartlett
parent c9ea47ec6b
commit 9c54e7484f

View File

@ -35,7 +35,8 @@ from ldb import SCOPE_BASE
import random
import time
from samba.dcerpc import drsuapi
from drs_base import AbstractLink
from samba.dcerpc import drsuapi, misc
# specifies the order to sync DCs in
DC1_TO_DC2 = 1
@ -55,6 +56,9 @@ class DrsReplicaLinkConflictTestCase(drs_base.DrsBaseTestCase):
"dn": self.ou,
"objectclass": "organizationalUnit"})
(self.drs, self.drs_handle) = self._ds_bind(self.dnsname_dc1)
(self.drs2, self.drs2_handle) = self._ds_bind(self.dnsname_dc2)
# disable replication for the tests so we can control at what point
# the DCs try to replicate
self._disable_inbound_repl(self.dnsname_dc1)
@ -68,7 +72,7 @@ class DrsReplicaLinkConflictTestCase(drs_base.DrsBaseTestCase):
super(DrsReplicaLinkConflictTestCase, self).tearDown()
def get_guid(self, samdb, dn):
"""Returns an object's GUID"""
"""Returns an object's GUID (in string format)"""
res = samdb.search(base=dn, attrs=["objectGUID"], scope=ldb.SCOPE_BASE)
return self._GUID_string(res[0]['objectGUID'][0])
@ -137,6 +141,37 @@ class DrsReplicaLinkConflictTestCase(drs_base.DrsBaseTestCase):
self.assertTrue(val in res2[0][attr],
"%s '%s' not found on DC2" %(attr, val))
def _check_replicated_links(self, src_obj_dn, expected_links):
"""Checks that replication sends back the expected linked attributes"""
hwm = drsuapi.DsReplicaHighWaterMark()
hwm.tmp_highest_usn = 0
hwm.reserved_usn = 0
hwm.highest_usn = 0
self._check_replication([src_obj_dn],
drsuapi.DRSUAPI_DRS_WRIT_REP,
dest_dsa=None,
drs_error=drsuapi.DRSUAPI_EXOP_ERR_SUCCESS,
nc_dn_str=src_obj_dn,
exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ,
expected_links=expected_links,
highwatermark=hwm)
# Check DC2 as well
self.set_test_ldb_dc(self.ldb_dc2)
self._check_replication([src_obj_dn],
drsuapi.DRSUAPI_DRS_WRIT_REP,
dest_dsa=None,
drs_error=drsuapi.DRSUAPI_EXOP_ERR_SUCCESS,
nc_dn_str=src_obj_dn,
exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ,
expected_links=expected_links,
highwatermark=hwm,
drs=self.drs2, drs_handle=self.drs2_handle)
self.set_test_ldb_dc(self.ldb_dc1)
def _test_conflict_single_valued_link(self, sync_order):
"""
Tests a simple single-value link conflict, i.e. each DC adds a link to
@ -176,6 +211,16 @@ class DrsReplicaLinkConflictTestCase(drs_base.DrsBaseTestCase):
self.assertTrue(res1[0]["managedBy"][0] == target2_ou,
"Expected most recent update to win conflict")
# we can't query the deleted links over LDAP, but we can check DRS
# to make sure the DC kept a copy of the conflicting link
link1 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, 0,
misc.GUID(src_guid), misc.GUID(target1_guid))
link2 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy,
drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
misc.GUID(src_guid), misc.GUID(target2_guid))
self._check_replicated_links(src_ou, [link1, link2])
def test_conflict_single_valued_link(self):
# repeat the test twice, to give each DC a chance to resolve the conflict
self._test_conflict_single_valued_link(sync_order=DC1_TO_DC2)