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