7e1b55
From dffccae7193b0616cb84792edec480f5f67e1fc6 Mon Sep 17 00:00:00 2001
7e1b55
From: Antonio Torres <antorres@redhat.com>
7e1b55
Date: Mon, 8 Mar 2021 18:15:50 +0100
7e1b55
Subject: [PATCH] Add checks to prevent adding auth indicators to internal IPA
7e1b55
 services
7e1b55
7e1b55
Authentication indicators should not be enforced against internal
7e1b55
IPA services, since not all users of those services are able to produce
7e1b55
Kerberos tickets with all the auth indicator options. This includes
7e1b55
host, ldap, HTTP and cifs in IPA server and cifs in IPA clients.
7e1b55
If a client that is being promoted to replica has an auth indicator
7e1b55
in its host principal then the promotion is aborted.
7e1b55
7e1b55
Fixes: https://pagure.io/freeipa/issue/8206
7e1b55
Signed-off-by: Antonio Torres <antorres@redhat.com>
7e1b55
---
7e1b55
 ipaserver/install/server/replicainstall.py | 13 ++++++++++++
7e1b55
 ipaserver/plugins/host.py                  |  5 ++++-
7e1b55
 ipaserver/plugins/service.py               | 24 ++++++++++++++++++++++
7e1b55
 3 files changed, 41 insertions(+), 1 deletion(-)
7e1b55
7e1b55
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
7e1b55
index 73967a2249d5c8944d70c5c3ca9a9d3b3bfc6b73..f1fb9103687ce9719ef24c8cb3c41088a4003b25 100644
7e1b55
--- a/ipaserver/install/server/replicainstall.py
7e1b55
+++ b/ipaserver/install/server/replicainstall.py
7e1b55
@@ -770,6 +770,15 @@ def promotion_check_ipa_domain(master_ldap_conn, basedn):
7e1b55
         ))
7e1b55
 
7e1b55
 
7e1b55
+def promotion_check_host_principal_auth_ind(conn, hostdn):
7e1b55
+    entry = conn.get_entry(hostdn, ['krbprincipalauthind'])
7e1b55
+    if 'krbprincipalauthind' in entry:
7e1b55
+        raise RuntimeError(
7e1b55
+            "Client cannot be promoted to a replica if the host principal "
7e1b55
+            "has an authentication indicator set."
7e1b55
+        )
7e1b55
+
7e1b55
+
7e1b55
 @common_cleanup
7e1b55
 @preserve_enrollment_state
7e1b55
 def promote_check(installer):
7e1b55
@@ -956,6 +965,10 @@ def promote_check(installer):
7e1b55
                                      config.master_host_name, None)
7e1b55
 
7e1b55
         promotion_check_ipa_domain(conn, remote_api.env.basedn)
7e1b55
+        hostdn = DN(('fqdn', api.env.host),
7e1b55
+                    api.env.container_host,
7e1b55
+                    api.env.basedn)
7e1b55
+        promotion_check_host_principal_auth_ind(conn, hostdn)
7e1b55
 
7e1b55
         # Make sure that domain fulfills minimal domain level
7e1b55
         # requirement
7e1b55
diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
7e1b55
index eb1f8ef042faf4b0deadfd5cef47f7688836506e..41fa933e2422184eafc4eae185a163082b96e045 100644
7e1b55
--- a/ipaserver/plugins/host.py
7e1b55
+++ b/ipaserver/plugins/host.py
7e1b55
@@ -38,7 +38,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
7e1b55
                                      LDAPAddAttributeViaOption,
7e1b55
                                      LDAPRemoveAttributeViaOption)
7e1b55
 from .service import (
7e1b55
-    validate_realm, normalize_principal,
7e1b55
+    validate_realm, validate_auth_indicator, normalize_principal,
7e1b55
     set_certificate_attrs, ticket_flags_params, update_krbticketflags,
7e1b55
     set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
7e1b55
     rename_ipaallowedtoperform_to_ldap, revoke_certs)
7e1b55
@@ -735,6 +735,8 @@ class host_add(LDAPCreate):
7e1b55
         update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
7e1b55
         if 'krbticketflags' in entry_attrs:
7e1b55
             entry_attrs['objectclass'].append('krbticketpolicyaux')
7e1b55
+        validate_auth_indicator(entry_attrs)
7e1b55
+
7e1b55
         return dn
7e1b55
 
7e1b55
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
7e1b55
@@ -993,6 +995,7 @@ class host_mod(LDAPUpdate):
7e1b55
             if 'krbprincipalaux' not in (item.lower() for item in
7e1b55
                                          entry_attrs['objectclass']):
7e1b55
                 entry_attrs['objectclass'].append('krbprincipalaux')
7e1b55
+            validate_auth_indicator(entry_attrs)
7e1b55
 
7e1b55
         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
7e1b55
 
7e1b55
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
7e1b55
index 1c93478049f5bdfdaf8503e459bd962dbbee9b44..cfbbff3c69c6a92535df58c51767c3d0952c7b0b 100644
7e1b55
--- a/ipaserver/plugins/service.py
7e1b55
+++ b/ipaserver/plugins/service.py
7e1b55
@@ -201,6 +201,28 @@ def validate_realm(ugettext, principal):
7e1b55
         raise errors.RealmMismatch()
7e1b55
 
7e1b55
 
7e1b55
+def validate_auth_indicator(entry):
7e1b55
+    new_value = entry.get('krbprincipalauthind', None)
7e1b55
+    if not new_value:
7e1b55
+        return
7e1b55
+    # The following services are considered internal IPA services
7e1b55
+    # and shouldn't be allowed to have auth indicators.
7e1b55
+    # https://pagure.io/freeipa/issue/8206
7e1b55
+    pkey = api.Object['service'].get_primary_key_from_dn(entry.dn)
7e1b55
+    principal = kerberos.Principal(pkey)
7e1b55
+    server = api.Command.server_find(principal.hostname)['result']
7e1b55
+    if server:
7e1b55
+        prefixes = ("host", "cifs", "ldap", "HTTP")
7e1b55
+    else:
7e1b55
+        prefixes = ("cifs",)
7e1b55
+    if principal.service_name in prefixes:
7e1b55
+        raise errors.ValidationError(
7e1b55
+            name='krbprincipalauthind',
7e1b55
+            error=_('authentication indicators not allowed '
7e1b55
+                    'in service "%s"' % principal.service_name)
7e1b55
+        )
7e1b55
+
7e1b55
+
7e1b55
 def normalize_principal(value):
7e1b55
     """
7e1b55
     Ensure that the name in the principal is lower-case. The realm is
7e1b55
@@ -652,6 +674,7 @@ class service_add(LDAPCreate):
7e1b55
                     hostname)
7e1b55
 
7e1b55
         self.obj.validate_ipakrbauthzdata(entry_attrs)
7e1b55
+        validate_auth_indicator(entry_attrs)
7e1b55
 
7e1b55
         if not options.get('force', False):
7e1b55
             # We know the host exists if we've gotten this far but we
7e1b55
@@ -846,6 +869,7 @@ class service_mod(LDAPUpdate):
7e1b55
         assert isinstance(dn, DN)
7e1b55
 
7e1b55
         self.obj.validate_ipakrbauthzdata(entry_attrs)
7e1b55
+        validate_auth_indicator(entry_attrs)
7e1b55
 
7e1b55
         # verify certificates
7e1b55
         certs = entry_attrs.get('usercertificate') or []
7e1b55
-- 
7e1b55
2.26.3
7e1b55