URL: https://github.com/freeipa/freeipa/pull/5990
Author: tiran
 Title: #5990: Temp commit
Action: opened

PR body:
"""
None
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/5990/head:pr5990
git checkout pr5990
From e6ef275388f92cccf70ee92485c266caeb6a38c8 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Wed, 25 Aug 2021 17:34:00 +0200
Subject: [PATCH 1/2] Temp commit

---
 .freeipa-pr-ci.yaml                        |  2 +-
 ipatests/prci_definitions/temp_commit.yaml | 18 +++++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/.freeipa-pr-ci.yaml b/.freeipa-pr-ci.yaml
index abcf8c5b634..80656690080 120000
--- a/.freeipa-pr-ci.yaml
+++ b/.freeipa-pr-ci.yaml
@@ -1 +1 @@
-ipatests/prci_definitions/gating.yaml
\ No newline at end of file
+ipatests/prci_definitions/temp_commit.yaml
\ No newline at end of file
diff --git a/ipatests/prci_definitions/temp_commit.yaml b/ipatests/prci_definitions/temp_commit.yaml
index 4b0398b9218..7f0df366a6e 100644
--- a/ipatests/prci_definitions/temp_commit.yaml
+++ b/ipatests/prci_definitions/temp_commit.yaml
@@ -61,14 +61,26 @@ jobs:
         timeout: 1800
         topology: *build
 
-  fedora-latest/temp_commit:
+  fedora-latest/dns_locations:
     requires: [fedora-latest/build]
     priority: 50
     job:
       class: RunPytest
       args:
         build_url: '{fedora-latest/build_url}'
-        test_suite: test_integration/test_REPLACEME.py
+        test_suite: test_integration/test_dns_locations.py
         template: *ci-master-latest
         timeout: 3600
-        topology: *master_1repl_1client
+        topology: *master_2repl_1client
+
+  fedora-latest/test_installation_TestInstallMaster:
+    requires: [fedora-latest/build]
+    priority: 100
+    job:
+      class: RunPytest
+      args:
+        build_url: '{fedora-latest/build_url}'
+        test_suite: test_integration/test_installation.py::TestInstallMaster
+        template: *ci-master-latest
+        timeout: 7200
+        topology: *master_1repl

From b25ff23d2971874d9e555d16a0e14370d69f5b21 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Wed, 25 Aug 2021 17:13:55 +0200
Subject: [PATCH 2/2] Add URI system records for KDC

MIT KRB5 1.15 introduced KDC service discovery with URI records.
_kerberos and _kpasswd URI records can provide TCP, UDP, and Kerberos
KDC-Proxy references. URI lookups take precedence over SRV lookups,
falling back to SRV lookups if no URI records are found.

See: https://web.mit.edu/kerberos/krb5-latest/doc/admin/realm_config.html#kdc-discovery
Fixes: https://pagure.io/freeipa/issue/8968
Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/dns_data_management.py              | 65 ++++++++++++-
 .../test_integration/test_dns_locations.py    | 97 ++++++++++++++++---
 .../test_installation_client.py               |  4 +
 3 files changed, 152 insertions(+), 14 deletions(-)

diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py
index aad00062a48..bd12259933d 100644
--- a/ipaserver/dns_data_management.py
+++ b/ipaserver/dns_data_management.py
@@ -32,6 +32,7 @@
 IPA_DEFAULT_MASTER_SRV_REC = (
     # srv record name, port
     (DNSName('_ldap._tcp'), 389),
+    # Kerberos records are provided for MIT KRB5 < 1.15 and AD
     (DNSName('_kerberos._tcp'), 88),
     (DNSName('_kerberos._udp'), 88),
     (DNSName('_kerberos-master._tcp'), 88),
@@ -40,6 +41,20 @@
     (DNSName('_kpasswd._udp'), 464),
 )
 
+IPA_DEFAULT_MASTER_URI_REC = (
+    # URI record name, URI template
+
+    # MIT KRB5 1.15+ prefers URI records for service discovery
+    # scheme (always krb5srv)
+    # flags (empty or 'm' for master)
+    # transport ('tcp', 'udp', or 'kkdcp')
+    # residual: 'hostname', 'hostname:port', or 'https://' URL
+    (DNSName('_kerberos'), "krb5srv:m:tcp:{hostname}"),
+    (DNSName('_kerberos'), "krb5srv:m:udp:{hostname}"),
+    (DNSName('_kpasswd'), "krb5srv:m:tcp:{hostname}"),
+    (DNSName('_kpasswd'), "krb5srv:m:udp:{hostname}"),
+)
+
 IPA_DEFAULT_ADTRUST_SRV_REC = (
     # srv record name, port
     (DNSName('_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs'), 389),
@@ -67,6 +82,8 @@ class IPASystemRecords:
     # fixme do it configurable
     PRIORITY_HIGH = 0
     PRIORITY_LOW = 50
+    # FIXME: use TTL from config
+    TTL = 86400
 
     def __init__(self, api_instance, all_servers=False):
         self.api_instance = api_instance
@@ -134,7 +151,35 @@ def __add_srv_records(
 
             rdataset = zone_obj.get_rdataset(
                 r_name, rdatatype.SRV, create=True)
-            rdataset.add(rd, ttl=86400)  # FIXME: use TTL from config
+            rdataset.add(rd, ttl=self.TTL)
+
+    def __add_uri_records(
+        self, zone_obj, hostname, rname_uri_map,
+        weight=100, priority=0, location=None
+    ):
+        assert isinstance(hostname, DNSName)
+        assert isinstance(priority, int)
+        assert isinstance(weight, int)
+
+        if location:
+            suffix = self.__get_location_suffix(location)
+        else:
+            suffix = self.domain_abs
+
+        for name, uri_template in rname_uri_map:
+            uri = uri_template.format(hostname=hostname.make_absolute())
+            rd = rdata.from_text(
+                rdataclass.IN, rdatatype.URI,
+                '{0} {1} {2}'.format(
+                    priority, weight, uri
+                )
+            )
+
+            r_name = name.derelativize(suffix)
+
+            rdataset = zone_obj.get_rdataset(
+                r_name, rdatatype.URI, create=True)
+            rdataset.add(rd, ttl=self.TTL)
 
     def __add_ca_records_from_hostname(self, zone_obj, hostname):
         assert isinstance(hostname, DNSName) and hostname.is_absolute()
@@ -163,7 +208,7 @@ def __add_ca_records_from_hostname(self, zone_obj, hostname):
             for rd in rrset:
                 rdataset = zone_obj.get_rdataset(
                     r_name, rd.rdtype, create=True)
-                rdataset.add(rd, ttl=86400)  # FIXME: use TTL from config
+                rdataset.add(rd, ttl=self.TTL)
 
     def __add_kerberos_txt_rec(self, zone_obj):
         # FIXME: with external DNS, this should generate records for all
@@ -174,7 +219,7 @@ def __add_kerberos_txt_rec(self, zone_obj):
         rdataset = zone_obj.get_rdataset(
             r_name, rdatatype.TXT, create=True
         )
-        rdataset.add(rd, ttl=86400)  # FIXME: use TTL from config
+        rdataset.add(rd, ttl=self.TTL)
 
     def _add_base_dns_records_for_server(
             self, zone_obj, hostname, roles=None, include_master_role=True,
@@ -198,6 +243,12 @@ def _add_base_dns_records_for_server(
                 IPA_DEFAULT_MASTER_SRV_REC,
                 weight=server['weight']
             )
+            self.__add_uri_records(
+                zone_obj,
+                hostname_abs,
+                IPA_DEFAULT_MASTER_URI_REC,
+                weight=server['weight']
+            )
 
         if 'CA server' in eff_roles:
             self.__add_ca_records_from_hostname(zone_obj, hostname_abs)
@@ -244,6 +295,14 @@ def _get_location_dns_records_for_server(
                     priority=priority,
                     location=location
                 )
+                self.__add_uri_records(
+                    zone_obj,
+                    hostname_abs,
+                    IPA_DEFAULT_MASTER_URI_REC,
+                    weight=server['weight'],
+                    priority=priority,
+                    location=location
+                )
 
             if 'AD trust controller' in eff_roles:
                 self.__add_srv_records(
diff --git a/ipatests/test_integration/test_dns_locations.py b/ipatests/test_integration/test_dns_locations.py
index 6eac0d01111..0ef2a6f7e7b 100644
--- a/ipatests/test_integration/test_dns_locations.py
+++ b/ipatests/test_integration/test_dns_locations.py
@@ -28,6 +28,14 @@
     (DNSName(u'_kpasswd._udp'), 464),
 )
 
+IPA_DEFAULT_MASTER_URI_REC = (
+    # URI record name, URI template
+    (DNSName('_kerberos'), "krb5srv:m:tcp:{hostname}"),
+    (DNSName('_kerberos'), "krb5srv:m:udp:{hostname}"),
+    (DNSName('_kpasswd'), "krb5srv:m:tcp:{hostname}"),
+    (DNSName('_kpasswd'), "krb5srv:m:udp:{hostname}"),
+)
+
 IPA_DEFAULT_ADTRUST_SRV_REC = (
     # srv record name, port
     (DNSName(u'_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs'), 389),
@@ -79,6 +87,20 @@ def _gen_expected_srv_rrset(rname, port, servers, ttl=86400):
     )
 
 
+def _gen_expected_uri_rrset(rname, uri_template, servers, ttl=86400):
+    rdata_list = [
+        "{prio} {weight} {uri}".format(
+            prio=prio,
+            weight=weight,
+            uri=uri_template.format(hostname=servername.make_absolute()),
+        )
+        for prio, weight, servername in servers
+    ]
+    return dns.rrset.from_text_list(
+        rname, ttl, dns.rdataclass.IN, dns.rdatatype.URI, rdata_list
+    )
+
+
 def _gen_expected_a_rrset(rname, servers, ttl=86400):
     return dns.rrset.from_text_list(rname, ttl, dns.rdataclass.IN,
                                     dns.rdatatype.A, servers)
@@ -174,6 +196,20 @@ def _test_SRV_rec_against_server(self, server_ip, domain, expected_servers,
                 "with IP: '{}' for name '{}' (expected:\n{}\ngot:\n{})".
                 format(server_ip, name_abs, expected, query))
 
+    def _test_URI_rec_against_server(self, server_ip, domain, expected_servers,
+                                     rec_list=IPA_DEFAULT_MASTER_URI_REC):
+        for rname, uri_template in rec_list:
+            name_abs = rname.derelativize(domain)
+            expected = _gen_expected_uri_rrset(
+                name_abs, uri_template, expected_servers)
+            query = resolve_records_from_server(
+                name_abs, 'URI', server_ip)
+
+            assert expected == query, (
+                "Expected and received DNS data do not match on server "
+                "with IP: '{}' for name '{}' (expected:\n{}\ngot:\n{})".
+                format(server_ip, name_abs, expected, query))
+
     def test_without_locations(self):
         """Servers are not in locations, this tests if basic system records
         are generated properly"""
@@ -185,6 +221,9 @@ def test_without_locations(self):
         for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip):
             self._test_SRV_rec_against_server(ip, self.domain,
                                               expected_servers)
+            self._test_URI_rec_against_server(
+                ip, self.domain, expected_servers
+            )
 
     def test_nsupdate_without_locations(self):
         """Test nsupdate file generated by dns-update-system-records
@@ -227,11 +266,19 @@ def test_one_replica_in_location(self):
         )
 
         self._test_SRV_rec_against_server(
-            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
+        self._test_URI_rec_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
 
         for ip in (self.master.ip, self.replicas[1].ip):
             self._test_SRV_rec_against_server(
-                ip, domain_without_loc, servers_without_loc)
+                ip, domain_without_loc, servers_without_loc
+            )
+            self._test_URI_rec_against_server(
+                ip, domain_without_loc, servers_without_loc
+            )
 
     def test_two_replicas_in_location(self):
         """Put second replica to location and test if records changed properly
@@ -270,13 +317,25 @@ def test_two_replicas_in_location(self):
                 self.master.domain.name).make_absolute())
 
         self._test_SRV_rec_against_server(
-            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
+        self._test_URI_rec_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
 
         self._test_SRV_rec_against_server(
-            self.replicas[1].ip, domain_paris_loc, servers_paris_loc)
+            self.replicas[1].ip, domain_paris_loc, servers_paris_loc
+        )
+        self._test_URI_rec_against_server(
+            self.replicas[1].ip, domain_paris_loc, servers_paris_loc
+        )
 
         self._test_SRV_rec_against_server(
-            self.master.ip, domain_without_loc, servers_without_loc)
+            self.master.ip, domain_without_loc, servers_without_loc
+        )
+        self._test_URI_rec_against_server(
+            self.master.ip, domain_without_loc, servers_without_loc
+        )
 
     def test_all_servers_in_location(self):
         """Put master (as second server) to location and test if records
@@ -308,11 +367,19 @@ def test_all_servers_in_location(self):
                 self.master.domain.name).make_absolute())
 
         self._test_SRV_rec_against_server(
-            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
+        self._test_URI_rec_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
 
         for ip in (self.replicas[1].ip, self.master.ip):
-            self._test_SRV_rec_against_server(ip, domain_paris_loc,
-                                              servers_paris_loc)
+            self._test_SRV_rec_against_server(
+                ip, domain_paris_loc, servers_paris_loc
+            )
+            self._test_URI_rec_against_server(
+                ip, domain_paris_loc, servers_paris_loc
+            )
 
     def test_change_weight(self):
         """Change weight of master and test if records changed properly
@@ -347,11 +414,19 @@ def test_change_weight(self):
                 self.master.domain.name).make_absolute())
 
         self._test_SRV_rec_against_server(
-            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
+        self._test_URI_rec_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc
+        )
 
         for ip in (self.replicas[1].ip, self.master.ip):
-            self._test_SRV_rec_against_server(ip, domain_paris_loc,
-                                              servers_paris_loc)
+            self._test_SRV_rec_against_server(
+                ip, domain_paris_loc, servers_paris_loc
+            )
+            self._test_URI_rec_against_server(
+                ip, domain_paris_loc, servers_paris_loc
+            )
 
     def test_change_weight_relative_zero_0(self):
         """Change weight of one master and check on relative weight %
diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py
index 014b0f6ab34..de661687481 100644
--- a/ipatests/test_integration/test_installation_client.py
+++ b/ipatests/test_integration/test_installation_client.py
@@ -140,6 +140,10 @@ def update_contents(path, pattern, replace):
         _kpasswd._tcp.{domain}. 	IN SRV 0 100 464 {fqdn}.
         _kpasswd._udp.{domain}. 	IN SRV 0 100 464 {fqdn}.
         _ldap._tcp.{domain}. 		IN SRV 0 100 389 {fqdn}.
+        _kerberos.{domain}. 	IN URI 0 100 krb5srv:m:tcp:{fqdn}.
+        _kerberos.{domain}. 	IN URI 0 100 krb5srv:m:udp:{fqdn}.
+        _kpasswd.{domain}. 	IN URI 0 100 krb5srv:m:tcp:{fqdn}.
+        _kpasswd.{domain}. 	IN URI 0 100 krb5srv:m:udp:{fqdn}.
         """).format(
             fqdn=bindserver.hostname,
             domain=bindserver.domain.name,
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to