Blame SOURCES/0002-Add-checks-to-prevent-adding-auth-indicators-to-inte_rhbz#1979625.patch

2834c6
From a5d2857297cfcf87ed8973df96e89ebcef22850d Mon Sep 17 00:00:00 2001
2834c6
From: Antonio Torres <antorres@redhat.com>
2834c6
Date: Mon, 8 Mar 2021 18:15:50 +0100
2834c6
Subject: [PATCH] Add checks to prevent adding auth indicators to internal IPA
2834c6
 services
2834c6
2834c6
Authentication indicators should not be enforced against internal
2834c6
IPA services, since not all users of those services are able to produce
2834c6
Kerberos tickets with all the auth indicator options. This includes
2834c6
host, ldap, HTTP and cifs in IPA server and cifs in IPA clients.
2834c6
If a client that is being promoted to replica has an auth indicator
2834c6
in its host principal then the promotion is aborted.
2834c6
2834c6
Fixes: https://pagure.io/freeipa/issue/8206
2834c6
Signed-off-by: Antonio Torres <antorres@redhat.com>
2834c6
---
2834c6
 ipaserver/install/server/replicainstall.py | 13 ++++++++++++
2834c6
 ipaserver/plugins/host.py                  |  5 ++++-
2834c6
 ipaserver/plugins/service.py               | 24 ++++++++++++++++++++++
2834c6
 3 files changed, 41 insertions(+), 1 deletion(-)
2834c6
2834c6
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
2834c6
index 73967a224..f1fb91036 100644
2834c6
--- a/ipaserver/install/server/replicainstall.py
2834c6
+++ b/ipaserver/install/server/replicainstall.py
2834c6
@@ -770,6 +770,15 @@ def promotion_check_ipa_domain(master_ldap_conn, basedn):
2834c6
         ))
2834c6
 
2834c6
 
2834c6
+def promotion_check_host_principal_auth_ind(conn, hostdn):
2834c6
+    entry = conn.get_entry(hostdn, ['krbprincipalauthind'])
2834c6
+    if 'krbprincipalauthind' in entry:
2834c6
+        raise RuntimeError(
2834c6
+            "Client cannot be promoted to a replica if the host principal "
2834c6
+            "has an authentication indicator set."
2834c6
+        )
2834c6
+
2834c6
+
2834c6
 @common_cleanup
2834c6
 @preserve_enrollment_state
2834c6
 def promote_check(installer):
2834c6
@@ -956,6 +965,10 @@ def promote_check(installer):
2834c6
                                      config.master_host_name, None)
2834c6
 
2834c6
         promotion_check_ipa_domain(conn, remote_api.env.basedn)
2834c6
+        hostdn = DN(('fqdn', api.env.host),
2834c6
+                    api.env.container_host,
2834c6
+                    api.env.basedn)
2834c6
+        promotion_check_host_principal_auth_ind(conn, hostdn)
2834c6
 
2834c6
         # Make sure that domain fulfills minimal domain level
2834c6
         # requirement
2834c6
diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
2834c6
index eb1f8ef04..41fa933e2 100644
2834c6
--- a/ipaserver/plugins/host.py
2834c6
+++ b/ipaserver/plugins/host.py
2834c6
@@ -38,7 +38,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
2834c6
                                      LDAPAddAttributeViaOption,
2834c6
                                      LDAPRemoveAttributeViaOption)
2834c6
 from .service import (
2834c6
-    validate_realm, normalize_principal,
2834c6
+    validate_realm, validate_auth_indicator, normalize_principal,
2834c6
     set_certificate_attrs, ticket_flags_params, update_krbticketflags,
2834c6
     set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
2834c6
     rename_ipaallowedtoperform_to_ldap, revoke_certs)
2834c6
@@ -735,6 +735,8 @@ class host_add(LDAPCreate):
2834c6
         update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
2834c6
         if 'krbticketflags' in entry_attrs:
2834c6
             entry_attrs['objectclass'].append('krbticketpolicyaux')
2834c6
+        validate_auth_indicator(entry_attrs)
2834c6
+
2834c6
         return dn
2834c6
 
2834c6
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
2834c6
@@ -993,6 +995,7 @@ class host_mod(LDAPUpdate):
2834c6
             if 'krbprincipalaux' not in (item.lower() for item in
2834c6
                                          entry_attrs['objectclass']):
2834c6
                 entry_attrs['objectclass'].append('krbprincipalaux')
2834c6
+            validate_auth_indicator(entry_attrs)
2834c6
 
2834c6
         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
2834c6
 
2834c6
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
2834c6
index 1c9347804..cfbbff3c6 100644
2834c6
--- a/ipaserver/plugins/service.py
2834c6
+++ b/ipaserver/plugins/service.py
2834c6
@@ -201,6 +201,28 @@ def validate_realm(ugettext, principal):
2834c6
         raise errors.RealmMismatch()
2834c6
 
2834c6
 
2834c6
+def validate_auth_indicator(entry):
2834c6
+    new_value = entry.get('krbprincipalauthind', None)
2834c6
+    if not new_value:
2834c6
+        return
2834c6
+    # The following services are considered internal IPA services
2834c6
+    # and shouldn't be allowed to have auth indicators.
2834c6
+    # https://pagure.io/freeipa/issue/8206
2834c6
+    pkey = api.Object['service'].get_primary_key_from_dn(entry.dn)
2834c6
+    principal = kerberos.Principal(pkey)
2834c6
+    server = api.Command.server_find(principal.hostname)['result']
2834c6
+    if server:
2834c6
+        prefixes = ("host", "cifs", "ldap", "HTTP")
2834c6
+    else:
2834c6
+        prefixes = ("cifs",)
2834c6
+    if principal.service_name in prefixes:
2834c6
+        raise errors.ValidationError(
2834c6
+            name='krbprincipalauthind',
2834c6
+            error=_('authentication indicators not allowed '
2834c6
+                    'in service "%s"' % principal.service_name)
2834c6
+        )
2834c6
+
2834c6
+
2834c6
 def normalize_principal(value):
2834c6
     """
2834c6
     Ensure that the name in the principal is lower-case. The realm is
2834c6
@@ -652,6 +674,7 @@ class service_add(LDAPCreate):
2834c6
                     hostname)
2834c6
 
2834c6
         self.obj.validate_ipakrbauthzdata(entry_attrs)
2834c6
+        validate_auth_indicator(entry_attrs)
2834c6
 
2834c6
         if not options.get('force', False):
2834c6
             # We know the host exists if we've gotten this far but we
2834c6
@@ -846,6 +869,7 @@ class service_mod(LDAPUpdate):
2834c6
         assert isinstance(dn, DN)
2834c6
 
2834c6
         self.obj.validate_ipakrbauthzdata(entry_attrs)
2834c6
+        validate_auth_indicator(entry_attrs)
2834c6
 
2834c6
         # verify certificates
2834c6
         certs = entry_attrs.get('usercertificate') or []
2834c6
-- 
2834c6
2.31.1
2834c6
2834c6
From 28484c3dee225662e41acc691bfe6b1c1cee99c8 Mon Sep 17 00:00:00 2001
2834c6
From: Antonio Torres <antorres@redhat.com>
2834c6
Date: Mon, 8 Mar 2021 18:20:35 +0100
2834c6
Subject: [PATCH] ipatests: ensure auth indicators can't be added to internal
2834c6
 IPA services
2834c6
2834c6
Authentication indicators should not be added to internal IPA services,
2834c6
since this can lead to a broken IPA setup. In case a client with
2834c6
an auth indicator set in its host principal, promoting it to a replica
2834c6
should fail.
2834c6
2834c6
Related: https://pagure.io/freeipa/issue/8206
2834c6
Signed-off-by: Antonio Torres <antorres@redhat.com>
2834c6
---
2834c6
 .../test_replica_promotion.py                 | 38 +++++++++++++++++++
2834c6
 ipatests/test_xmlrpc/test_host_plugin.py      | 10 +++++
2834c6
 ipatests/test_xmlrpc/test_service_plugin.py   | 21 ++++++++++
2834c6
 3 files changed, 69 insertions(+)
2834c6
2834c6
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
2834c6
index 0a137dbdc..b9c56f775 100644
2834c6
--- a/ipatests/test_integration/test_replica_promotion.py
2834c6
+++ b/ipatests/test_integration/test_replica_promotion.py
2834c6
@@ -101,6 +101,44 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
2834c6
         assert result.returncode == 1
2834c6
         assert expected_err in result.stderr_text
2834c6
 
2834c6
+    @replicas_cleanup
2834c6
+    def test_install_with_host_auth_ind_set(self):
2834c6
+        """ A client shouldn't be able to be promoted if it has
2834c6
+        any auth indicator set in the host principal.
2834c6
+        https://pagure.io/freeipa/issue/8206
2834c6
+        """
2834c6
+
2834c6
+        client = self.replicas[0]
2834c6
+        # Configure firewall first
2834c6
+        Firewall(client).enable_services(["freeipa-ldap",
2834c6
+                                          "freeipa-ldaps"])
2834c6
+
2834c6
+        client.run_command(['ipa-client-install', '-U',
2834c6
+                            '--domain', self.master.domain.name,
2834c6
+                            '--realm', self.master.domain.realm,
2834c6
+                            '-p', 'admin',
2834c6
+                            '-w', self.master.config.admin_password,
2834c6
+                            '--server', self.master.hostname,
2834c6
+                            '--force-join'])
2834c6
+
2834c6
+        tasks.kinit_admin(client)
2834c6
+
2834c6
+        client.run_command(['ipa', 'host-mod', '--auth-ind=otp',
2834c6
+                            client.hostname])
2834c6
+
2834c6
+        res = client.run_command(['ipa-replica-install', '-U', '-w',
2834c6
+                                  self.master.config.dirman_password],
2834c6
+                                 raiseonerr=False)
2834c6
+
2834c6
+        client.run_command(['ipa', 'host-mod', '--auth-ind=',
2834c6
+                            client.hostname])
2834c6
+
2834c6
+        expected_err = ("Client cannot be promoted to a replica if the host "
2834c6
+                        "principal has an authentication indicator set.")
2834c6
+        assert res.returncode == 1
2834c6
+        assert expected_err in res.stderr_text
2834c6
+
2834c6
+
2834c6
     @replicas_cleanup
2834c6
     def test_one_command_installation(self):
2834c6
         """
2834c6
diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py
2834c6
index c66bbc865..9cfde3565 100644
2834c6
--- a/ipatests/test_xmlrpc/test_host_plugin.py
2834c6
+++ b/ipatests/test_xmlrpc/test_host_plugin.py
2834c6
@@ -605,6 +605,16 @@ class TestProtectedMaster(XMLRPC_test):
2834c6
                 error=u'An IPA master host cannot be deleted or disabled')):
2834c6
             command()
2834c6
 
2834c6
+    def test_try_add_auth_ind_master(self, this_host):
2834c6
+        command = this_host.make_update_command({
2834c6
+            u'krbprincipalauthind': u'radius'})
2834c6
+        with raises_exact(errors.ValidationError(
2834c6
+            name='krbprincipalauthind',
2834c6
+            error=u'authentication indicators not allowed '
2834c6
+                'in service "host"'
2834c6
+        )):
2834c6
+            command()
2834c6
+
2834c6
 
2834c6
 @pytest.mark.tier1
2834c6
 class TestValidation(XMLRPC_test):
2834c6
diff --git a/ipatests/test_xmlrpc/test_service_plugin.py b/ipatests/test_xmlrpc/test_service_plugin.py
2834c6
index 4c845938c..ed634a045 100644
2834c6
--- a/ipatests/test_xmlrpc/test_service_plugin.py
2834c6
+++ b/ipatests/test_xmlrpc/test_service_plugin.py
2834c6
@@ -25,6 +25,7 @@ from ipalib import api, errors
2834c6
 from ipatests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_hash
2834c6
 from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_digits, fuzzy_date, fuzzy_issuer
2834c6
 from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_hex, XMLRPC_test
2834c6
+from ipatests.test_xmlrpc.xmlrpc_test import raises_exact
2834c6
 from ipatests.test_xmlrpc import objectclasses
2834c6
 from ipatests.test_xmlrpc.testcert import get_testcert, subject_base
2834c6
 from ipatests.test_xmlrpc.test_user_plugin import get_user_result, get_group_dn
2834c6
@@ -1552,6 +1553,15 @@ def indicators_host(request):
2834c6
     return tracker.make_fixture(request)
2834c6
 
2834c6
 
2834c6
+@pytest.fixture(scope='function')
2834c6
+def this_host(request):
2834c6
+    """Fixture for the current master"""
2834c6
+    tracker = HostTracker(name=api.env.host.partition('.')[0],
2834c6
+                          fqdn=api.env.host)
2834c6
+    tracker.exists = True
2834c6
+    return tracker
2834c6
+
2834c6
+
2834c6
 @pytest.fixture(scope='function')
2834c6
 def indicators_service(request):
2834c6
     tracker = ServiceTracker(
2834c6
@@ -1587,6 +1597,17 @@ class TestAuthenticationIndicators(XMLRPC_test):
2834c6
             expected_updates={u'krbprincipalauthind': [u'radius']}
2834c6
         )
2834c6
 
2834c6
+    def test_update_indicator_internal_service(self, this_host):
2834c6
+        command = this_host.make_command('service_mod',
2834c6
+                                         'ldap/' + this_host.fqdn,
2834c6
+                                         **dict(krbprincipalauthind='otp'))
2834c6
+        with raises_exact(errors.ValidationError(
2834c6
+            name='krbprincipalauthind',
2834c6
+            error=u'authentication indicators not allowed '
2834c6
+                 'in service "ldap"'
2834c6
+        )):
2834c6
+            command()
2834c6
+
2834c6
 
2834c6
 @pytest.fixture(scope='function')
2834c6
 def managing_host(request):
2834c6
-- 
2834c6
2.31.1
2834c6