Blob Blame History Raw
From a8b52eaf3cf56c90e3d94fdef0b9e426052634ea Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 18 Dec 2019 12:08:59 +0200
Subject: [PATCH] Reset per-indicator Kerberos policy

When 'ipa krbtpolicy-reset' is called, we need to reset all policy
settings, including per-indicator ones. Per-indicator policy uses
subtyped attributes (foo;bar), the current krbtpolicy-reset code does
not deal with those.

Add support for per-indicator policy reset. It is a bit tricky, as we
need to drop the values to defaults but avoid adding non-per-indicator
variants of the same attributes.

Add test to check that policy has been resetted by observing a new
Kerberos TGT for the user after its policy reset.

Fixes: https://pagure.io/freeipa/issue/8153

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
 ipaserver/plugins/krbtpolicy.py              | 21 +++++++++++++++++++-
 ipatests/test_integration/test_krbtpolicy.py | 13 ++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/ipaserver/plugins/krbtpolicy.py b/ipaserver/plugins/krbtpolicy.py
index 997fe7e81..b01c44e93 100644
--- a/ipaserver/plugins/krbtpolicy.py
+++ b/ipaserver/plugins/krbtpolicy.py
@@ -68,6 +68,8 @@ register = Registry()
 _default_values = {
     'krbmaxticketlife': 86400,
     'krbmaxrenewableage': 604800,
+    'krbauthindmaxticketlife': 86400,
+    'krbauthindmaxrenewableage': 604800,
 }
 
 # These attributes never have non-optional values, so they should be
@@ -311,9 +313,26 @@ class krbtpolicy_reset(baseldap.LDAPQuery):
                 def_values[a] = None
         # if reseting global policy - set values to default
         else:
-            def_values = _default_values
+            def_values = _default_values.copy()
 
         entry = ldap.get_entry(dn, list(def_values))
+
+        # For per-indicator policies, drop them to defaults
+        for subtype in _supported_options:
+            for attr in _option_based_attrs:
+                name = '{};{}'.format(attr, subtype)
+                if name in entry:
+                    if uid is not None:
+                        def_values[name] = None
+                    else:
+                        def_values[name] = _default_values[attr]
+
+        # Remove non-subtyped attrs variants,
+        # they should never be used directly.
+        for attr in _option_based_attrs:
+            if attr in def_values:
+                del def_values[attr]
+
         entry.update(def_values)
         try:
             ldap.update_entry(entry)
diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
index b2264de7a..08e332096 100644
--- a/ipatests/test_integration/test_krbtpolicy.py
+++ b/ipatests/test_integration/test_krbtpolicy.py
@@ -112,3 +112,16 @@ class TestPWPolicy(IntegrationTest):
         assert maxlife_within_policy(result.stdout_text, 1200) is True
 
         tasks.kdestroy_all(master)
+
+    def test_krbtpolicy_reset(self):
+        """Test a hardened kerberos ticket policy reset"""
+        master = self.master
+
+        tasks.kinit_admin(master)
+        master.run_command(['ipa', 'krbtpolicy-reset', USER2])
+        master.run_command(['kinit', USER2],
+                           stdin_text=PASSWORD + '\n')
+        result = master.run_command('klist | grep krbtgt')
+        assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
+
+        tasks.kdestroy_all(master)
-- 
2.24.1