[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Mar 30 00:21:01 UTC 2021


The branch, master has been updated
       via  d1c47d0c830 rpc/idl dnsserver s/DNS_RPC_DATA/DNS_RPC_RECORD_DATA/
       via  162e6fb25ab librpc/idl: dnsp tombstone timestamp name matches MS-DNSP
       via  5f4b7390117 pytest/dnsserver: extend record_type_int to all types
       via  49f434ca08e pytest/dns: use self.assertIn() and .assertNotIn()
       via  820c735578b pytest/dns: remove redundant argument
       via  59f45fa7f65 dsdb/dns scavange: make a helper function static
       via  f1b59e8cb1a dsdb/scavange dns: reserve NTTIME type for NTTIME values
       via  a32c229b095 dns: use unix_to_dns_timestamp almost everywhere
       via  146c23fb7d9 pydns: expose dns timestamp utils to python, and test
       via  2b9279bd31d dns: add common dns_timestamp util functions
       via  b2ee40b5123 dns common: always check a talloc NULL.
      from  1432314f5c1 libcli smb smb2: Use correct enumeration type

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d1c47d0c83091763be5231792e4e089b5d5365dd
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Mar 24 13:36:18 2021 +1300

    rpc/idl dnsserver s/DNS_RPC_DATA/DNS_RPC_RECORD_DATA/
    
    Following MS-DNSP.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Mar 30 00:20:53 UTC 2021 on sn-devel-184

commit 162e6fb25ab9f61b7c1fe69c54dc5e8b17601bcf
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Mar 24 12:49:22 2021 +1300

    librpc/idl: dnsp tombstone timestamp name matches MS-DNSP
    
    MS-DNSP uses the term "EntombedTime" in e.g. "2.2.2.2.4.23 DNS_RPC_RECORD_TS"
    which is more descriptive than the generic "timestamp", and less likely to be
    confused with dwTimestamp, which has been our curse. Let's make it grep-able,
    google-able, and evocative.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5f4b73901175a0caedf8f5de7ffda6bb3f2f2a6c
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Mar 25 17:47:04 2021 +1300

    pytest/dnsserver: extend record_type_int to all types
    
    with improved diagnostics on bad arguments
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 49f434ca08ee4f35fba57082603f3dc83447a2e6
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Mar 24 15:16:21 2021 +1300

    pytest/dns: use self.assertIn() and .assertNotIn()
    
    These give a more detailed message than assertTrue(x in y).
    
    They were new in Python 3.1, so we avoided them until recently.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 820c735578b3a84d33fb8ccb1899790ac8823487
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Mar 24 14:57:32 2021 +1300

    pytest/dns: remove redundant argument
    
    We are always setting zone to the same thing which we already know,
    and we can reduce cognative stress by mentioning it less and not doing
    that weird pop thing.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 59f45fa7f650aab15045f6c38d5ae26217be64cc
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sun Mar 28 11:20:25 2021 +1300

    dsdb/dns scavange: make a helper function static
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f1b59e8cb1a0d6e255d2dc90791afa1c96a4ce6c
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sun Mar 28 11:20:48 2021 +1300

    dsdb/scavange dns: reserve NTTIME type for NTTIME values
    
    We know it "really" just means uint64_t, but we also know it means
    100-nanosecond intervals since 1601, and that makes any other use very
    confusing (and not just to me, or there wouldn't be these bugs we're
    chasing).
    
    In these cases we are talking about 32 bit hours-since-1601 timestamps.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a32c229b0956f6ed1cf1ad20599539141bbff15d
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Mar 11 15:58:37 2021 +1300

    dns: use unix_to_dns_timestamp almost everywhere
    
    In places we change NTTIME to uint32_t, because that is what is
    actually wanted.
    
    There is one instance of the calculation that we are not changing,
    because there are other problems there.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 146c23fb7d98515c4dd0349d0406b7f459d3b696
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Mar 27 09:09:56 2021 +0000

    pydns: expose dns timestamp utils to python, and test
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2b9279bd31dfb13209d828dd57f92beb67ba2f71
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Mar 11 15:17:28 2021 +1300

    dns: add common dns_timestamp util functions
    
    The dns structs have an unsigned 32 bit timestamp in hours since the
    beginning of 1601. In a number of places we need to convert from unix
    time to this timestamp, or from the timestamp to NTTIME.
    
    You'll see subsequent patches that make use of these functions.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b2ee40b5123ce466bfda67cdf63a540ae82a212e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Mar 24 17:38:15 2021 +1300

    dns common: always check a talloc NULL.
    
    Also, since we're there, avoid sorting an array of 1 element.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/dnsp.idl                            |   2 +-
 librpc/idl/dnsserver.idl                       |  10 +--
 python/samba/tests/blackbox/samba_dnsupdate.py |   6 +-
 python/samba/tests/dcerpc/dnsserver.py         |  29 ++-----
 python/samba/tests/dns.py                      |  46 ++++++-----
 python/samba/tests/dsdb_dns.py                 |  86 +++++++++++++++++++++
 source4/dns_server/dlz_bind9.c                 |   6 +-
 source4/dns_server/dns_update.c                |   6 +-
 source4/dns_server/dnsserver_common.c          | 103 ++++++++++++++++++++++---
 source4/dns_server/dnsserver_common.h          |  14 ++++
 source4/dns_server/pydns.c                     |  48 ++++++++++++
 source4/dsdb/kcc/scavenge_dns_records.c        |  30 ++++---
 source4/dsdb/kcc/scavenge_dns_records.h        |   7 +-
 source4/rpc_server/dnsserver/dnsdata.c         |   6 +-
 source4/selftest/tests.py                      |   2 +
 15 files changed, 302 insertions(+), 99 deletions(-)
 create mode 100644 python/samba/tests/dsdb_dns.py


Changeset truncated at 500 lines:

diff --git a/librpc/idl/dnsp.idl b/librpc/idl/dnsp.idl
index 2fb45a217a4..2270ed5584c 100644
--- a/librpc/idl/dnsp.idl
+++ b/librpc/idl/dnsp.idl
@@ -200,7 +200,7 @@ interface dnsp
 	} dnsp_string_list;
 
 	typedef [nodiscriminant,gensize] union {
-		[case(DNS_TYPE_TOMBSTONE)] 		    NTTIME timestamp;
+		[case(DNS_TYPE_TOMBSTONE)] 		    NTTIME EntombedTime;
 		[case(DNS_TYPE_A)] [flag(NDR_BIG_ENDIAN)]   ipv4address ipv4;
 		[case(DNS_TYPE_NS)]                         dnsp_name ns;
 		[case(DNS_TYPE_CNAME)]                      dnsp_name cname;
diff --git a/librpc/idl/dnsserver.idl b/librpc/idl/dnsserver.idl
index 50cbfbee90f..a6c413a9d68 100644
--- a/librpc/idl/dnsserver.idl
+++ b/librpc/idl/dnsserver.idl
@@ -118,7 +118,7 @@ import "misc.idl", "dnsp.idl";
 	DNS_RPC_RECORD_SRV;
 
 	typedef [nodiscriminant,gensize,flag(NDR_NOALIGN)] union {
-		[case(DNS_TYPE_TOMBSTONE)] 		    NTTIME timestamp;
+		[case(DNS_TYPE_TOMBSTONE)] 		    NTTIME EntombedTime;
 		[case(DNS_TYPE_A)] [flag(NDR_BIG_ENDIAN)]   ipv4address ipv4;
 		[case(DNS_TYPE_NS)]    				DNS_RPC_NAME name;
 		[case(DNS_TYPE_MD)]    				DNS_RPC_NAME name;
@@ -136,22 +136,22 @@ import "misc.idl", "dnsp.idl";
 		[case(DNS_TYPE_SRV)]   				DNS_RPC_RECORD_SRV srv;
 		[case(DNS_TYPE_DNAME)] 				DNS_RPC_NAME name;
 	}
-	DNS_RPC_DATA;
+	DNS_RPC_RECORD_DATA;
 
 	typedef [public] struct {
-		[value(ndr_size_DNS_RPC_DATA(&data,wType,0))] uint16 wDataLength;
+		[value(ndr_size_DNS_RPC_RECORD_DATA(&data,wType,0))] uint16 wDataLength;
 		dns_record_type        wType;
 		DWORD       dwFlags;
 		DWORD       dwSerial;
 		DWORD       dwTtlSeconds;
 		DWORD       dwTimeStamp;
 		DWORD       dwReserved;
-		[subcontext(0),subcontext_size(wDataLength),switch_is(wType)] DNS_RPC_DATA data;
+		[subcontext(0),subcontext_size(wDataLength),switch_is(wType)] DNS_RPC_RECORD_DATA data;
 	}
 	DNS_RPC_RECORD;
 
 	typedef struct {
-		[value(ndr_size_DNS_RPC_DATA(&rec.data,rec.wType,0))] uint3264 wContextLength;
+		[value(ndr_size_DNS_RPC_RECORD_DATA(&rec.data,rec.wType,0))] uint3264 wContextLength;
 		DNS_RPC_RECORD rec;
 	}
 	DNS_RPC_RECORD_BUF;
diff --git a/python/samba/tests/blackbox/samba_dnsupdate.py b/python/samba/tests/blackbox/samba_dnsupdate.py
index ae65426e57d..f51ee4dff27 100644
--- a/python/samba/tests/blackbox/samba_dnsupdate.py
+++ b/python/samba/tests/blackbox/samba_dnsupdate.py
@@ -108,15 +108,15 @@ class SambaDnsUpdateTests(samba.tests.BlackboxTestCase):
 
         dns_c = "samba_dnsupdate --verbose --use-file={0}".format(tmp_uc)
         out = get_string(self.check_output(dns_c))
-        self.assertFalse(site_name.lower() in out, out)
+        self.assertNotIn(site_name.lower(), out)
 
         self.samdb.modify(m)
 
         shutil.copyfile(uc_fn, tmp_uc)
         out = get_string(self.check_output(dns_c))
 
-        self.assertFalse("No DNS updates needed" in out, out)
-        self.assertTrue(site_name.lower() in out, out)
+        self.assertNotIn("No DNS updates needed", out)
+        self.assertIn(site_name.lower(), out)
 
         result = cmd._run("samba-tool %s" % name, 'remove', site_name)
         if result is not None:
diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py
index 540ba009850..604add7e642 100644
--- a/python/samba/tests/dcerpc/dnsserver.py
+++ b/python/samba/tests/dcerpc/dnsserver.py
@@ -763,23 +763,8 @@ class DnsserverTests(RpcInterfaceTestCase):
         elif record_type_str == 'TXT':
             return TXTRecord(record_str)
 
-    def record_type_int(self, record_type_str):
-        if record_type_str == 'A':
-            return dnsp.DNS_TYPE_A
-        elif record_type_str == 'AAAA':
-            return dnsp.DNS_TYPE_AAAA
-        elif record_type_str == 'PTR':
-            return dnsp.DNS_TYPE_PTR
-        elif record_type_str == 'CNAME':
-            return dnsp.DNS_TYPE_CNAME
-        elif record_type_str == 'NS':
-            return dnsp.DNS_TYPE_NS
-        elif record_type_str == 'MX':
-            return dnsp.DNS_TYPE_MX
-        elif record_type_str == 'SRV':
-            return dnsp.DNS_TYPE_SRV
-        elif record_type_str == 'TXT':
-            return dnsp.DNS_TYPE_TXT
+    def record_type_int(self, s):
+        return getattr(dnsp, 'DNS_TYPE_' + s)
 
     def add_record(self, zone, name, record_type_str, record_str,
                    assertion=True, client_version=dnsserver.DNS_CLIENT_VERSION_LONGHORN):
@@ -1107,7 +1092,7 @@ class DnsserverTests(RpcInterfaceTestCase):
                                   expression="(&(objectClass=dnsZone)(name=_msdcs*))",
                                   attrs=["nTSecurityDescriptor", "objectClass"])
         self.assertEqual(len(zones), 1)
