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

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