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

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