[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Tue Jun 22 02:06:02 UTC 2021
The branch, master has been updated
via 002ef728bb0 torture: Fix build on freebsd, missing deps on cmdline
via e267cea8179 samba-tool: dbcheck search DnsAdmins from wellknown container
via 0db57db80a5 samba-tool: Provision search DnsAdmins from wellknown container
via 151f432ca8c samba-tool: Demote computer to wellknown container
via fee11c35586 samdb: Create computer in wellknown user container
via 4602f4fc1b5 samdb: Create group in wellknown user container
via 43ab8a4a1b4 samdb: Create user in wellknown user container
via 5e559528b34 pytest: dcerpc/dnsserver: fix tombstone test
via 97b9f45a764 pytest/dns_forwarder: remove unused function and imports
via aa97974c0e4 pytest segfaults: add a couple more failing tests
via 24493ccceb1 pytest samba-tool dns: avoid testing update of '.' PTR
via de2b775e9ac pytest: dns_aging: do not insist on non-aging timestamp updates
via ad6637afa5e pytest: dns_aging sibling test fails on windows
via 7fbb8f8e957 pytest dns_aging: add windows_variation
via ebfa200bfd9 pytest: dns_aging: fix two tests (bad arithmetic)
via eac8d6b30b3 pytest dns_aging: add sibling tests
via 61355d36cbf pytest dns_aging: add simple delete tests
via 663a154e3e0 pytest: samba-tool dns: allow identical updates
via b2453a0f5c2 pytest: samba-tool dns: allow valid updates
via 6fb83b454cc pytest: dns_aging: test delete multiple records
via b24b82336f2 pytest: dns_aging: test RPC updates of disparate types
via 8d32cdf1849 python dns: dns_record_match() matches IPv6 semantically
from 91f5b5f3d07 selftest: Remove -d10 from test startup
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 002ef728bb02819385c0a8c2ca1b216ed712d153
Author: Amitay Isaacs <amitay at gmail.com>
Date: Wed Jun 16 12:58:27 2021 +1000
torture: Fix build on freebsd, missing deps on cmdline
Missing dependency causes build failure on freebsd.
[2928/3944] Compiling source4/torture/util_smb.c
In file included from ../../source4/torture/util_smb.c:22:
../../lib/cmdline/cmdline.h:22:10: fatal error: 'popt.h' file not found
^~~~~~~~
1 error generated.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Tue Jun 22 02:05:17 UTC 2021 on sn-devel-184
commit e267cea8179886995b46f0796c969a56a1becd3f
Author: David Mulder <dmulder at suse.com>
Date: Wed Aug 26 14:59:24 2020 -0600
samba-tool: dbcheck search DnsAdmins from wellknown container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 0db57db80a59e2ecfb1c626f66a72987d9fedcef
Author: David Mulder <dmulder at suse.com>
Date: Wed Aug 26 14:33:13 2020 -0600
samba-tool: Provision search DnsAdmins from wellknown container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 151f432ca8c173e7bad488dfbd507517908102da
Author: David Mulder <dmulder at suse.com>
Date: Wed Aug 26 10:06:21 2020 -0600
samba-tool: Demote computer to wellknown container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit fee11c35586adfa7e3ce79f03798732ffb870829
Author: David Mulder <dmulder at suse.com>
Date: Wed Aug 26 08:15:07 2020 -0600
samdb: Create computer in wellknown user container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 4602f4fc1b537e74fdee8d9f1a390a4ea1ba18d5
Author: David Mulder <dmulder at suse.com>
Date: Tue Aug 25 14:16:30 2020 -0600
samdb: Create group in wellknown user container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 43ab8a4a1b4152ae86e3dad23f10b40d4f61fb89
Author: David Mulder <dmulder at suse.com>
Date: Tue Aug 25 12:44:02 2020 -0600
samdb: Create user in wellknown user container
BUG: https://bugzilla.samba.org/show_bug.cgi?id=9143
Signed-off-by: David Mulder <dmulder at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 5e559528b34e4b6b26fc708cdc0976e042d91eb3
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Fri Mar 26 16:37:52 2021 +1300
pytest: dcerpc/dnsserver: fix tombstone test
It worked accidentally, like all our tombstone tests.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 97b9f45a76434c5c00f467ec93f21a111bf35c0f
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed May 19 01:12:49 2021 +0000
pytest/dns_forwarder: remove unused function and imports
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit aa97974c0e42f5eb7c663b05407964ff816dae3b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed May 19 02:38:20 2021 +0000
pytest segfaults: add a couple more failing tests
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 24493ccceb16b2b1b05040659216535c89069c54
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Fri Jun 18 13:26:53 2021 +1200
pytest samba-tool dns: avoid testing update of '.' PTR
This will fail for reasons that maybe we don't care about.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit de2b775e9ac3af87010a2d4b71220980f8e04f07
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sun Jun 20 10:18:46 2021 +1200
pytest: dns_aging: do not insist on non-aging timestamp updates
With Windows, when aging is off, the record timestamps are updated
anyway, but the timestamp change is not replicated.
We are not going to do it like that. With aging off, our records will
keep their first timestamp.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ad6637afa5e912f97dc21cb43f7893bd435c88b2
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sat Jun 19 15:54:11 2021 +1200
pytest: dns_aging sibling test fails on windows
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 7fbb8f8e95786e7361e25ff647326b1f37911c2b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sat Jun 19 15:43:29 2021 +1200
pytest dns_aging: add windows_variation
We want to sometimes be able to say "we know Windows fails, it fails
like this, it is OK", so that when we run the tests on Windows we know
the failures are not unexpected.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ebfa200bfd9e63588d59c97232ade2ca4d0ae996
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sat Jun 19 14:52:47 2021 +1200
pytest: dns_aging: fix two tests (bad arithmetic)
oops.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit eac8d6b30b3045021667bf4eda521eb64bea5075
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sat Jun 19 14:18:05 2021 +1200
pytest dns_aging: add sibling tests
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 61355d36cbfc123ee61479257845eff4864d3d0b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Sat Jun 19 13:35:54 2021 +1200
pytest dns_aging: add simple delete tests
When records are added and deleted and added again, Windows gets all
kinds of ideas about what should happen, and many of our tests explore
that. Here we focus the simplest case with a variety of timestamp
combinations.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 663a154e3e0e25b50772063cba9a99ac7fa338c4
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Jun 17 22:43:39 2021 +1200
pytest: samba-tool dns: allow identical updates
We know this should work from tests of the underlying RPC calls on
Windows (see dns_aging).
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b2453a0f5c2fbb0c002ebb5fd274ca57ff66ee9f
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Jun 17 22:22:46 2021 +1200
pytest: samba-tool dns: allow valid updates
Without this patch we will get errors like this when in-place RPC
updates start to work:
AssertionError: unexpectedly None : Successfully updated record
'192.168.0.1' to '192.168.0.1', even though the latter is of type
'A' where 'A' was expected.
That's because we have always rejected updates that try to modify an
existing record. We shouldn't.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 6fb83b454ccac7e01ab0f5d48c1c5b6a66bea173
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Fri Jun 18 18:32:22 2021 +1200
pytest: dns_aging: test delete multiple records
Using dns.DNS_QCLASS_ANY we can delete all the records of a certain
type. What happens to other timestamps? The answer should be nothing.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b24b82336f22570314c8240872213109d80ef641
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Jun 17 23:10:50 2021 +1200
pytest: dns_aging: test RPC updates of disparate types
Can a TXT record be replaced by an A record in an RPC update?
According to Windows, yes.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8d32cdf18490be254e3d2c780af1a234ad86cc39
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Fri Jun 18 11:30:09 2021 +1200
python dns: dns_record_match() matches IPv6 semantically
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
python/samba/dbchecker.py | 5 +-
python/samba/dnsserver.py | 9 +-
python/samba/netcmd/domain.py | 5 +-
python/samba/provision/sambadns.py | 8 +-
python/samba/samdb.py | 17 +-
python/samba/tests/dcerpc/dnsserver.py | 92 ++++++-
python/samba/tests/dns_aging.py | 426 +++++++++++++++++++++++++++--
python/samba/tests/dns_forwarder.py | 14 +-
python/samba/tests/samba_tool/dnscmd.py | 44 +--
python/samba/tests/segfault.py | 20 +-
selftest/knownfail.d/dns-aging | 47 +++-
selftest/knownfail.d/dnscmd | 2 +
selftest/knownfail.d/python-segfaults | 2 +
source4/torture/libnetapi/wscript_build | 2 +-
source4/torture/libsmbclient/wscript_build | 2 +-
source4/torture/smb2/wscript_build | 2 +-
source4/torture/wscript_build | 6 +-
17 files changed, 621 insertions(+), 82 deletions(-)
create mode 100644 selftest/knownfail.d/dnscmd
Changeset truncated at 500 lines:
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index d133b2aa55e..eb6dfe97cb0 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -124,7 +124,10 @@ class dbcheck(object):
self.link_id_cache = {}
self.name_map = {}
try:
- res = samdb.search(base="CN=DnsAdmins,CN=Users,%s" % samdb.domain_dn(), scope=ldb.SCOPE_BASE,
+ base_dn = "CN=DnsAdmins,%s" % samdb.get_wellknown_dn(
+ samdb.get_default_basedn(),
+ dsdb.DS_GUID_USERS_CONTAINER)
+ res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE,
attrs=["objectSid"])
dnsadmins_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
self.name_map['DnsAdmins'] = str(dnsadmins_sid)
diff --git a/python/samba/dnsserver.py b/python/samba/dnsserver.py
index 9bcab7fb023..8453b442b50 100644
--- a/python/samba/dnsserver.py
+++ b/python/samba/dnsserver.py
@@ -17,6 +17,7 @@
#
import shlex
+import socket
from samba.dcerpc import dnsserver, dnsp
# Note: these are not quite the same as similar looking classes in
@@ -309,6 +310,12 @@ def dns_name_equal(n1, n2):
return n1.str.rstrip('.').lower() == n2.str.rstrip('.').lower()
+def ipv6_normalise(addr):
+ """Convert an AAAA adresss into a canonical form."""
+ packed = socket.inet_pton(socket.AF_INET6, addr)
+ return socket.inet_ntop(socket.AF_INET6, packed)
+
+
def dns_record_match(dns_conn, server, zone, name, record_type, data):
"""Find a dns record that matches the specified data"""
@@ -350,7 +357,7 @@ def dns_record_match(dns_conn, server, zone, name, record_type, data):
if rec.data == urec.data:
found = True
elif record_type == dnsp.DNS_TYPE_AAAA:
- if rec.data == urec.data:
+ if ipv6_normalise(rec.data) == ipv6_normalise(urec.data):
found = True
elif record_type == dnsp.DNS_TYPE_PTR:
if dns_name_equal(rec.data, urec.data):
diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index eccae4e2f75..de6f2b0ca1d 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -107,6 +107,7 @@ from samba.netcmd.domain_backup import cmd_domain_backup
from samba.common import get_string
from samba.trust_utils import CreateTrustedDomainRelax
+from samba import dsdb
string_version_to_constant = {
"2008_R2": DS_DOMAIN_FUNCTION_2008_R2,
@@ -902,7 +903,9 @@ class cmd_domain_demote(Command):
i = 0
newrdn = str(rdn)
- computer_dn = ldb.Dn(remote_samdb, "CN=Computers,%s" % str(remote_samdb.domain_dn()))
+ computer_dn = remote_samdb.get_wellknown_dn(
+ remote_samdb.get_default_basedn(),
+ dsdb.DS_GUID_COMPUTERS_CONTAINER)
res = remote_samdb.search(base=computer_dn, expression=rdn, scope=ldb.SCOPE_ONELEVEL)
if (len(res) != 0):
diff --git a/python/samba/provision/sambadns.py b/python/samba/provision/sambadns.py
index cd8df680749..6823f9ee56b 100644
--- a/python/samba/provision/sambadns.py
+++ b/python/samba/provision/sambadns.py
@@ -38,7 +38,8 @@ from samba.dsdb import (
DS_DOMAIN_FUNCTION_2003,
DS_DOMAIN_FUNCTION_2008_R2,
DS_DOMAIN_FUNCTION_2012_R2,
- DS_DOMAIN_FUNCTION_2016
+ DS_DOMAIN_FUNCTION_2016,
+ DS_GUID_USERS_CONTAINER
)
from samba.descriptor import (
get_domain_descriptor,
@@ -69,8 +70,9 @@ def get_domainguid(samdb, domaindn):
def get_dnsadmins_sid(samdb, domaindn):
- res = samdb.search(base="CN=DnsAdmins,CN=Users,%s" % domaindn, scope=ldb.SCOPE_BASE,
- attrs=["objectSid"])
+ base_dn = "CN=DnsAdmins,%s" % samdb.get_wellknown_dn(ldb.Dn(samdb,
+ domaindn), DS_GUID_USERS_CONTAINER)
+ res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE, attrs=["objectSid"])
dnsadmins_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
return dnsadmins_sid
diff --git a/python/samba/samdb.py b/python/samba/samdb.py
index 424d6d2e88a..5e4f07bb679 100644
--- a/python/samba/samdb.py
+++ b/python/samba/samdb.py
@@ -228,7 +228,12 @@ lockoutTime: 0
:param sd: security descriptor of the object
"""
- group_dn = "CN=%s,%s,%s" % (groupname, (groupou or "CN=Users"), self.domain_dn())
+ if groupou:
+ group_dn = "CN=%s,%s,%s" % (groupname, groupou, self.domain_dn())
+ else:
+ group_dn = "CN=%s,%s" % (groupname, self.get_wellknown_dn(
+ self.get_default_basedn(),
+ dsdb.DS_GUID_USERS_CONTAINER))
# The new user record. Note the reliance on the SAMLDB module which
# fills in the default information
@@ -530,7 +535,12 @@ member: %s
if useusernameascn is None and displayname != "":
cn = displayname
- user_dn = "CN=%s,%s,%s" % (cn, (userou or "CN=Users"), self.domain_dn())
+ if userou:
+ user_dn = "CN=%s,%s,%s" % (cn, userou, self.domain_dn())
+ else:
+ user_dn = "CN=%s,%s" % (cn, self.get_wellknown_dn(
+ self.get_default_basedn(),
+ dsdb.DS_GUID_USERS_CONTAINER))
dnsdomain = ldb.Dn(self, self.domain_dn()).canonical_str().replace("/", "")
user_principal_name = "%s@%s" % (username, dnsdomain)
@@ -763,7 +773,8 @@ member: %s
raise Exception('Illegal computername "%s"' % computername)
samaccountname = "%s$" % cn
- computercontainer_dn = "CN=Computers,%s" % self.domain_dn()
+ computercontainer_dn = self.get_wellknown_dn(self.get_default_basedn(),
+ dsdb.DS_GUID_COMPUTERS_CONTAINER)
if computerou:
computercontainer_dn = self.normalize_dn_in_domain(computerou)
diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py
index 340bb454324..a757e6f5a6d 100644
--- a/python/samba/tests/dcerpc/dnsserver.py
+++ b/python/samba/tests/dcerpc/dnsserver.py
@@ -330,24 +330,79 @@ class DnsserverTests(RpcInterfaceTestCase):
self.delete_record(self.custom_zone, "testrecord", record_type_str, record_str)
self.assert_num_records(self.custom_zone, "testrecord", record_type_str, 0)
- def test_dns_tombstoned(self):
- """
- See what happens when we set a record to be tombstoned.
- """
+ def test_dns_tombstoned_zero_timestamp(self):
+ """What happens with a zero EntombedTime tombstone?"""
+ # A zero-timestamp tombstone record has a special meaning for
+ # dns_common_replace(), which is the function exposed by
+ # samdb.dns_replace_by_dn(), and which is *NOT* a general
+ # purpose record replacement function but a specialised part
+ # of the dns update mechanism (for both DLZ and internal).
+ #
+ # In the earlier stages of handling updates, a record that
+ # needs to be deleted is set to be a tombstone with a zero
+ # timestamp. dns_common_replace() notices this specific
+ # marker, and if there are no other records, marks the node as
+ # tombstoned, in the process adding a "real" tombstone.
+ #
+ # If the tombstone has a non-zero timestamp, as you'll see in
+ # the next test, dns_common_replace will decide that the node
+ # is already tombstoned, and that no action needs to be taken.
+ #
+ # This test has worked historically, entirely by accident, as
+ # changing the wType appears to
record_str = "192.168.50.50"
- record_type_str = "A"
- self.add_record(self.custom_zone, "testrecord", record_type_str, record_str)
+ self.add_record(self.custom_zone, "testrecord", 'A', record_str)
dn, record = self.get_record_from_db(self.custom_zone, "testrecord")
record.wType = dnsp.DNS_TYPE_TOMBSTONE
- res = self.samdb.dns_replace_by_dn(dn, [record])
- if res is not None:
- self.fail("Unable to update dns record to be tombstoned.")
+ record.data = 0
+ self.samdb.dns_replace_by_dn(dn, [record])
+
+ # there should be no A record, and one TOMBSTONE record.
+ self.assert_num_records(self.custom_zone, "testrecord", 'A', 0)
+ # we can't make assertions about the tombstone count based on
+ # RPC calls, as ther are no tombstones in RPCs (there is
+ # "DNS_TYPE_ZERO" instead). Nor do tombstones show up if we
+ # use DNS_TYPE_ALL.
+ self.assert_num_records(self.custom_zone, "testrecord", 'ALL', 0)
+
+ # But we can use LDAP:
+ records = self.ldap_get_records(self.custom_zone, "testrecord")
+ self.assertEqual(len(records), 1)
+ r = records[0]
+ self.assertEqual(r.wType, dnsp.DNS_TYPE_TOMBSTONE)
+ self.assertGreater(r.data, 1e17) # ~ October 1916
+
+ # this should fail, because no A records.
+ self.delete_record(self.custom_zone, "testrecord", 'A', record_str,
+ assertion=False)
+
+ def test_dns_tombstoned_nonzero_timestamp(self):
+ """See what happens when we set a record to be tombstoned with an
+ EntombedTime timestamp.
+ """
+ # Because this tombstone has a non-zero EntombedTime,
+ # dns_common_replace() will decide the node was already
+ # tombstoned and there is nothing to be done, leaving the A
+ # record where it was.
- self.assert_num_records(self.custom_zone, "testrecord", record_type_str)
- self.delete_record(self.custom_zone, "testrecord", record_type_str, record_str)
- self.assert_num_records(self.custom_zone, "testrecord", record_type_str, 0)
+ record_str = "192.168.50.50"
+ self.add_record(self.custom_zone, "testrecord", 'A', record_str)
+
+ dn, record = self.get_record_from_db(self.custom_zone, "testrecord")
+ record.wType = dnsp.DNS_TYPE_TOMBSTONE
+ record.data = 0x123456789A
+ self.samdb.dns_replace_by_dn(dn, [record])
+
+ # there should be the A record and no TOMBSTONE
+ self.assert_num_records(self.custom_zone, "testrecord", 'A', 1)
+ self.assert_num_records(self.custom_zone, "testrecord", 'TOMBSTONE', 0)
+ # this should succeed
+ self.delete_record(self.custom_zone, "testrecord", 'A', record_str,
+ assertion=True)
+ self.assert_num_records(self.custom_zone, "testrecord", 'TOMBSTONE', 0)
+ self.assert_num_records(self.custom_zone, "testrecord", 'A', 0)
def get_record_from_db(self, zone_name, record_name):
"""
@@ -376,6 +431,19 @@ class DnsserverTests(RpcInterfaceTestCase):
rec = ndr_unpack(dnsp.DnssrvRpcRecord, old_packed_record["dnsRecord"][0])
return (old_packed_record.dn, rec)
+ def ldap_get_records(self, zone, name):
+ zone_dn = (f"DC={zone},CN=MicrosoftDNS,DC=DomainDNSZones,"
+ f"{self.samdb.get_default_basedn()}")
+
+ expr = f"(&(objectClass=dnsNode)(name={name}))"
+ nodes = self.samdb.search(base=zone_dn,
+ scope=ldb.SCOPE_SUBTREE,
+ expression=expr,
+ attrs=["dnsRecord"])
+
+ records = nodes[0].get('dnsRecord')
+ return [ndr_unpack(dnsp.DnssrvRpcRecord, r) for r in records]
+
def test_duplicate_matching(self):
"""
Make sure that records which should be distinct from each other or duplicate
diff --git a/python/samba/tests/dns_aging.py b/python/samba/tests/dns_aging.py
index 3219e63151b..2e7369bed00 100644
--- a/python/samba/tests/dns_aging.py
+++ b/python/samba/tests/dns_aging.py
@@ -25,15 +25,15 @@ from samba.auth import system_session
import ldb
from samba import credentials
from samba.dcerpc import dns, dnsp, dnsserver
-from samba.dnsserver import TXTRecord
-from samba.dnsserver import recbuf_from_string
+from samba.dnsserver import TXTRecord, ARecord
+from samba.dnsserver import recbuf_from_string, ipv6_normalise
from samba.tests.subunitrun import SubunitOptions, TestProgram
from samba import werror, WERRORError
from samba.tests.dns_base import DNSTest
import samba.getopt as options
import optparse
import time
-
+from samba.colour import c_RED, c_GREEN, c_DARK_YELLOW
parser = optparse.OptionParser(
"dns_aging.py <server name> <server ip> [options]")
@@ -314,8 +314,11 @@ class TestDNSAging(DNSTest):
r.rr_type = wtype
r.rr_class = qclass
r.ttl = ttl
- r.length = 0xffff
- r.rdata = data
+ if data is not None:
+ r.length = 0xffff
+ r.rdata = data
+ else:
+ r.length = 0
p.nscount = 1
p.nsrecs = [r]
@@ -330,6 +333,12 @@ class TestDNSAging(DNSTest):
wtype,
qclass=dns.DNS_QCLASS_NONE)
+ def dns_delete_type(self, name, wtype):
+ return self.dns_update_non_text(name,
+ None,
+ wtype,
+ qclass=dns.DNS_QCLASS_ANY)
+
def dns_update_record(self, name, txt, ttl=900):
if isinstance(txt, str):
txt = [txt]
@@ -1622,8 +1631,8 @@ class TestDNSAging(DNSTest):
def test_aging_refresh(self):
name, txt = 'agingtest', ['test txt']
- no_refresh = 100
- refresh = 80
+ no_refresh = 200
+ refresh = 160
self.set_zone_int_params(NoRefreshInterval=no_refresh,
RefreshInterval=refresh,
Aging=1)
@@ -1631,22 +1640,22 @@ class TestDNSAging(DNSTest):
start_time = before_mod.dwTimeStamp
# go back 86 hours, which is in the no-refresh time (but
- # wouldn't be if we had stuck to the default of 84).
- self.ldap_modify_timestamps(name, -86)
+ # wouldn't be if we had stuck to the default of 168).
+ self.ldap_modify_timestamps(name, -170)
rec = self.dns_update_record(name, txt)
self.assert_timestamps_equal(rec.dwTimeStamp,
- start_time - 86)
+ start_time - 170)
- # back to -102 hours, into the refresh zone
+ # back to -202 hours, into the refresh zone
# the update should reset the timestamp to now.
- self.ldap_modify_timestamps(name, -16)
+ self.ldap_modify_timestamps(name, -32)
rec = self.dns_update_record(name, txt)
self.assert_soon_after(rec.dwTimeStamp, start_time)
- # back to -182 hours, beyond the end of the refresh period.
+ # back to -362 hours, beyond the end of the refresh period.
# Actually nothing changes at this time -- we can still
# refresh, but the record is liable for scavenging.
- self.ldap_modify_timestamps(name, -182)
+ self.ldap_modify_timestamps(name, -160)
rec = self.dns_update_record(name, txt)
self.assert_soon_after(rec.dwTimeStamp, start_time)
@@ -1798,6 +1807,21 @@ class TestDNSAging(DNSTest):
rec = self.dns_update_record('ldap', 'test')
self.assertEqual(rec.dwSerial, 123)
+ def test_rpc_update_disparate_types(self):
+ """Can we use update to replace a TXT with an AAAA?"""
+ name = 'x'
+ old = TXTRecord("x")
+ new = ARecord("127.0.0.111")
+ self.rpc_replace(name, None, old)
+ recs = self.ldap_get_records(name)
+ self.assertEqual(len(recs), 1)
+ self.assertEqual(recs[0].wType, old.wType)
+
+ self.rpc_replace(name, old, new)
+ recs = self.ldap_get_records(name)
+ self.assertEqual(len(recs), 1)
+ self.assertEqual(recs[0].wType, new.wType)
+
def test_add_update_many(self):
# Samba fails often in this set, but we want to see how it
# goes further down, so we print the problems and defer the
@@ -2006,8 +2030,8 @@ class TestDNSAging(DNSTest):
# the database directly.
# just to be sure we have the right limits.
- self.set_zone_int_params(NoRefreshInterval=84,
- RefreshInterval=84,
+ self.set_zone_int_params(NoRefreshInterval=168,
+ RefreshInterval=168,
Aging=1)
ts1, ts2, ts3, ts4, ts5, ts6 = ('1', '2', '3', '4', '5', '6')
@@ -2227,8 +2251,12 @@ class TestDNSAging(DNSTest):
# check the B timestamp
rec_b = self.get_unique_ip_record(name, B)
-
- self.assert_soon_after(rec_b, now)
+ if not aging:
+ self.windows_variation(
+ self.assert_soon_after, rec_b, now,
+ msg="windows updates non-aging, samba does not")
+ else:
+ self.assert_soon_after(rec_b, now)
# rewind B
rec_b = self.add_ip_record(name, B, dwTimeStamp=b_initial)
@@ -2297,6 +2325,82 @@ class TestDNSAging(DNSTest):
def test_AAAA_5_days_AAAA_6_days_no_aging(self):
self._test_A_and_AAAA_records(IPv6_ADDR, IPv6_ADDR_2, 5, 6, aging=False)
+ def _test_multi_records_delete(self, aging):
+ # Batch deleting a type doesn't update other types timestamps.
+ self.set_aging(aging)
+
+ name = 'aargh'
+ now = dsdb_dns.unix_to_dns_timestamp(int(time.time()))
+
+ back_5_days = now - 5 * 24
+ back_10_days = now - 10 * 24
+ back_25_days = now - 25 * 24
+
+ ip4s = {
+ '1.1.1.1': now,
+ '2.2.2.2': back_5_days,
+ '3.3.3.3': back_10_days,
+ }
+ ip6s = {
+ '::1': now,
+ '::2': back_5_days,
+ '::3': back_25_days,
+ }
+
+ txts = {
+ '1': now,
+ '2': back_5_days,
+ '3': back_25_days,
+ }
+
+ # For windows, if we don't DNS update something, it won't know
+ # there's anything.
+ self.dns_update_record(name, '3')
+
+ for k, v in ip4s.items():
+ r = self.add_ip_record(name, k, wtype=dns.DNS_QTYPE_A, dwTimeStamp=v)
+
+ for k, v in ip6s.items():
+ r = self.add_ip_record(name, k, wtype=dns.DNS_QTYPE_AAAA, dwTimeStamp=v)
+
+ for k, v in txts.items():
+ r = self.ldap_update_record(name, k, dwTimeStamp=v)
+
+ self.dns_delete_type(name, dnsp.DNS_TYPE_A)
+
+ r = self.dns_query(name, dns.DNS_QTYPE_A)
+ self.assertEqual(r.ancount, 0)
+
+ r = self.dns_query(name, dns.DNS_QTYPE_TXT)
+ self.assertEqual(r.ancount, 3)
+ rset = set(x.rdata.txt.str[0] for x in r.answers)
+ self.assertEqual(rset, set(txts))
+
+ r = self.dns_query(name, dns.DNS_QTYPE_AAAA)
+ self.assertEqual(r.ancount, 3)
+ rset = set(ipv6_normalise(x.rdata) for x in r.answers)
+ self.assertEqual(rset, set(ip6s))
+
+ recs = self.ldap_get_records(name)
+ self.assertEqual(len(recs), 6)
+ for r in recs:
+ if r.wType == dns.DNS_QTYPE_AAAA:
+ k = ipv6_normalise(r.data)
+ expected = ip6s[k]
+ elif r.wType == dns.DNS_QTYPE_TXT:
+ k = r.data.str[0]
+ expected = txts[k]
+ else:
+ self.fail(f"unexpected wType {r.wType}")
+
+ self.assert_timestamps_equal(r.dwTimeStamp, expected)
+
+ def test_multi_records_delete_aging(self):
+ self._test_multi_records_delete(True)
+
+ def test_multi_records_delete_no_aging(self):
+ self._test_multi_records_delete(False)
+
def _test_dns_delete_times(self, n_days, aging=True):
# In these tests, Windows replaces the records with
# tombstones, while Samba just removes them. Both are
@@ -2392,5 +2496,291 @@ class TestDNSAging(DNSTest):
def test_dns_delete_times_static_no_aging(self):
self._test_dns_delete_times(1e10, False)
+ def _test_dns_delete_simple(self, a_days, b_days, aging=True, touch=False):
+ # Here we show that with aging enabled, the timestamp of
+ # sibling records is *not* modified when a record is deleted.
+ #
+ # With aging disabled, it *is* modified, if the dns server has
+ # seen it updated before ldap set the time (that is, probably
+ # the dns server overwrites AD). This happens even if AD
+ # thinks the record is static.
+ name = 'test'
+ A = ['A']
+ B = ['B']
+ self.set_aging(aging)
+ now = dsdb_dns.unix_to_dns_timestamp(int(time.time()))
+ a_days_ago = max(now - a_days * 24, 0)
+ b_days_ago = max(now - b_days * 24, 0)
+
+ if touch:
--
Samba Shared Repository
More information about the samba-cvs
mailing list