1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

pydns: expose dns timestamp utils to python, and test

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Douglas Bagnall 2021-03-27 09:09:56 +00:00 committed by Jeremy Allison
parent 2b9279bd31
commit 146c23fb7d
3 changed files with 136 additions and 0 deletions

View File

@ -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)

View File

@ -325,6 +325,48 @@ static PyObject *py_dsdb_dns_replace_by_dn(PyObject *self, PyObject *args)
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", &lt)) {
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", &timestamp)) {
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),
@ -336,6 +378,12 @@ static PyMethodDef py_dsdb_dns_methods[] = {
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}
};

View File

@ -823,6 +823,8 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests",
'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]: