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

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