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

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