-        self.assertTrue("nTSecurityDescriptor" in zones[0])
+        self.assertIn("nTSecurityDescriptor", zones[0])
         tmp = zones[0]["nTSecurityDescriptor"][0]
         utils = sd_utils.SDUtils(self.samdb)
         sd = ndr_unpack(security.descriptor, tmp)
@@ -1166,7 +1151,7 @@ class DnsserverTests(RpcInterfaceTestCase):
                                   attrs=["nTSecurityDescriptor"])
         self.assertEqual(len(zones), 1)
         current_dn = zones[0].dn
-        self.assertTrue("nTSecurityDescriptor" in zones[0])
+        self.assertIn("nTSecurityDescriptor", zones[0])
         tmp = zones[0]["nTSecurityDescriptor"][0]
         utils = sd_utils.SDUtils(self.samdb)
         sd = ndr_unpack(security.descriptor, tmp)
@@ -1205,7 +1190,7 @@ class DnsserverTests(RpcInterfaceTestCase):
             for (key, sec_desc) in security_desc_dict:
                 zones = self.samdb.search(base=key, scope=ldb.SCOPE_BASE,
                                           attrs=["nTSecurityDescriptor"])
-                self.assertTrue("nTSecurityDescriptor" in zones[0])
+                self.assertIn("nTSecurityDescriptor", zones[0])
                 tmp = zones[0]["nTSecurityDescriptor"][0]
                 utils = sd_utils.SDUtils(self.samdb)
 
