From 1e3c12470dfbe9b7532db01896c47e3903959865 Mon Sep 17 00:00:00 2001
From: Antonio Torres <antorres@redhat.com>
Date: Mon, 8 Mar 2021 18:15:50 +0100
Subject: [PATCH 1/2] Add checks to prevent adding auth indicators to internal
 IPA services

Authentication indicators should not be enforced against internal
IPA services, since not all users of those servers are able to produce
Kerberos tickets with all the auth indicator options. This includes
host, ldap, HTTP and cifs in IPA server and host and cifs in IPA clients.

Fixes: https://pagure.io/freeipa/issue/8206
Signed-off-by: Antonio Torres <antorres@redhat.com>
---
 ipaserver/plugins/service.py | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
index 1c93478049f..cfa8d1cd27a 100644
--- a/ipaserver/plugins/service.py
+++ b/ipaserver/plugins/service.py
@@ -568,6 +568,27 @@ def validate_ipakrbauthzdata(self, entry):
             raise errors.ValidationError(name='ipakrbauthzdata',
                 error=_('NONE value cannot be combined with other PAC types'))
 
+    def validate_auth_indicator(self, entry):
+        new_value = entry.get('krbprincipalauthind', None)
+
+        if not new_value:
+            return
+
+        # The following services are considered internal IPA services
+        # and shouldn't be allowed to have auth indicators.
+        # https://pagure.io/freeipa/issue/8206
+        server_services = ('host', 'ldap', 'HTTP', 'cifs')
+        client_services = ('host', 'cifs')
+        services = server_services if api.env.in_server else client_services
+        name = unicode(self.get_primary_key_from_dn(entry.dn))
+        for service in services:
+            if service + '/' in name:
+                raise errors.ValidationError(
+                    name='krbprincipalauthind',
+                    error=_('authentication indicators not allowed '
+                            'in service "%s"' % service)
+                )
+
     def get_dn(self, *keys, **kwargs):
         key = keys[0]
         if isinstance(key, str):
@@ -652,6 +673,7 @@ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
                     hostname)
 
         self.obj.validate_ipakrbauthzdata(entry_attrs)
+        self.obj.validate_auth_indicator(entry_attrs)
 
         if not options.get('force', False):
             # We know the host exists if we've gotten this far but we
@@ -846,6 +868,7 @@ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
         self.obj.validate_ipakrbauthzdata(entry_attrs)
+        self.obj.validate_auth_indicator(entry_attrs)
 
         # verify certificates
         certs = entry_attrs.get('usercertificate') or []

From 0ff329574722874c426bd646b01884cf1125abbd Mon Sep 17 00:00:00 2001
From: Antonio Torres <antorres@redhat.com>
Date: Mon, 8 Mar 2021 18:20:35 +0100
Subject: [PATCH 2/2] ipatests: ensure auth indicators can't be added to
 internal IPA services

Authentication indicators should not be added to internal IPA services,
since this can lead to a broken IPA setup.

Related: https://pagure.io/freeipa/issue/8206
Signed-off-by: Antonio Torres <antorres@redhat.com>
---
 ipatests/test_xmlrpc/test_service_plugin.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/ipatests/test_xmlrpc/test_service_plugin.py b/ipatests/test_xmlrpc/test_service_plugin.py
index 4c845938c33..69159030854 100644
--- a/ipatests/test_xmlrpc/test_service_plugin.py
+++ b/ipatests/test_xmlrpc/test_service_plugin.py
@@ -25,6 +25,7 @@
 from ipatests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_hash
 from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_digits, fuzzy_date, fuzzy_issuer
 from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_hex, XMLRPC_test
+from ipatests.test_xmlrpc.xmlrpc_test import raises_exact
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.test_xmlrpc.testcert import get_testcert, subject_base
 from ipatests.test_xmlrpc.test_user_plugin import get_user_result, get_group_dn
@@ -1560,6 +1561,13 @@ def indicators_service(request):
     return tracker.make_fixture(request)
 
 
+@pytest.fixture(scope='function')
+def indicators_internal_service(request):
+    tracker = ServiceTracker(
+        name=u'ldap', host_fqdn=fqdn1)
+    return tracker.make_fixture(request)
+
+
 @pytest.mark.tier1
 class TestAuthenticationIndicators(XMLRPC_test):
     def test_create_service_with_otp_indicator(
@@ -1587,6 +1595,19 @@ def test_update_indicator(self, indicators_host, indicators_service):
             expected_updates={u'krbprincipalauthind': [u'radius']}
         )
 
+    def test_update_indicator_internal_service(self, indicators_host,
+                                               indicators_internal_service):
+        indicators_host.create()
+        indicators_internal_service.create()
+        with raises_exact(errors.ValidationError(
+            name='krbprincipalauthind',
+            error=u'authentication indicators not allowed '
+                'in service "ldap"'
+        )):
+            indicators_internal_service.update(
+                updates={u'krbprincipalauthind': u'radius'}
+            )
+
 
 @pytest.fixture(scope='function')
 def managing_host(request):
