示例#1
0
    def test_sort_behaviour_ncchanges(self):
        """Testing sorting behaviour on a group of objects."""
        user1_dn = "cn=test_user1,%s" % self.ou
        group_dn = "cn=test_group,%s" % self.ou
        self.ldb_dc1.add({"dn": user1_dn, "objectclass": "user"})
        self.ldb_dc1.add({"dn": group_dn, "objectclass": "group"})

        self.add_linked_attribute(group_dn, user1_dn, attr='member')

        dc_guid_1 = self.ldb_dc1.get_invocation_id()

        drs, drs_handle = self._ds_bind(self.dnsname_dc1)

        # Make sure the max objects count is high enough
        req8 = self._exop_req8(dest_dsa=None,
                               invocation_id=dc_guid_1,
                               nc_dn_str=self.base_dn,
                               replica_flags=0,
                               max_objects=100,
                               exop=drsuapi.DRSUAPI_EXOP_NONE)

        # Loop until we get linked attributes, or we get to the end.
        # Samba sends linked attributes at the end, unlike Windows.
        while True:
            (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8)
            if ctr.more_data == 0 or ctr.linked_attributes_count != 0:
                break
            req8.highwatermark = ctr.new_highwatermark

        self.assertTrue(ctr.linked_attributes_count != 0)

        no_inactive = []
        for link in ctr.linked_attributes:
            try:
                target_guid = ndr_unpack(drsuapi.DsReplicaObjectIdentifier3,
                                         link.value.blob).guid
            except:
                target_guid = ndr_unpack(
                    drsuapi.DsReplicaObjectIdentifier3Binary,
                    link.value.blob).guid
            no_inactive.append((link, target_guid))

        no_inactive.sort(key=cmp_to_key_fn(_linked_attribute_compare))

        # assert the two arrays are the same
        self.assertEqual([x[0] for x in no_inactive], ctr.linked_attributes)
示例#2
0
文件: sort.py 项目: wade1990/samba
    def _test_server_sort_different_attr(self):
        def cmp_locale(a, b):
            return locale.strcoll(a[0], b[0])

        def cmp_binary(a, b):
            return cmp_fn(a[0], b[0])

        def cmp_numeric(a, b):
            return cmp_fn(int(a[0]), int(b[0]))

        # For testing simplicity, the attributes in here need to be
        # unique for each user. Otherwise there are multiple possible
        # valid answers.
        sort_functions = {
            'cn': cmp_binary,
            "employeeNumber": cmp_locale,
            "accountExpires": cmp_numeric,
            "msTSExpireDate4": cmp_binary
        }
        attrs = list(sort_functions.keys())
        attr_pairs = zip(attrs, attrs[1:] + attrs[:1])

        for sort_attr, result_attr in attr_pairs:
            forward = sorted(((norm(x[sort_attr]), norm(x[result_attr]))
                              for x in self.users),
                             key=cmp_to_key_fn(sort_functions[sort_attr]))
            reverse = list(reversed(forward))

            for rev in (0, 1):
                res = self.ldb.search(
                    self.ou,
                    scope=ldb.SCOPE_ONELEVEL,
                    attrs=[result_attr],
                    controls=["server_sort:1:%d:%s" % (rev, sort_attr)])
                self.assertEqual(len(res), len(self.users))
                pairs = (forward, reverse)[rev]

                expected_order = [x[1] for x in pairs]
                received_order = [norm(x[result_attr][0]) for x in res]

                if expected_order != received_order:
                    print(sort_attr, result_attr, ['forward', 'reverse'][rev])
                    print("expected", expected_order)
                    print("received", received_order)
                    print("unnormalised:", [x[result_attr][0] for x in res])
                    print("unnormalised: «%s»" %
                          '»  «'.join(str(x[result_attr][0]) for x in res))
                    print("pairs:", pairs)
                    # There are bugs in Windows that we don't want (or
                    # know how) to replicate regarding timestamp sorting.
                    # Let's remind ourselves.
                    if result_attr == "msTSExpireDate4":
                        print('-' * 72)
                        print("This test fails against Windows with the "
                              "default number of elements (33).")
                        print("Try with --elements=27 (or similar).")
                        print('-' * 72)

                self.assertEquals(expected_order, received_order)
                for x in res:
                    if sort_attr in x:
                        self.fail('the search for %s should not return %s' %
                                  (result_attr, sort_attr))