@@ -1238,7 +1223,7 @@ class DnsserverTests(RpcInterfaceTestCase):
                                   attrs=["nTSecurityDescriptor"])
         self.assertEqual(len(zones), 1)
         current_dn = zones[0].dn
-        self.assertTrue("nTSecurityDescriptor" in zones[0])
+        self.assertIn("nTSecurityDescriptor", zones[0])
         tmp = zones[0]["nTSecurityDescriptor"][0]
         utils = sd_utils.SDUtils(self.samdb)
         sd = ndr_unpack(security.descriptor, tmp)
@@ -1277,7 +1262,7 @@ class DnsserverTests(RpcInterfaceTestCase):
         for (key, sec_desc) in security_desc_dict:
             zones = self.samdb.search(base=key, scope=ldb.SCOPE_BASE,
                                       attrs=["nTSecurityDescriptor"])
-            self.assertTrue("nTSecurityDescriptor" in zones[0])
+            self.assertIn("nTSecurityDescriptor", zones[0])
             tmp = zones[0]["nTSecurityDescriptor"][0]
             utils = sd_utils.SDUtils(self.samdb)
 
diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py
index 093cae14078..77aa43a856f 100644
--- a/python/samba/tests/dns.py
+++ b/python/samba/tests/dns.py
@@ -1126,7 +1126,6 @@ class TestZones(DNSTest):
             self.fail(e)
 
     def set_params(self, **kwargs):
