Blob Blame History Raw
From dffccae7193b0616cb84792edec480f5f67e1fc6 Mon Sep 17 00:00:00 2001
From: Antonio Torres <antorres@redhat.com>
Date: Mon, 8 Mar 2021 18:15:50 +0100
Subject: [PATCH] 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 services are able to produce
Kerberos tickets with all the auth indicator options. This includes
host, ldap, HTTP and cifs in IPA server and cifs in IPA clients.
If a client that is being promoted to replica has an auth indicator
in its host principal then the promotion is aborted.

Fixes: https://pagure.io/freeipa/issue/8206
Signed-off-by: Antonio Torres <antorres@redhat.com>
---
 ipaserver/install/server/replicainstall.py | 13 ++++++++++++
 ipaserver/plugins/host.py                  |  5 ++++-
 ipaserver/plugins/service.py               | 24 ++++++++++++++++++++++
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 73967a2249d5c8944d70c5c3ca9a9d3b3bfc6b73..f1fb9103687ce9719ef24c8cb3c41088a4003b25 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -770,6 +770,15 @@ def promotion_check_ipa_domain(master_ldap_conn, basedn):
         ))
 
 
+def promotion_check_host_principal_auth_ind(conn, hostdn):
+    entry = conn.get_entry(hostdn, ['krbprincipalauthind'])
+    if 'krbprincipalauthind' in entry:
+        raise RuntimeError(
+            "Client cannot be promoted to a replica if the host principal "
+            "has an authentication indicator set."
+        )
+
+
 @common_cleanup
 @preserve_enrollment_state
 def promote_check(installer):
@@ -956,6 +965,10 @@ def promote_check(installer):
                                      config.master_host_name, None)
 
         promotion_check_ipa_domain(conn, remote_api.env.basedn)
+        hostdn = DN(('fqdn', api.env.host),
+                    api.env.container_host,
+                    api.env.basedn)
+        promotion_check_host_principal_auth_ind(conn, hostdn)
 
         # Make sure that domain fulfills minimal domain level
         # requirement
diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
index eb1f8ef042faf4b0deadfd5cef47f7688836506e..41fa933e2422184eafc4eae185a163082b96e045 100644
--- a/ipaserver/plugins/host.py
+++ b/ipaserver/plugins/host.py
@@ -38,7 +38,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
                                      LDAPAddAttributeViaOption,
                                      LDAPRemoveAttributeViaOption)
 from .service import (
-    validate_realm, normalize_principal,
+    validate_realm, validate_auth_indicator, normalize_principal,
     set_certificate_attrs, ticket_flags_params, update_krbticketflags,
     set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
     rename_ipaallowedtoperform_to_ldap, revoke_certs)
@@ -735,6 +735,8 @@ class host_add(LDAPCreate):
         update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
         if 'krbticketflags' in entry_attrs:
             entry_attrs['objectclass'].append('krbticketpolicyaux')
+        validate_auth_indicator(entry_attrs)
+
         return dn
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -993,6 +995,7 @@ class host_mod(LDAPUpdate):
             if 'krbprincipalaux' not in (item.lower() for item in
                                          entry_attrs['objectclass']):
                 entry_attrs['objectclass'].append('krbprincipalaux')
+            validate_auth_indicator(entry_attrs)
 
         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
 
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
index 1c93478049f5bdfdaf8503e459bd962dbbee9b44..cfbbff3c69c6a92535df58c51767c3d0952c7b0b 100644
--- a/ipaserver/plugins/service.py
+++ b/ipaserver/plugins/service.py
@@ -201,6 +201,28 @@ def validate_realm(ugettext, principal):
         raise errors.RealmMismatch()
 
 
+def validate_auth_indicator(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
+    pkey = api.Object['service'].get_primary_key_from_dn(entry.dn)
+    principal = kerberos.Principal(pkey)
+    server = api.Command.server_find(principal.hostname)['result']
+    if server:
+        prefixes = ("host", "cifs", "ldap", "HTTP")
+    else:
+        prefixes = ("cifs",)
+    if principal.service_name in prefixes:
+        raise errors.ValidationError(
+            name='krbprincipalauthind',
+            error=_('authentication indicators not allowed '
+                    'in service "%s"' % principal.service_name)
+        )
+
+
 def normalize_principal(value):
     """
     Ensure that the name in the principal is lower-case. The realm is
@@ -652,6 +674,7 @@ class service_add(LDAPCreate):
                     hostname)
 
         self.obj.validate_ipakrbauthzdata(entry_attrs)
+        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 +869,7 @@ class service_mod(LDAPUpdate):
         assert isinstance(dn, DN)
 
         self.obj.validate_ipakrbauthzdata(entry_attrs)
+        validate_auth_indicator(entry_attrs)
 
         # verify certificates
         certs = entry_attrs.get('usercertificate') or []
-- 
2.26.3