[PATCH] Some selftest tidy-ups to centralize IP address logic

Tim Beale timbeale at catalyst.net.nz
Tue Mar 5 23:09:46 UTC 2019


This tries to tidy up and centralize the assumptions that selftest makes
on what IP addresses the testenvs have. It also moves the
IP-to-DNS-realm mapping out of dns_hub and into Samba.pm, so it's all in
one place. Hopefully this will make it easier to keep the testenv realms
and IPs in sync longer-term.

CI pass: https://gitlab.com/catalyst-samba/samba/pipelines/50458108

Review appreciated. Thanks.

-------------- next part --------------
From 02e282b840af31528b48c22600184bb1953adc84 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Tue, 19 Feb 2019 16:18:11 +1300
Subject: [PATCH 01/10] selftest: Add helper functions to get IP addresses

Let's centralize these assumptions in one place.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba.pm  | 16 ++++++++++++++++
 selftest/target/Samba3.pm |  4 ++--
 selftest/target/Samba4.pm | 18 +++++++++---------
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index d74a443..8e8723c 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -446,6 +446,22 @@ sub get_interface($)
     return $interfaces{$netbiosname};
 }
 
+sub get_ipv4_addr
+{
+	(my $hostname) = @_;
+	my $swiface = Samba::get_interface($hostname);
+
+	return "127.0.0.$swiface";
+}
+
+sub get_ipv6_addr
+{
+	(my $hostname) = @_;
+	my $swiface = Samba::get_interface($hostname);
+
+	return sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
+}
+
 sub cleanup_child($$)
 {
     my ($pid, $name) = @_;
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 19a2d2f..e176e31 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1459,8 +1459,8 @@ sub provision($$$$$$$$$)
 	my $swiface = Samba::get_interface($server);
 	my %ret = ();
 	my %createuser_env = ();
-	my $server_ip = "127.0.0.$swiface";
-	my $server_ipv6 = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
+	my $server_ip = Samba::get_ipv4_addr($server);
+	my $server_ipv6 = Samba::get_ipv6_addr($server);
 
 	my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
 	chomp $unix_name;
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 8b62c5e..bbe3ece 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -394,8 +394,8 @@ sub setup_dns_hub_internal($$$)
 	$env->{hostname} = $hostname;
 	$env->{swiface} = $swiface;
 
-	$env->{ipv4} = "127.0.0.$swiface";
-	$env->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
+	$env->{ipv4} = Samba::get_ipv4_addr($hostname);
+	$env->{ipv6} = Samba::get_ipv6_addr($hostname);
 
 	$env->{DNS_HUB_LOG} = "$prefix_abs/dns_hub.log";
 
@@ -673,8 +673,8 @@ sub provision_raw_prepare($$$$$$$$$$$$)
 
 	$ctx->{tlsdir} = "$ctx->{privatedir}/tls";
 
-	$ctx->{ipv4} = "127.0.0.$swiface";
-	$ctx->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
+	$ctx->{ipv4} = Samba::get_ipv4_addr($hostname);
+	$ctx->{ipv6} = Samba::get_ipv6_addr($hostname);
 	$ctx->{interfaces} = "$ctx->{ipv4}/8 $ctx->{ipv6}/64";
 
 	push(@{$ctx->{directories}}, $ctx->{privatedir});
@@ -1722,14 +1722,14 @@ sub provision_fl2000dc($$)
 sub provision_fl2003dc($$$)
 {
 	my ($self, $prefix, $dcvars) = @_;
-	my $swiface1 = Samba::get_interface("fakednsforwarder1");
-	my $swiface2 = Samba::get_interface("fakednsforwarder2");
+	my $ip_addr1 = Samba::get_ipv4_addr("fakednsforwarder1");
+	my $ip_addr2 = Samba::get_ipv4_addr("fakednsforwarder2");
 
 	print "PROVISIONING DC WITH FOREST LEVEL 2003...\n";
 	my $extra_conf_options = "allow dns updates = nonsecure and secure
 	dcesrv:header signing = no
 	dcesrv:max auth states = 0
-	dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2";
+	dns forwarder = $ip_addr1 $ip_addr2";
 	my $extra_provision_options = ["--use-ntvfs"];
 	my $ret = $self->provision($prefix,
 				   "domain controller",
@@ -1747,8 +1747,8 @@ sub provision_fl2003dc($$$)
 		return undef;
 	}
 
-	$ret->{DNS_FORWARDER1} = "127.0.0.$swiface1";
-	$ret->{DNS_FORWARDER2} = "127.0.0.$swiface2";
+	$ret->{DNS_FORWARDER1} = $ip_addr1;
+	$ret->{DNS_FORWARDER2} = $ip_addr2;
 
 	my @samba_tool_options;
 	push (@samba_tool_options, Samba::bindir_path($self, "samba-tool"));
-- 
2.7.4


From d78fc7914aa52679a418ee3b118198742ab6dba4 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 13 Feb 2019 14:21:16 +1300
Subject: [PATCH 02/10] selftest: dns_hub doesn't need to store $swiface

dns_hub doesn't need to store $ctx->{swiface}. Other testenvs store this
and export it as SOCKET_WRAPPER_DEFAULT_IFACE (i.e. for the tests to
use), but dns_hub doesn't need to do this.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba4.pm | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index bbe3ece..84b7fa9 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -385,14 +385,11 @@ sub setup_dns_hub_internal($$$)
 		warn("Unable to clean up");
 	}
 
-	my $swiface = Samba::get_interface($hostname);
-
 	my $env = undef;
 	$env->{prefix} = $prefix;
 	$env->{prefix_abs} = $prefix_abs;
 
 	$env->{hostname} = $hostname;
-	$env->{swiface} = $swiface;
 
 	$env->{ipv4} = Samba::get_ipv4_addr($hostname);
 	$env->{ipv6} = Samba::get_ipv6_addr($hostname);
@@ -420,6 +417,7 @@ sub setup_dns_hub_internal($$$)
 		open STDOUT, "| tee $env->{DNS_HUB_LOG} 1>&2";
 		open STDERR, '>&STDOUT';
 
+		my $swiface = Samba::get_interface($hostname);
 		SocketWrapper::set_default_iface($swiface);
 		my $pcap_file = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/env-$hostname$.pcap";
 		SocketWrapper::setup_pcap($pcap_file);
-- 
2.7.4


From 695778405b3fa87ae02de47f592abae39af73803 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu, 14 Feb 2019 14:37:16 +1300
Subject: [PATCH 03/10] selftest: Avoid hard-coding client IP address

We implicitly assume the client IP used by selftest is always
127.0.0.11. Add an iface entry for the client to make this a little more
explicit.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba.pm  | 1 +
 selftest/target/Samba4.pm | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 8e8723c..fdba455 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -400,6 +400,7 @@ sub get_interface($)
     $interfaces{"localnt4dc9"} = 9;
 
     # 11-16 used by selftest.pl for client interfaces
+    $interfaces{"client"} = 11;
 
     $interfaces{"addc_no_nss"} = 17;
     $interfaces{"addc_no_ntlm"} = 18;
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 84b7fa9..de7307d 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -333,12 +333,13 @@ sub write_ldb_file($$$)
 sub add_wins_config($$)
 {
 	my ($self, $privatedir) = @_;
+	my $client_ip = Samba::get_ipv4_addr("client");
 
 	return $self->write_ldb_file("$privatedir/wins_config.ldb", "
 dn: name=TORTURE_11,CN=PARTNERS
 objectClass: wreplPartner
 name: TORTURE_11
-address: 127.0.0.11
+address: $client_ip
 pullInterval: 0
 pushChangeCount: 0
 type: 0x3
-- 
2.7.4


From 1d85051d9376239b82c9cdfda854fef15f7275a2 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu, 14 Feb 2019 16:19:50 +1300
Subject: [PATCH 04/10] selftest: Cleanup Samba.pm iface mapping

It looks a bit cleaner if we declare the hash-map in one go, rather than
adding each entry one at a time. Also added a comment explaining what
the hash-map is for, and fixed up tab vs spaces inconsistencies.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba.pm | 121 +++++++++++++++++++++++++----------------------
 1 file changed, 64 insertions(+), 57 deletions(-)

diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index fdba455..98aac65 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -387,64 +387,71 @@ sub mk_mitkdc_conf($$)
 
 sub get_interface($)
 {
-    my ($netbiosname) = @_;
-    $netbiosname = lc($netbiosname);
-
-    my %interfaces = ();
-    $interfaces{"localnt4dc2"} = 3;
-    $interfaces{"localnt4member3"} = 4;
-    $interfaces{"localshare4"} = 5;
-
-    $interfaces{"localktest6"} = 7;
-    $interfaces{"maptoguest"} = 8;
-    $interfaces{"localnt4dc9"} = 9;
-
-    # 11-16 used by selftest.pl for client interfaces
-    $interfaces{"client"} = 11;
-
-    $interfaces{"addc_no_nss"} = 17;
-    $interfaces{"addc_no_ntlm"} = 18;
-    $interfaces{"idmapadmember"} = 19;
-    $interfaces{"idmapridmember"} = 20;
-    $interfaces{"localdc"} = 21;
-    $interfaces{"localvampiredc"} = 22;
-    $interfaces{"s4member"} = 23;
-    $interfaces{"localrpcproxy"} = 24;
-    $interfaces{"dc5"} = 25;
-    $interfaces{"dc6"} = 26;
-    $interfaces{"dc7"} = 27;
-    $interfaces{"rodc"} = 28;
-    $interfaces{"localadmember"} = 29;
-    $interfaces{"addc"} = 30;
-    $interfaces{"localsubdc"} = 31;
-    $interfaces{"chgdcpass"} = 32;
-    $interfaces{"promotedvdc"} = 33;
-    $interfaces{"rfc2307member"} = 34;
-    $interfaces{"fileserver"} = 35;
-    $interfaces{"fakednsforwarder1"} = 36;
-    $interfaces{"fakednsforwarder2"} = 37;
-    $interfaces{"s4member_dflt"} = 38;
-    $interfaces{"vampire2000dc"} = 39;
-    $interfaces{"backupfromdc"} = 40;
-    $interfaces{"restoredc"} = 41;
-    $interfaces{"renamedc"} = 42;
-    $interfaces{"labdc"} = 43;
-    $interfaces{"offlinebackupdc"} = 44;
-    $interfaces{"customdc"} = 45;
-    $interfaces{"prockilldc"} = 46;
-    $interfaces{"proclimitdc"} = 47;
-
-    $interfaces{"rootdnsforwarder"} = 64;
-
-    # update lib/socket_wrapper/socket_wrapper.c
-    #  #define MAX_WRAPPED_INTERFACES 64
-    # if you wish to have more than 64 interfaces
-
-    if (not defined($interfaces{$netbiosname})) {
-	die();
-    }
+	my ($netbiosname) = @_;
+	$netbiosname = lc($netbiosname);
+
+	# this maps the SOCKET_WRAPPER_DEFAULT_IFACE value for each possible
+	# testenv to the DC's NETBIOS name. This value also corresponds to last
+	# digit of the DC's IP address. Note that the NETBIOS name may differ from
+	# the testenv name.
+	# Note that when adding a DC with a new realm, also update dns_hub.py.
+	my %testenv_iface_mapping = (
+		localnt4dc2       => 3,
+		localnt4member3   => 4,
+		localshare4       => 5,
+		# 6 is spare
+		localktest6       => 7,
+		maptoguest        => 8,
+		localnt4dc9       => 9,
+		# 10 is spare
+
+		# 11-16 used by selftest.pl for client interfaces
+		client            => 11,
+
+		addc_no_nss       => 17,
+		addc_no_ntlm      => 18,
+		idmapadmember     => 19,
+		idmapridmember    => 20,
+		localdc           => 21,
+		localvampiredc    => 22,
+		s4member          => 23,
+		localrpcproxy     => 24,
+		dc5               => 25,
+		dc6               => 26,
+		dc7               => 27,
+		rodc              => 28,
+		localadmember     => 29,
+		addc              => 30,
+		localsubdc        => 31,
+		chgdcpass         => 32,
+		promotedvdc       => 33,
+		rfc2307member     => 34,
+		fileserver        => 35,
+		fakednsforwarder1 => 36,
+		fakednsforwarder2 => 37,
+		s4member_dflt     => 38,
+		vampire2000dc     => 39,
+		backupfromdc      => 40,
+		restoredc         => 41,
+		renamedc          => 42,
+		labdc             => 43,
+		offlinebackupdc   => 44,
+		customdc          => 45,
+		prockilldc        => 46,
+		proclimitdc       => 47,
+
+		rootdnsforwarder  => 64,
+
+		# update lib/socket_wrapper/socket_wrapper.c
+		#  #define MAX_WRAPPED_INTERFACES 64
+		# if you wish to have more than 64 interfaces
+	);
+
+	if (not defined($testenv_iface_mapping{$netbiosname})) {
+		die();
+	}
 
-    return $interfaces{$netbiosname};
+	return $testenv_iface_mapping{$netbiosname};
 }
 
 sub get_ipv4_addr
-- 
2.7.4


From 8d3cdaad1eff196ca6cf6fed57d2425e074e8f82 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu, 14 Feb 2019 15:38:54 +1300
Subject: [PATCH 05/10] selftest: Try to tie dns_hub IP mapping to Samba.pm
 better

dns_hub.py maps the testenv realm to an IP and Samba.pm maps the testenv
NetBIOS name to an IP. We need to keep the two places consistent, as we
add or remove testenvs.

This patch changes dns_hub.py so that it uses a similar hashmap to
Samba.pm. We now have a hashmap with the same name in 2 different
places, so hopefully that's easier to tie them together and keep them in
sync.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/dns_hub.py | 53 +++++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index e440e72..14a58b1 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -83,30 +83,35 @@ class DnsHandler(sserver.BaseRequestHandler):
             return 'torture'
         if lname.endswith('torturedom.samba.example.com'):
             return 'torture'
-        if lname.endswith('adnonssdom.samba.example.com'):
-            return '127.0.0.17'
-        if lname.endswith('adnontlmdom.samba.example.com'):
-            return '127.0.0.18'
-        if lname.endswith('samba2000.example.com'):
-            return '127.0.0.25'
-        if lname.endswith('samba2003.example.com'):
-            return '127.0.0.26'
-        if lname.endswith('samba2008r2.example.com'):
-            return '127.0.0.27'
-        if lname.endswith('addom.samba.example.com'):
-            return '127.0.0.30'
-        if lname.endswith('sub.samba.example.com'):
-            return '127.0.0.31'
-        if lname.endswith('chgdcpassword.samba.example.com'):
-            return '127.0.0.32'
-        if lname.endswith('backupdom.samba.example.com'):
-            return '127.0.0.40'
-        if lname.endswith('renamedom.samba.example.com'):
-            return '127.0.0.42'
-        if lname.endswith('labdom.samba.example.com'):
-            return '127.0.0.43'
-        if lname.endswith('samba.example.com'):
-            return '127.0.0.21'
+
+        # this maps the SOCKET_WRAPPER_DEFAULT_IFACE value (which is the
+        # last byte of the IP address) for the various testenv PDCs to the
+        # corresponding DNS realm.
+        # This should always match %testenv_iface_mapping in Samba.pm.
+        testenv_iface_mapping = {
+            'adnonssdom.samba.example.com': 17,     # addc_no_nss
+            'adnontlmdom.samba.example.com': 18,    # addc_no_ntlm
+            'samba2000.example.com': 25,            # dc5
+            'samba2003.example.com': 26,            # dc6
+            'samba2008r2.example.com': 27,          # dc7
+            'addom.samba.example.com': 30,          # addc
+            'sub.samba.example.com': 31,            # localsubdc
+            'chgdcpassword.samba.example.com': 32,  # chgdcpass
+            'backupdom.samba.example.com': 40,      # backupfromdc
+            'renamedom.samba.example.com': 42,      # renamedc
+            'labdom.samba.example.com': 43,         # labdc
+            'samba.example.com': 21,                # localdc
+        }
+
+        # sort the realms so we find the longest-match first
+        testenv_realms = sorted(testenv_iface_mapping.keys(), key=len)
+        testenv_realms.reverse()
+
+        for realm in testenv_realms:
+            if lname.endswith(realm):
+                iface = testenv_iface_mapping[realm]
+                return '127.0.0.' + str(iface)
+
         return None
 
     def handle(self):
-- 
2.7.4


From 4e4d04bbbfd74f28d3180743aac2ac412909eb80 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu, 14 Feb 2019 17:36:40 +1300
Subject: [PATCH 06/10] selftest: Split out dns_hub's testenv realm-to-IP logic

Add a separate helper function, as the realm-to-IPv4-addr logic is
fairly self-contained.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/dns_hub.py | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index 14a58b1..4450993 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -69,20 +69,8 @@ class DnsHandler(sserver.BaseRequestHandler):
                 s.close()
         return None
 
-    def forwarder(self, name):
-        lname = name.lower()
-
-        if lname.endswith('an-address-that-will-not-resolve'):
-            return 'ignore'
-        if lname.endswith('dsfsdfs'):
-            return 'fail'
-        if lname.endswith("torture1", 0, len(lname)-2):
-            # CATCH TORTURE100, TORTURE101, ...
-            return 'torture'
-        if lname.endswith('_none_.example.com'):
-            return 'torture'
-        if lname.endswith('torturedom.samba.example.com'):
-            return 'torture'
+    def get_pdc_ipv4_addr(self, lookup_name):
+        """Maps a DNS realm to the IPv4 address of the PDC for that testenv"""
 
         # this maps the SOCKET_WRAPPER_DEFAULT_IFACE value (which is the
         # last byte of the IP address) for the various testenv PDCs to the
@@ -108,12 +96,31 @@ class DnsHandler(sserver.BaseRequestHandler):
         testenv_realms.reverse()
 
         for realm in testenv_realms:
-            if lname.endswith(realm):
+            if lookup_name.endswith(realm):
                 iface = testenv_iface_mapping[realm]
                 return '127.0.0.' + str(iface)
 
         return None
 
+    def forwarder(self, name):
+        lname = name.lower()
+
+        # check for special cases used by tests (e.g. dns_forwarder.py)
+        if lname.endswith('an-address-that-will-not-resolve'):
+            return 'ignore'
+        if lname.endswith('dsfsdfs'):
+            return 'fail'
+        if lname.endswith("torture1", 0, len(lname)-2):
+            # CATCH TORTURE100, TORTURE101, ...
+            return 'torture'
+        if lname.endswith('_none_.example.com'):
+            return 'torture'
+        if lname.endswith('torturedom.samba.example.com'):
+            return 'torture'
+
+        # return the testenv PDC matching the realm being requested
+        return self.get_pdc_ipv4_addr(lname)
+
     def handle(self):
         start = time.monotonic()
         data, sock = self.request
-- 
2.7.4


From 6e43e3235aeffcb0cf421cc9e9662a153c873156 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 20 Feb 2019 16:09:54 +1300
Subject: [PATCH 07/10] selftest: Pass realm-to-IP mapping to dns_hub as an
 argument

Instead of storing hashmaps in 2 different files, we can just convert a
perl hashmap into a string, pass it to dns_hub, and convert it back into
a python dictionary.

The main reason for doing this is the IP-to-testenv mapping now all
lives in a single file (Samba.pm). All this logic is right next to each
other rather than being split across multiple files. Hopefully this will
make it easier to keep it up to date as we add new testenvs.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba.pm   | 34 +++++++++++++++++++++++++++++++++-
 selftest/target/Samba4.pm  |  1 +
 selftest/target/dns_hub.py | 26 ++++++++------------------
 3 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 98aac65..3f8a38f 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -385,6 +385,37 @@ sub mk_mitkdc_conf($$)
 	close(KDCCONF);
 }
 
+sub realm_to_ip_mappings
+{
+	# this maps the SOCKET_WRAPPER_DEFAULT_IFACE value (which is the
+	# last byte of the IP address) for the various testenv PDCs to the
+	# corresponding DNS realm.
+	# This should always match the values in get_interface()
+	my %testenv_iface_mapping = (
+		'adnonssdom.samba.example.com'    => 17,    # addc_no_nss
+		'adnontlmdom.samba.example.com'   => 18,    # addc_no_ntlm
+		'samba2000.example.com'           => 25,    # dc5
+		'samba2003.example.com'           => 26,    # dc6
+		'samba2008r2.example.com'         => 27,    # dc7
+		'addom.samba.example.com'         => 30,    # addc
+		'sub.samba.example.com'           => 31,    # localsubdc
+		'chgdcpassword.samba.example.com' => 32,    # chgdcpass
+		'backupdom.samba.example.com'     => 40,    # backupfromdc
+		'renamedom.samba.example.com'     => 42,    # renamedc
+		'labdom.samba.example.com'        => 43,    # labdc
+		'samba.example.com'               => 21,    # localdc
+	);
+
+	my @mapping = ();
+
+	# convert the hashmap to a list of key=value strings
+	while (my ($key, $val) = each(%testenv_iface_mapping)) {
+		push(@mapping, "$key=$val");
+	}
+	# return the mapping as a single comma-separated string
+	return join(',', @mapping);
+}
+
 sub get_interface($)
 {
 	my ($netbiosname) = @_;
@@ -394,7 +425,8 @@ sub get_interface($)
 	# testenv to the DC's NETBIOS name. This value also corresponds to last
 	# digit of the DC's IP address. Note that the NETBIOS name may differ from
 	# the testenv name.
-	# Note that when adding a DC with a new realm, also update dns_hub.py.
+	# Note that when adding a DC with a new realm, also update
+	# get_realm_ip_mappings() above.
 	my %testenv_iface_mapping = (
 		localnt4dc2       => 3,
 		localnt4member3   => 4,
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index de7307d..12f1a60 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -435,6 +435,7 @@ sub setup_dns_hub_internal($$$)
 		$ENV{MAKE_TEST_BINARY} = "$self->{srcdir}/selftest/target/dns_hub.py";
 		push (@args, "$self->{server_maxtime}");
 		push (@args, "$env->{ipv4}");
+		push (@args, Samba::realm_to_ip_mappings());
 		close($env->{STDIN_PIPE});
 		open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
 
diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index 4450993..b0e2a2b 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -72,24 +72,7 @@ class DnsHandler(sserver.BaseRequestHandler):
     def get_pdc_ipv4_addr(self, lookup_name):
         """Maps a DNS realm to the IPv4 address of the PDC for that testenv"""
 
-        # this maps the SOCKET_WRAPPER_DEFAULT_IFACE value (which is the
-        # last byte of the IP address) for the various testenv PDCs to the
-        # corresponding DNS realm.
-        # This should always match %testenv_iface_mapping in Samba.pm.
-        testenv_iface_mapping = {
-            'adnonssdom.samba.example.com': 17,     # addc_no_nss
-            'adnontlmdom.samba.example.com': 18,    # addc_no_ntlm
-            'samba2000.example.com': 25,            # dc5
-            'samba2003.example.com': 26,            # dc6
-            'samba2008r2.example.com': 27,          # dc7
-            'addom.samba.example.com': 30,          # addc
-            'sub.samba.example.com': 31,            # localsubdc
-            'chgdcpassword.samba.example.com': 32,  # chgdcpass
-            'backupdom.samba.example.com': 40,      # backupfromdc
-            'renamedom.samba.example.com': 42,      # renamedc
-            'labdom.samba.example.com': 43,         # labdc
-            'samba.example.com': 21,                # localdc
-        }
+        testenv_iface_mapping = self.server.realm_to_ip_mappings
 
         # sort the realms so we find the longest-match first
         testenv_realms = sorted(testenv_iface_mapping.keys(), key=len)
@@ -183,7 +166,14 @@ def main():
     timeout = int(sys.argv[1]) * 1000
     timeout = min(timeout, 2**31 - 1)  # poll with 32-bit int can't take more
     host = sys.argv[2]
+
     server = sserver.UDPServer((host, int(53)), DnsHandler)
+
+    # we pass in the realm-to-IP mappings as a comma-separated key=value
+    # string. Convert this back into a dictionary that the DnsHandler can use
+    realm_mapping = dict(kv.split('=') for kv in sys.argv[3].split(','))
+    server.realm_to_ip_mappings = realm_mapping
+
     t = server_thread(server)
     t.start()
     p = select.poll()
-- 
2.7.4


From ceb0b9494bc74f79a8bc6d77df91564435a7f2a8 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 20 Feb 2019 16:34:23 +1300
Subject: [PATCH 08/10] selftest: Map realm to IP address (instead of iface)

The code is more readable if the hashmap translates between realm and
DC-name, rather than realm-to-iface. We already have a function to map
between DC-name and iface (and since we're doing this, we might as well
map straight to IP address).

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/Samba.pm   | 40 ++++++++++++++++++++--------------------
 selftest/target/dns_hub.py |  3 +--
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 3f8a38f..324e1bf 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -387,30 +387,30 @@ sub mk_mitkdc_conf($$)
 
 sub realm_to_ip_mappings
 {
-	# this maps the SOCKET_WRAPPER_DEFAULT_IFACE value (which is the
-	# last byte of the IP address) for the various testenv PDCs to the
-	# corresponding DNS realm.
-	# This should always match the values in get_interface()
-	my %testenv_iface_mapping = (
-		'adnonssdom.samba.example.com'    => 17,    # addc_no_nss
-		'adnontlmdom.samba.example.com'   => 18,    # addc_no_ntlm
-		'samba2000.example.com'           => 25,    # dc5
-		'samba2003.example.com'           => 26,    # dc6
-		'samba2008r2.example.com'         => 27,    # dc7
-		'addom.samba.example.com'         => 30,    # addc
-		'sub.samba.example.com'           => 31,    # localsubdc
-		'chgdcpassword.samba.example.com' => 32,    # chgdcpass
-		'backupdom.samba.example.com'     => 40,    # backupfromdc
-		'renamedom.samba.example.com'     => 42,    # renamedc
-		'labdom.samba.example.com'        => 43,    # labdc
-		'samba.example.com'               => 21,    # localdc
+	# this maps the DNS realms for the various testenvs to the corresponding
+	# PDC (i.e. the first DC created for that realm).
+	my %realm_to_pdc_mapping = (
+		'adnonssdom.samba.example.com'    => 'addc_no_nss',
+		'adnontlmdom.samba.example.com'   => 'addc_no_ntlm',
+		'samba2000.example.com'           => 'dc5',
+		'samba2003.example.com'           => 'dc6',
+		'samba2008r2.example.com'         => 'dc7',
+		'addom.samba.example.com'         => 'addc',
+		'sub.samba.example.com'           => 'localsubdc',
+		'chgdcpassword.samba.example.com' => 'chgdcpass',
+		'backupdom.samba.example.com'     => 'backupfromdc',
+		'renamedom.samba.example.com'     => 'renamedc',
+		'labdom.samba.example.com'        => 'labdc',
+		'samba.example.com'               => 'localdc',
 	);
 
 	my @mapping = ();
 
-	# convert the hashmap to a list of key=value strings
-	while (my ($key, $val) = each(%testenv_iface_mapping)) {
-		push(@mapping, "$key=$val");
+	# convert the hashmap to a list of key=value strings, where key is the
+	# realm and value is the IP address
+	while (my ($realm, $pdc) = each(%realm_to_pdc_mapping)) {
+		my $ipaddr = get_ipv4_addr($pdc);
+		push(@mapping, "$realm=$ipaddr");
 	}
 	# return the mapping as a single comma-separated string
 	return join(',', @mapping);
diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index b0e2a2b..00c1ebd 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -80,8 +80,7 @@ class DnsHandler(sserver.BaseRequestHandler):
 
         for realm in testenv_realms:
             if lookup_name.endswith(realm):
-                iface = testenv_iface_mapping[realm]
-                return '127.0.0.' + str(iface)
+                return testenv_iface_mapping[realm]
 
         return None
 
-- 
2.7.4


From fa8bf2dc06a4a42f3011170cd00dd4038c045d3f Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 20 Feb 2019 16:41:47 +1300
Subject: [PATCH 09/10] dns_hub: Minor variable rename

We've dropped the iface logic now - this dictionary maps from
realm-to-IP.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/dns_hub.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index 00c1ebd..f1a5eee 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -72,15 +72,16 @@ class DnsHandler(sserver.BaseRequestHandler):
     def get_pdc_ipv4_addr(self, lookup_name):
         """Maps a DNS realm to the IPv4 address of the PDC for that testenv"""
 
-        testenv_iface_mapping = self.server.realm_to_ip_mappings
+        realm_to_ip_mappings = self.server.realm_to_ip_mappings
 
         # sort the realms so we find the longest-match first
-        testenv_realms = sorted(testenv_iface_mapping.keys(), key=len)
+        testenv_realms = sorted(realm_to_ip_mappings.keys(), key=len)
         testenv_realms.reverse()
 
         for realm in testenv_realms:
             if lookup_name.endswith(realm):
-                return testenv_iface_mapping[realm]
+                # return the corresponding IP address for this realm's PDC
+                return realm_to_ip_mappings[realm]
 
         return None
 
-- 
2.7.4


From 863f796450c83a52f6e795193686da80c39074e7 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 20 Feb 2019 16:51:14 +1300
Subject: [PATCH 10/10] dns_hub: Add some debug as to what DNS proxying is
 happening

This should make it clear at run-time how dns_hub is actually proxying
DNS requests, which will hopefully aid in debugging problems (i.e.
forgetting to add a mapping when adding a new DNS realm).

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/dns_hub.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index f1a5eee..49fbeff 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -174,6 +174,10 @@ def main():
     realm_mapping = dict(kv.split('=') for kv in sys.argv[3].split(','))
     server.realm_to_ip_mappings = realm_mapping
 
+    print("dns_hub will proxy DNS requests for the following realms:")
+    for realm, ip in server.realm_to_ip_mappings.items():
+        print("  {0} ==> {1}".format(realm, ip))
+
     t = server_thread(server)
     t.start()
     p = select.poll()
-- 
2.7.4



More information about the samba-technical mailing list