-        zone = kwargs.pop('zone', None)
         for key, val in kwargs.items():
             name_param = dnsserver.DNS_RPC_NAME_AND_PARAM()
             name_param.dwParam = val
@@ -1138,7 +1137,7 @@ class TestZones(DNSTest):
                 self.rpc_conn.DnssrvOperation2(client_version,
                                                0,
                                                self.server,
-                                               zone,
+                                               self.zone,
                                                0,
                                                'ResetDwordProperty',
                                                nap_type,
@@ -1218,8 +1217,9 @@ class TestZones(DNSTest):
 
     def set_aging(self, enable=False):
         self.create_zone(self.zone, aging_enabled=enable)
-        self.set_params(NoRefreshInterval=1, RefreshInterval=1,
-                        Aging=int(bool(enable)), zone=self.zone,
+        self.set_params(NoRefreshInterval=1,
+                        RefreshInterval=1,
+                        Aging=int(bool(enable)),
                         AllowUpdate=dnsp.DNS_ZONE_UPDATE_UNSECURE)
 
     def test_set_aging(self, enable=True, name='agingtest', txt=['test txt']):
@@ -1245,7 +1245,7 @@ class TestZones(DNSTest):
         self.set_aging(enable=True)
         before_mod = self.dns_update_record(name, txt)
         if not enable:
-            self.set_params(zone=self.zone, Aging=0)
+            self.set_params(Aging=0)
         dec = 2
 
         def mod_ts(rec):
@@ -1269,8 +1269,9 @@ class TestZones(DNSTest):
         name, txt = 'agingtest', ['test txt']
         self.create_zone(self.zone, aging_enabled=True)
         interval = 10
-        self.set_params(NoRefreshInterval=interval, RefreshInterval=interval,
-                        Aging=1, zone=self.zone,
+        self.set_params(NoRefreshInterval=interval,
+                        RefreshInterval=interval,
+                        Aging=1,
                         AllowUpdate=dnsp.DNS_ZONE_UPDATE_UNSECURE)
         before_mod = self.dns_update_record(name, txt)
 
@@ -1367,8 +1368,9 @@ class TestZones(DNSTest):
 
         self.create_zone(self.zone, aging_enabled=True)
         interval = 10
-        self.set_params(NoRefreshInterval=interval, RefreshInterval=interval,
-                        Aging=1, zone=self.zone,
+        self.set_params(NoRefreshInterval=interval,
+                        RefreshInterval=interval,
+                        Aging=1,
                         AllowUpdate=dnsp.DNS_ZONE_UPDATE_UNSECURE)
 
         self.dns_update_record(name, txt)
@@ -1422,8 +1424,9 @@ class TestZones(DNSTest):
 
         self.create_zone(self.zone, aging_enabled=True)
         interval = 10
-        self.set_params(NoRefreshInterval=interval, RefreshInterval=interval,
-                        Aging=1, zone=self.zone,
+        self.set_params(NoRefreshInterval=interval,
+                        RefreshInterval=interval,
+                        Aging=1,
                         AllowUpdate=dnsp.DNS_ZONE_UPDATE_UNSECURE)
 
         expr = "(dnsRecord:1.3.6.1.4.1.7165.4.5.3:={0})"
@@ -1517,8 +1520,9 @@ class TestZones(DNSTest):
 
         self.create_zone(self.zone, aging_enabled=True)
         interval = 1
-        self.set_params(NoRefreshInterval=interval, RefreshInterval=interval,
-                        zone=self.zone, Aging=1,
+        self.set_params(NoRefreshInterval=interval,
+                        RefreshInterval=interval,
+                        Aging=1,
                         AllowUpdate=dnsp.DNS_ZONE_UPDATE_UNSECURE)
         name, txt = 'agingtest', ['test txt']
         name2, txt2 = 'agingtest2', ['test txt2']
@@ -1531,11 +1535,11 @@ class TestZones(DNSTest):
         self.dns_update_record(name3, txt)
         self.dns_update_record(name3, txt2)
 
-        # Create a tomb stoned record.
+        # Create a tombstoned record.
         self.dns_update_record(name4, txt4)
         self.dns_tombstone(name4, txt4, self.zone)
         records = self.ldap_get_records(name4)
-        self.assertTrue("dNSTombstoned" in records[0])
+        self.assertIn("dNSTombstoned", records[0])
         self.assertEqual(records[0]["dNSTombstoned"][0], b"TRUE")
 
         # Create an un-tombstoned record, with dnsTombstoned: FALSE
@@ -1543,7 +1547,7 @@ class TestZones(DNSTest):
         self.dns_tombstone(name5, txt5, self.zone)
         self.dns_update_record(name5, txt5)
         records = self.ldap_get_records(name5)
-        self.assertTrue("dNSTombstoned" in records[0])
+        self.assertIn("dNSTombstoned", records[0])
         self.assertEqual(records[0]["dNSTombstoned"][0], b"FALSE")
 
         last_add = self.dns_update_record(name3, txt3)
@@ -1566,7 +1570,7 @@ class TestZones(DNSTest):
         self.assertEqual(len(recs), 1)
         self.assertEqual(recs[0].wType, dnsp.DNS_TYPE_TOMBSTONE)
         records = self.ldap_get_records(name)
-        self.assertTrue("dNSTombstoned" in records[0])
+        self.assertIn("dNSTombstoned", records[0])
         self.assertEqual(records[0]["dNSTombstoned"][0], b"TRUE")
 
         recs = self.ldap_get_dns_records(name2)
@@ -1585,14 +1589,14 @@ class TestZones(DNSTest):
         self.assertEqual(len(recs), 1)
         self.assertEqual(recs[0].wType, dnsp.DNS_TYPE_TOMBSTONE)
         records = self.ldap_get_records(name4)
-        self.assertTrue("dNSTombstoned" in records[0])
+        self.assertIn("dNSTombstoned", records[0])
         self.assertEqual(records[0]["dNSTombstoned"][0], b"TRUE")
 
         recs = self.ldap_get_dns_records(name5)
         self.assertEqual(len(recs), 1)
         self.assertEqual(recs[0].wType, dnsp.DNS_TYPE_TOMBSTONE)
         records = self.ldap_get_records(name5)
-        self.assertTrue("dNSTombstoned" in records[0])
+        self.assertIn("dNSTombstoned", records[0])
         self.assertEqual(records[0]["dNSTombstoned"][0], b"TRUE")
 
         for make_it_work in [False, True]:
@@ -1747,12 +1751,12 @@ class TestZones(DNSTest):
     def test_rpc_zone_update_while_dnsProperty_zero_length(self):
         self.create_zone(self.zone)
         self.set_dnsProperty_zero_length(dnsp.DSPROPERTY_ZONE_ALLOW_UPDATE)
-        self.set_params(zone=self.zone, AllowUpdate=dnsp.DNS_ZONE_UPDATE_SECURE)
+        self.set_params(AllowUpdate=dnsp.DNS_ZONE_UPDATE_SECURE)
 
     def test_rpc_zone_update_while_other_dnsProperty_zero_length(self):
         self.create_zone(self.zone)
         self.set_dnsProperty_zero_length(dnsp.DSPROPERTY_ZONE_MASTER_SERVERS_DA)
-        self.set_params(zone=self.zone, AllowUpdate=dnsp.DNS_ZONE_UPDATE_SECURE)
+        self.set_params(AllowUpdate=dnsp.DNS_ZONE_UPDATE_SECURE)
 
 class TestRPCRoundtrip(DNSTest):
     def setUp(self):
diff --git a/python/samba/tests/dsdb_dns.py b/python/samba/tests/dsdb_dns.py
new file mode 100644
index 00000000000..8c7fc343278
--- /dev/null
+++ b/python/samba/tests/dsdb_dns.py
@@ -0,0 +1,86 @@
+# Unix SMB/CIFS implementation. Tests for dsdb_dns module
+# Copyright © Catalyst IT 2021
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+from samba.tests import TestCase
+from samba import dsdb_dns
+import time
+
+
+def unix2nttime(t):
+    # here we reimplement unix_to_nt_time from lib/util/time.c
+    if t == -1:
+        return t
+    if t == (1 << 63) - 1:
+        return (1 << 63) - 1
+    if t == 0:
+        return 0
+    t += 11644473600
+    t *= 1e7
+    return int(t)
+
+
+def unix2dns_timestamp(t):
+    nt = unix2nttime(t)
+    if nt < 0:
+        # because NTTIME is a uint64_t.
+        nt += 1 << 64
+    return nt // int(3.6e10)
+
+
+def timestamp2nttime(ts):
+    nt = ts * int(3.6e10)
+    if nt >= 1 << 63:
+        raise OverflowError("nt time won't fit this")
+    return nt
+
+
+class DsdbDnsTestCase(TestCase):
+    def test_unix_to_dns_timestamp(self):
+        unixtimes = [1616829393,
+                     1,
+                     0,
+                     -1,
+                     1 << 31 - 1]
+
+        for t in unixtimes:
+            expected = unix2dns_timestamp(t)
+            result = dsdb_dns.unix_to_dns_timestamp(t)
+            self.assertEqual(result, expected)
+
+    def test_dns_timestamp_to_nt_time(self):
+        timestamps = [16168393,
+                      1,
+                      0,
+                      (1 << 32) - 1,
+                      (1 << 63) - 1,
+                      int((1 << 63) / 3.6e10),
+                      int((1 << 63) / 3.6e10) + 1, # overflows
+                      ]
+
+        for t in timestamps:
+            overflows = False
+            try:
+                expected = timestamp2nttime(t)
+            except OverflowError:
+                overflows = True
+            try:
+                result = dsdb_dns.dns_timestamp_to_nt_time(t)
+            except ValueError:
+                self.assertTrue(overflows, f"timestamp {t} should not overflow")
+                continue
+            self.assertFalse(overflows, f"timestamp {t} should overflow")
+
+            self.assertEqual(result, expected)
diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c
index 687313b0a78..6f729f46561 100644
--- a/source4/dns_server/dlz_bind9.c
+++ b/source4/dns_server/dlz_bind9.c
@@ -1908,7 +1908,6 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo
 	uint16_t num_recs = 0;
 	uint16_t first = 0;
 	uint16_t i;
-	NTTIME t;
 	WERROR werr;
 
 	if (state->transaction_token != (void*)version) {
@@ -1993,10 +1992,7 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo
 		if (dns_name_is_static(recs, num_recs)) {
 			rec->dwTimeStamp = 0;
 		} else {
-			unix_to_nt_time(&t, time(NULL));
-			t /= 10 * 1000 * 1000; /* convert to seconds */
-			t /= 3600;	     /* convert to hours */
-			rec->dwTimeStamp = (uint32_t)t;
+			rec->dwTimeStamp = unix_to_dns_timestamp(time(NULL));
 		}
 	}
 
diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c
index 529ee7894a3..d1e7825bf07 100644
--- a/source4/dns_server/dns_update.c
+++ b/source4/dns_server/dns_update.c
@@ -302,7 +302,6 @@ static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
 			     bool name_is_static)
 {
 	enum ndr_err_code ndr_err;
-	NTTIME t;
 
 	if (rrec->rr_type == DNS_QTYPE_ALL) {
 		return DNS_ERR(FORMAT_ERROR);
@@ -316,10 +315,7 @@ static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
 	if (name_is_static) {
 		r->dwTimeStamp = 0;
 	} else {
-		unix_to_nt_time(&t, time(NULL));
-		t /= 10 * 1000 * 1000;
-		t /= 3600;
-		r->dwTimeStamp = t;
+		r->dwTimeStamp = unix_to_dns_timestamp(time(NULL));
 	}
 
 	/* If we get QCLASS_ANY, we're done here */
diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c
index bcb0d087faf..7bd6e4f64bd 100644
--- a/source4/dns_server/dnsserver_common.c
+++ b/source4/dns_server/dnsserver_common.c
@@ -214,7 +214,7 @@ WERROR dns_common_lookup(struct ldb_context *samdb,
 				 * a tombstone, this will be used
 				 * in dns_common_replace()
 				 */
-				.data.timestamp = 1,
+				.data.EntombedTime = 1,
 			};
 
 			*tombstoned = true;
@@ -941,7 +941,7 @@ WERROR dns_common_replace(struct ldb_context *samdb,
 	bool become_tombstoned = false;
 	struct ldb_dn *zone_dn = NULL;
 	struct dnsserver_zoneinfo *zoneinfo = NULL;
-	NTTIME t;
+	uint32_t t;
 
 	msg = ldb_msg_new(mem_ctx);
 	W_ERROR_HAVE_NO_MEMORY(msg);
@@ -989,12 +989,12 @@ WERROR dns_common_replace(struct ldb_context *samdb,
 	 * which might be used for the tombstone marker
 	 */
 	el->values = talloc_zero_array(el, struct ldb_val, MAX(1, rec_count));
-	if (rec_count > 0) {
-		if (el->values == NULL) {
-			werr = WERR_NOT_ENOUGH_MEMORY;
-			goto exit;
-		}
+	if (el->values == NULL) {
+		werr = WERR_NOT_ENOUGH_MEMORY;
+		goto exit;
+	}
 
+	if (rec_count > 1) {
 		/*
 		 * We store a sorted list with the high wType values first
 		 * that's what windows does. It also simplifies the
@@ -1008,16 +1008,14 @@ WERROR dns_common_replace(struct ldb_context *samdb,
 		enum ndr_err_code ndr_err;
 
 		if (records[i].wType == DNS_TYPE_TOMBSTONE) {
-			if (records[i].data.timestamp != 0) {
+			if (records[i].data.EntombedTime != 0) {
 				was_tombstoned = true;
 			}
 			continue;
 		}
 
 		if (zoneinfo->fAging == 1 && records[i].dwTimeStamp != 0) {
-			unix_to_nt_time(&t, time(NULL));
-			t /= 10 * 1000 * 1000;
-			t /= 3600;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list