--- /dev/null
+# 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)
Py_RETURN_NONE;
}
+static PyObject *py_dsdb_dns_unix_to_dns_timestamp(PyObject *self, PyObject *args)
+{
+ uint32_t timestamp;
+ time_t t;
+ long long lt;
+
+ if (!PyArg_ParseTuple(args, "L", <)) {
+ return NULL;
+ }
+
+ t = lt;
+ if (t != lt) {
+ /* time_t is presumably 32 bit here */
+ PyErr_SetString(PyExc_ValueError, "Time out of range");
+ return NULL;
+ }
+ timestamp = unix_to_dns_timestamp(t);
+ return Py_BuildValue("k", (unsigned long) timestamp);
+}
+
+static PyObject *py_dsdb_dns_timestamp_to_nt_time(PyObject *self, PyObject *args)
+{
+ unsigned long long timestamp;
+ NTSTATUS status;
+ NTTIME nt;
+ if (!PyArg_ParseTuple(args, "K", ×tamp)) {
+ return NULL;
+ }
+
+ if (timestamp > UINT32_MAX || timestamp < 0) {
+ PyErr_SetString(PyExc_ValueError, "Time out of range");
+ return NULL;
+ }
+ status = dns_timestamp_to_nt_time(&nt, (uint32_t)timestamp);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_SetString(PyExc_ValueError, "Time out of range");
+ return NULL;
+ }
+ return Py_BuildValue("L", (long long) nt);
+}
+
+
static PyMethodDef py_dsdb_dns_methods[] = {
{ "lookup", PY_DISCARD_FUNC_SIG(PyCFunction, py_dsdb_dns_lookup),
METH_VARARGS, "Replace the DNS database entries for a LDB DN"},
{ "extract", (PyCFunction)py_dsdb_dns_extract,
METH_VARARGS, "Return the DNS database entry as a python structure from an Ldb.MessageElement of type dnsRecord"},
+ { "unix_to_dns_timestamp", (PyCFunction)py_dsdb_dns_unix_to_dns_timestamp,
+ METH_VARARGS,
+ "Convert a time.time() value to a dns timestamp (hours since 1601)"},
+ { "dns_timestamp_to_nt_time", (PyCFunction)py_dsdb_dns_timestamp_to_nt_time,
+ METH_VARARGS,
+ "Convert a dns timestamp to an NTTIME value"},
{0}
};
'SERVICE_PASSWORD':'$PASSWORD',
'FOR_USER':'$USERNAME'})
+planoldpythontestsuite("ad_dc_default", "samba.tests.dsdb_dns")
+
planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests")
for env in ["ad_dc", smbv1_disabled_testenv]: