# Unix SMB/CIFS implementation.
# Copyright (C) Andrew Bartlett <abartlet@catalyst.net.nz>
#
# 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/>.
#
import os
import ldb
import re
from samba.ndr import ndr_unpack, ndr_pack
from samba.dcerpc import dnsp
from samba.tests.samba_tool.base import SambaToolCmdTest
import time
from samba import dsdb_dns
class DnsCmdTestCase(SambaToolCmdTest):
def setUp(self):
super().setUp()
self.dburl = "ldap://%s" % os.environ["SERVER"]
self.creds_string = "-U%s%%%s" % (os.environ["DC_USERNAME"],
os.environ["DC_PASSWORD"])
self.samdb = self.getSamDB("-H", self.dburl, self.creds_string)
self.config_dn = str(self.samdb.get_config_basedn())
self.testip = "192.168.0.193"
self.testip2 = "192.168.0.194"
self.addCleanup(self.deleteZone)
self.addZone()
# Note: SOA types don't work (and shouldn't), as we only have one zone per DNS record.
good_dns = ["SAMDOM.EXAMPLE.COM",
"1.EXAMPLE.COM",
"%sEXAMPLE.COM" % ("1." * 100),
"EXAMPLE",
"!@#$%^&*()_",
"HIGH\xFFBYTE",
"@.EXAMPLE.COM",
"."]
bad_dns = ["...",
".EXAMPLE.COM",
".EXAMPLE.",
"",
"SAMDOM..EXAMPLE.COM"]
good_mx = ["SAMDOM.EXAMPLE.COM 65530",
"SAMDOM.EXAMPLE.COM 0"]
bad_mx = ["SAMDOM.EXAMPLE.COM -1",
"SAMDOM.EXAMPLE.COM",
" ",
"SAMDOM.EXAMPLE.COM 1 1",
"SAMDOM.EXAMPLE.COM SAMDOM.EXAMPLE.COM"]
good_srv = ["SAMDOM.EXAMPLE.COM 65530 65530 65530",
"SAMDOM.EXAMPLE.COM 1 1 1"]
bad_srv = ["SAMDOM.EXAMPLE.COM 0 65536 0",
"SAMDOM.EXAMPLE.COM 0 0 65536",
"SAMDOM.EXAMPLE.COM 65536 0 0"]
for bad_dn in bad_dns:
bad_mx.append("%s 1" % bad_dn)
bad_srv.append("%s 0 0 0" % bad_dn)
for good_dn in good_dns:
good_mx.append("%s 1" % good_dn)
good_srv.append("%s 0 0 0" % good_dn)
self.good_records = {
"A":["192.168.0.1", "255.255.255.255"],
"AAAA":["1234:5678:9ABC:DEF0:0000:0000:0000:0000",
"0000:0000:0000:0000:0000:0000:0000:0000",
"1234:5678:9ABC:DEF0:1234:5678:9ABC:DEF0",
"1234:1234:1234::",
"1234:5678:9ABC:DEF0::",
"0000:0000::0000",
"1234::5678:9ABC:0000:0000:0000:0000",
"::1",
"::",
"1:1:1:1:1:1:1:1"],
"PTR": good_dns,
"CNAME": good_dns,
"NS": good_dns,
"MX": good_mx,
"SRV": good_srv,
"TXT": ["text", "", "@#!", "\n"]
}
self.bad_records = {
"A":["192.168.0.500",
"255.255.255.255/32"],
"AAAA":["GGGG:1234:5678:9ABC:0000:0000:0000:0000",
"0000:0000:0000:0000:0000:0000:0000:0000/1",
"AAAA:AAAA:AAAA:AAAA:G000:0000:0000:1234",
"1234:5678:9ABC:DEF0:1234:5678:9ABC:DEF0:1234",
"1234:5678:9ABC:DEF0:1234:5678:9ABC",
"1111::1111::1111"],
"PTR": bad_dns,
"CNAME": bad_dns,
"NS": bad_dns,
"MX": bad_mx,
"SRV": bad_srv
}
def resetZone(self):
self.deleteZone()
self.addZone()
def addZone(self):
self.zone = "zone"
result, out, err = self.runsubcmd("dns",
"zonecreate",
os.environ["SERVER"],
self.zone,
self.creds_string)
self.assertCmdSuccess(result, out, err)
def deleteZone(self):
result, out, err = self.runsubcmd("dns",
"zonedelete",
os.environ["SERVER"],
self.zone,
self.creds_string)
self.assertCmdSuccess(result, out, err)
def get_all_records(self, zone_name):
zone_dn = (f"DC={zone_name},CN=MicrosoftDNS,DC=DomainDNSZones,"
f"{self.samdb.get_default_basedn()}")
expression = "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))"
nodes = self.samdb.search(base=zone_dn, scope=ldb.SCOPE_SUBTREE,
expression=expression,
attrs=["dnsRecord", "name"])
record_map = {}
for node in nodes:
name = node["name"][0].decode()
record_map[name] = list(node["dnsRecord"])
return record_map
def get_record_from_db(self, zone_name, record_name):
zones = self.samdb.search(base="DC=DomainDnsZones,%s"
% self.samdb.get_default_basedn(),
scope=ldb.SCOPE_SUBTREE,
expression="(objectClass=dnsZone)",
attrs=["cn"])
for zone in zones:
if zone_name in str(zone.dn):
zone_dn = zone.dn
break
records = self.samdb.search(base=zone_dn, scope=ldb.SCOPE_SUBTREE,
expression="(objectClass=dnsNode)",
attrs=["dnsRecord"])
for old_packed_record in records:
if record_name in str(old_packed_record.dn):
return (old_packed_
|