From: Andrew Bartlett Date: Tue, 29 Oct 2019 04:25:28 +0000 (+1300) Subject: CVE-2019-14861: s4-rpc/dnsserver: Confirm sort behaviour in dcesrv_DnssrvEnumRecords X-Git-Tag: ldb-2.1.0~309 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a25a2e4513e48d0408b1f5e78ada0b3569d3426d;p=thirdparty%2Fsamba.git CVE-2019-14861: s4-rpc/dnsserver: Confirm sort behaviour in dcesrv_DnssrvEnumRecords The sort behaviour for child records is not correct in Samba so we add a flapping entry. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138 Signed-off-by: Andrew Bartlett --- diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py index 0da9614d066..b2dffc924cb 100644 --- a/python/samba/tests/dcerpc/dnsserver.py +++ b/python/samba/tests/dcerpc/dnsserver.py @@ -156,6 +156,107 @@ class DnsserverTests(RpcInterfaceTestCase): None) super(DnsserverTests, self).tearDown() + def test_enum_is_sorted(self): + """ + Confirm the zone is sorted + """ + + record_str = "192.168.50.50" + record_type_str = "A" + self.add_record(self.custom_zone, "atestrecord-1", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-2", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-3", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-4", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-0", record_type_str, record_str) + + # This becomes an extra A on the zone itself by server-side magic + self.add_record(self.custom_zone, self.custom_zone, record_type_str, record_str) + + _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN, + 0, + self.server, + self.custom_zone, + "@", + None, + self.record_type_int(record_type_str), + dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA, + None, + None) + + self.assertEqual(len(result.rec), 6) + self.assertEqual(result.rec[0].dnsNodeName.str, "") + self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0") + self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1") + self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2") + self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3") + self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4") + + def test_enum_is_sorted_children_prefix_first(self): + """ + Confirm the zone returns the selected prefix first but no more + as Samba is flappy for the full sort + """ + + record_str = "192.168.50.50" + record_type_str = "A" + self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str) + + # Not expected to be returned + self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str) + + _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN, + 0, + self.server, + self.custom_zone, + "a.b", + None, + self.record_type_int(record_type_str), + dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA, + None, + None) + + self.assertEqual(len(result.rec), 6) + self.assertEqual(result.rec[0].dnsNodeName.str, "") + + def test_enum_is_sorted_children(self): + """ + Confirm the zone is sorted + """ + + record_str = "192.168.50.50" + record_type_str = "A" + self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str) + self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str) + + # Not expected to be returned + self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str) + + _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN, + 0, + self.server, + self.custom_zone, + "a.b", + None, + self.record_type_int(record_type_str), + dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA, + None, + None) + + self.assertEqual(len(result.rec), 6) + self.assertEqual(result.rec[0].dnsNodeName.str, "") + self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0") + self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1") + self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2") + self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3") + self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4") + # This test fails against Samba (but passes against Windows), # because Samba does not return the record when we enum records. # Records can be given DNS_RANK_NONE when the zone they are in diff --git a/selftest/flapping.d/dnsserver b/selftest/flapping.d/dnsserver new file mode 100644 index 00000000000..9b33e8522a3 --- /dev/null +++ b/selftest/flapping.d/dnsserver @@ -0,0 +1,2 @@ +# This is not stable in samba due to a bug +^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_enum_is_sorted_children \ No newline at end of file