mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
df60fe15b3
not netcmd.dns.data_to_dns_record, which is a UI function. The only practical difference is it will raise DNSParseError, not CommandError. Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andreas Schneider <asn@samba.org>
337 lines
13 KiB
Python
337 lines
13 KiB
Python
# Unix SMB/CIFS implementation.
|
|
# Copyright (C) Andrew Bartlett 2007
|
|
#
|
|
# 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 sys
|
|
from samba import credentials
|
|
from samba.dcerpc import dns, dnsserver
|
|
from samba.dnsserver import record_from_string
|
|
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
|
|
|
|
parser = optparse.OptionParser(
|
|
"dns_wildcard.py <server name> <server ip> [options]")
|
|
sambaopts = options.SambaOptions(parser)
|
|
parser.add_option_group(sambaopts)
|
|
|
|
# This timeout only has relevance when testing against Windows
|
|
# Format errors tend to return patchy responses, so a timeout is needed.
|
|
parser.add_option("--timeout", type="int", dest="timeout",
|
|
help="Specify timeout for DNS requests")
|
|
|
|
# To run against Windows
|
|
# python python/samba/tests/dns_wildcard.py computer_name ip
|
|
# -U"Administrator%admin_password"
|
|
# --realm=Domain_name
|
|
# --timeout 10
|
|
#
|
|
|
|
# use command line creds if available
|
|
credopts = options.CredentialsOptions(parser)
|
|
parser.add_option_group(credopts)
|
|
subunitopts = SubunitOptions(parser)
|
|
parser.add_option_group(subunitopts)
|
|
|
|
opts, args = parser.parse_args()
|
|
|
|
lp = sambaopts.get_loadparm()
|
|
creds = credopts.get_credentials(lp)
|
|
|
|
timeout = opts.timeout
|
|
|
|
if len(args) < 2:
|
|
parser.print_usage()
|
|
sys.exit(1)
|
|
|
|
server_name = args[0]
|
|
server_ip = args[1]
|
|
creds.set_krb_forwardable(credentials.NO_KRB_FORWARDABLE)
|
|
|
|
WILDCARD_IP = "1.1.1.1"
|
|
WILDCARD = "*.wildcardtest"
|
|
EXACT_IP = "1.1.1.2"
|
|
EXACT = "exact.wildcardtest"
|
|
LEVEL2_WILDCARD_IP = "1.1.1.3"
|
|
LEVEL2_WILDCARD = "*.level2.wildcardtest"
|
|
LEVEL2_EXACT_IP = "1.1.1.4"
|
|
LEVEL2_EXACT = "exact.level2.wildcardtest"
|
|
|
|
|
|
class TestWildCardQueries(DNSTest):
|
|
|
|
def setUp(self):
|
|
super(TestWildCardQueries, self).setUp()
|
|
global server, server_ip, lp, creds, timeout
|
|
self.server = server_name
|
|
self.server_ip = server_ip
|
|
self.lp = lp
|
|
self.creds = creds
|
|
self.timeout = timeout
|
|
|
|
# Create the dns records
|
|
self.dns_records = [(dns.DNS_QTYPE_A,
|
|
"%s.%s" % (WILDCARD, self.get_dns_domain()),
|
|
WILDCARD_IP),
|
|
(dns.DNS_QTYPE_A,
|
|
"%s.%s" % (EXACT, self.get_dns_domain()),
|
|
EXACT_IP),
|
|
(dns.DNS_QTYPE_A,
|
|
("%s.%s" % (
|
|
LEVEL2_WILDCARD,
|
|
self.get_dns_domain())),
|
|
LEVEL2_WILDCARD_IP),
|
|
(dns.DNS_QTYPE_A,
|
|
("%s.%s" % (
|
|
LEVEL2_EXACT,
|
|
self.get_dns_domain())),
|
|
LEVEL2_EXACT_IP)]
|
|
|
|
c = self.dns_connect()
|
|
for (typ, name, data) in self.dns_records:
|
|
self.add_record(c, typ, name, data)
|
|
|
|
def tearDown(self):
|
|
c = self.dns_connect()
|
|
for (typ, name, data) in self.dns_records:
|
|
self.delete_record(c, typ, name, data)
|
|
|
|
def dns_connect(self):
|
|
binding_str = "ncacn_ip_tcp:%s[sign]" % self.server_ip
|
|
return dnsserver.dnsserver(binding_str, self.lp, self.creds)
|
|
|
|
def delete_record(self, dns_conn, typ, name, data):
|
|
|
|
rec = record_from_string(typ, data)
|
|
del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
|
|
del_rec_buf.rec = rec
|
|
|
|
try:
|
|
dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
|
|
0,
|
|
self.server,
|
|
self.get_dns_domain(),
|
|
name,
|
|
None,
|
|
del_rec_buf)
|
|
except WERRORError as e:
|
|
# Ignore record does not exist errors
|
|
if e.args[0] != werror.WERR_DNS_ERROR_NAME_DOES_NOT_EXIST:
|
|
raise e
|
|
|
|
def add_record(self, dns_conn, typ, name, data):
|
|
|
|
rec = record_from_string(typ, data)
|
|
add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
|
|
add_rec_buf.rec = rec
|
|
try:
|
|
dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
|
|
0,
|
|
self.server,
|
|
self.get_dns_domain(),
|
|
name,
|
|
add_rec_buf,
|
|
None)
|
|
except WERRORError as e:
|
|
raise e
|
|
|
|
def test_one_a_query_match_wildcard(self):
|
|
"Query an A record, should match the wildcard entry"
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "miss.wildcardtest.%s" % self.get_dns_domain()
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, WILDCARD_IP)
|
|
|
|
def test_one_a_query_match_wildcard_2_labels(self):
|
|
""" Query an A record, should match the wild card entry
|
|
have two labels to the left of the wild card target.
|
|
"""
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "label2.label1.wildcardtest.%s" % self.get_dns_domain()
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, WILDCARD_IP)
|
|
|
|
def test_one_a_query_wildcard_entry(self):
|
|
"Query the wildcard entry"
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "%s.%s" % (WILDCARD, self.get_dns_domain())
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, WILDCARD_IP)
|
|
|
|
def test_one_a_query_exact_match(self):
|
|
"""Query an entry that matches the wild card but has an exact match as
|
|
well.
|
|
"""
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "%s.%s" % (EXACT, self.get_dns_domain())
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, EXACT_IP)
|
|
|
|
def test_one_a_query_match_wildcard_l2(self):
|
|
"Query an A record, should match the level 2 wildcard entry"
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "miss.level2.wildcardtest.%s" % self.get_dns_domain()
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP)
|
|
|
|
def test_one_a_query_match_wildcard_l2_2_labels(self):
|
|
"""Query an A record, should match the level 2 wild card entry
|
|
have two labels to the left of the wild card target
|
|
"""
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "label1.label2.level2.wildcardtest.%s" % self.get_dns_domain()
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP)
|
|
|
|
def test_one_a_query_exact_match_l2(self):
|
|
"""Query an entry that matches the wild card but has an exact match as
|
|
well.
|
|
"""
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "%s.%s" % (LEVEL2_EXACT, self.get_dns_domain())
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, LEVEL2_EXACT_IP)
|
|
|
|
def test_one_a_query_wildcard_entry_l2(self):
|
|
"Query the level 2 wildcard entry"
|
|
|
|
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
questions = []
|
|
|
|
# Check the record
|
|
name = "%s.%s" % (LEVEL2_WILDCARD, self.get_dns_domain())
|
|
q = self.make_name_question(name,
|
|
dns.DNS_QTYPE_A,
|
|
dns.DNS_QCLASS_IN)
|
|
questions.append(q)
|
|
|
|
self.finish_name_packet(p, questions)
|
|
(response, response_packet) =\
|
|
self.dns_transaction_udp(p, host=self.server_ip)
|
|
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
|
|
self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
|
|
self.assertEqual(response.ancount, 1)
|
|
self.assertEqual(response.answers[0].rr_type, dns.DNS_QTYPE_A)
|
|
self.assertEqual(response.answers[0].rdata, LEVEL2_WILDCARD_IP)
|
|
|
|
|
|
TestProgram(module=__name__, opts=subunitopts)
|