示例#3
0
    def test_sort_behaviour_single_object(self):
        """Testing sorting behaviour on single objects"""

        user1_dn = "cn=test_user1,%s" % self.ou
        user2_dn = "cn=test_user2,%s" % self.ou
        user3_dn = "cn=test_user3,%s" % self.ou
        group_dn = "cn=test_group,%s" % self.ou

        self.ldb_dc1.add({"dn": user1_dn, "objectclass": "user"})
        self.ldb_dc1.add({"dn": user2_dn, "objectclass": "user"})
        self.ldb_dc1.add({"dn": user3_dn, "objectclass": "user"})
        self.ldb_dc1.add({"dn": group_dn, "objectclass": "group"})

        u1_guid = misc.GUID(
            self.ldb_dc1.search(base=user1_dn,
                                attrs=["objectGUID"])[0]['objectGUID'][0])
        u2_guid = misc.GUID(
            self.ldb_dc1.search(base=user2_dn,
                                attrs=["objectGUID"])[0]['objectGUID'][0])
        u3_guid = misc.GUID(
            self.ldb_dc1.search(base=user3_dn,
                                attrs=["objectGUID"])[0]['objectGUID'][0])
        g_guid = misc.GUID(
            self.ldb_dc1.search(base=group_dn,
                                attrs=["objectGUID"])[0]['objectGUID'][0])

        self.add_linked_attribute(group_dn, user1_dn, attr='member')
        self.add_linked_attribute(group_dn, user2_dn, attr='member')
        self.add_linked_attribute(group_dn, user3_dn, attr='member')
        self.add_linked_attribute(group_dn, user1_dn, attr='managedby')
        self.add_linked_attribute(group_dn, user2_dn, attr='nonSecurityMember')
        self.add_linked_attribute(group_dn, user3_dn, attr='nonSecurityMember')

        set_inactive = AbstractLink(
            drsuapi.DRSUAPI_ATTID_nonSecurityMember,
            drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE, g_guid, u3_guid)

        expected_links = set([
            set_inactive,
            AbstractLink(drsuapi.DRSUAPI_ATTID_member,
                         drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
                         g_guid, u1_guid),
            AbstractLink(drsuapi.DRSUAPI_ATTID_member,
                         drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
                         g_guid, u2_guid),
            AbstractLink(drsuapi.DRSUAPI_ATTID_member,
                         drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
                         g_guid, u3_guid),
            AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy,
                         drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
                         g_guid, u1_guid),
            AbstractLink(drsuapi.DRSUAPI_ATTID_nonSecurityMember,
                         drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE,
                         g_guid, u2_guid),
        ])

        dc_guid_1 = self.ldb_dc1.get_invocation_id()

        drs, drs_handle = self._ds_bind(self.dnsname_dc1)

        req8 = self._exop_req8(dest_dsa=None,
                               invocation_id=dc_guid_1,
                               nc_dn_str=group_dn,
                               exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ)

        (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8)

        no_inactive = []
        for link in ctr.linked_attributes:
            target_guid = ndr_unpack(drsuapi.DsReplicaObjectIdentifier3,
                                     link.value.blob).guid
            no_inactive.append((link, target_guid))
            self.assertTrue(
                AbstractLink(link.attid, link.flags, link.identifier.guid,
                             target_guid) in expected_links)

        no_inactive.sort(key=cmp_to_key_fn(_linked_attribute_compare))

        # assert the two arrays are the same
        self.assertEqual(len(expected_links), ctr.linked_attributes_count)
        self.assertEqual([x[0] for x in no_inactive], ctr.linked_attributes)

        self.remove_linked_attribute(group_dn,
                                     user3_dn,
                                     attr='nonSecurityMember')

        # Set the link inactive
        expected_links.remove(set_inactive)
        set_inactive.flags = 0
        expected_links.add(set_inactive)

        has_inactive = []
        (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8)
        for link in ctr.linked_attributes:
            target_guid = ndr_unpack(drsuapi.DsReplicaObjectIdentifier3,
                                     link.value.blob).guid
            has_inactive.append((link, target_guid))
            self.assertTrue(
                AbstractLink(link.attid, link.flags, link.identifier.guid,
                             target_guid) in expected_links)

        has_inactive.sort(key=cmp_to_key_fn(_linked_attribute_compare))

        # assert the two arrays are the same
        self.assertEqual(len(expected_links), ctr.linked_attributes_count)
        self.assertEqual([x[0] for x in has_inactive], ctr.linked_attributes)