import ipa-4.10.1-6.el9
This commit is contained in:
parent
d43259bde1
commit
8d6169b43d
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/freeipa-4.10.0.tar.gz
|
SOURCES/freeipa-4.10.1.tar.gz
|
||||||
|
@ -1 +1 @@
|
|||||||
901ede9686abffef511c6477d90d5e6fd32d6fbc SOURCES/freeipa-4.10.0.tar.gz
|
6203cf7c2e003c35eb9ac40e4fd2954c6bea1856 SOURCES/freeipa-4.10.1.tar.gz
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
From 22d1392a8a0d2887c389dcd78be06104cff88d30 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Wed, 29 Jun 2022 13:25:55 +0000
|
|
||||||
Subject: [PATCH] Only calculate LDAP password grace when the password is
|
|
||||||
expired
|
|
||||||
|
|
||||||
The user's pwd expiration was retrieved but inadvertently was never
|
|
||||||
compared to current time. So any LDAP bind, including from the
|
|
||||||
IPA API, counted against the grace period. There is no need to go
|
|
||||||
through the graceperiod code for non-expired passwords.
|
|
||||||
|
|
||||||
https://pagure.io/freeipa/issue/1539
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../ipa-graceperiod/ipa_graceperiod.c | 12 +++++++++---
|
|
||||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
index 0860b5c20fc86687f80ee6f2426e23c87123130f..a3f57cb4bd7a2a66d70fae98cca0f62a8f0c017f 100644
|
|
||||||
--- a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
+++ b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
@@ -359,7 +359,8 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
Slapi_ValueSet *values = NULL;
|
|
||||||
long grace_limit = 0;
|
|
||||||
int grace_user_time;
|
|
||||||
- char *pwd_expiration = NULL;
|
|
||||||
+ char *tmpstr = NULL;
|
|
||||||
+ time_t pwd_expiration;
|
|
||||||
int pwresponse_requested = 0;
|
|
||||||
Slapi_PBlock *pbtm = NULL;
|
|
||||||
Slapi_Mods *smods = NULL;
|
|
||||||
@@ -414,12 +415,17 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
}
|
|
||||||
slapi_value_free(&objectclass);
|
|
||||||
|
|
||||||
- pwd_expiration = slapi_entry_attr_get_charptr(target_entry, "krbPasswordExpiration");
|
|
||||||
- if (pwd_expiration == NULL) {
|
|
||||||
+ tmpstr = slapi_entry_attr_get_charptr(target_entry, "krbPasswordExpiration");
|
|
||||||
+ if (tmpstr == NULL) {
|
|
||||||
/* No expiration means nothing to do */
|
|
||||||
LOG_TRACE("No krbPasswordExpiration for %s, nothing to do\n", dn);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
+ pwd_expiration = ipapwd_gentime_to_time_t(tmpstr);
|
|
||||||
+ if (pwd_expiration > time(NULL)) {
|
|
||||||
+ /* Not expired, nothing to see here */
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
ldrc = ipagraceperiod_getpolicy(target_entry, &policy_entry,
|
|
||||||
&values, &actual_type_name,
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From 42be04fe4ff317efe599dcbc2637f94ecc6fa220 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Date: Mon, 21 Nov 2022 16:12:46 +0200
|
||||||
|
Subject: [PATCH] updates: fix memberManager ACI to allow managers from a
|
||||||
|
specified group
|
||||||
|
|
||||||
|
The original implementation of the member manager added support for both
|
||||||
|
user and group managers but left out upgrade scenario. This means when
|
||||||
|
upgrading existing installation a manager whose rights defined by the
|
||||||
|
group membership would not be able to add group members until the ACI is
|
||||||
|
fixed.
|
||||||
|
|
||||||
|
Remove old ACI and add a full one during upgrade step.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9286
|
||||||
|
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
install/updates/20-aci.update | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
|
||||||
|
index a168bb9573a9fbb9ff15f0b19bb8ec75b48d82a9..4a7ba137c4711aa3f8b064fdd482ffee76c59949 100644
|
||||||
|
--- a/install/updates/20-aci.update
|
||||||
|
+++ b/install/updates/20-aci.update
|
||||||
|
@@ -141,11 +141,13 @@ add:aci:(targetattr = "usercertificate")(version 3.0;acl "selfservice:Users can
|
||||||
|
|
||||||
|
# Allow member managers to modify members of user groups
|
||||||
|
dn: cn=groups,cn=accounts,$SUFFIX
|
||||||
|
-add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+remove:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN" or userattr = "memberManager#GROUPDN";)
|
||||||
|
|
||||||
|
# Allow member managers to modify members of host groups
|
||||||
|
dn: cn=hostgroups,cn=accounts,$SUFFIX
|
||||||
|
-add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+remove:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN" or userattr = "memberManager#GROUPDN";)
|
||||||
|
|
||||||
|
# Hosts can add and delete their own services
|
||||||
|
dn: cn=services,cn=accounts,$SUFFIX
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 2d0a0cc40fb8674f30ba62980b1953cef840009e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Thu, 1 Dec 2022 13:58:58 +0100
|
||||||
|
Subject: [PATCH] Spec file: ipa-client depends on krb5-pkinit-openssl
|
||||||
|
|
||||||
|
Now that ipa-client-installs supports pkinit, the package
|
||||||
|
depends on krb5-pkinit-openssl.
|
||||||
|
Update the spec file, move the dependency from ipa-server
|
||||||
|
to ipa-client subpackage.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9290
|
||||||
|
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
freeipa.spec.in | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||||
|
index f09741d7ad6c09e52c4bd24fcc9300584f83a49d..7dcf2e66abe40e6bde3491268b9c012f7578a8b6 100755
|
||||||
|
--- a/freeipa.spec.in
|
||||||
|
+++ b/freeipa.spec.in
|
||||||
|
@@ -449,7 +449,6 @@ Requires: nss-tools >= %{nss_version}
|
||||||
|
Requires(post): krb5-server >= %{krb5_version}
|
||||||
|
Requires(post): krb5-server >= %{krb5_base_version}
|
||||||
|
Requires: krb5-kdb-version = %{krb5_kdb_version}
|
||||||
|
-Requires: krb5-pkinit-openssl >= %{krb5_version}
|
||||||
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
|
Requires: chrony
|
||||||
|
Requires: httpd >= %{httpd_version}
|
||||||
|
@@ -675,6 +674,8 @@ Requires: python3-sssdconfig >= %{sssd_version}
|
||||||
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
|
Requires: chrony
|
||||||
|
Requires: krb5-workstation >= %{krb5_version}
|
||||||
|
+# support pkinit with client install
|
||||||
|
+Requires: krb5-pkinit-openssl >= %{krb5_version}
|
||||||
|
# authselect: sssd profile with-subid
|
||||||
|
%if 0%{?fedora} >= 36
|
||||||
|
Requires: authselect >= 1.4.0
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -1,67 +0,0 @@
|
|||||||
From 02d3fb8266d8199fd1ed983de6c57b269546df82 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Armando Neto <abiagion@redhat.com>
|
|
||||||
Date: Fri, 8 Jul 2022 15:56:31 -0300
|
|
||||||
Subject: [PATCH] webui: Do not allow empty pagination size
|
|
||||||
|
|
||||||
Pagination size must be required, the current validators are triggered after
|
|
||||||
form is submitted, thus the only way for check if data is not empty is by making
|
|
||||||
the field required.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9192
|
|
||||||
|
|
||||||
Signed-off-by: Armando Neto <abiagion@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../ui/src/freeipa/Application_controller.js | 1 +
|
|
||||||
ipatests/test_webui/test_misc_cases.py | 19 +++++++++++++++++++
|
|
||||||
2 files changed, 20 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
|
|
||||||
index 46aabc9c4dd47aa3874cb3ddf27da048607b7516..140ee8fe0d7adc274396248aae0be2f4559db27a 100644
|
|
||||||
--- a/install/ui/src/freeipa/Application_controller.js
|
|
||||||
+++ b/install/ui/src/freeipa/Application_controller.js
|
|
||||||
@@ -318,6 +318,7 @@ define([
|
|
||||||
$type: 'text',
|
|
||||||
name: 'pagination_size',
|
|
||||||
label: '@i18n:customization.table_pagination',
|
|
||||||
+ required: true,
|
|
||||||
validators: ['positive_integer']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/ipatests/test_webui/test_misc_cases.py b/ipatests/test_webui/test_misc_cases.py
|
|
||||||
index 5f7ffb54ee33e9b453d6b987b7bf84d6f4311ebd..aca9e1a99e1e2cf60790fe8c33a65430e0d535e2 100644
|
|
||||||
--- a/ipatests/test_webui/test_misc_cases.py
|
|
||||||
+++ b/ipatests/test_webui/test_misc_cases.py
|
|
||||||
@@ -11,6 +11,11 @@ from ipatests.test_webui.ui_driver import screenshot
|
|
||||||
import pytest
|
|
||||||
import re
|
|
||||||
|
|
||||||
+try:
|
|
||||||
+ from selenium.webdriver.common.by import By
|
|
||||||
+except ImportError:
|
|
||||||
+ pass
|
|
||||||
+
|
|
||||||
|
|
||||||
@pytest.mark.tier1
|
|
||||||
class TestMiscCases(UI_driver):
|
|
||||||
@@ -26,3 +31,17 @@ class TestMiscCases(UI_driver):
|
|
||||||
ver_re = re.compile('version: .*')
|
|
||||||
assert re.search(ver_re, about_text), 'Version not found'
|
|
||||||
self.dialog_button_click('ok')
|
|
||||||
+
|
|
||||||
+ @screenshot
|
|
||||||
+ def test_customization_pagination_input_required(self):
|
|
||||||
+ """Test if 'pagination size' is required when submitting the form."""
|
|
||||||
+ self.init_app()
|
|
||||||
+
|
|
||||||
+ self.profile_menu_action('configuration')
|
|
||||||
+ self.fill_input('pagination_size', '')
|
|
||||||
+ self.dialog_button_click('save')
|
|
||||||
+
|
|
||||||
+ pagination_size_elem = self.find(
|
|
||||||
+ ".widget[name='pagination_size']", By.CSS_SELECTOR)
|
|
||||||
+
|
|
||||||
+ self.assert_field_validation_required(parent=pagination_size_elem)
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
|||||||
|
From 894dca12c120f0bfa705307a0609da47326b8fb2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 11:26:53 +0100
|
||||||
|
Subject: [PATCH] server install: remove error log about missing bkup file
|
||||||
|
|
||||||
|
The client installer code can be called in 3 different ways:
|
||||||
|
- from ipa-client-install CLI
|
||||||
|
- from ipa-replica-install CLI if the client is not already installed
|
||||||
|
- from ipa-server-install
|
||||||
|
|
||||||
|
In the last case, the client installer is called with
|
||||||
|
options.on_master=True
|
||||||
|
As a result, it's skipping the part that is creating the krb5
|
||||||
|
configuration:
|
||||||
|
if not options.on_master:
|
||||||
|
nolog = tuple()
|
||||||
|
configure_krb5_conf(...)
|
||||||
|
|
||||||
|
The configure_krb5_conf method is the place where the krb5.conf file is
|
||||||
|
backup'ed with the extention ".ipabkp". For a master installation, this
|
||||||
|
code is not called and the ipabkp file does not exist => delete raises
|
||||||
|
an error.
|
||||||
|
|
||||||
|
When delete fails because the file does not exist, no need to log an
|
||||||
|
error message.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9306
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipaclient/install/client.py | 7 +++----
|
||||||
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||||
|
index e5d3e8223efa1ebb69a1b7e963c394f9e1f38816..6e7f17d5b69581320866627cb5747a050cb6e32e 100644
|
||||||
|
--- a/ipaclient/install/client.py
|
||||||
|
+++ b/ipaclient/install/client.py
|
||||||
|
@@ -124,10 +124,9 @@ def cleanup(func):
|
||||||
|
os.rmdir(ccache_dir)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
- try:
|
||||||
|
- os.remove(krb_name + ".ipabkp")
|
||||||
|
- except OSError:
|
||||||
|
- logger.error("Could not remove %s.ipabkp", krb_name)
|
||||||
|
+ # During master installation, the .ipabkp file is not created
|
||||||
|
+ # Ignore the delete error if it is "file does not exist"
|
||||||
|
+ remove_file(krb_name + ".ipabkp")
|
||||||
|
|
||||||
|
return inner
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
From aca97507cd119ad55e0c3c18ca65087cb5576c82 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sumedh Sidhaye <ssidhaye@redhat.com>
|
|
||||||
Date: Mon, 13 Jun 2022 13:49:08 +0530
|
|
||||||
Subject: [PATCH] Added a check while removing 'cert_dir'. The teardown method
|
|
||||||
is called even if all the tests are skipped since the required PKI version is
|
|
||||||
not present. The teardown is trying to remove a non-existent directory.
|
|
||||||
|
|
||||||
Currently the cert_dir attribute is only present if IPA installation was
|
|
||||||
done. If IPA was not installed the attribute does not exist.
|
|
||||||
In order that the uninstall code finds the attribute a class attribute
|
|
||||||
is added.
|
|
||||||
|
|
||||||
Pagure Issue: https://pagure.io/freeipa/issue/9179
|
|
||||||
|
|
||||||
Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
---
|
|
||||||
ipatests/test_integration/test_caless.py | 12 +++++++++++-
|
|
||||||
.../test_integration/test_random_serial_numbers.py | 6 ++++++
|
|
||||||
2 files changed, 17 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/test_integration/test_caless.py b/ipatests/test_integration/test_caless.py
|
|
||||||
index 96f477bbe4b0e25184605a80659b5ec6529a2320..4c370f77e84215714e533b1b6ebeb89216319c0f 100644
|
|
||||||
--- a/ipatests/test_integration/test_caless.py
|
|
||||||
+++ b/ipatests/test_integration/test_caless.py
|
|
||||||
@@ -122,6 +122,15 @@ def replica_install_teardown(func):
|
|
||||||
|
|
||||||
|
|
||||||
class CALessBase(IntegrationTest):
|
|
||||||
+ # The teardown method is called even if all the tests are skipped
|
|
||||||
+ # since the required PKI version is not present.
|
|
||||||
+ # The teardown is trying to remove a non-existent directory.
|
|
||||||
+ # Currently the cert_dir attribute is only present if IPA installation was
|
|
||||||
+ # done. If IPA was not installed the attribute does not exist.
|
|
||||||
+ # In order that the uninstall code finds the attribute a class attribute
|
|
||||||
+ # is added.
|
|
||||||
+ cert_dir = None
|
|
||||||
+
|
|
||||||
@classmethod
|
|
||||||
def install(cls, mh):
|
|
||||||
cls.cert_dir = tempfile.mkdtemp(prefix="ipatest-")
|
|
||||||
@@ -164,7 +173,8 @@ class CALessBase(IntegrationTest):
|
|
||||||
@classmethod
|
|
||||||
def uninstall(cls, mh):
|
|
||||||
# Remove the NSS database
|
|
||||||
- shutil.rmtree(cls.cert_dir)
|
|
||||||
+ if cls.cert_dir:
|
|
||||||
+ shutil.rmtree(cls.cert_dir)
|
|
||||||
super(CALessBase, cls).uninstall(mh)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
diff --git a/ipatests/test_integration/test_random_serial_numbers.py b/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
index a931c7b562f00f94e10d1e9e891fbf0624d5fd88..c52cfa4ed50e2718791b0844d743fb240d26b365 100644
|
|
||||||
--- a/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
+++ b/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
@@ -64,3 +64,9 @@ class TestServerCALessToExternalCA_RSN(TestServerCALessToExternalCA):
|
|
||||||
if not pki_supports_RSNv3(mh.master):
|
|
||||||
raise pytest.skip("RNSv3 not supported")
|
|
||||||
super(TestServerCALessToExternalCA_RSN, cls).install(mh)
|
|
||||||
+
|
|
||||||
+ @classmethod
|
|
||||||
+ def uninstall(cls, mh):
|
|
||||||
+ if not pki_supports_RSNv3(mh.master):
|
|
||||||
+ raise pytest.skip("RSNv3 not supported")
|
|
||||||
+ super(TestServerCALessToExternalCA_RSN, cls).uninstall(mh)
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
|||||||
|
From 2520a7adff7a49ddcddaaf19f0e586425dc0d878 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Filip Dvorak <fdvorak@redhat.com>
|
||||||
|
Date: Tue, 6 Dec 2022 15:51:27 +0100
|
||||||
|
Subject: [PATCH] ipa tests: Add LANG before kinit command to fix issue with
|
||||||
|
locale settings
|
||||||
|
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_krbtpolicy.py | 20 ++++++++++----------
|
||||||
|
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
|
||||||
|
index eae16247bdfb195c1d91209cf2d11eac4c25018f..269cfb0a191821c229aaeb5a3eda0181c6e3ae62 100644
|
||||||
|
--- a/ipatests/test_integration/test_krbtpolicy.py
|
||||||
|
+++ b/ipatests/test_integration/test_krbtpolicy.py
|
||||||
|
@@ -23,7 +23,7 @@ PASSWORD = "Secret123"
|
||||||
|
USER1 = "testuser1"
|
||||||
|
USER2 = "testuser2"
|
||||||
|
MAXLIFE = 86400
|
||||||
|
-
|
||||||
|
+LANG_PKG = ["langpacks-en"]
|
||||||
|
|
||||||
|
def maxlife_within_policy(input, maxlife, slush=3600):
|
||||||
|
"""Given klist output of the TGT verify that it is within policy
|
||||||
|
@@ -45,7 +45,6 @@ def maxlife_within_policy(input, maxlife, slush=3600):
|
||||||
|
|
||||||
|
return maxlife >= diff >= maxlife - slush
|
||||||
|
|
||||||
|
-
|
||||||
|
@pytest.fixture
|
||||||
|
def reset_to_default_policy():
|
||||||
|
"""Reset default user authentication and user authentication type"""
|
||||||
|
@@ -70,7 +69,7 @@ def reset_to_default_policy():
|
||||||
|
def kinit_check_life(master, user):
|
||||||
|
"""Acquire a TGT and check if it's within the lifetime window"""
|
||||||
|
master.run_command(["kinit", user], stdin_text=f"{PASSWORD}\n")
|
||||||
|
- result = master.run_command("klist | grep krbtgt")
|
||||||
|
+ result = master.run_command("LANG=en_US.utf-8 klist | grep krbtgt")
|
||||||
|
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
|
||||||
|
|
||||||
|
|
||||||
|
@@ -81,6 +80,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def install(cls, mh):
|
||||||
|
+ tasks.install_packages(cls.master, LANG_PKG)
|
||||||
|
tasks.install_master(cls.master)
|
||||||
|
tasks.create_active_user(cls.master, USER1, PASSWORD)
|
||||||
|
tasks.create_active_user(cls.master, USER2, PASSWORD)
|
||||||
|
@@ -100,7 +100,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
|
||||||
|
master.run_command(['kinit', USER1],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command("LANG=en_US.utf-8 klist | grep krbtgt")
|
||||||
|
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
|
||||||
|
|
||||||
|
def test_krbtpolicy_password_and_hardended(self):
|
||||||
|
@@ -122,7 +122,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
|
||||||
|
master.run_command(['kinit', USER1],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, 600,
|
||||||
|
slush=600) is True
|
||||||
|
|
||||||
|
@@ -131,7 +131,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
# Verify that the short policy only applies to USER1
|
||||||
|
master.run_command(['kinit', USER2],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
|
||||||
|
|
||||||
|
def test_krbtpolicy_hardended(self):
|
||||||
|
@@ -151,7 +151,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
|
||||||
|
master.run_command(['kinit', USER1],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, 1800,
|
||||||
|
slush=1800) is True
|
||||||
|
|
||||||
|
@@ -160,7 +160,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
# Verify that the short policy only applies to USER1
|
||||||
|
master.run_command(['kinit', USER2],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
|
||||||
|
|
||||||
|
def test_krbtpolicy_password(self):
|
||||||
|
@@ -173,7 +173,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
|
||||||
|
master.run_command(['kinit', USER2],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, 1200,
|
||||||
|
slush=1200) is True
|
||||||
|
|
||||||
|
@@ -183,7 +183,7 @@ class TestPWPolicy(IntegrationTest):
|
||||||
|
master.run_command(['ipa', 'krbtpolicy-reset', USER2])
|
||||||
|
master.run_command(['kinit', USER2],
|
||||||
|
stdin_text=PASSWORD + '\n')
|
||||||
|
- result = master.run_command('klist | grep krbtgt')
|
||||||
|
+ result = master.run_command('LANG=en_US.utf-8 klist | grep krbtgt')
|
||||||
|
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
|
||||||
|
|
||||||
|
def test_krbtpolicy_otp(self, reset_to_default_policy):
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
From c55185d3dc3c6cd2ffebab77fbf8caa40a32bcd1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Erik <ebelko@redhat.com>
|
|
||||||
Date: Mon, 18 Jul 2022 11:59:24 +0200
|
|
||||||
Subject: [PATCH] ipatests: healthcheck: test if system is FIPS enabled
|
|
||||||
|
|
||||||
Test if FIPS is enabled and the check exists.
|
|
||||||
|
|
||||||
Related: https://pagure.io/freeipa/issue/8951
|
|
||||||
|
|
||||||
Signed-off-by: Erik Belko <ebelko@redhat.com>
|
|
||||||
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
---
|
|
||||||
.../test_integration/test_ipahealthcheck.py | 25 +++++++++++++++++++
|
|
||||||
1 file changed, 25 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
|
||||||
index 23af09f3a7eaa8012e7a898ce6a534d1fad45323..a0c85f79e6e84f9e63072c6d70276480e4af97ad 100644
|
|
||||||
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
|
||||||
+++ b/ipatests/test_integration/test_ipahealthcheck.py
|
|
||||||
@@ -340,6 +340,31 @@ class TestIpaHealthCheck(IntegrationTest):
|
|
||||||
assert returncode == 0
|
|
||||||
assert output == "No issues found."
|
|
||||||
|
|
||||||
+ def test_ipa_healthcheck_fips_enabled(self):
|
|
||||||
+ """
|
|
||||||
+ Test if FIPS is enabled and the check exists.
|
|
||||||
+
|
|
||||||
+ https://pagure.io/freeipa/issue/8951
|
|
||||||
+ """
|
|
||||||
+ returncode, check = run_healthcheck(self.master,
|
|
||||||
+ source="ipahealthcheck.meta.core",
|
|
||||||
+ check="MetaCheck",
|
|
||||||
+ output_type="json",
|
|
||||||
+ failures_only=False)
|
|
||||||
+ assert returncode == 0
|
|
||||||
+
|
|
||||||
+ cmd = self.master.run_command(['fips-mode-setup', '--is-enabled'],
|
|
||||||
+ raiseonerr=False)
|
|
||||||
+ returncode = cmd.returncode
|
|
||||||
+
|
|
||||||
+ # If this produces IndexError, the check does not exist
|
|
||||||
+ if check[0]["kw"]["fips"] == "disabled":
|
|
||||||
+ assert returncode == 2
|
|
||||||
+ elif check[0]["kw"]["fips"] == "enabled":
|
|
||||||
+ assert returncode == 0
|
|
||||||
+ else:
|
|
||||||
+ assert returncode == 1
|
|
||||||
+
|
|
||||||
def test_ipa_healthcheck_after_certupdate(self):
|
|
||||||
"""
|
|
||||||
Verify that ipa-certupdate hasn't messed up tracking
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 97fc368df2db3b559a9def236d3c3e0a12bcdd0a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Mon, 23 Jan 2023 20:28:17 +0100
|
||||||
|
Subject: [PATCH] trust-add: handle missing msSFU30MaxGidNumber
|
||||||
|
|
||||||
|
When ipa trust-add is executed with --range-type ad-trust-posix,
|
||||||
|
the server tries to find the max uidnumber and max gidnumber
|
||||||
|
from AD domain controller.
|
||||||
|
The values are extracted from the entry
|
||||||
|
CN=<domain>,CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System,<AD suffix>
|
||||||
|
in the msSFU30MaxUidNumber and msSFU30MaxGidNumber attributes.
|
||||||
|
|
||||||
|
msSFU30MaxUidNumber is required but not msSFU30MaxGidNumber.
|
||||||
|
In case msSFU30MaxGidNumber is missing, the code is currently assigning
|
||||||
|
a "None" value and later on evaluates the max between this value and
|
||||||
|
msSFU30MaxUidNumber. The max function cannot compare None and a list
|
||||||
|
of string and triggers an exception.
|
||||||
|
|
||||||
|
To avoid the exception, assign [b'0'] to max gid if msSFU30MaxGidNumber
|
||||||
|
is missing. This way, the comparison succeeds and max returns the
|
||||||
|
value from msSFU30MaxUidNumber.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9310
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipaserver/plugins/trust.py | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
|
||||||
|
index c074f6d6e609476e416c95bcbe607654718ae9ce..79264b8d8a3b15dd4e5d0553e4ce42194b0ae044 100644
|
||||||
|
--- a/ipaserver/plugins/trust.py
|
||||||
|
+++ b/ipaserver/plugins/trust.py
|
||||||
|
@@ -379,7 +379,10 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
|
||||||
|
range_type = u'ipa-ad-trust-posix'
|
||||||
|
|
||||||
|
max_uid = info.get('msSFU30MaxUidNumber')
|
||||||
|
- max_gid = info.get('msSFU30MaxGidNumber', None)
|
||||||
|
+ # if max_gid is missing, assume 0 and the max will
|
||||||
|
+ # be obtained from max_uid. We just checked that
|
||||||
|
+ # msSFU30MaxUidNumber is defined
|
||||||
|
+ max_gid = info.get('msSFU30MaxGidNumber', [b'0'])
|
||||||
|
max_id = int(max(max_uid, max_gid)[0])
|
||||||
|
|
||||||
|
base_id = int(info.get('msSFU30OrderNumber')[0])
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,125 +0,0 @@
|
|||||||
From 1bb4ff9ed2313fb3c2bd1418258c5bcec557b6a5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 21 Jul 2022 09:28:46 -0400
|
|
||||||
Subject: [PATCH] Disabling gracelimit does not prevent LDAP binds
|
|
||||||
|
|
||||||
Originally the code treated 0 as disabled. This was
|
|
||||||
changed during the review process to -1 but one remnant
|
|
||||||
was missed effetively allowing gracelimit 0 to also mean
|
|
||||||
disabled.
|
|
||||||
|
|
||||||
Add explicit tests for testing with gracelimit = 0 and
|
|
||||||
gracelimit = -1.
|
|
||||||
|
|
||||||
Also remove some extranous "str(self.master.domain.basedn)"
|
|
||||||
lines from some of the tests.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9206
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
---
|
|
||||||
.../ipa-graceperiod/ipa_graceperiod.c | 2 +-
|
|
||||||
ipatests/test_integration/test_pwpolicy.py | 55 ++++++++++++++++++-
|
|
||||||
2 files changed, 53 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
index a3f57cb4bd7a2a66d70fae98cca0f62a8f0c017f..345e1dee7d163167373ca82dedb1e827f0e1bc8c 100644
|
|
||||||
--- a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
+++ b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
@@ -479,7 +479,7 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
if (pwresponse_requested) {
|
|
||||||
slapi_pwpolicy_make_response_control(pb, -1, grace_limit - grace_user_time , -1);
|
|
||||||
}
|
|
||||||
- } else if ((grace_limit > 0) && (grace_user_time >= grace_limit)) {
|
|
||||||
+ } else if (grace_user_time >= grace_limit) {
|
|
||||||
LOG_TRACE("%s password is expired and out of grace limit\n", dn);
|
|
||||||
errstr = "Password is expired.\n";
|
|
||||||
ret = LDAP_INVALID_CREDENTIALS;
|
|
||||||
diff --git a/ipatests/test_integration/test_pwpolicy.py b/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
index 6d66982848ac5a0061b47d30fad022be055c93e4..41d6e9070a90c2bde7b3182ad6ecf1a923bba203 100644
|
|
||||||
--- a/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
+++ b/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
@@ -36,7 +36,7 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
cls.master.run_command(['ipa', 'group-add-member', POLICY,
|
|
||||||
'--users', USER])
|
|
||||||
cls.master.run_command(['ipa', 'pwpolicy-add', POLICY,
|
|
||||||
- '--priority', '1'])
|
|
||||||
+ '--priority', '1', '--gracelimit', '-1'])
|
|
||||||
cls.master.run_command(['ipa', 'passwd', USER],
|
|
||||||
stdin_text='{password}\n{password}\n'.format(
|
|
||||||
password=PASSWORD
|
|
||||||
@@ -265,7 +265,6 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
|
|
||||||
def test_graceperiod_expired(self):
|
|
||||||
"""Test the LDAP bind grace period"""
|
|
||||||
- str(self.master.domain.basedn)
|
|
||||||
dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
|
|
||||||
@@ -308,7 +307,6 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
|
|
||||||
def test_graceperiod_not_replicated(self):
|
|
||||||
"""Test that the grace period is reset on password reset"""
|
|
||||||
- str(self.master.domain.basedn)
|
|
||||||
dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
|
|
||||||
@@ -341,3 +339,54 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
)
|
|
||||||
assert 'passwordgraceusertime: 0' in result.stdout_text.lower()
|
|
||||||
self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ def test_graceperiod_zero(self):
|
|
||||||
+ """Test the LDAP bind with zero grace period"""
|
|
||||||
+ dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
+ user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
+
|
|
||||||
+ self.master.run_command(
|
|
||||||
+ ["ipa", "pwpolicy-mod", POLICY, "--gracelimit", "0", ],
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # Resetting the password will mark it as expired
|
|
||||||
+ self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ # Now grace is done and binds should fail.
|
|
||||||
+ result = self.master.run_command(
|
|
||||||
+ ["ldapsearch", "-e", "ppolicy", "-D", dn,
|
|
||||||
+ "-w", PASSWORD, "-b", dn], raiseonerr=False
|
|
||||||
+ )
|
|
||||||
+ assert result.returncode == 49
|
|
||||||
+
|
|
||||||
+ assert 'Password is expired' in result.stderr_text
|
|
||||||
+ assert 'Password expired, 0 grace logins remain' in result.stderr_text
|
|
||||||
+
|
|
||||||
+ def test_graceperiod_disabled(self):
|
|
||||||
+ """Test the LDAP bind with grace period disabled (-1)"""
|
|
||||||
+ str(self.master.domain.basedn)
|
|
||||||
+ dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
+ user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
+
|
|
||||||
+ # This can fail if gracelimit is already -1 so ignore it
|
|
||||||
+ self.master.run_command(
|
|
||||||
+ ["ipa", "pwpolicy-mod", POLICY, "--gracelimit", "-1",],
|
|
||||||
+ raiseonerr=False,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # Ensure the password is expired
|
|
||||||
+ self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ result = self.kinit_as_user(self.master, PASSWORD, PASSWORD)
|
|
||||||
+
|
|
||||||
+ for _i in range(0, 10):
|
|
||||||
+ result = self.master.run_command(
|
|
||||||
+ ["ldapsearch", "-e", "ppolicy", "-D", dn,
|
|
||||||
+ "-w", PASSWORD, "-b", dn]
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # With graceperiod disabled it should not increment
|
|
||||||
+ result = tasks.ldapsearch_dm(
|
|
||||||
+ self.master, dn, ['passwordgraceusertime',],
|
|
||||||
+ )
|
|
||||||
+ assert 'passwordgraceusertime: 0' in result.stdout_text.lower()
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
337
SOURCES/0006-doc-Design-for-certificate-pruning.patch
Normal file
337
SOURCES/0006-doc-Design-for-certificate-pruning.patch
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
From 51b1c22d025bf40e9ef488bb0faf0c8dff303ccd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Thu, 8 Dec 2022 16:18:07 -0500
|
||||||
|
Subject: [PATCH] doc: Design for certificate pruning
|
||||||
|
|
||||||
|
This describes how the certificate pruning capability of PKI
|
||||||
|
introduced in v11.3.0 will be integrated into IPA, primarily for
|
||||||
|
ACME.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9294
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||||
|
---
|
||||||
|
doc/designs/expired_certificate_pruning.md | 297 +++++++++++++++++++++
|
||||||
|
doc/designs/index.rst | 1 +
|
||||||
|
2 files changed, 298 insertions(+)
|
||||||
|
create mode 100644 doc/designs/expired_certificate_pruning.md
|
||||||
|
|
||||||
|
diff --git a/doc/designs/expired_certificate_pruning.md b/doc/designs/expired_certificate_pruning.md
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..2c10d914020d3c12b6abb028323cd6796ec33e00
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/doc/designs/expired_certificate_pruning.md
|
||||||
|
@@ -0,0 +1,297 @@
|
||||||
|
+# Expired Certificate Pruning
|
||||||
|
+
|
||||||
|
+## Overview
|
||||||
|
+
|
||||||
|
+https://pagure.io/dogtagpki/issue/1750
|
||||||
|
+
|
||||||
|
+When using short-lived certs and regular issuance, the expired certs can build up in the PKI database and cause issues with replication, performance and overall database size.
|
||||||
|
+
|
||||||
|
+PKI has provided a new feature in 11.3.0, pruning, which is a job that can be executed on a schedule or manually to remove expired certificates and requests.
|
||||||
|
+
|
||||||
|
+Random Serial Numbers v3 (RSNv3) is mandatory to enable pruning.
|
||||||
|
+
|
||||||
|
+Both pruning and RSNv3 require PKI 11.3.0 or higher.
|
||||||
|
+
|
||||||
|
+## Use Cases
|
||||||
|
+
|
||||||
|
+ACME certificates in particular are generally short-lived and expired certificates can build up quickly in a dynamic environment. An example is a CI system that requests one or more certificates per run. These will build up infinitely without a way to remove the expired certificates.
|
||||||
|
+
|
||||||
|
+Another case is simply a very long-lived installation. Over time as hosts come and go certificates build up.
|
||||||
|
+
|
||||||
|
+## How to Use
|
||||||
|
+
|
||||||
|
+https://github.com/dogtagpki/pki/wiki/Configuring-CA-Database-Pruning provides a thorough description of the capabilities of the pruning job.
|
||||||
|
+
|
||||||
|
+The default configuration is to remove expired certificates and incomplete requests after 30 days.
|
||||||
|
+
|
||||||
|
+Pruning is disabled by default.
|
||||||
|
+
|
||||||
|
+Configuration is a four-step process:
|
||||||
|
+
|
||||||
|
+1. Configure the expiration thresholds
|
||||||
|
+2. Enable the job
|
||||||
|
+3. Schedule the job
|
||||||
|
+4. Restart the CA
|
||||||
|
+
|
||||||
|
+The job will be scheduled to use the PKI built-in cron-like timer. It is configured nearly identically to `crontab(5)`. On execution it will remove certificates and requests that fall outside the configured thresholds. LDAP search/time limits can be used to control how many are removed at once.
|
||||||
|
+
|
||||||
|
+In addition to the automated schedule it is possible to manually run the pruning job.
|
||||||
|
+
|
||||||
|
+The tool will not restart the CA. It will be left as an exercise for the user, who will be notified as needed.
|
||||||
|
+
|
||||||
|
+### Where to use
|
||||||
|
+
|
||||||
|
+The pruning configuration is not replicated. It should not be necessary to enable this task on all IPA servers, or more than one.
|
||||||
|
+
|
||||||
|
+Running the task simultaneously on multiple servers has a few downsides:
|
||||||
|
+
|
||||||
|
+* Additional stress on the LDAP server searching for expired certificates and requests
|
||||||
|
+* Unnecessary replication load deleting the same entries on multiple servers
|
||||||
|
+
|
||||||
|
+While enabling this on a single server represents a single-point-of-failure there should be no catastrophic consequences other than expired certificates and requests potentially building up. This can be cleared by enabling pruning on a different server. Depending on the size of the backlog this could take a couple of executions to catch up.
|
||||||
|
+
|
||||||
|
+## Design
|
||||||
|
+
|
||||||
|
+There are several operations, most of which act locally and one of which uses the PKI REST API.
|
||||||
|
+
|
||||||
|
+1. Updating the job configuration (enable, thresholds, etc). This will be done by running the `pki-server ca-config-set` command which modifies CS.cfg directly per the PKI wiki. A restart is required.
|
||||||
|
+
|
||||||
|
+2. Retrieving the current configuration for display. The `pki-server ca-config-find` command returns the entire configuration so the results will need to be filtered.
|
||||||
|
+
|
||||||
|
+3. Managing the job. This can be done using the REST API, https://github.com/dogtagpki/pki/wiki/PKI-REST-API . Operations include enabling the job and triggering it to run now.
|
||||||
|
+
|
||||||
|
+Theoretically for operations 1 and 2 we could use existing code to manually update `CS.cfg` and retrieve values. For future-proofing purposes calling `pki-server` is probably the better long-term option given the limited number of times this will be used. Configuration is likely to be one and done.
|
||||||
|
+
|
||||||
|
+There are four values each that can be managed for pruning certificates and requests:
|
||||||
|
+
|
||||||
|
+* expired cert/incomplete request time
|
||||||
|
+* time unit
|
||||||
|
+* LDAP search size limit
|
||||||
|
+* LDAP search time limit
|
||||||
|
+
|
||||||
|
+The first two configure when an expired certificate or incomplete request will be deleted. The unit can be one of: minute, hour, day, year. By default it is 30 days.
|
||||||
|
+
|
||||||
|
+The LDAP limits control how many entries are returned and how long the search can take. By default it is 1000 entries and unlimited time.
|
||||||
|
+
|
||||||
|
+### Configuration settings
|
||||||
|
+
|
||||||
|
+The configuration values will be set by running `pki-server ca-config-set` This will ensure best forward compatibility. The options are case-sensitive and not validated by the CA until restart. The values are not applied until the CA is restarted.
|
||||||
|
+
|
||||||
|
+### Configuring job execution time
|
||||||
|
+
|
||||||
|
+The CA provides a cron-like interface for scheduling jobs. To configure the job to run at midnight on the first of every month the PKI equivalent command-line is:
|
||||||
|
+
|
||||||
|
+```
|
||||||
|
+pki-server ca-config-set jobsScheduler.job.pruning.cron `"0 0 1 * *"`
|
||||||
|
+```
|
||||||
|
+
|
||||||
|
+This will be the default when pruning is enabled. A separate configuration option will be available for fine-tuning execution time.
|
||||||
|
+
|
||||||
|
+The format is defined https://access.redhat.com/documentation/en-us/red_hat_certificate_system/9/html/administration_guide/setting_up_specific_jobs#Frequency_Settings_for_Automated_Jobs
|
||||||
|
+
|
||||||
|
+### REST Authentication and Authorization
|
||||||
|
+
|
||||||
|
+The REST API for pruning is documented at https://github.com/dogtagpki/pki/wiki/PKI-Start-Job-REST-API
|
||||||
|
+
|
||||||
|
+A PKI job can define an owner that can manage the job over the REST API. We will automatically define the owner as `ipara` when pruning is enabled.
|
||||||
|
+
|
||||||
|
+Manually running the job will be done using the PKI REST API. Authentication to this API for our purposes is done at the `/ca/rest/account/login` endpoint. A cookie is returned which will be used in any subsequent calls. The IPA RA agent certificate will be used for authentication and authorization.
|
||||||
|
+
|
||||||
|
+### Commands
|
||||||
|
+
|
||||||
|
+This will be implemented in the ipa-acme-manage command. While strictly not completely ACME-related this is the primary driver for pruning.
|
||||||
|
+
|
||||||
|
+A new verb will be added, pruning, to be used for enabling and configuring pruning.
|
||||||
|
+
|
||||||
|
+### Enabling pruning
|
||||||
|
+
|
||||||
|
+`# ipa-acme-manage pruning --enable=TRUE`
|
||||||
|
+
|
||||||
|
+Enabling the job will call
|
||||||
|
+
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.enabled true`
|
||||||
|
+
|
||||||
|
+This will also set jobsScheduler.job.pruning.cron to `"0 0 1 * *"` if it has not already been set.
|
||||||
|
+
|
||||||
|
+Additionally it will set the job owner to `ipara` with:
|
||||||
|
+
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.owner ipara`
|
||||||
|
+
|
||||||
|
+Disabling the job will call
|
||||||
|
+
|
||||||
|
+`# pki-server ca-config-unset jobsScheduler.job.pruning.enabled`
|
||||||
|
+
|
||||||
|
+### Cron settings
|
||||||
|
+
|
||||||
|
+To modify the cron settings:
|
||||||
|
+
|
||||||
|
+`# ipa-acme-manage pruning --cron="Minute Hour Day_of_month Month_of_year Day_of_week"`
|
||||||
|
+
|
||||||
|
+Validation of the value will be:
|
||||||
|
+* each of the options is an integer
|
||||||
|
+* minute is within 0-59
|
||||||
|
+* hour is within 0-23
|
||||||
|
+* day of month is within 0-31
|
||||||
|
+* month of year is within 1-12
|
||||||
|
+* day of week is within 0-6
|
||||||
|
+
|
||||||
|
+No validation of setting February 31st will be done. That will be left to PKI. Buyer beware.
|
||||||
|
+
|
||||||
|
+### Disabling pruning
|
||||||
|
+
|
||||||
|
+`$ ipa-acme-manage pruning --enable=FALSE`
|
||||||
|
+
|
||||||
|
+This will remove the configuration option for `jobsScheduler.job.pruning.cron` just to be sure it no longer runs.
|
||||||
|
+
|
||||||
|
+### Configuration
|
||||||
|
+
|
||||||
|
+#### Pruning certificates
|
||||||
|
+
|
||||||
|
+`$ ipa-acme-manage pruning --certretention=VALUE --certretentionunit=UNIT`
|
||||||
|
+
|
||||||
|
+will be the equivalent of:
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.certRetentionTime 30`
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.certRetentionUnit day`
|
||||||
|
+
|
||||||
|
+The unit will always be required when modifying the time.
|
||||||
|
+
|
||||||
|
+`$ ipa-acme-manage pruning --certsearchsizelimit=VALUE --certsearchtimelimit=VALUE`
|
||||||
|
+
|
||||||
|
+will be the equivalent of:
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.certSearchSizeLimit 1000`
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.certSearchTimeLimit 0`
|
||||||
|
+
|
||||||
|
+A value of 0 for searchtimelimit is unlimited.
|
||||||
|
+
|
||||||
|
+#### Pruning requests
|
||||||
|
+
|
||||||
|
+`$ ipa-acme-manage pruning --requestretention=VALUE --requestretentionunit=UNIT`
|
||||||
|
+
|
||||||
|
+will be the equivalent of:
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionTime 30`
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionUnit day`
|
||||||
|
+
|
||||||
|
+The unit will always be required when modifying the time.
|
||||||
|
+
|
||||||
|
+`$ ipa-acme-manage pruning --requestsearchsizelimit=VALUE --requestsearchtimelimit=VALUE`
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+will be the equivalent of:
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.requestSearchSizeLimit 1000`
|
||||||
|
+
|
||||||
|
+`$ pki-server ca-config-set jobsScheduler.job.pruning.requestSearchTimeLimit 0`
|
||||||
|
+
|
||||||
|
+A value of 0 for searchtimelimit is unlimited.
|
||||||
|
+
|
||||||
|
+These options set the client-side limits. The server imposes its own search size and look through limits. This can be tuned for the uid=pkidbuser,ou=people,o=ipaca user via https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/ldapsearch-ex-complex-range
|
||||||
|
+
|
||||||
|
+### Showing the Configuration
|
||||||
|
+
|
||||||
|
+To display the current configuration run `pki-server ca-config-find` and filter the results to only those that contain `jobsScheduler.job.pruning`.
|
||||||
|
+
|
||||||
|
+Default values are not included so will need to be set by `ipa-acme-manage` before displaying.
|
||||||
|
+
|
||||||
|
+Output may look something like:
|
||||||
|
+
|
||||||
|
+```console
|
||||||
|
+# ipa-acme-manage pruning --config-show
|
||||||
|
+Enabled: TRUE
|
||||||
|
+Certificate retention time: 30 days
|
||||||
|
+Certificate search size limit: 1000
|
||||||
|
+Certificate search time limit: 0
|
||||||
|
+Request retention time: 30 days
|
||||||
|
+Request search size limit: 1000
|
||||||
|
+Request search time limit: 0
|
||||||
|
+Cron: 0 0 1 * *
|
||||||
|
+```
|
||||||
|
+
|
||||||
|
+## Implementation
|
||||||
|
+
|
||||||
|
+For online REST operations (login, run job) we will use the `ipaserver/plugins/dogtag.py::RestClient` class to manage the requests. This will take care of the authentication cookie, etc.
|
||||||
|
+
|
||||||
|
+The class uses dogtag.https_request() will can take PEM cert and key files as arguments. These will be used for authentication.
|
||||||
|
+
|
||||||
|
+For the non-REST operations (configuration, cron settings) the tool will fork out to pki-server ca-config-set.
|
||||||
|
+
|
||||||
|
+### UI
|
||||||
|
+
|
||||||
|
+This will only be configurable on the command-line.
|
||||||
|
+
|
||||||
|
+### CLI
|
||||||
|
+
|
||||||
|
+Overview of the CLI commands. Example:
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+| Command | Options |
|
||||||
|
+| --- | ----- |
|
||||||
|
+| ipa-acme-manage pruning | --enable=TRUE |
|
||||||
|
+| ipa-acme-manage pruning | --enable=FALSE |
|
||||||
|
+| ipa-acme-manage pruning | --cron=`"0 0 1 * *"` |
|
||||||
|
+| ipa-acme-manage pruning | --certretention=30 --certretentionunit=day |
|
||||||
|
+| ipa-acme-manage pruning | --certsearchsizelimit=1000 --certsearchtimelimit=0 |
|
||||||
|
+| ipa-acme-manage pruning | --requestretention=30 --requestretentionunit=day |
|
||||||
|
+| ipa-acme-manage pruning | --requestsearchsizelimit=1000 --requestsearchtimelimit=0 |
|
||||||
|
+| ipa-acme-manage pruning | --config-show |
|
||||||
|
+
|
||||||
|
+ipa-acme-manage can only be run as root.
|
||||||
|
+
|
||||||
|
+### Configuration
|
||||||
|
+
|
||||||
|
+Configuration changes will be made to /etc/pki/pki-tomcat/ca/CS.cfg
|
||||||
|
+
|
||||||
|
+## Upgrade
|
||||||
|
+
|
||||||
|
+No expected impact on upgrades.
|
||||||
|
+
|
||||||
|
+## Test plan
|
||||||
|
+
|
||||||
|
+Testing will consist of:
|
||||||
|
+
|
||||||
|
+* Use the default configuration
|
||||||
|
+* enabling the pruning job
|
||||||
|
+* issue one or more certificates
|
||||||
|
+* move time forward +1 days after expiration
|
||||||
|
+* manually running the job
|
||||||
|
+* validating that the certificates are removed
|
||||||
|
+
|
||||||
|
+For size/time limit testing, create a large number of certificates/requests and set the search limit to a low value, then ensure that the number of deleted certs is equal to the search limit. Testing timelimit in this way may be less predictable as it may require a massive number of entries to find to timeout on a non-busy server.
|
||||||
|
+
|
||||||
|
+## Troubleshooting and debugging
|
||||||
|
+
|
||||||
|
+The PKI debug log will contain job information.
|
||||||
|
+
|
||||||
|
+```
|
||||||
|
+2022-12-08 21:14:25 [https-jsse-nio-8443-exec-8] INFO: JobService: Starting job pruning
|
||||||
|
+2022-12-08 21:14:25 [https-jsse-nio-8443-exec-8] INFO: JobService: - principal: null
|
||||||
|
+2022-12-08 21:14:51 [https-jsse-nio-8443-exec-10] INFO: JobService: Starting job pruning 2022-12-08 21:14:51 [https-jsse-nio-8443-exec-10] INFO: JobService: - principal: null
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: Authenticating certificate chain:
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - CN=IPA RA,O=EXAMPLE.TEST
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - CN=Certificate Authority,O=EXAMPLE.TEST
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: LDAPSession: Retrieving cn=19072098145751813471503860299601579276,ou=certificateRepository, ou=ca,o=ipaca
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: CertUserDBAuthentication: UID ipara authenticated.
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: User ipara authenticated
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: UGSubsystem: Retrieving user uid=ipara,ou=People,o=ipaca
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: User DN: uid=ipara,ou=people,o=ipaca
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: Roles:
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - Certificate Manager Agents
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - Registration Manager Agents
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - Security Domain Administrators
|
||||||
|
+2022-12-08 21:15:11 [https-jsse-nio-8443-exec-11] INFO: PKIRealm: - Enterprise ACME Administrators
|
||||||
|
+2022-12-08 21:15:24 [https-jsse-nio-8443-exec-12] INFO: JobService: Starting job pruning
|
||||||
|
+2022-12-08 21:15:24 [https-jsse-nio-8443-exec-12] INFO: JobService: - principal: GenericPrincipal[ipara(Certificate Manager Agents,Enterprise ACME Administrators,Registration Manager Agents,Security Domain Administrators,)]
|
||||||
|
+2022-12-08 21:15:24 [https-jsse-nio-8443-exec-12] INFO: JobsScheduler: Starting job pruning
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: PruningJob: Running pruning job at Thu Dec 08 21:15:24 UTC 2022
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: PruningJob: Pruning certs expired before Tue Nov 08 21:15:24 UTC 2022
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: PruningJob: - filter: (&(x509Cert.notAfter<=1667942124527)(!(x509Cert.notAfter=1667942124527)))
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: LDAPSession: Searching ou=certificateRepository, ou=ca,o=ipaca for (&(notAfter<=20221108211524Z)(!(notAfter=20221108211524Z)))
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: PruningJob: Pruning incomplete requests last modified before Tue Nov 08 21:15:24 UTC 2022
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: PruningJob: - filter: (&(!(requestState=complete))(requestModifyTime<=1667942124527)(!(requestModifyTime=1667942124527)))
|
||||||
|
+2022-12-08 21:15:24 [pruning] INFO: LDAPSession: Searching ou=ca, ou=requests,o=ipaca for (&(!(requestState=complete))(dateOfModify<=20221108211524Z)(!(dateOfModify=20221108211524Z)))
|
||||||
|
+```
|
||||||
|
diff --git a/doc/designs/index.rst b/doc/designs/index.rst
|
||||||
|
index 570e526fe35d510feeac62a44dd59224289e0506..1d41c0f84f0d7d3d5f184a47e31b4e71a890805d 100644
|
||||||
|
--- a/doc/designs/index.rst
|
||||||
|
+++ b/doc/designs/index.rst
|
||||||
|
@@ -14,6 +14,7 @@ FreeIPA design documentation
|
||||||
|
hsm.md
|
||||||
|
krb-ticket-policy.md
|
||||||
|
extdom-plugin-protocol.md
|
||||||
|
+ expired_certificate_pruning.md
|
||||||
|
expiring-password-notification.md
|
||||||
|
ldap_grace_period.md
|
||||||
|
ldap_pam_passthrough.md
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,684 @@
|
|||||||
|
From 9246a8a003b2b0062e07c289cd7cde8fe902b16f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 15:06:27 -0500
|
||||||
|
Subject: [PATCH] ipa-acme-manage: add certificate/request pruning management
|
||||||
|
|
||||||
|
Configures PKI to remove expired certificates and non-resolved
|
||||||
|
requests on a schedule.
|
||||||
|
|
||||||
|
This is geared towards ACME which can generate a lot of certificates
|
||||||
|
over a short period of time but is general purpose. It lives in
|
||||||
|
ipa-acme-manage because that is the primary reason for including it.
|
||||||
|
|
||||||
|
Random Serial Numbers v3 must be enabled for this to work.
|
||||||
|
|
||||||
|
Enabling pruning enables the job scheduler within CS and sets the
|
||||||
|
job user as the IPA RA user which has full rights to certificates
|
||||||
|
and requests.
|
||||||
|
|
||||||
|
Disabling pruning does not disable the job scheduler because the
|
||||||
|
tool is stateless. Having the scheduler enabled should not be a
|
||||||
|
problem.
|
||||||
|
|
||||||
|
A restart of PKI is required to apply any changes. This tool forks
|
||||||
|
out to pki-server which does direct writes to CS.cfg. It might
|
||||||
|
be easier to use our own tooling for this but this makes the
|
||||||
|
integration tighter so we pick up any improvements in PKI.
|
||||||
|
|
||||||
|
The "cron" setting is quite limited, taking only integer values
|
||||||
|
and *. It does not accept ranges, either - or /.
|
||||||
|
|
||||||
|
No error checking is done in PKI when setting a value, only when
|
||||||
|
attempting to use it, so some rudimentary validation is done.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9294
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden rcritten@redhat.com
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
install/tools/man/ipa-acme-manage.1 | 83 +++++++
|
||||||
|
ipaserver/install/ipa_acme_manage.py | 303 ++++++++++++++++++++++++-
|
||||||
|
ipatests/test_integration/test_acme.py | 158 +++++++++++++
|
||||||
|
3 files changed, 534 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/install/tools/man/ipa-acme-manage.1 b/install/tools/man/ipa-acme-manage.1
|
||||||
|
index e15d25bd0017d8bd71e425fcb633827fa6f67693..e6cec4e4a7fd460c514a72456a2dc9a2e3682ebd 100644
|
||||||
|
--- a/install/tools/man/ipa-acme-manage.1
|
||||||
|
+++ b/install/tools/man/ipa-acme-manage.1
|
||||||
|
@@ -27,6 +27,89 @@ Disable the ACME service on this host.
|
||||||
|
.TP
|
||||||
|
\fBstatus\fR
|
||||||
|
Display the status of the ACME service.
|
||||||
|
+.TP
|
||||||
|
+\fBpruning\fR
|
||||||
|
+Configure certificate and request pruning.
|
||||||
|
+
|
||||||
|
+.SH "PRUNING"
|
||||||
|
+Pruning is a job that runs in the CA that can remove expired
|
||||||
|
+certificates and certificate requests which have not been issued.
|
||||||
|
+This is particularly important when using short-lived certificates
|
||||||
|
+like those issued with the ACME protocol. Pruning requires that
|
||||||
|
+the IPA server be installed with random serial numbers enabled.
|
||||||
|
+
|
||||||
|
+The CA needs to be restarted after modifying the pruning configuration.
|
||||||
|
+
|
||||||
|
+The job is a cron-like task within the CA that is controlled by a
|
||||||
|
+number of options which dictate how long after the certificate or
|
||||||
|
+request is considered no longer valid and removed from the LDAP
|
||||||
|
+database.
|
||||||
|
+
|
||||||
|
+The cron time and date fields are:
|
||||||
|
+.IP
|
||||||
|
+.ta 1.5i
|
||||||
|
+field allowed values
|
||||||
|
+.br
|
||||||
|
+----- --------------
|
||||||
|
+.br
|
||||||
|
+minute 0-59
|
||||||
|
+.br
|
||||||
|
+hour 0-23
|
||||||
|
+.br
|
||||||
|
+day of month 1-31
|
||||||
|
+.br
|
||||||
|
+month 1-12
|
||||||
|
+.br
|
||||||
|
+day of week 0-6 (0 is Sunday)
|
||||||
|
+.br
|
||||||
|
+.PP
|
||||||
|
+
|
||||||
|
+The cron syntax is limited to * or specific numbers. Ranges are not supported.
|
||||||
|
+
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-enable\fR
|
||||||
|
+Enable certificate pruning.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-disable\fR
|
||||||
|
+Disable certificate pruning.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-cron=CRON\fR
|
||||||
|
+Configure the pruning cron job. The syntax is similar to crontab(5) syntax.
|
||||||
|
+For example, "0 0 1 * *" schedules the job to run at 12:00am on the first
|
||||||
|
+day of each month.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-certretention=CERTRETENTION\fR
|
||||||
|
+Certificate retention time. The default is 30.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-certretentionunit=CERTRETENTIONUNIT\fR
|
||||||
|
+Certificate retention units. Valid units are: minute, hour, day, year.
|
||||||
|
+The default is days.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-certsearchsizelimit=CERTSEARCHSIZELIMIT\fR
|
||||||
|
+LDAP search size limit searching for expired certificates. The default is 1000. This is a client-side limit. There may be additional server-side limitations.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-certsearchtimelimit=CERTSEARCHTIMELIMIT\fR
|
||||||
|
+LDAP search time limit searching for expired certificates. The default is 0, no limit. This is a client-side limit. There may be additional server-side limitations.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-requestretention=REQUESTRETENTION\fR
|
||||||
|
+Request retention time. The default is 30.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-requestretentionunit=REQUESTRETENTIONUNIT\fR
|
||||||
|
+Request retention units. Valid units are: minute, hour, day, year.
|
||||||
|
+The default is days.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-requestsearchsizelimit=REQUESTSEARCHSIZELIMIT\fR
|
||||||
|
+LDAP search size limit searching for unfulfilled requests. The default is 1000. There may be additional server-side limitations.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-requestsearchtimelimit=REQUESTSEARCHTIMELIMIT\fR
|
||||||
|
+LDAP search time limit searching for unfulfilled requests. The default is 0, no limit. There may be additional server-side limitations.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-config\-show\fR
|
||||||
|
+Show the current pruning configuration
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-run\fR
|
||||||
|
+Run the pruning job now. The IPA RA certificate is used to authenticate to the PKI REST backend.
|
||||||
|
+
|
||||||
|
|
||||||
|
.SH "EXIT STATUS"
|
||||||
|
0 if the command was successful
|
||||||
|
diff --git a/ipaserver/install/ipa_acme_manage.py b/ipaserver/install/ipa_acme_manage.py
|
||||||
|
index 0474b9f4a051063ac6df41a81877a2af9d4a2096..b7b2111d9edcec2580aa4a485d7a7340146ff065 100644
|
||||||
|
--- a/ipaserver/install/ipa_acme_manage.py
|
||||||
|
+++ b/ipaserver/install/ipa_acme_manage.py
|
||||||
|
@@ -2,7 +2,12 @@
|
||||||
|
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||||
|
#
|
||||||
|
|
||||||
|
+
|
||||||
|
import enum
|
||||||
|
+import pki.util
|
||||||
|
+import logging
|
||||||
|
+
|
||||||
|
+from optparse import OptionGroup # pylint: disable=deprecated-module
|
||||||
|
|
||||||
|
from ipalib import api, errors, x509
|
||||||
|
from ipalib import _
|
||||||
|
@@ -10,10 +15,64 @@ from ipalib.facts import is_ipa_configured
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
from ipapython.admintool import AdminTool
|
||||||
|
from ipapython import cookie, dogtag
|
||||||
|
+from ipapython.ipautil import run
|
||||||
|
+from ipapython.certdb import NSSDatabase, EXTERNAL_CA_TRUST_FLAGS
|
||||||
|
from ipaserver.install import cainstance
|
||||||
|
+from ipaserver.install.ca import lookup_random_serial_number_version
|
||||||
|
|
||||||
|
from ipaserver.plugins.dogtag import RestClient
|
||||||
|
|
||||||
|
+logger = logging.getLogger(__name__)
|
||||||
|
+
|
||||||
|
+default_pruning_options = {
|
||||||
|
+ 'certRetentionTime': '30',
|
||||||
|
+ 'certRetentionUnit': 'day',
|
||||||
|
+ 'certSearchSizeLimit': '1000',
|
||||||
|
+ 'certSearchTimeLimit': '0',
|
||||||
|
+ 'requestRetentionTime': 'day',
|
||||||
|
+ 'requestRetentionUnit': '30',
|
||||||
|
+ 'requestSearchSizeLimit': '1000',
|
||||||
|
+ 'requestSearchTimeLimit': '0',
|
||||||
|
+ 'cron': ''
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+pruning_labels = {
|
||||||
|
+ 'certRetentionTime': 'Certificate Retention Time',
|
||||||
|
+ 'certRetentionUnit': 'Certificate Retention Unit',
|
||||||
|
+ 'certSearchSizeLimit': 'Certificate Search Size Limit',
|
||||||
|
+ 'certSearchTimeLimit': 'Certificate Search Time Limit',
|
||||||
|
+ 'requestRetentionTime': 'Request Retention Time',
|
||||||
|
+ 'requestRetentionUnit': 'Request Retention Unit',
|
||||||
|
+ 'requestSearchSizeLimit': 'Request Search Size Limit',
|
||||||
|
+ 'requestSearchTimeLimit': 'Request Search Time Limit',
|
||||||
|
+ 'cron': 'cron Schedule'
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def validate_range(val, min, max):
|
||||||
|
+ """dogtag appears to have no error checking in the cron
|
||||||
|
+ entry so do some minimum amount of validation. It is
|
||||||
|
+ left as an exercise for the user to do month/day
|
||||||
|
+ validation so requesting Feb 31 will be accepted.
|
||||||
|
+
|
||||||
|
+ Only * and a number within a min/max range are allowed.
|
||||||
|
+ """
|
||||||
|
+ if val == '*':
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ if '-' in val or '/' in val:
|
||||||
|
+ raise ValueError(f"{val} ranges are not supported")
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ int(val)
|
||||||
|
+ except ValueError:
|
||||||
|
+ # raise a clearer error
|
||||||
|
+ raise ValueError(f"{val} is not a valid integer")
|
||||||
|
+
|
||||||
|
+ if int(val) < min or int(val) > max:
|
||||||
|
+ raise ValueError(f"{val} not within the range {min}-{max}")
|
||||||
|
+
|
||||||
|
+
|
||||||
|
# Manages the FreeIPA ACME service on a per-server basis.
|
||||||
|
#
|
||||||
|
# This program is a stop-gap until the deployment-wide management of
|
||||||
|
@@ -66,32 +125,121 @@ class acme_state(RestClient):
|
||||||
|
status, unused, _unused = self._request('/acme/disable',
|
||||||
|
headers=headers)
|
||||||
|
if status != 200:
|
||||||
|
- raise RuntimeError('Failed to disble ACME')
|
||||||
|
+ raise RuntimeError('Failed to disable ACME')
|
||||||
|
|
||||||
|
|
||||||
|
class Command(enum.Enum):
|
||||||
|
ENABLE = 'enable'
|
||||||
|
DISABLE = 'disable'
|
||||||
|
STATUS = 'status'
|
||||||
|
+ PRUNE = 'pruning'
|
||||||
|
|
||||||
|
|
||||||
|
class IPAACMEManage(AdminTool):
|
||||||
|
command_name = "ipa-acme-manage"
|
||||||
|
- usage = "%prog [enable|disable|status]"
|
||||||
|
+ usage = "%prog [enable|disable|status|pruning]"
|
||||||
|
description = "Manage the IPA ACME service"
|
||||||
|
|
||||||
|
+ @classmethod
|
||||||
|
+ def add_options(cls, parser):
|
||||||
|
+
|
||||||
|
+ group = OptionGroup(parser, 'Pruning')
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--enable", dest="enable", action="store_true",
|
||||||
|
+ default=False, help="Enable certificate pruning")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--disable", dest="disable", action="store_true",
|
||||||
|
+ default=False, help="Disable certificate pruning")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--cron", dest="cron", action="store",
|
||||||
|
+ default=None, help="Configure the pruning cron job")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--certretention", dest="certretention", action="store",
|
||||||
|
+ default=None, help="Certificate retention time", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--certretentionunit", dest="certretentionunit", action="store",
|
||||||
|
+ choices=['minute', 'hour', 'day', 'year'],
|
||||||
|
+ default=None, help="Certificate retention units")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--certsearchsizelimit", dest="certsearchsizelimit",
|
||||||
|
+ action="store",
|
||||||
|
+ default=None, help="LDAP search size limit", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--certsearchtimelimit", dest="certsearchtimelimit", action="store",
|
||||||
|
+ default=None, help="LDAP search time limit", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--requestretention", dest="requestretention", action="store",
|
||||||
|
+ default=None, help="Request retention time", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--requestretentionunit", dest="requestretentionunit",
|
||||||
|
+ choices=['minute', 'hour', 'day', 'year'],
|
||||||
|
+ action="store", default=None, help="Request retention units")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--requestsearchsizelimit", dest="requestsearchsizelimit",
|
||||||
|
+ action="store",
|
||||||
|
+ default=None, help="LDAP search size limit", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--requestsearchtimelimit", dest="requestsearchtimelimit",
|
||||||
|
+ action="store",
|
||||||
|
+ default=None, help="LDAP search time limit", type=int)
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--config-show", dest="config_show", action="store_true",
|
||||||
|
+ default=False, help="Show the current pruning configuration")
|
||||||
|
+ group.add_option(
|
||||||
|
+ "--run", dest="run", action="store_true",
|
||||||
|
+ default=False, help="Run the pruning job now")
|
||||||
|
+ parser.add_option_group(group)
|
||||||
|
+ super(IPAACMEManage, cls).add_options(parser, debug_option=True)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def validate_options(self):
|
||||||
|
- # needs root now - if/when this program changes to an API
|
||||||
|
- # wrapper we will no longer need root.
|
||||||
|
super(IPAACMEManage, self).validate_options(needs_root=True)
|
||||||
|
|
||||||
|
if len(self.args) < 1:
|
||||||
|
self.option_parser.error(f'missing command argument')
|
||||||
|
- else:
|
||||||
|
- try:
|
||||||
|
- self.command = Command(self.args[0])
|
||||||
|
- except ValueError:
|
||||||
|
- self.option_parser.error(f'unknown command "{self.args[0]}"')
|
||||||
|
+
|
||||||
|
+ if self.args[0] == "pruning":
|
||||||
|
+ if self.options.enable and self.options.disable:
|
||||||
|
+ self.option_parser.error("Cannot both enable and disable")
|
||||||
|
+ elif (
|
||||||
|
+ any(
|
||||||
|
+ [
|
||||||
|
+ self.options.enable,
|
||||||
|
+ self.options.disable,
|
||||||
|
+ self.options.cron,
|
||||||
|
+ self.options.certretention,
|
||||||
|
+ self.options.certretentionunit,
|
||||||
|
+ self.options.requestretention,
|
||||||
|
+ self.options.requestretentionunit,
|
||||||
|
+ self.options.certsearchsizelimit,
|
||||||
|
+ self.options.certsearchtimelimit,
|
||||||
|
+ self.options.requestsearchsizelimit,
|
||||||
|
+ self.options.requestsearchtimelimit,
|
||||||
|
+ ]
|
||||||
|
+ )
|
||||||
|
+ and (self.options.config_show or self.options.run)
|
||||||
|
+ ):
|
||||||
|
+
|
||||||
|
+ self.option_parser.error(
|
||||||
|
+ "Cannot change and show config or run at the same time"
|
||||||
|
+ )
|
||||||
|
+ elif self.options.cron:
|
||||||
|
+ if len(self.options.cron.split()) != 5:
|
||||||
|
+ self.option_parser.error("Invalid format for --cron")
|
||||||
|
+ # dogtag does no validation when setting an option so
|
||||||
|
+ # do the minimum. The dogtag cron is limited compared to
|
||||||
|
+ # crontab(5).
|
||||||
|
+ opt = self.options.cron.split()
|
||||||
|
+ validate_range(opt[0], 0, 59)
|
||||||
|
+ validate_range(opt[1], 0, 23)
|
||||||
|
+ validate_range(opt[2], 1, 31)
|
||||||
|
+ validate_range(opt[3], 1, 12)
|
||||||
|
+ validate_range(opt[4], 0, 6)
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ self.command = Command(self.args[0])
|
||||||
|
+ except ValueError:
|
||||||
|
+ self.option_parser.error(f'unknown command "{self.args[0]}"')
|
||||||
|
|
||||||
|
def check_san_status(self):
|
||||||
|
"""
|
||||||
|
@@ -100,6 +248,140 @@ class IPAACMEManage(AdminTool):
|
||||||
|
cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
|
||||||
|
cainstance.check_ipa_ca_san(cert)
|
||||||
|
|
||||||
|
+ def pruning(self):
|
||||||
|
+ def run_pki_server(command, directive, prefix, value=None):
|
||||||
|
+ """Take a set of arguments to append to pki-server"""
|
||||||
|
+ args = [
|
||||||
|
+ 'pki-server', command,
|
||||||
|
+ f'{prefix}.{directive}'
|
||||||
|
+ ]
|
||||||
|
+ if value:
|
||||||
|
+ args.extend([str(value)])
|
||||||
|
+ logger.debug(args)
|
||||||
|
+ result = run(args, raiseonerr=False, capture_output=True,
|
||||||
|
+ capture_error=True)
|
||||||
|
+ if result.returncode != 0:
|
||||||
|
+ raise RuntimeError(result.error_output)
|
||||||
|
+ return result
|
||||||
|
+
|
||||||
|
+ def ca_config_set(directive, value,
|
||||||
|
+ prefix='jobsScheduler.job.pruning'):
|
||||||
|
+ run_pki_server('ca-config-set', directive, prefix, value)
|
||||||
|
+ # ca-config-set always succeeds, even if the option is
|
||||||
|
+ # not supported.
|
||||||
|
+ newvalue = ca_config_show(directive)
|
||||||
|
+ if str(value) != newvalue.strip():
|
||||||
|
+ raise RuntimeError('Updating %s failed' % directive)
|
||||||
|
+
|
||||||
|
+ def ca_config_show(directive):
|
||||||
|
+ result = run_pki_server('ca-config-show', directive,
|
||||||
|
+ prefix='jobsScheduler.job.pruning')
|
||||||
|
+ return result.output.strip()
|
||||||
|
+
|
||||||
|
+ def config_show():
|
||||||
|
+ status = ca_config_show('enabled')
|
||||||
|
+ if status.strip() == 'true':
|
||||||
|
+ print("Status: enabled")
|
||||||
|
+ else:
|
||||||
|
+ print("Status: disabled")
|
||||||
|
+ for option in (
|
||||||
|
+ 'certRetentionTime', 'certRetentionUnit',
|
||||||
|
+ 'certSearchSizeLimit', 'certSearchTimeLimit',
|
||||||
|
+ 'requestRetentionTime', 'requestRetentionUnit',
|
||||||
|
+ 'requestSearchSizeLimit', 'requestSearchTimeLimit',
|
||||||
|
+ 'cron',
|
||||||
|
+ ):
|
||||||
|
+ value = ca_config_show(option)
|
||||||
|
+ if value:
|
||||||
|
+ print("{}: {}".format(pruning_labels[option], value))
|
||||||
|
+ else:
|
||||||
|
+ print("{}: {}".format(pruning_labels[option],
|
||||||
|
+ default_pruning_options[option]))
|
||||||
|
+
|
||||||
|
+ def run_pruning():
|
||||||
|
+ """Run the pruning job manually"""
|
||||||
|
+
|
||||||
|
+ with NSSDatabase() as tmpdb:
|
||||||
|
+ print("Preparing...")
|
||||||
|
+ tmpdb.create_db()
|
||||||
|
+ tmpdb.import_files((paths.RA_AGENT_PEM, paths.RA_AGENT_KEY),
|
||||||
|
+ import_keys=True)
|
||||||
|
+ tmpdb.import_files((paths.IPA_CA_CRT,))
|
||||||
|
+ for nickname, trust_flags in tmpdb.list_certs():
|
||||||
|
+ if trust_flags.has_key:
|
||||||
|
+ ra_nickname = nickname
|
||||||
|
+ continue
|
||||||
|
+ # external is suffucient for our purposes: C,,
|
||||||
|
+ tmpdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)
|
||||||
|
+ print("Starting job...")
|
||||||
|
+ args = ['pki', '-C', tmpdb.pwd_file, '-d', tmpdb.secdir,
|
||||||
|
+ '-n', ra_nickname,
|
||||||
|
+ 'ca-job-start', 'pruning']
|
||||||
|
+ logger.debug(args)
|
||||||
|
+ run(args, stdin='y')
|
||||||
|
+
|
||||||
|
+ pki_version = pki.util.Version(pki.specification_version())
|
||||||
|
+ if pki_version < pki.util.Version("11.3.0"):
|
||||||
|
+ raise RuntimeError(
|
||||||
|
+ 'Certificate pruning is not supported in PKI version %s'
|
||||||
|
+ % pki_version
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ if lookup_random_serial_number_version(api) == 0:
|
||||||
|
+ raise RuntimeError(
|
||||||
|
+ 'Certificate pruning requires random serial numbers'
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ if self.options.config_show:
|
||||||
|
+ config_show()
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ if self.options.run:
|
||||||
|
+ run_pruning()
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ # Don't play the enable/disable at the same time game
|
||||||
|
+ if self.options.enable:
|
||||||
|
+ ca_config_set('owner', 'ipara')
|
||||||
|
+ ca_config_set('enabled', 'true')
|
||||||
|
+ ca_config_set('enabled', 'true', 'jobsScheduler')
|
||||||
|
+ elif self.options.disable:
|
||||||
|
+ ca_config_set('enabled', 'false')
|
||||||
|
+
|
||||||
|
+ # pki-server ca-config-set can only set one option at a time so
|
||||||
|
+ # loop through all the options and set what is there.
|
||||||
|
+ if self.options.certretention:
|
||||||
|
+ ca_config_set('certRetentionTime',
|
||||||
|
+ self.options.certretention)
|
||||||
|
+ if self.options.certretentionunit:
|
||||||
|
+ ca_config_set('certRetentionUnit',
|
||||||
|
+ self.options.certretentionunit)
|
||||||
|
+ if self.options.certsearchtimelimit:
|
||||||
|
+ ca_config_set('certSearchTimeLimit',
|
||||||
|
+ self.options.certsearchtimelimit)
|
||||||
|
+ if self.options.certsearchsizelimit:
|
||||||
|
+ ca_config_set('certSearchSizeLimit',
|
||||||
|
+ self.options.certsearchsizelimit)
|
||||||
|
+ if self.options.requestretention:
|
||||||
|
+ ca_config_set('requestRetentionTime',
|
||||||
|
+ self.options.requestretention)
|
||||||
|
+ if self.options.requestretentionunit:
|
||||||
|
+ ca_config_set('requestRetentionUnit',
|
||||||
|
+ self.options.requestretentionunit)
|
||||||
|
+ if self.options.requestsearchsizelimit:
|
||||||
|
+ ca_config_set('requestSearchSizeLimit',
|
||||||
|
+ self.options.requestsearchsizelimit)
|
||||||
|
+ if self.options.requestsearchtimelimit:
|
||||||
|
+ ca_config_set('requestSearchTimeLimit',
|
||||||
|
+ self.options.requestsearchtimelimit)
|
||||||
|
+ if self.options.cron:
|
||||||
|
+ ca_config_set('cron', self.options.cron)
|
||||||
|
+
|
||||||
|
+ config_show()
|
||||||
|
+
|
||||||
|
+ print("The CA service must be restarted for changes to take effect")
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def run(self):
|
||||||
|
if not is_ipa_configured():
|
||||||
|
print("IPA is not configured.")
|
||||||
|
@@ -123,7 +405,8 @@ class IPAACMEManage(AdminTool):
|
||||||
|
elif self.command == Command.STATUS:
|
||||||
|
status = "enabled" if dogtag.acme_status() else "disabled"
|
||||||
|
print("ACME is {}".format(status))
|
||||||
|
- return 0
|
||||||
|
+ elif self.command == Command.PRUNE:
|
||||||
|
+ self.pruning()
|
||||||
|
else:
|
||||||
|
raise RuntimeError('programmer error: unhandled enum case')
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||||
|
index 15d7543cfb0fa0fcb921166f7cd8f13d0535a41d..93e785d8febd9fa8d7b3ef87ecb3f2eb42ac5da2 100644
|
||||||
|
--- a/ipatests/test_integration/test_acme.py
|
||||||
|
+++ b/ipatests/test_integration/test_acme.py
|
||||||
|
@@ -12,6 +12,9 @@ from ipalib.constants import IPA_CA_RECORD
|
||||||
|
from ipatests.test_integration.base import IntegrationTest
|
||||||
|
from ipatests.pytest_ipa.integration import tasks
|
||||||
|
from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
|
||||||
|
+from ipatests.test_integration.test_random_serial_numbers import (
|
||||||
|
+ pki_supports_RSNv3
|
||||||
|
+)
|
||||||
|
from ipaplatform.osinfo import osinfo
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
from ipatests.test_integration.test_external_ca import (
|
||||||
|
@@ -388,6 +391,16 @@ class TestACME(CALessBase):
|
||||||
|
status = check_acme_status(self.replicas[0], 'disabled')
|
||||||
|
assert status == 'disabled'
|
||||||
|
|
||||||
|
+ def test_acme_pruning_no_random_serial(self):
|
||||||
|
+ """This ACME install is configured without random serial
|
||||||
|
+ numbers. Verify that we can't enable pruning on it."""
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'enable'])
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning', '--enable'],
|
||||||
|
+ raiseonerr=False)
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "requires random serial numbers" in result.stderr_text
|
||||||
|
+
|
||||||
|
@server_install_teardown
|
||||||
|
def test_third_party_certs(self):
|
||||||
|
"""Require ipa-ca SAN on replacement web certificates"""
|
||||||
|
@@ -630,3 +643,148 @@ class TestACMERenew(IntegrationTest):
|
||||||
|
renewed_expiry = cert.not_valid_after
|
||||||
|
|
||||||
|
assert initial_expiry != renewed_expiry
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestACMEPrune(IntegrationTest):
|
||||||
|
+ """Validate that ipa-acme-manage configures dogtag for pruning"""
|
||||||
|
+
|
||||||
|
+ random_serial = True
|
||||||
|
+
|
||||||
|
+ @classmethod
|
||||||
|
+ def install(cls, mh):
|
||||||
|
+ if not pki_supports_RSNv3(mh.master):
|
||||||
|
+ raise pytest.skip("RNSv3 not supported")
|
||||||
|
+ tasks.install_master(cls.master, setup_dns=True,
|
||||||
|
+ random_serial=True)
|
||||||
|
+
|
||||||
|
+ @classmethod
|
||||||
|
+ def uninstall(cls, mh):
|
||||||
|
+ if not pki_supports_RSNv3(mh.master):
|
||||||
|
+ raise pytest.skip("RSNv3 not supported")
|
||||||
|
+ super(TestACMEPrune, cls).uninstall(mh)
|
||||||
|
+
|
||||||
|
+ def test_enable_pruning(self):
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+ cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
+ assert "jobsScheduler.job.pruning.enabled=false".encode() in cs_cfg
|
||||||
|
+
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+
|
||||||
|
+ cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
+ assert "jobsScheduler.enabled=true".encode() in cs_cfg
|
||||||
|
+ assert "jobsScheduler.job.pruning.enabled=true".encode() in cs_cfg
|
||||||
|
+ assert "jobsScheduler.job.pruning.owner=ipara".encode() in cs_cfg
|
||||||
|
+
|
||||||
|
+ def test_pruning_options(self):
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--certretention=60',
|
||||||
|
+ '--certretentionunit=minute',
|
||||||
|
+ '--certsearchsizelimit=2000',
|
||||||
|
+ '--certsearchtimelimit=5',]
|
||||||
|
+ )
|
||||||
|
+ cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.certRetentionTime=60".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.certRetentionUnit=minute".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.certSearchSizeLimit=2000".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.certSearchTimeLimit=5".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--requestretention=60',
|
||||||
|
+ '--requestretentionunit=minute',
|
||||||
|
+ '--requestresearchsizelimit=2000',
|
||||||
|
+ '--requestsearchtimelimit=5',]
|
||||||
|
+ )
|
||||||
|
+ cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.requestRetentionTime=60".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.requestRetentionUnit=minute".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.requestSearchSizeLimit=2000".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.requestSearchTimeLimit=5".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron="0 23 1 * *',]
|
||||||
|
+ )
|
||||||
|
+ cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
+ assert (
|
||||||
|
+ "jobsScheduler.job.pruning.cron=0 23 1 * *".encode()
|
||||||
|
+ in cs_cfg
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ def test_pruning_negative_options(self):
|
||||||
|
+ """Negative option testing for things we directly cover"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--enable', '--disable'],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "Cannot both enable and disable" in result.stderr_text
|
||||||
|
+
|
||||||
|
+ for cmd in ('--config-show', '--run'):
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ cmd, '--enable'],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "Cannot change and show config" in result.stderr_text
|
||||||
|
+
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron="* *"'],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "Invalid format format --cron" in result.stderr_text
|
||||||
|
+
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron="100 * * * *"'],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "100 not within the range 0-59" in result.stderr_text
|
||||||
|
+
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron="10 1-5 * * *"'],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert result.returncode == 1
|
||||||
|
+ assert "1-5 ranges are not supported" in result.stderr_text
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
From a39af6b7228d8ba85b9e97aa5decbc056d081c77 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sudhir Menon <sumenon@redhat.com>
|
|
||||||
Date: Thu, 23 Jun 2022 16:14:39 +0530
|
|
||||||
Subject: [PATCH] ipatests: ipa-client-install --subid adds entry in
|
|
||||||
nsswitch.conf
|
|
||||||
|
|
||||||
This testcase checks that when ipa-client-install command
|
|
||||||
is run with --subid option, /etc/nsswitch.conf file is updated
|
|
||||||
with the below entry
|
|
||||||
|
|
||||||
subid: nss
|
|
||||||
Related: https://pagure.io/freeipa/issue/9159
|
|
||||||
|
|
||||||
Since the newly added testsuite required client
|
|
||||||
system, hence modified the below yaml files to change the topology
|
|
||||||
from *master_1repl to *master_1repl_1client in the below files
|
|
||||||
|
|
||||||
gating.yaml
|
|
||||||
nightly_latest.yaml
|
|
||||||
nightly_rawhide.yaml
|
|
||||||
|
|
||||||
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
|
||||||
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
|
||||||
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
ipatests/prci_definitions/gating.yaml | 2 +-
|
|
||||||
.../nightly_ipa-4-10_latest.yaml | 2 +-
|
|
||||||
.../nightly_ipa-4-10_latest_selinux.yaml | 2 +-
|
|
||||||
.../nightly_ipa-4-10_previous.yaml | 2 +-
|
|
||||||
ipatests/test_integration/test_subids.py | 38 +++++++++++++++++++
|
|
||||||
5 files changed, 42 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/prci_definitions/gating.yaml b/ipatests/prci_definitions/gating.yaml
|
|
||||||
index 4083c650a17ce76bdefa243f1a7c5924039ff0bb..db4875dcfae8676287ef771805b34d988330bb40 100644
|
|
||||||
--- a/ipatests/prci_definitions/gating.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/gating.yaml
|
|
||||||
@@ -309,4 +309,4 @@ jobs:
|
|
||||||
test_suite: test_integration/test_subids.py
|
|
||||||
template: *ci-ipa-4-10-latest
|
|
||||||
timeout: 3600
|
|
||||||
- topology: *master_1repl
|
|
||||||
+ topology: *master_1repl_1client
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
index 24aa6e7cf29e448ba9d838d1cb98169213ea63ef..027b2a5b6c0b7ec3c3b5784ec4569661a06d4ed7 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
@@ -1748,7 +1748,7 @@ jobs:
|
|
||||||
test_suite: test_integration/test_subids.py
|
|
||||||
template: *ci-ipa-4-10-latest
|
|
||||||
timeout: 3600
|
|
||||||
- topology: *master_1repl
|
|
||||||
+ topology: *master_1repl_1client
|
|
||||||
|
|
||||||
fedora-latest-ipa-4-10/test_custom_plugins:
|
|
||||||
requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
index f22cc08384b3d50e49278d38e73bf93cd7804e80..bcc17bef935666735bfb2c2e51209362a374b511 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
@@ -1887,7 +1887,7 @@ jobs:
|
|
||||||
test_suite: test_integration/test_subids.py
|
|
||||||
template: *ci-ipa-4-10-latest
|
|
||||||
timeout: 3600
|
|
||||||
- topology: *master_1repl
|
|
||||||
+ topology: *master_1repl_1client
|
|
||||||
|
|
||||||
fedora-latest-ipa-4-10/test_custom_plugins:
|
|
||||||
requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
index df98a66871fd90daaebd83f063e48f1580675049..37d38762e696a6394ef146a0e2b68bbc8ced515d 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
@@ -1748,7 +1748,7 @@ jobs:
|
|
||||||
test_suite: test_integration/test_subids.py
|
|
||||||
template: *ci-ipa-4-10-previous
|
|
||||||
timeout: 3600
|
|
||||||
- topology: *master_1repl
|
|
||||||
+ topology: *master_1repl_1client
|
|
||||||
|
|
||||||
fedora-previous-ipa-4-10/test_custom_plugins:
|
|
||||||
requires: [fedora-previous-ipa-4-10/build]
|
|
||||||
diff --git a/ipatests/test_integration/test_subids.py b/ipatests/test_integration/test_subids.py
|
|
||||||
index f6d8607f237bf03358baae008dd2a6ad819751c0..8158499e1a2b71bdc1a308dec0939fd0d491599d 100644
|
|
||||||
--- a/ipatests/test_integration/test_subids.py
|
|
||||||
+++ b/ipatests/test_integration/test_subids.py
|
|
||||||
@@ -17,6 +17,7 @@ from ipatests.test_integration.base import IntegrationTest
|
|
||||||
|
|
||||||
class TestSubordinateId(IntegrationTest):
|
|
||||||
num_replicas = 0
|
|
||||||
+ num_clients = 1
|
|
||||||
topology = "star"
|
|
||||||
|
|
||||||
def _parse_result(self, result):
|
|
||||||
@@ -268,3 +269,40 @@ class TestSubordinateId(IntegrationTest):
|
|
||||||
f"--subuid={subuid}"])
|
|
||||||
owner = self._parse_result(result)["owner"]
|
|
||||||
assert owner == uid
|
|
||||||
+
|
|
||||||
+ def test_nsswitch_doesnot_contain_subid_entry(self):
|
|
||||||
+ """
|
|
||||||
+ This testcase checks that when ipa-client-install
|
|
||||||
+ is installed without subid option, the nsswitch.conf
|
|
||||||
+ does not contain subid entry or does not use sss as
|
|
||||||
+ source for subid
|
|
||||||
+ """
|
|
||||||
+ cmd = self.clients[0].run_command(
|
|
||||||
+ ["grep", "^subid", "/etc/nsswitch.conf"],
|
|
||||||
+ raiseonerr=False
|
|
||||||
+ )
|
|
||||||
+ # a source is defined for the subid database.
|
|
||||||
+ # Ensure it is not "sss"
|
|
||||||
+ if cmd.returncode == 0:
|
|
||||||
+ assert 'sss' not in cmd.stdout_text
|
|
||||||
+ else:
|
|
||||||
+ # grep command returncode 1 means no matching line
|
|
||||||
+ # was found = no source is defined for the subid database,
|
|
||||||
+ # which is valid other return codes would
|
|
||||||
+ # mean an error occurred
|
|
||||||
+ assert cmd.returncode == 1
|
|
||||||
+
|
|
||||||
+ def test_nsswitch_is_updated_with_subid_entry(self):
|
|
||||||
+ """
|
|
||||||
+ This test case checks that when ipa-client-install
|
|
||||||
+ is installed with --subid option, the nsswitch.conf
|
|
||||||
+ file is modified with the entry 'subid: sss'
|
|
||||||
+ """
|
|
||||||
+ tasks.uninstall_client(self.clients[0])
|
|
||||||
+ tasks.install_client(self.master, self.clients[0],
|
|
||||||
+ extra_args=['--subid'])
|
|
||||||
+ cmd = self.clients[0].run_command(
|
|
||||||
+ ["grep", "^subid", "/etc/nsswitch.conf"]
|
|
||||||
+ )
|
|
||||||
+ subid = cmd.stdout_text.split()
|
|
||||||
+ assert ['subid:', 'sss'] == subid
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -0,0 +1,138 @@
|
|||||||
|
From f10d1a0f84ed0f16ab4a1469f16ffadb3e79e59e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Fri, 27 Jan 2023 14:05:37 -0500
|
||||||
|
Subject: [PATCH] doc: add the --run command for manual job execution
|
||||||
|
|
||||||
|
A manual method was mentioned with no specificity. Include
|
||||||
|
the --run command. Also update the troubleshooting section
|
||||||
|
to show what failure to restart the CA after configuration
|
||||||
|
looks like.
|
||||||
|
|
||||||
|
Import the IPA CA chain for manual execution.
|
||||||
|
|
||||||
|
Also fix up some $ -> # to indicate root is needed.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9294
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
doc/designs/expired_certificate_pruning.md | 46 +++++++++++++++-------
|
||||||
|
1 file changed, 32 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/designs/expired_certificate_pruning.md b/doc/designs/expired_certificate_pruning.md
|
||||||
|
index 2c10d914020d3c12b6abb028323cd6796ec33e00..a23e452696ba2a150c4ad5a3e57360ae0a16a338 100644
|
||||||
|
--- a/doc/designs/expired_certificate_pruning.md
|
||||||
|
+++ b/doc/designs/expired_certificate_pruning.md
|
||||||
|
@@ -139,7 +139,7 @@ No validation of setting February 31st will be done. That will be left to PKI. B
|
||||||
|
|
||||||
|
### Disabling pruning
|
||||||
|
|
||||||
|
-`$ ipa-acme-manage pruning --enable=FALSE`
|
||||||
|
+`# ipa-acme-manage pruning --enable=FALSE`
|
||||||
|
|
||||||
|
This will remove the configuration option for `jobsScheduler.job.pruning.cron` just to be sure it no longer runs.
|
||||||
|
|
||||||
|
@@ -147,46 +147,46 @@ This will remove the configuration option for `jobsScheduler.job.pruning.cron` j
|
||||||
|
|
||||||
|
#### Pruning certificates
|
||||||
|
|
||||||
|
-`$ ipa-acme-manage pruning --certretention=VALUE --certretentionunit=UNIT`
|
||||||
|
+`# ipa-acme-manage pruning --certretention=VALUE --certretentionunit=UNIT`
|
||||||
|
|
||||||
|
will be the equivalent of:
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.certRetentionTime 30`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.certRetentionTime 30`
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.certRetentionUnit day`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.certRetentionUnit day`
|
||||||
|
|
||||||
|
The unit will always be required when modifying the time.
|
||||||
|
|
||||||
|
-`$ ipa-acme-manage pruning --certsearchsizelimit=VALUE --certsearchtimelimit=VALUE`
|
||||||
|
+`# ipa-acme-manage pruning --certsearchsizelimit=VALUE --certsearchtimelimit=VALUE`
|
||||||
|
|
||||||
|
will be the equivalent of:
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.certSearchSizeLimit 1000`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.certSearchSizeLimit 1000`
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.certSearchTimeLimit 0`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.certSearchTimeLimit 0`
|
||||||
|
|
||||||
|
A value of 0 for searchtimelimit is unlimited.
|
||||||
|
|
||||||
|
#### Pruning requests
|
||||||
|
|
||||||
|
-`$ ipa-acme-manage pruning --requestretention=VALUE --requestretentionunit=UNIT`
|
||||||
|
+`# ipa-acme-manage pruning --requestretention=VALUE --requestretentionunit=UNIT`
|
||||||
|
|
||||||
|
will be the equivalent of:
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionTime 30`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionTime 30`
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionUnit day`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.requestRetentionUnit day`
|
||||||
|
|
||||||
|
The unit will always be required when modifying the time.
|
||||||
|
|
||||||
|
-`$ ipa-acme-manage pruning --requestsearchsizelimit=VALUE --requestsearchtimelimit=VALUE`
|
||||||
|
+`# ipa-acme-manage pruning --requestsearchsizelimit=VALUE --requestsearchtimelimit=VALUE`
|
||||||
|
|
||||||
|
|
||||||
|
will be the equivalent of:
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.requestSearchSizeLimit 1000`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.requestSearchSizeLimit 1000`
|
||||||
|
|
||||||
|
-`$ pki-server ca-config-set jobsScheduler.job.pruning.requestSearchTimeLimit 0`
|
||||||
|
+`# pki-server ca-config-set jobsScheduler.job.pruning.requestSearchTimeLimit 0`
|
||||||
|
|
||||||
|
A value of 0 for searchtimelimit is unlimited.
|
||||||
|
|
||||||
|
@@ -212,10 +212,15 @@ Request search time limit: 0
|
||||||
|
Cron: 0 0 1 * *
|
||||||
|
```
|
||||||
|
|
||||||
|
+### Manual pruning
|
||||||
|
+
|
||||||
|
+`# ipa-acme-manage pruning --run`
|
||||||
|
+
|
||||||
|
+This is useful for testing the configuration or if the user wants to use the system cron or systemd timers for handling automation.
|
||||||
|
+
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
For online REST operations (login, run job) we will use the `ipaserver/plugins/dogtag.py::RestClient` class to manage the requests. This will take care of the authentication cookie, etc.
|
||||||
|
-
|
||||||
|
The class uses dogtag.https_request() will can take PEM cert and key files as arguments. These will be used for authentication.
|
||||||
|
|
||||||
|
For the non-REST operations (configuration, cron settings) the tool will fork out to pki-server ca-config-set.
|
||||||
|
@@ -239,6 +244,7 @@ Overview of the CLI commands. Example:
|
||||||
|
| ipa-acme-manage pruning | --requestretention=30 --requestretentionunit=day |
|
||||||
|
| ipa-acme-manage pruning | --requestsearchsizelimit=1000 --requestsearchtimelimit=0 |
|
||||||
|
| ipa-acme-manage pruning | --config-show |
|
||||||
|
+| ipa-acme-manage pruning | --run |
|
||||||
|
|
||||||
|
ipa-acme-manage can only be run as root.
|
||||||
|
|
||||||
|
@@ -295,3 +301,15 @@ The PKI debug log will contain job information.
|
||||||
|
2022-12-08 21:15:24 [pruning] INFO: PruningJob: - filter: (&(!(requestState=complete))(requestModifyTime<=1667942124527)(!(requestModifyTime=1667942124527)))
|
||||||
|
2022-12-08 21:15:24 [pruning] INFO: LDAPSession: Searching ou=ca, ou=requests,o=ipaca for (&(!(requestState=complete))(dateOfModify<=20221108211524Z)(!(dateOfModify=20221108211524Z)))
|
||||||
|
```
|
||||||
|
+
|
||||||
|
+### Manual execution fails with Forbidden
|
||||||
|
+
|
||||||
|
+If manually running pruning fails with a message like:
|
||||||
|
+
|
||||||
|
+```console
|
||||||
|
+# ipa-acme-manage pruning --run
|
||||||
|
+CalledProcessError(Command ['pki', '-C', '/tmp/tmppyyd3hfq/pwdfile.txt', '-d', '/tmp/tmppyyd3hfq', '-n', 'CN=IPA RA,O=EXAMPLE.TEST', 'ca-job-start', 'pruning'] returned non-zero exit status 255: 'PKIException: Forbidden\n')
|
||||||
|
+The ipa-acme-manage command failed.
|
||||||
|
+```
|
||||||
|
+
|
||||||
|
+You probably forgot to restart the CA after enabling pruning.
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
From 7a1e1d9f1cb13679c28f12d05b156a08bcc4d856 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Carla Martinez <carlmart@redhat.com>
|
|
||||||
Date: Fri, 29 Jul 2022 13:16:16 +0200
|
|
||||||
Subject: [PATCH] webui: Allow grace login limit
|
|
||||||
|
|
||||||
There was no support for setting the grace login limit on the WebUI. The
|
|
||||||
only way to so was only via CLI:
|
|
||||||
|
|
||||||
`ipa pwpolicy-mod --gracelimit=2 global_policy`
|
|
||||||
|
|
||||||
Thus, the grace login limit must be updated from the policy section and
|
|
||||||
this will reflect also on the user settings (under the 'Password Policy'
|
|
||||||
section)
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9211
|
|
||||||
|
|
||||||
Signed-off-by: Carla Martinez <carlmart@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
---
|
|
||||||
install/ui/src/freeipa/policy.js | 3 +++
|
|
||||||
install/ui/src/freeipa/user.js | 5 +++++
|
|
||||||
2 files changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/policy.js b/install/ui/src/freeipa/policy.js
|
|
||||||
index fa2028a52b1118b6125f91153280da0a2ffe0584..7ec103636ced0cce34997d81a02b25ba73bda33f 100644
|
|
||||||
--- a/install/ui/src/freeipa/policy.js
|
|
||||||
+++ b/install/ui/src/freeipa/policy.js
|
|
||||||
@@ -72,6 +72,9 @@ return {
|
|
||||||
{
|
|
||||||
name: 'cospriority',
|
|
||||||
required: true
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: 'passwordgracelimit'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
|
|
||||||
index a580db03599457eefd85f8c23d74c284946393c7..b47c97f72008f2f4e75b4cb88e9ff6756827b26e 100644
|
|
||||||
--- a/install/ui/src/freeipa/user.js
|
|
||||||
+++ b/install/ui/src/freeipa/user.js
|
|
||||||
@@ -318,6 +318,11 @@ return {
|
|
||||||
label: '@mo-param:pwpolicy:krbpwdlockoutduration:label',
|
|
||||||
read_only: true,
|
|
||||||
measurement_unit: 'seconds'
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: 'passwordgracelimit',
|
|
||||||
+ label: '@mo-param:pwpolicy:passwordgracelimit:label',
|
|
||||||
+ read_only: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
|||||||
From bfe074ed478c20a9537dc2a714bba50dbc2cd34f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sumedh Sidhaye <ssidhaye@redhat.com>
|
|
||||||
Date: Fri, 5 Aug 2022 11:22:59 +0530
|
|
||||||
Subject: [PATCH] Additional tests for RSN v3
|
|
||||||
|
|
||||||
New Tests include
|
|
||||||
TestRSNPKIConfig
|
|
||||||
TestRSNVault
|
|
||||||
|
|
||||||
The new tests are just extending existing classes to be run
|
|
||||||
with random serial numbers enabled
|
|
||||||
|
|
||||||
The tests also include a new method to check params set in CS.cfg for both CA and
|
|
||||||
KRA, and another test to check Random Serial Number version while
|
|
||||||
running `ipa ca-find`
|
|
||||||
|
|
||||||
Added nightly definitions
|
|
||||||
|
|
||||||
Related Ticket: https://pagure.io/freeipa/issue/2016
|
|
||||||
|
|
||||||
Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../nightly_ipa-4-10_latest.yaml | 24 +++++++++
|
|
||||||
.../nightly_ipa-4-10_latest_selinux.yaml | 26 ++++++++++
|
|
||||||
.../nightly_ipa-4-10_previous.yaml | 24 +++++++++
|
|
||||||
.../test_random_serial_numbers.py | 51 ++++++++++++++++++-
|
|
||||||
ipatests/test_integration/test_vault.py | 4 +-
|
|
||||||
5 files changed, 127 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
index 027b2a5b6c0b7ec3c3b5784ec4569661a06d4ed7..547320d258f51132266b56e9193533d2291c623c 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_latest.yaml
|
|
||||||
@@ -1821,3 +1821,27 @@ jobs:
|
|
||||||
template: *ci-ipa-4-10-latest
|
|
||||||
timeout: 5400
|
|
||||||
topology: *master_1repl
|
|
||||||
+
|
|
||||||
+ fedora-latest-ipa-4-10/test_random_serial_numbers_TestRSNPKIConfig:
|
|
||||||
+ requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-latest-ipa-4-10/build_url}'
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNPKIConfig
|
|
||||||
+ template: *ci-ipa-4-10-latest
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_3repl_1client
|
|
||||||
+
|
|
||||||
+ fedora-latest-ipa-4-10/test_random_serial_numbers_TestRSNVault:
|
|
||||||
+ requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-latest-ipa-4-10/build_url}'
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNVault
|
|
||||||
+ template: *ci-ipa-4-10-latest
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_1repl
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
index bcc17bef935666735bfb2c2e51209362a374b511..f6e5f1cff22de9db4df4577d1cd615499cf0fab3 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_latest_selinux.yaml
|
|
||||||
@@ -1966,3 +1966,29 @@ jobs:
|
|
||||||
template: *ci-ipa-4-10-latest
|
|
||||||
timeout: 5400
|
|
||||||
topology: *master_1repl
|
|
||||||
+
|
|
||||||
+ fedora-latest-ipa-4-10/test_random_serial_numbers_TestRSNPKIConfig:
|
|
||||||
+ requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-latest-ipa-4-10/build_url}'
|
|
||||||
+ selinux_enforcing: True
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNPKIConfig
|
|
||||||
+ template: *ci-ipa-4-10-latest
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_3repl_1client
|
|
||||||
+
|
|
||||||
+ fedora-latest-ipa-4-10/test_random_serial_numbers_TestRSNVault:
|
|
||||||
+ requires: [fedora-latest-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-latest-ipa-4-10/build_url}'
|
|
||||||
+ selinux_enforcing: True
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNVault
|
|
||||||
+ template: *ci-ipa-4-10-latest
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_1repl
|
|
||||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml b/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
index 37d38762e696a6394ef146a0e2b68bbc8ced515d..463f4b92fecc7fbc0be969de422352fb7baeb797 100644
|
|
||||||
--- a/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-10_previous.yaml
|
|
||||||
@@ -1821,3 +1821,27 @@ jobs:
|
|
||||||
template: *ci-ipa-4-10-previous
|
|
||||||
timeout: 5400
|
|
||||||
topology: *master_1repl
|
|
||||||
+
|
|
||||||
+ fedora-previous-ipa-4-10/test_random_serial_numbers_TestRSNPKIConfig:
|
|
||||||
+ requires: [fedora-previous-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-previous-ipa-4-10/build_url}'
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNPKIConfig
|
|
||||||
+ template: *ci-ipa-4-10-previous
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_3repl_1client
|
|
||||||
+
|
|
||||||
+ fedora-previous-ipa-4-10/test_random_serial_numbers_TestRSNVault:
|
|
||||||
+ requires: [fedora-previous-ipa-4-10/build]
|
|
||||||
+ priority: 50
|
|
||||||
+ job:
|
|
||||||
+ class: RunPytest
|
|
||||||
+ args:
|
|
||||||
+ build_url: '{fedora-previous-ipa-4-10/build_url}'
|
|
||||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestRSNVault
|
|
||||||
+ template: *ci-ipa-4-10-previous
|
|
||||||
+ timeout: 10800
|
|
||||||
+ topology: *master_1repl
|
|
||||||
diff --git a/ipatests/test_integration/test_random_serial_numbers.py b/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
index c52cfa4ed50e2718791b0844d743fb240d26b365..ab58b1c622b010994ed93a17dd80cfd02095508d 100644
|
|
||||||
--- a/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
+++ b/ipatests/test_integration/test_random_serial_numbers.py
|
|
||||||
@@ -4,12 +4,15 @@
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
+from ipaplatform.paths import paths
|
|
||||||
+
|
|
||||||
+from ipatests.pytest_ipa.integration import tasks
|
|
||||||
from ipatests.test_integration.test_installation import (
|
|
||||||
TestInstallWithCA_DNS1,
|
|
||||||
TestInstallWithCA_KRA1,
|
|
||||||
)
|
|
||||||
from ipatests.test_integration.test_caless import TestServerCALessToExternalCA
|
|
||||||
-
|
|
||||||
+from ipatests.test_integration.test_vault import TestInstallKRA
|
|
||||||
from ipatests.test_integration.test_commands import TestIPACommand
|
|
||||||
|
|
||||||
|
|
||||||
@@ -26,6 +29,18 @@ def pki_supports_RSNv3(host):
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
+def check_pki_config_params(host):
|
|
||||||
+ # Check CS.cfg
|
|
||||||
+ try:
|
|
||||||
+ cs_cfg = host.get_file_contents(paths.CA_CS_CFG_PATH)
|
|
||||||
+ kra_cfg = host.get_file_contents(paths.KRA_CS_CFG_PATH)
|
|
||||||
+ assert "dbs.cert.id.generator=random".encode() in cs_cfg
|
|
||||||
+ assert "dbs.request.id.generator=random".encode() in cs_cfg
|
|
||||||
+ assert "dbs.key.id.generator=random".encode() in kra_cfg
|
|
||||||
+ except IOError:
|
|
||||||
+ pytest.skip("PKI config not present.Skipping test")
|
|
||||||
+
|
|
||||||
+
|
|
||||||
class TestInstallWithCA_DNS1_RSN(TestInstallWithCA_DNS1):
|
|
||||||
random_serial = True
|
|
||||||
|
|
||||||
@@ -70,3 +85,37 @@ class TestServerCALessToExternalCA_RSN(TestServerCALessToExternalCA):
|
|
||||||
if not pki_supports_RSNv3(mh.master):
|
|
||||||
raise pytest.skip("RSNv3 not supported")
|
|
||||||
super(TestServerCALessToExternalCA_RSN, cls).uninstall(mh)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class TestRSNPKIConfig(TestInstallWithCA_KRA1):
|
|
||||||
+ random_serial = True
|
|
||||||
+ num_replicas = 3
|
|
||||||
+
|
|
||||||
+ @classmethod
|
|
||||||
+ def install(cls, mh):
|
|
||||||
+ if not pki_supports_RSNv3(mh.master):
|
|
||||||
+ raise pytest.skip("RSNv3 not supported")
|
|
||||||
+ super(TestRSNPKIConfig, cls).install(mh)
|
|
||||||
+
|
|
||||||
+ def test_check_pki_config(self):
|
|
||||||
+ check_pki_config_params(self.master)
|
|
||||||
+ check_pki_config_params(self.replicas[0])
|
|
||||||
+ check_pki_config_params(self.replicas[1])
|
|
||||||
+
|
|
||||||
+ def test_check_rsn_version(self):
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ res = self.master.run_command(['ipa', 'ca-find'])
|
|
||||||
+ assert 'RSN Version: 3' in res.stdout_text
|
|
||||||
+ tasks.kinit_admin(self.replicas[0])
|
|
||||||
+ res = self.replicas[0].run_command(['ipa', 'ca-find'])
|
|
||||||
+ assert 'RSN Version: 3' in res.stdout_text
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class TestRSNVault(TestInstallKRA):
|
|
||||||
+ random_serial = True
|
|
||||||
+
|
|
||||||
+ @classmethod
|
|
||||||
+ def install(cls, mh):
|
|
||||||
+ if not pki_supports_RSNv3(mh.master):
|
|
||||||
+ raise pytest.skip("RSNv3 not supported")
|
|
||||||
+ super(TestRSNVault, cls).install(mh)
|
|
||||||
diff --git a/ipatests/test_integration/test_vault.py b/ipatests/test_integration/test_vault.py
|
|
||||||
index 548822d049070d6f9d42da772264eb24010fafda..6288e557f96cae60d031b44c49fbe830712eb7be 100644
|
|
||||||
--- a/ipatests/test_integration/test_vault.py
|
|
||||||
+++ b/ipatests/test_integration/test_vault.py
|
|
||||||
@@ -33,7 +33,9 @@ class TestInstallKRA(IntegrationTest):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def install(cls, mh):
|
|
||||||
- tasks.install_master(cls.master, setup_kra=True)
|
|
||||||
+ tasks.install_master(cls.master,
|
|
||||||
+ setup_kra=True,
|
|
||||||
+ random_serial=cls.random_serial)
|
|
||||||
# do not install KRA on replica, it is part of test
|
|
||||||
tasks.install_replica(cls.master, cls.replicas[0], setup_kra=False)
|
|
||||||
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
43
SOURCES/0009-tests-add-wrapper-around-ACME-RSNv3-test.patch
Normal file
43
SOURCES/0009-tests-add-wrapper-around-ACME-RSNv3-test.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From d24b69981d94fce7b1e1aa4a5c1ab88a123f96b5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Fri, 3 Feb 2023 10:04:31 -0500
|
||||||
|
Subject: [PATCH] tests: add wrapper around ACME RSNv3 test
|
||||||
|
|
||||||
|
This test is located outside of the TestACMEPrune because
|
||||||
|
it enables RSNv3 while the server installed by TestACME doesn't.
|
||||||
|
|
||||||
|
It still needs a wrapper to enforce a version of PKI that
|
||||||
|
supports pruning because that is checked first in the tool.
|
||||||
|
Re-ordering that wouldn't be a good user experience.
|
||||||
|
|
||||||
|
https://pagure.io/freeipa/issue/9322
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_acme.py | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||||
|
index 93e785d8febd9fa8d7b3ef87ecb3f2eb42ac5da2..5ceba05976059de69414a79634d98045c3ab68bb 100644
|
||||||
|
--- a/ipatests/test_integration/test_acme.py
|
||||||
|
+++ b/ipatests/test_integration/test_acme.py
|
||||||
|
@@ -393,7 +393,14 @@ class TestACME(CALessBase):
|
||||||
|
|
||||||
|
def test_acme_pruning_no_random_serial(self):
|
||||||
|
"""This ACME install is configured without random serial
|
||||||
|
- numbers. Verify that we can't enable pruning on it."""
|
||||||
|
+ numbers. Verify that we can't enable pruning on it.
|
||||||
|
+
|
||||||
|
+ This test is located here because by default installs
|
||||||
|
+ don't enable RSNv3.
|
||||||
|
+ """
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
self.master.run_command(['ipa-acme-manage', 'enable'])
|
||||||
|
result = self.master.run_command(
|
||||||
|
['ipa-acme-manage', 'pruning', '--enable'],
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From 2857bc69957bde7e59fff1c66c5a83c7f560616b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 31 Jan 2023 15:53:08 +0100
|
||||||
|
Subject: [PATCH] automember-rebuild: add a notice about high CPU usage
|
||||||
|
|
||||||
|
The automember-rebuild task may require high CPU usage
|
||||||
|
if many users/hosts/groups are processed.
|
||||||
|
Add a note in the ipa automember-rebuild CLI output
|
||||||
|
and in the WebUI confirmation message.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9320
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
||||||
|
---
|
||||||
|
install/ui/test/data/i18n_messages.json | 2 +-
|
||||||
|
ipaclient/plugins/automember.py | 8 ++++++++
|
||||||
|
ipaserver/plugins/internal.py | 6 +++++-
|
||||||
|
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/install/ui/test/data/i18n_messages.json b/install/ui/test/data/i18n_messages.json
|
||||||
|
index 49d288326d8cea192a16e93a274599805b0ea666..5b735487bf33805e8f0534d378d1497f05a11be8 100644
|
||||||
|
--- a/install/ui/test/data/i18n_messages.json
|
||||||
|
+++ b/install/ui/test/data/i18n_messages.json
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
"actions": {
|
||||||
|
"apply": "Apply",
|
||||||
|
"automember_rebuild": "Rebuild auto membership",
|
||||||
|
- "automember_rebuild_confirm": "Are you sure you want to rebuild auto membership?",
|
||||||
|
+ "automember_rebuild_confirm": "Are you sure you want to rebuild auto membership? In case of a high number of users, hosts or groups, the operation may require high CPU usage.",
|
||||||
|
"automember_rebuild_success": "Automember rebuild membership task completed",
|
||||||
|
"confirm": "Are you sure you want to proceed with the action?",
|
||||||
|
"delete_confirm": "Are you sure you want to delete ${object}?",
|
||||||
|
diff --git a/ipaclient/plugins/automember.py b/ipaclient/plugins/automember.py
|
||||||
|
index df4a2e5a01744e0ff22c74180e13c2e7dc33fbaa..7108dc948753b9f6a4439842bd75e7c5e064bda6 100644
|
||||||
|
--- a/ipaclient/plugins/automember.py
|
||||||
|
+++ b/ipaclient/plugins/automember.py
|
||||||
|
@@ -34,3 +34,11 @@ class automember_add_condition(MethodOverride):
|
||||||
|
flags=['suppress_empty'],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+@register(override=True, no_fail=True)
|
||||||
|
+class automember_rebuild(MethodOverride):
|
||||||
|
+ def interactive_prompt_callback(self, kw):
|
||||||
|
+ msg = _('IMPORTANT: In case of a high number of users, hosts or '
|
||||||
|
+ 'groups, the operation may require high CPU usage.')
|
||||||
|
+ self.Backend.textui.print_plain(msg)
|
||||||
|
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
|
||||||
|
index 5ffa7a281548a0658386f8740dbddd96fd0bc7d6..e1e920f8bb49dd8ba8f30b727111bb1316f6a918 100644
|
||||||
|
--- a/ipaserver/plugins/internal.py
|
||||||
|
+++ b/ipaserver/plugins/internal.py
|
||||||
|
@@ -160,7 +160,11 @@ class i18n_messages(Command):
|
||||||
|
"actions": {
|
||||||
|
"apply": _("Apply"),
|
||||||
|
"automember_rebuild": _("Rebuild auto membership"),
|
||||||
|
- "automember_rebuild_confirm": _("Are you sure you want to rebuild auto membership?"),
|
||||||
|
+ "automember_rebuild_confirm": _(
|
||||||
|
+ "Are you sure you want to rebuild auto membership? In case of "
|
||||||
|
+ "a high number of users, hosts or groups, the operation "
|
||||||
|
+ "may require high CPU usage."
|
||||||
|
+ ),
|
||||||
|
"automember_rebuild_success": _("Automember rebuild membership task completed"),
|
||||||
|
"confirm": _("Are you sure you want to proceed with the action?"),
|
||||||
|
"delete_confirm": _("Are you sure you want to delete ${object}?"),
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 2003eb6b3d4a27a5de5eaa79418f115dd99886cd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Date: Sun, 7 Aug 2022 12:44:47 +0200
|
|
||||||
Subject: [PATCH] check_repl_update: in progress is a boolean
|
|
||||||
|
|
||||||
With the fix for https://pagure.io/freeipa/issue/9171,
|
|
||||||
nsds5replicaUpdateInProgress is now handled as a boolean.
|
|
||||||
One remaining occurrence was still handling it as a string
|
|
||||||
and calling lower() on its value.
|
|
||||||
|
|
||||||
Replace with direct boolean comparison.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9218
|
|
||||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
---
|
|
||||||
ipaserver/install/replication.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
|
|
||||||
index 16be3760cb14bfeb1cc9a761400752071639dc7c..9d9aa1c4bfc99109c0cf1e6d1619ec1b38e20c02 100644
|
|
||||||
--- a/ipaserver/install/replication.py
|
|
||||||
+++ b/ipaserver/install/replication.py
|
|
||||||
@@ -1152,7 +1152,7 @@ class ReplicationManager:
|
|
||||||
except (ValueError, TypeError, KeyError):
|
|
||||||
end = 0
|
|
||||||
# incremental update is done if inprogress is false and end >= start
|
|
||||||
- done = inprogress and inprogress.lower() == 'false' and start <= end
|
|
||||||
+ done = inprogress is not None and not inprogress and start <= end
|
|
||||||
logger.info("Replication Update in progress: %s: status: %s: "
|
|
||||||
"start: %d: end: %d",
|
|
||||||
inprogress, status, start, end)
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
158
SOURCES/0011-Fix-setting-values-of-0-in-ACME-pruning.patch
Normal file
158
SOURCES/0011-Fix-setting-values-of-0-in-ACME-pruning.patch
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
From 20ff7c16022793c707f6c2b8fb38a801870bc0e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Wed, 8 Feb 2023 10:42:58 -0500
|
||||||
|
Subject: [PATCH] Fix setting values of 0 in ACME pruning
|
||||||
|
|
||||||
|
Replace comparisons of "if value" with "if value is not None"
|
||||||
|
in order to handle 0.
|
||||||
|
|
||||||
|
Add a short reference to the man page to indicat that a cert
|
||||||
|
or request retention time of 0 means remove at the next
|
||||||
|
execution.
|
||||||
|
|
||||||
|
Also indicate that the search time limit is in seconds.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9325
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
||||||
|
---
|
||||||
|
doc/designs/expired_certificate_pruning.md | 4 ++--
|
||||||
|
install/tools/man/ipa-acme-manage.1 | 8 +++----
|
||||||
|
ipaserver/install/ipa_acme_manage.py | 28 +++++++++++-----------
|
||||||
|
3 files changed, 20 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/designs/expired_certificate_pruning.md b/doc/designs/expired_certificate_pruning.md
|
||||||
|
index a23e452696ba2a150c4ad5a3e57360ae0a16a338..35ead7b00145b5df44caf542cba277f0e6e08b6a 100644
|
||||||
|
--- a/doc/designs/expired_certificate_pruning.md
|
||||||
|
+++ b/doc/designs/expired_certificate_pruning.md
|
||||||
|
@@ -67,11 +67,11 @@ There are four values each that can be managed for pruning certificates and requ
|
||||||
|
* expired cert/incomplete request time
|
||||||
|
* time unit
|
||||||
|
* LDAP search size limit
|
||||||
|
-* LDAP search time limit
|
||||||
|
+* LDAP search time limit (in seconds)
|
||||||
|
|
||||||
|
The first two configure when an expired certificate or incomplete request will be deleted. The unit can be one of: minute, hour, day, year. By default it is 30 days.
|
||||||
|
|
||||||
|
-The LDAP limits control how many entries are returned and how long the search can take. By default it is 1000 entries and unlimited time.
|
||||||
|
+The LDAP limits control how many entries are returned and how long the search can take. By default it is 1000 entries and unlimited time (0 == unlimited, unit is seconds).
|
||||||
|
|
||||||
|
### Configuration settings
|
||||||
|
|
||||||
|
diff --git a/install/tools/man/ipa-acme-manage.1 b/install/tools/man/ipa-acme-manage.1
|
||||||
|
index e6cec4e4a7fd460c514a72456a2dc9a2e3682ebd..b8383c14f482698d2bcc8b08f0c0bf5882c3c298 100644
|
||||||
|
--- a/install/tools/man/ipa-acme-manage.1
|
||||||
|
+++ b/install/tools/man/ipa-acme-manage.1
|
||||||
|
@@ -79,7 +79,7 @@ For example, "0 0 1 * *" schedules the job to run at 12:00am on the first
|
||||||
|
day of each month.
|
||||||
|
.TP
|
||||||
|
\fB\-\-certretention=CERTRETENTION\fR
|
||||||
|
-Certificate retention time. The default is 30.
|
||||||
|
+Certificate retention time. The default is 30. A value of 0 will remove expired certificates with no delay.
|
||||||
|
.TP
|
||||||
|
\fB\-\-certretentionunit=CERTRETENTIONUNIT\fR
|
||||||
|
Certificate retention units. Valid units are: minute, hour, day, year.
|
||||||
|
@@ -89,10 +89,10 @@ The default is days.
|
||||||
|
LDAP search size limit searching for expired certificates. The default is 1000. This is a client-side limit. There may be additional server-side limitations.
|
||||||
|
.TP
|
||||||
|
\fB\-\-certsearchtimelimit=CERTSEARCHTIMELIMIT\fR
|
||||||
|
-LDAP search time limit searching for expired certificates. The default is 0, no limit. This is a client-side limit. There may be additional server-side limitations.
|
||||||
|
+LDAP search time limit (seconds) searching for expired certificates. The default is 0, no limit. This is a client-side limit. There may be additional server-side limitations.
|
||||||
|
.TP
|
||||||
|
\fB\-\-requestretention=REQUESTRETENTION\fR
|
||||||
|
-Request retention time. The default is 30.
|
||||||
|
+Request retention time. The default is 30. A value of 0 will remove expired requests with no delay.
|
||||||
|
.TP
|
||||||
|
\fB\-\-requestretentionunit=REQUESTRETENTIONUNIT\fR
|
||||||
|
Request retention units. Valid units are: minute, hour, day, year.
|
||||||
|
@@ -102,7 +102,7 @@ The default is days.
|
||||||
|
LDAP search size limit searching for unfulfilled requests. The default is 1000. There may be additional server-side limitations.
|
||||||
|
.TP
|
||||||
|
\fB\-\-requestsearchtimelimit=REQUESTSEARCHTIMELIMIT\fR
|
||||||
|
-LDAP search time limit searching for unfulfilled requests. The default is 0, no limit. There may be additional server-side limitations.
|
||||||
|
+LDAP search time limit (seconds) searching for unfulfilled requests. The default is 0, no limit. There may be additional server-side limitations.
|
||||||
|
.TP
|
||||||
|
\fB\-\-config\-show\fR
|
||||||
|
Show the current pruning configuration
|
||||||
|
diff --git a/ipaserver/install/ipa_acme_manage.py b/ipaserver/install/ipa_acme_manage.py
|
||||||
|
index b7b2111d9edcec2580aa4a485d7a7340146ff065..e7c35ff6fb5b7a30ac9e2c0c18f8db805cf06ee9 100644
|
||||||
|
--- a/ipaserver/install/ipa_acme_manage.py
|
||||||
|
+++ b/ipaserver/install/ipa_acme_manage.py
|
||||||
|
@@ -207,14 +207,14 @@ class IPAACMEManage(AdminTool):
|
||||||
|
self.options.enable,
|
||||||
|
self.options.disable,
|
||||||
|
self.options.cron,
|
||||||
|
- self.options.certretention,
|
||||||
|
+ self.options.certretention is not None,
|
||||||
|
self.options.certretentionunit,
|
||||||
|
- self.options.requestretention,
|
||||||
|
+ self.options.requestretention is not None,
|
||||||
|
self.options.requestretentionunit,
|
||||||
|
- self.options.certsearchsizelimit,
|
||||||
|
- self.options.certsearchtimelimit,
|
||||||
|
- self.options.requestsearchsizelimit,
|
||||||
|
- self.options.requestsearchtimelimit,
|
||||||
|
+ self.options.certsearchsizelimit is not None,
|
||||||
|
+ self.options.certsearchtimelimit is not None,
|
||||||
|
+ self.options.requestsearchsizelimit is not None,
|
||||||
|
+ self.options.requestsearchtimelimit is not None,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
and (self.options.config_show or self.options.run)
|
||||||
|
@@ -226,7 +226,7 @@ class IPAACMEManage(AdminTool):
|
||||||
|
elif self.options.cron:
|
||||||
|
if len(self.options.cron.split()) != 5:
|
||||||
|
self.option_parser.error("Invalid format for --cron")
|
||||||
|
- # dogtag does no validation when setting an option so
|
||||||
|
+ # dogtag does no validation when setting this option so
|
||||||
|
# do the minimum. The dogtag cron is limited compared to
|
||||||
|
# crontab(5).
|
||||||
|
opt = self.options.cron.split()
|
||||||
|
@@ -255,7 +255,7 @@ class IPAACMEManage(AdminTool):
|
||||||
|
'pki-server', command,
|
||||||
|
f'{prefix}.{directive}'
|
||||||
|
]
|
||||||
|
- if value:
|
||||||
|
+ if value is not None:
|
||||||
|
args.extend([str(value)])
|
||||||
|
logger.debug(args)
|
||||||
|
result = run(args, raiseonerr=False, capture_output=True,
|
||||||
|
@@ -350,28 +350,28 @@ class IPAACMEManage(AdminTool):
|
||||||
|
|
||||||
|
# pki-server ca-config-set can only set one option at a time so
|
||||||
|
# loop through all the options and set what is there.
|
||||||
|
- if self.options.certretention:
|
||||||
|
+ if self.options.certretention is not None:
|
||||||
|
ca_config_set('certRetentionTime',
|
||||||
|
self.options.certretention)
|
||||||
|
if self.options.certretentionunit:
|
||||||
|
ca_config_set('certRetentionUnit',
|
||||||
|
self.options.certretentionunit)
|
||||||
|
- if self.options.certsearchtimelimit:
|
||||||
|
+ if self.options.certsearchtimelimit is not None:
|
||||||
|
ca_config_set('certSearchTimeLimit',
|
||||||
|
self.options.certsearchtimelimit)
|
||||||
|
- if self.options.certsearchsizelimit:
|
||||||
|
+ if self.options.certsearchsizelimit is not None:
|
||||||
|
ca_config_set('certSearchSizeLimit',
|
||||||
|
self.options.certsearchsizelimit)
|
||||||
|
- if self.options.requestretention:
|
||||||
|
+ if self.options.requestretention is not None:
|
||||||
|
ca_config_set('requestRetentionTime',
|
||||||
|
self.options.requestretention)
|
||||||
|
if self.options.requestretentionunit:
|
||||||
|
ca_config_set('requestRetentionUnit',
|
||||||
|
self.options.requestretentionunit)
|
||||||
|
- if self.options.requestsearchsizelimit:
|
||||||
|
+ if self.options.requestsearchsizelimit is not None:
|
||||||
|
ca_config_set('requestSearchSizeLimit',
|
||||||
|
self.options.requestsearchsizelimit)
|
||||||
|
- if self.options.requestsearchtimelimit:
|
||||||
|
+ if self.options.requestsearchtimelimit is not None:
|
||||||
|
ca_config_set('requestSearchTimeLimit',
|
||||||
|
self.options.requestsearchtimelimit)
|
||||||
|
if self.options.cron:
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
From b6520bef2ef05dd87636d8b57e3247d451af81d8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Date: Tue, 14 Dec 2021 16:33:29 +0100
|
|
||||||
Subject: [PATCH] ipatests: Fix expected object classes
|
|
||||||
|
|
||||||
Because the sidgen plugin is a postop plugin, it is not
|
|
||||||
always triggered before the result of an ADD is returned
|
|
||||||
and the objectclasses of the user may / may not contain
|
|
||||||
ipantuserattrs.
|
|
||||||
Fix the expected object classes.
|
|
||||||
|
|
||||||
Related: https://pagure.io/freeipa/issue/9062
|
|
||||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
|
||||||
---
|
|
||||||
ipatests/test_xmlrpc/test_user_plugin.py | 20 ++++++++++++++------
|
|
||||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py
|
|
||||||
index 74d78b0c6d75590640da1357da1f9f4570307878..c156a8793c5765df96029753f4a278e961d4e895 100644
|
|
||||||
--- a/ipatests/test_xmlrpc/test_user_plugin.py
|
|
||||||
+++ b/ipatests/test_xmlrpc/test_user_plugin.py
|
|
||||||
@@ -125,7 +125,9 @@ def user_npg(request, group):
|
|
||||||
del tracker.attrs['mepmanagedentry']
|
|
||||||
tracker.attrs.update(
|
|
||||||
description=[], memberof_group=[group.cn],
|
|
||||||
- objectclass=objectclasses.user_base + [u'ipantuserattrs'],
|
|
||||||
+ objectclass=fuzzy_set_optional_oc(
|
|
||||||
+ objectclasses.user_base, 'ipantuserattrs'
|
|
||||||
+ ),
|
|
||||||
)
|
|
||||||
return tracker.make_fixture(request)
|
|
||||||
|
|
||||||
@@ -139,7 +141,9 @@ def user_npg2(request, group):
|
|
||||||
del tracker.attrs['mepmanagedentry']
|
|
||||||
tracker.attrs.update(
|
|
||||||
gidnumber=[u'1000'], description=[], memberof_group=[group.cn],
|
|
||||||
- objectclass=objectclasses.user_base + [u'ipantuserattrs'],
|
|
||||||
+ objectclass=fuzzy_set_optional_oc(
|
|
||||||
+ objectclasses.user_base, 'ipantuserattrs'
|
|
||||||
+ ),
|
|
||||||
)
|
|
||||||
return tracker.make_fixture(request)
|
|
||||||
|
|
||||||
@@ -151,8 +155,9 @@ def user_radius(request, xmlrpc_setup):
|
|
||||||
sn=u'radiususer1',
|
|
||||||
ipatokenradiususername=u'radiususer')
|
|
||||||
tracker.track_create()
|
|
||||||
- tracker.attrs.update(
|
|
||||||
- objectclass=objectclasses.user + [u'ipatokenradiusproxyuser']
|
|
||||||
+ tracker.attrs.update(objectclass=fuzzy_set_optional_oc(
|
|
||||||
+ objectclasses.user + [u'ipatokenradiusproxyuser'],
|
|
||||||
+ 'ipantuserattrs'),
|
|
||||||
)
|
|
||||||
return tracker.make_fixture(request)
|
|
||||||
|
|
||||||
@@ -647,7 +652,8 @@ class TestCreate(XMLRPC_test):
|
|
||||||
testuser.attrs.update(gidnumber=[u'1000'])
|
|
||||||
testuser.attrs.update(
|
|
||||||
description=[],
|
|
||||||
- objectclass=objectclasses.user_base + [u'ipantuserattrs']
|
|
||||||
+ objectclass=fuzzy_set_optional_oc(
|
|
||||||
+ objectclasses.user_base, 'ipantuserattrs'),
|
|
||||||
)
|
|
||||||
command = testuser.make_create_command()
|
|
||||||
result = command()
|
|
||||||
@@ -865,7 +871,9 @@ class TestUserWithUPGDisabled(XMLRPC_test):
|
|
||||||
testuser.attrs.update(gidnumber=[u'1000'])
|
|
||||||
testuser.attrs.update(
|
|
||||||
description=[],
|
|
||||||
- objectclass=objectclasses.user_base + [u'ipantuserattrs'],
|
|
||||||
+ objectclass=fuzzy_set_optional_oc(
|
|
||||||
+ objectclasses.user_base, 'ipantuserattrs'
|
|
||||||
+ ),
|
|
||||||
)
|
|
||||||
command = testuser.make_create_command()
|
|
||||||
result = command()
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From 4e0ad96fbd9f438c884eeeaa60c2fb0c910a2b61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Mon, 11 Jul 2022 14:20:32 -0400
|
||||||
|
Subject: [PATCH] Wipe the ipa-ca DNS record when updating system records
|
||||||
|
|
||||||
|
If a server with a CA has been marked as hidden and
|
||||||
|
contains the last A or AAAA address then that address
|
||||||
|
would remain in the ipa-ca entry.
|
||||||
|
|
||||||
|
This is because update-dns-system-records did not delete
|
||||||
|
values, it just re-computed them. So if no A or AAAA
|
||||||
|
records were found then the existing value was left.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9195
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
||||||
|
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
||||||
|
---
|
||||||
|
ipaserver/dns_data_management.py | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py
|
||||||
|
index e2bc530ee8a8d7ade853652680c524ccd229205c..aaae5446856aba5e39ca9bb9c03decd434e4f71a 100644
|
||||||
|
--- a/ipaserver/dns_data_management.py
|
||||||
|
+++ b/ipaserver/dns_data_management.py
|
||||||
|
@@ -19,6 +19,7 @@ from dns import (
|
||||||
|
from time import sleep, time
|
||||||
|
|
||||||
|
from ipalib import errors
|
||||||
|
+from ipalib.constants import IPA_CA_RECORD
|
||||||
|
from ipalib.dns import record_name_format
|
||||||
|
from ipapython.dnsutil import DNSName
|
||||||
|
from ipaserver.install import installutils
|
||||||
|
@@ -187,7 +188,7 @@ class IPASystemRecords:
|
||||||
|
|
||||||
|
def __add_ca_records_from_hostname(self, zone_obj, hostname):
|
||||||
|
assert isinstance(hostname, DNSName) and hostname.is_absolute()
|
||||||
|
- r_name = DNSName('ipa-ca') + self.domain_abs
|
||||||
|
+ r_name = DNSName(IPA_CA_RECORD) + self.domain_abs
|
||||||
|
rrsets = None
|
||||||
|
end_time = time() + CA_RECORDS_DNS_TIMEOUT
|
||||||
|
while True:
|
||||||
|
@@ -210,6 +211,7 @@ class IPASystemRecords:
|
||||||
|
|
||||||
|
for rrset in rrsets:
|
||||||
|
for rd in rrset:
|
||||||
|
+ logger.debug("Adding CA IP %s for %s", rd.to_text(), hostname)
|
||||||
|
rdataset = zone_obj.get_rdataset(
|
||||||
|
r_name, rd.rdtype, create=True)
|
||||||
|
rdataset.add(rd, ttl=self.TTL)
|
||||||
|
@@ -461,6 +463,14 @@ class IPASystemRecords:
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
+ # Remove the ipa-ca record(s). They will be reconstructed in
|
||||||
|
+ # get_base_records().
|
||||||
|
+ r_name = DNSName(IPA_CA_RECORD) + self.domain_abs
|
||||||
|
+ try:
|
||||||
|
+ self.api_instance.Command.dnsrecord_del(
|
||||||
|
+ self.domain_abs, r_name, del_all=True)
|
||||||
|
+ except errors.NotFound:
|
||||||
|
+ pass
|
||||||
|
base_zone = self.get_base_records()
|
||||||
|
for record_name, node in base_zone.items():
|
||||||
|
set_cname_template = record_name in names_requiring_cname_templates
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
From 1aa39529cda4ab9620539dbad705cedd23c21b42 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 18 Aug 2022 08:21:58 -0400
|
|
||||||
Subject: [PATCH] doc: Update LDAP grace period design with default values
|
|
||||||
|
|
||||||
New group password policies will get -1 (unlimited) on creation
|
|
||||||
by default.
|
|
||||||
|
|
||||||
Existing group password policies will remain untouched and
|
|
||||||
those created prior will be treated as no BIND allowed.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
doc/designs/ldap_grace_period.md | 17 ++++++++++++++++-
|
|
||||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/doc/designs/ldap_grace_period.md b/doc/designs/ldap_grace_period.md
|
|
||||||
index 4b9db34247c1446aec3f5bcce7dfa1bd8a2bd359..e26aedda976b19f3ba26593ba3b3c06c30506a21 100644
|
|
||||||
--- a/doc/designs/ldap_grace_period.md
|
|
||||||
+++ b/doc/designs/ldap_grace_period.md
|
|
||||||
@@ -51,7 +51,22 @@ The basic flow is:
|
|
||||||
|
|
||||||
On successful password reset (by anyone) reset the user's passwordGraceUserTime to 0.
|
|
||||||
|
|
||||||
-The default value on install/upgrade will be -1 to retail existing behavior.
|
|
||||||
+Range values for passwordgracelimit are:
|
|
||||||
+
|
|
||||||
+-1 : password grace checking is disabled
|
|
||||||
+ 0 : no grace BIND are allowed at all post-expiration
|
|
||||||
+ 1..MAXINT: the number of BIND allowed post-expiration
|
|
||||||
+
|
|
||||||
+The default value for the global policy on install/upgrade will be -1 to
|
|
||||||
+retain existing behavior.
|
|
||||||
+
|
|
||||||
+New group password policies will default to -1 to retain previous
|
|
||||||
+behavior.
|
|
||||||
+
|
|
||||||
+Existing group policies with no grace limit set are updated to use
|
|
||||||
+the default unlimited value, -1. This is done because lack of value in
|
|
||||||
+LDAP is treated as 0 so any existing group policies would not allow
|
|
||||||
+post-expiration BIND so this will avoid confusion.
|
|
||||||
|
|
||||||
The per-user attempts will not be replicated.
|
|
||||||
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
From 45e6d49b94da78cd82eb016b3266a17a1359a087 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 4 Aug 2022 12:04:22 -0400
|
|
||||||
Subject: [PATCH] Set default gracelimit on group password policies to -1
|
|
||||||
|
|
||||||
This will retain previous behavior of unlimited LDAP BIND
|
|
||||||
post-expiration.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
API.txt | 2 +-
|
|
||||||
ipaserver/plugins/pwpolicy.py | 2 ++
|
|
||||||
ipatests/test_xmlrpc/test_pwpolicy_plugin.py | 2 ++
|
|
||||||
3 files changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/API.txt b/API.txt
|
|
||||||
index 66929b921b197e27ede847fb6b10bf1e44c3464a..210bfc4950e6a7346dbdd6e29d1096b2f8750b1e 100644
|
|
||||||
--- a/API.txt
|
|
||||||
+++ b/API.txt
|
|
||||||
@@ -4076,7 +4076,7 @@ option: Int('krbpwdlockoutduration?', cli_name='lockouttime')
|
|
||||||
option: Int('krbpwdmaxfailure?', cli_name='maxfail')
|
|
||||||
option: Int('krbpwdmindiffchars?', cli_name='minclasses')
|
|
||||||
option: Int('krbpwdminlength?', cli_name='minlength')
|
|
||||||
-option: Int('passwordgracelimit?', cli_name='gracelimit', default=-1)
|
|
||||||
+option: Int('passwordgracelimit?', autofill=True, cli_name='gracelimit', default=-1)
|
|
||||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
|
||||||
option: Str('setattr*', cli_name='setattr')
|
|
||||||
option: Str('version?')
|
|
||||||
diff --git a/ipaserver/plugins/pwpolicy.py b/ipaserver/plugins/pwpolicy.py
|
|
||||||
index 4428aede2dcc7a2a0b6128bf7f58eb47e4a8e07d..f4ebffd5c8f06a53b6c4d5e48ff6eeafa240e3a4 100644
|
|
||||||
--- a/ipaserver/plugins/pwpolicy.py
|
|
||||||
+++ b/ipaserver/plugins/pwpolicy.py
|
|
||||||
@@ -408,6 +408,7 @@ class pwpolicy(LDAPObject):
|
|
||||||
minvalue=-1,
|
|
||||||
maxvalue=Int.MAX_UINT32,
|
|
||||||
default=-1,
|
|
||||||
+ autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@@ -539,6 +540,7 @@ class pwpolicy_add(LDAPCreate):
|
|
||||||
keys[-1], krbpwdpolicyreference=dn,
|
|
||||||
cospriority=options.get('cospriority')
|
|
||||||
)
|
|
||||||
+
|
|
||||||
return dn
|
|
||||||
|
|
||||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
|
||||||
diff --git a/ipatests/test_xmlrpc/test_pwpolicy_plugin.py b/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
index 8eee69c185b15be72870050ed247f252c72d1c66..fc785223bfe56269ad8b211e8f1c3ac9f4064c3c 100644
|
|
||||||
--- a/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
+++ b/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
@@ -387,6 +387,7 @@ class test_pwpolicy_mod_cospriority(Declarative):
|
|
||||||
krbpwdhistorylength=[u'10'],
|
|
||||||
krbpwdmindiffchars=[u'3'],
|
|
||||||
krbpwdminlength=[u'8'],
|
|
||||||
+ passwordgracelimit=[u'-1'],
|
|
||||||
objectclass=objectclasses.pwpolicy,
|
|
||||||
),
|
|
||||||
summary=None,
|
|
||||||
@@ -417,6 +418,7 @@ class test_pwpolicy_mod_cospriority(Declarative):
|
|
||||||
krbpwdhistorylength=[u'10'],
|
|
||||||
krbpwdmindiffchars=[u'3'],
|
|
||||||
krbpwdminlength=[u'8'],
|
|
||||||
+ passwordgracelimit=[u'-1'],
|
|
||||||
),
|
|
||||||
summary=None,
|
|
||||||
value=u'ipausers',
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
|||||||
|
From 0206369eec8530e96c66986c4ca501d8962193ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 14:22:30 +0200
|
||||||
|
Subject: [PATCH] ipa-kdb: PAC consistency checker needs to handle child
|
||||||
|
domains as well
|
||||||
|
|
||||||
|
When PAC check is performed, we might get a signing TGT instead of the
|
||||||
|
client DB entry. This means it is a principal from a trusted domain but
|
||||||
|
we don't know which one exactly because we only have a krbtgt for the
|
||||||
|
forest root. This happens in MIT Kerberos 1.20 or later where KDB's
|
||||||
|
issue_pac() callback never gets the original client principal directly.
|
||||||
|
|
||||||
|
Look into known child domains as well and make pass the check if both
|
||||||
|
NetBIOS name and SID correspond to one of the trusted domains under this
|
||||||
|
forest root. Move check for the SID before NetBIOS name check because we
|
||||||
|
can use SID of the domain in PAC to find out the right child domain in
|
||||||
|
our trusted domains' topology list.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9316
|
||||||
|
|
||||||
|
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
daemons/ipa-kdb/ipa_kdb_mspac.c | 51 +++++++++++++++++++++------------
|
||||||
|
1 file changed, 32 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
index a15050e2166f95c227d2e3c7d238e1ea2fe01235..476d1cb558a53420821ccfb1b794cb6bedce7794 100644
|
||||||
|
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
@@ -1827,11 +1827,43 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
bool result;
|
||||||
|
char *domstr = NULL;
|
||||||
|
|
||||||
|
+ ipactx = ipadb_get_context(context);
|
||||||
|
+ if (!ipactx || !ipactx->mspac) {
|
||||||
|
+ return KRB5_KDB_DBNOTINITED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
domain = get_domain_from_realm_update(context, realm);
|
||||||
|
if (!domain) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* check exact sid */
|
||||||
|
+ result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
|
||||||
|
+ if (!result) {
|
||||||
|
+ struct ipadb_mspac *mspac_ctx = ipactx->mspac;
|
||||||
|
+ result = FALSE;
|
||||||
|
+ /* Didn't match but perhaps the original PAC was issued by a child domain's DC? */
|
||||||
|
+ for (k = 0; k < mspac_ctx->num_trusts; k++) {
|
||||||
|
+ result = dom_sid_check(&mspac_ctx->trusts[k].domsid,
|
||||||
|
+ info->info->info3.base.domain_sid, true);
|
||||||
|
+ if (result) {
|
||||||
|
+ domain = &mspac_ctx->trusts[k];
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!result) {
|
||||||
|
+ domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
|
||||||
|
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
||||||
|
+ "expected domain SID = %s, "
|
||||||
|
+ "found domain SID = %s",
|
||||||
|
+ domain->domain_name, domain->domain_sid,
|
||||||
|
+ domstr ? domstr : "<failed to display>");
|
||||||
|
+ talloc_free(domstr);
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* At this point we may have changed the domain we look at, */
|
||||||
|
/* check netbios/flat name */
|
||||||
|
if (strcasecmp(info->info->info3.base.logon_domain.string,
|
||||||
|
domain->flat_name) != 0) {
|
||||||
|
@@ -1843,21 +1875,6 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* check exact sid */
|
||||||
|
- result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
|
||||||
|
- if (!result) {
|
||||||
|
- domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
|
||||||
|
- if (!domstr) {
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
- krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
||||||
|
- "expected domain SID = %s, "
|
||||||
|
- "found domain SID = %s",
|
||||||
|
- domain->domain_name, domain->domain_sid, domstr);
|
||||||
|
- talloc_free(domstr);
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* Check if this domain has been filtered out by the trust itself*/
|
||||||
|
if (domain->parent != NULL) {
|
||||||
|
for(k = 0; k < domain->parent->len_sid_blocklist_incoming; k++) {
|
||||||
|
@@ -1944,10 +1961,6 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
* should include different possibilities into account
|
||||||
|
* */
|
||||||
|
if (info->info->info3.sidcount != 0) {
|
||||||
|
- ipactx = ipadb_get_context(context);
|
||||||
|
- if (!ipactx || !ipactx->mspac) {
|
||||||
|
- return KRB5_KDB_DBNOTINITED;
|
||||||
|
- }
|
||||||
|
count = info->info->info3.sidcount;
|
||||||
|
i = 0;
|
||||||
|
j = 0;
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
83
SOURCES/0014-Add-test-for-SSH-with-GSSAPI-auth.patch
Normal file
83
SOURCES/0014-Add-test-for-SSH-with-GSSAPI-auth.patch
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
From a6cb905de74da38d62f9c3bd7957018924282521 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anuja More <amore@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 19:27:49 +0530
|
||||||
|
Subject: [PATCH] Add test for SSH with GSSAPI auth.
|
||||||
|
|
||||||
|
Added test for aduser with GSSAPI authentication.
|
||||||
|
|
||||||
|
Related : https://pagure.io/freeipa/issue/9316
|
||||||
|
|
||||||
|
Signed-off-by: Anuja More <amore@redhat.com>
|
||||||
|
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_trust.py | 46 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 46 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
|
||||||
|
index c4b3b99ce1abbc16817b6530939fd9bae3f9500a..0d5b71cb0277a79eed7c34eb7e3d7eb6c09faa5e 100644
|
||||||
|
--- a/ipatests/test_integration/test_trust.py
|
||||||
|
+++ b/ipatests/test_integration/test_trust.py
|
||||||
|
@@ -527,6 +527,35 @@ class TestTrust(BaseTestTrust):
|
||||||
|
.format(self.ad_domain, subordinate_suffix))
|
||||||
|
self.ad.run_command(['powershell', '-c', cmd])
|
||||||
|
|
||||||
|
+ def test_ssh_aduser(self):
|
||||||
|
+ """Test ssh with GSSAPI is working with aduser
|
||||||
|
+
|
||||||
|
+ When kerberos ticket is obtained for child domain user
|
||||||
|
+ and ssh with this ticket should be successful
|
||||||
|
+ with no password prompt.
|
||||||
|
+
|
||||||
|
+ Related : https://pagure.io/freeipa/issue/9316
|
||||||
|
+ """
|
||||||
|
+ testuser = 'testuser@{0}'.format(self.ad_domain)
|
||||||
|
+ testusersub = 'subdomaintestuser@{0}'.format(self.ad_subdomain)
|
||||||
|
+
|
||||||
|
+ def sshuser(host, user):
|
||||||
|
+ tasks.kdestroy_all(host)
|
||||||
|
+ try:
|
||||||
|
+ tasks.kinit_as_user(host, user,
|
||||||
|
+ host.config.ad_admin_password
|
||||||
|
+ )
|
||||||
|
+ ssh_cmd = "ssh -q -K -l {user} {host} hostname"
|
||||||
|
+ valid_ssh = host.run_command(
|
||||||
|
+ ssh_cmd.format(user=user, host=host.hostname)
|
||||||
|
+ )
|
||||||
|
+ assert host.hostname in valid_ssh.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ tasks.kdestroy_all(host)
|
||||||
|
+
|
||||||
|
+ sshuser(self.master, testuser)
|
||||||
|
+ sshuser(self.master, testusersub)
|
||||||
|
+
|
||||||
|
def test_remove_nonposix_trust(self):
|
||||||
|
self.remove_trust(self.ad)
|
||||||
|
tasks.unconfigure_dns_for_trust(self.master, self.ad)
|
||||||
|
@@ -785,6 +814,23 @@ class TestTrust(BaseTestTrust):
|
||||||
|
assert re.search(
|
||||||
|
testuser_regex, result.stdout_text), result.stdout_text
|
||||||
|
|
||||||
|
+ def test_ssh_adtreeuser(self):
|
||||||
|
+ testuser = 'treetestuser@{0}'.format(self.ad_treedomain)
|
||||||
|
+ self.master.run_command(["id", testuser])
|
||||||
|
+ tasks.clear_sssd_cache(self.master)
|
||||||
|
+ tasks.kdestroy_all(self.master)
|
||||||
|
+ try:
|
||||||
|
+ tasks.kinit_as_user(self.master, testuser,
|
||||||
|
+ password="Secret123456"
|
||||||
|
+ )
|
||||||
|
+ ssh_cmd = "ssh -q -K -l {user} {host} hostname"
|
||||||
|
+ valid_ssh = self.master.run_command(
|
||||||
|
+ ssh_cmd.format(user=testuser, host=self.master.hostname)
|
||||||
|
+ )
|
||||||
|
+ assert self.master.hostname in valid_ssh.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ tasks.kdestroy_all(self.master)
|
||||||
|
+
|
||||||
|
def test_remove_external_treedomain_trust(self):
|
||||||
|
self.remove_trust(self.tree_ad)
|
||||||
|
tasks.unconfigure_dns_for_trust(self.master, self.ad, self.tree_ad)
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,106 +0,0 @@
|
|||||||
From de6f074538f6641fd9d84bed204a3d4d50eccbe5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 4 Aug 2022 12:04:41 -0400
|
|
||||||
Subject: [PATCH] Set default on group pwpolicy with no grace limit in upgrade
|
|
||||||
|
|
||||||
If an existing group policy lacks a password grace limit
|
|
||||||
update it to -1 on upgrade.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../updates/90-post_upgrade_plugins.update | 1 +
|
|
||||||
ipaserver/install/plugins/update_pwpolicy.py | 66 +++++++++++++++++++
|
|
||||||
2 files changed, 67 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
|
|
||||||
index c7ec71d492b0ac0e7641d586b7e7fa7501743bc2..6fe91aa6c6310a69a7f0feb1ad62243945db67f9 100644
|
|
||||||
--- a/install/updates/90-post_upgrade_plugins.update
|
|
||||||
+++ b/install/updates/90-post_upgrade_plugins.update
|
|
||||||
@@ -26,6 +26,7 @@ plugin: update_ra_cert_store
|
|
||||||
plugin: update_mapping_Guests_to_nobody
|
|
||||||
plugin: fix_kra_people_entry
|
|
||||||
plugin: update_pwpolicy
|
|
||||||
+plugin: update_pwpolicy_grace
|
|
||||||
|
|
||||||
# last
|
|
||||||
# DNS version 1
|
|
||||||
diff --git a/ipaserver/install/plugins/update_pwpolicy.py b/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
index dca44ce4369dfc11f83a412a1249bb045d46713f..4185f034313bd49ca68e86c620043af6ead5f6d6 100644
|
|
||||||
--- a/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
+++ b/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
@@ -78,3 +78,69 @@ class update_pwpolicy(Updater):
|
|
||||||
return False, []
|
|
||||||
|
|
||||||
return False, []
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+@register()
|
|
||||||
+class update_pwpolicy_grace(Updater):
|
|
||||||
+ """
|
|
||||||
+ Ensure all group policies have a grace period set.
|
|
||||||
+ """
|
|
||||||
+
|
|
||||||
+ def execute(self, **options):
|
|
||||||
+ ldap = self.api.Backend.ldap2
|
|
||||||
+
|
|
||||||
+ base_dn = DN(('cn', self.api.env.realm), ('cn', 'kerberos'),
|
|
||||||
+ self.api.env.basedn)
|
|
||||||
+ search_filter = (
|
|
||||||
+ "(&(objectClass=krbpwdpolicy)(!(passwordgracelimit=*)))"
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ while True:
|
|
||||||
+ # Run the search in loop to avoid issues when LDAP limits are hit
|
|
||||||
+ # during update
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ (entries, truncated) = ldap.find_entries(
|
|
||||||
+ search_filter, ['objectclass'], base_dn, time_limit=0,
|
|
||||||
+ size_limit=0)
|
|
||||||
+
|
|
||||||
+ except errors.EmptyResult:
|
|
||||||
+ logger.debug("update_pwpolicy: no policies without "
|
|
||||||
+ "passwordgracelimit set")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ except errors.ExecutionError as e:
|
|
||||||
+ logger.error("update_pwpolicy: cannot retrieve list "
|
|
||||||
+ "of policies missing passwordgracelimit: %s", e)
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ logger.debug("update_pwpolicy: found %d "
|
|
||||||
+ "policies to update, truncated: %s",
|
|
||||||
+ len(entries), truncated)
|
|
||||||
+
|
|
||||||
+ error = False
|
|
||||||
+
|
|
||||||
+ for entry in entries:
|
|
||||||
+ # Set unlimited BIND by default
|
|
||||||
+ entry['passwordgracelimit'] = -1
|
|
||||||
+ try:
|
|
||||||
+ ldap.update_entry(entry)
|
|
||||||
+ except (errors.EmptyModlist, errors.NotFound):
|
|
||||||
+ pass
|
|
||||||
+ except errors.ExecutionError as e:
|
|
||||||
+ logger.debug("update_pwpolicy: cannot "
|
|
||||||
+ "update policy: %s", e)
|
|
||||||
+ error = True
|
|
||||||
+
|
|
||||||
+ if error:
|
|
||||||
+ # Exit loop to avoid infinite cycles
|
|
||||||
+ logger.error("update_pwpolicy: error(s) "
|
|
||||||
+ "detected during pwpolicy update")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ elif not truncated:
|
|
||||||
+ # All affected entries updated, exit the loop
|
|
||||||
+ logger.debug("update_pwpolicy: all policies updated")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ return False, []
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
From a0928fe164712303a7c24ee61500ac7326bd9e4a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
Date: Tue, 23 Aug 2022 16:58:07 +0300
|
|
||||||
Subject: [PATCH] fix canonicalization issue in Web UI
|
|
||||||
|
|
||||||
When Kerberos principal alias is used to login to a Web UI, we end up
|
|
||||||
with a request that is authenticated by a ticket issued in the alias
|
|
||||||
name but metadata processed for the canonical user name. This confuses
|
|
||||||
RPC layer of Web UI code and causes infinite loop to reload the page.
|
|
||||||
|
|
||||||
Fix it by doing two things:
|
|
||||||
|
|
||||||
- force use of canonicalization of an enterprise principal on server
|
|
||||||
side, not just specifying that the principal is an enterprise one;
|
|
||||||
|
|
||||||
- recognize that a principal in the whoami()-returned object can have
|
|
||||||
aliases and the principal returned by the server in the JSON response
|
|
||||||
may be one of those aliases.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9226
|
|
||||||
|
|
||||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
Reviewed-By: Armando Neto <abiagion@redhat.com>
|
|
||||||
---
|
|
||||||
install/ui/src/freeipa/ipa.js | 8 +++++++-
|
|
||||||
ipaserver/rpcserver.py | 1 +
|
|
||||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
|
|
||||||
index 758db1b00..a08d632e9 100644
|
|
||||||
--- a/install/ui/src/freeipa/ipa.js
|
|
||||||
+++ b/install/ui/src/freeipa/ipa.js
|
|
||||||
@@ -271,7 +271,13 @@ var IPA = function () {
|
|
||||||
var cn = that.whoami.data.krbcanonicalname;
|
|
||||||
if (cn) that.principal = cn[0];
|
|
||||||
if (!that.principal) {
|
|
||||||
- that.principal = that.whoami.data.krbprincipalname[0];
|
|
||||||
+ var principal = data.principal;
|
|
||||||
+ var idx = that.whoami.data.krbprincipalname.indexOf(principal);
|
|
||||||
+ if (idx > -1) {
|
|
||||||
+ that.principal = principal;
|
|
||||||
+ } else {
|
|
||||||
+ that.principal = that.whoami.data.krbprincipalname[0];
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
} else if (entity === 'idoverrideuser') {
|
|
||||||
that.principal = that.whoami.data.ipaoriginaluid[0];
|
|
||||||
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
|
|
||||||
index 1f85e9898..4e8a08b66 100644
|
|
||||||
--- a/ipaserver/rpcserver.py
|
|
||||||
+++ b/ipaserver/rpcserver.py
|
|
||||||
@@ -1109,6 +1109,7 @@ class login_password(Backend, KerberosSession):
|
|
||||||
ccache_name,
|
|
||||||
armor_ccache_name=armor_path,
|
|
||||||
enterprise=True,
|
|
||||||
+ canonicalize=True,
|
|
||||||
lifetime=self.api.env.kinit_lifetime)
|
|
||||||
|
|
||||||
if armor_path:
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From c411c2e7b2e400829ffac250db81609ef3c56faa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 29 Nov 2022 10:04:41 +0100
|
||||||
|
Subject: [PATCH] webui tests: fix assertion in test_subid.py
|
||||||
|
|
||||||
|
The test wants to check the error related to an
|
||||||
|
exception obtained inside a "with pytest.raises" instruction.
|
||||||
|
The object is an ExceptionInfo and offers a match method
|
||||||
|
to check the content of the string representation.
|
||||||
|
Use this match() method instead of str(excinfo) which now
|
||||||
|
returns
|
||||||
|
'<ExceptionInfo NoSuchElementException() tblen=10>'
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9282
|
||||||
|
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Mohammad Rizwan Yusuf <myusuf@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_webui/test_subid.py | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_webui/test_subid.py b/ipatests/test_webui/test_subid.py
|
||||||
|
index 104b5692da94437880e638c0b2bc8efd41bd969e..3aaf80ac885fea08d0bac7e2f46645fe207f2cb0 100644
|
||||||
|
--- a/ipatests/test_webui/test_subid.py
|
||||||
|
+++ b/ipatests/test_webui/test_subid.py
|
||||||
|
@@ -146,5 +146,5 @@ class test_subid(UI_driver):
|
||||||
|
with pytest.raises(NoSuchElementException) as excinfo:
|
||||||
|
self.delete_record(admin_uid, table_name="ipauniqueid")
|
||||||
|
# Ensure that the exception is really related to missing remove button
|
||||||
|
- msg = "Unable to locate element: .facet-controls button[name=remove]"
|
||||||
|
- assert msg in str(excinfo)
|
||||||
|
+ msg = r"Unable to locate element: .facet-controls button\[name=remove\]"
|
||||||
|
+ assert excinfo.match(msg)
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,475 +0,0 @@
|
|||||||
From 3cbf2b25422100cc4105dfb09ee8c7bf87232198 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Mon, 22 Aug 2022 10:57:14 -0400
|
|
||||||
Subject: [PATCH] Defer creating the final krb5.conf on clients
|
|
||||||
|
|
||||||
A temporary krb5.conf is created early during client enrollment
|
|
||||||
and was previously used only during the initial ipa-join call.
|
|
||||||
The final krb5.conf was written soon afterward.
|
|
||||||
|
|
||||||
If there are multiple servers it is possible that the client
|
|
||||||
may then choose a different KDC to connect. If the client
|
|
||||||
is faster than replication then the client may not exist
|
|
||||||
on all servers and therefore enrollment will fail.
|
|
||||||
|
|
||||||
This was seen in performance testing of how many simultaneous
|
|
||||||
client enrollments are possible.
|
|
||||||
|
|
||||||
Use a decorator to wrap the _install() method to ensure the
|
|
||||||
temporary files created during installation are cleaned up.
|
|
||||||
|
|
||||||
https://pagure.io/freeipa/issue/9228
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
---
|
|
||||||
ipaclient/install/client.py | 377 +++++++++++++++++++-----------------
|
|
||||||
1 file changed, 196 insertions(+), 181 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
|
||||||
index 920c517d4f2b5414d8d2af63d029949cb4f02dc6..93bc7400805dafffcb3909771f0458e5b7e4a764 100644
|
|
||||||
--- a/ipaclient/install/client.py
|
|
||||||
+++ b/ipaclient/install/client.py
|
|
||||||
@@ -101,6 +101,37 @@ cli_basedn = None
|
|
||||||
# end of global variables
|
|
||||||
|
|
||||||
|
|
||||||
+def cleanup(func):
|
|
||||||
+ def inner(options, tdict):
|
|
||||||
+ # Add some additional options which contain the temporary files
|
|
||||||
+ # needed during installation.
|
|
||||||
+ fd, krb_name = tempfile.mkstemp()
|
|
||||||
+ os.close(fd)
|
|
||||||
+ ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
|
||||||
+
|
|
||||||
+ tdict['krb_name'] = krb_name
|
|
||||||
+ tdict['ccache_dir'] = ccache_dir
|
|
||||||
+
|
|
||||||
+ func(options, tdict)
|
|
||||||
+
|
|
||||||
+ os.environ.pop('KRB5_CONFIG', None)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ os.remove(krb_name)
|
|
||||||
+ except OSError:
|
|
||||||
+ logger.error("Could not remove %s", krb_name)
|
|
||||||
+ try:
|
|
||||||
+ os.rmdir(ccache_dir)
|
|
||||||
+ except OSError:
|
|
||||||
+ pass
|
|
||||||
+ try:
|
|
||||||
+ os.remove(krb_name + ".ipabkp")
|
|
||||||
+ except OSError:
|
|
||||||
+ logger.error("Could not remove %s.ipabkp", krb_name)
|
|
||||||
+
|
|
||||||
+ return inner
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def remove_file(filename):
|
|
||||||
"""
|
|
||||||
Deletes a file. If the file does not exist (OSError 2) does nothing.
|
|
||||||
@@ -2652,7 +2683,7 @@ def restore_time_sync(statestore, fstore):
|
|
||||||
|
|
||||||
def install(options):
|
|
||||||
try:
|
|
||||||
- _install(options)
|
|
||||||
+ _install(options, dict())
|
|
||||||
except ScriptError as e:
|
|
||||||
if e.rval == CLIENT_INSTALL_ERROR:
|
|
||||||
if options.force:
|
|
||||||
@@ -2679,7 +2710,8 @@ def install(options):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
-def _install(options):
|
|
||||||
+@cleanup
|
|
||||||
+def _install(options, tdict):
|
|
||||||
env = {'PATH': SECURE_PATH}
|
|
||||||
|
|
||||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
|
||||||
@@ -2687,6 +2719,9 @@ def _install(options):
|
|
||||||
|
|
||||||
statestore.backup_state('installation', 'complete', False)
|
|
||||||
|
|
||||||
+ krb_name = tdict['krb_name']
|
|
||||||
+ ccache_dir = tdict['ccache_dir']
|
|
||||||
+
|
|
||||||
if not options.on_master:
|
|
||||||
# Try removing old principals from the keytab
|
|
||||||
purge_host_keytab(cli_realm)
|
|
||||||
@@ -2719,182 +2754,162 @@ def _install(options):
|
|
||||||
host_principal = 'host/%s@%s' % (hostname, cli_realm)
|
|
||||||
if not options.on_master:
|
|
||||||
nolog = tuple()
|
|
||||||
- # First test out the kerberos configuration
|
|
||||||
- fd, krb_name = tempfile.mkstemp()
|
|
||||||
- os.close(fd)
|
|
||||||
- ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
|
||||||
- try:
|
|
||||||
- configure_krb5_conf(
|
|
||||||
- cli_realm=cli_realm,
|
|
||||||
- cli_domain=cli_domain,
|
|
||||||
- cli_server=cli_server,
|
|
||||||
- cli_kdc=cli_kdc,
|
|
||||||
- dnsok=False,
|
|
||||||
- filename=krb_name,
|
|
||||||
- client_domain=client_domain,
|
|
||||||
- client_hostname=hostname,
|
|
||||||
- configure_sssd=options.sssd,
|
|
||||||
- force=options.force)
|
|
||||||
- env['KRB5_CONFIG'] = krb_name
|
|
||||||
- ccache_name = os.path.join(ccache_dir, 'ccache')
|
|
||||||
- join_args = [
|
|
||||||
- paths.SBIN_IPA_JOIN,
|
|
||||||
- "-s", cli_server[0],
|
|
||||||
- "-b", str(realm_to_suffix(cli_realm)),
|
|
||||||
- "-h", hostname,
|
|
||||||
- "-k", paths.KRB5_KEYTAB
|
|
||||||
- ]
|
|
||||||
- if options.debug:
|
|
||||||
- join_args.append("-d")
|
|
||||||
- env['XMLRPC_TRACE_CURL'] = 'yes'
|
|
||||||
- if options.force_join:
|
|
||||||
- join_args.append("-f")
|
|
||||||
- if options.principal is not None:
|
|
||||||
- stdin = None
|
|
||||||
- principal = options.principal
|
|
||||||
- if principal.find('@') == -1:
|
|
||||||
- principal = '%s@%s' % (principal, cli_realm)
|
|
||||||
- if options.password is not None:
|
|
||||||
- stdin = options.password
|
|
||||||
+ configure_krb5_conf(
|
|
||||||
+ cli_realm=cli_realm,
|
|
||||||
+ cli_domain=cli_domain,
|
|
||||||
+ cli_server=cli_server,
|
|
||||||
+ cli_kdc=cli_kdc,
|
|
||||||
+ dnsok=False,
|
|
||||||
+ filename=krb_name,
|
|
||||||
+ client_domain=client_domain,
|
|
||||||
+ client_hostname=hostname,
|
|
||||||
+ configure_sssd=options.sssd,
|
|
||||||
+ force=options.force)
|
|
||||||
+ env['KRB5_CONFIG'] = krb_name
|
|
||||||
+ ccache_name = os.path.join(ccache_dir, 'ccache')
|
|
||||||
+ join_args = [
|
|
||||||
+ paths.SBIN_IPA_JOIN,
|
|
||||||
+ "-s", cli_server[0],
|
|
||||||
+ "-b", str(realm_to_suffix(cli_realm)),
|
|
||||||
+ "-h", hostname,
|
|
||||||
+ "-k", paths.KRB5_KEYTAB
|
|
||||||
+ ]
|
|
||||||
+ if options.debug:
|
|
||||||
+ join_args.append("-d")
|
|
||||||
+ env['XMLRPC_TRACE_CURL'] = 'yes'
|
|
||||||
+ if options.force_join:
|
|
||||||
+ join_args.append("-f")
|
|
||||||
+ if options.principal is not None:
|
|
||||||
+ stdin = None
|
|
||||||
+ principal = options.principal
|
|
||||||
+ if principal.find('@') == -1:
|
|
||||||
+ principal = '%s@%s' % (principal, cli_realm)
|
|
||||||
+ if options.password is not None:
|
|
||||||
+ stdin = options.password
|
|
||||||
+ else:
|
|
||||||
+ if not options.unattended:
|
|
||||||
+ try:
|
|
||||||
+ stdin = getpass.getpass(
|
|
||||||
+ "Password for %s: " % principal)
|
|
||||||
+ except EOFError:
|
|
||||||
+ stdin = None
|
|
||||||
+ if not stdin:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided for {}.".format(
|
|
||||||
+ principal),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
else:
|
|
||||||
- if not options.unattended:
|
|
||||||
- try:
|
|
||||||
- stdin = getpass.getpass(
|
|
||||||
- "Password for %s: " % principal)
|
|
||||||
- except EOFError:
|
|
||||||
- stdin = None
|
|
||||||
- if not stdin:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided for {}.".format(
|
|
||||||
- principal),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ if sys.stdin.isatty():
|
|
||||||
+ logger.error(
|
|
||||||
+ "Password must be provided in "
|
|
||||||
+ "non-interactive mode.")
|
|
||||||
+ logger.info(
|
|
||||||
+ "This can be done via "
|
|
||||||
+ "echo password | ipa-client-install ... "
|
|
||||||
+ "or with the -w option.")
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
else:
|
|
||||||
- if sys.stdin.isatty():
|
|
||||||
- logger.error(
|
|
||||||
- "Password must be provided in "
|
|
||||||
- "non-interactive mode.")
|
|
||||||
- logger.info(
|
|
||||||
- "This can be done via "
|
|
||||||
- "echo password | ipa-client-install ... "
|
|
||||||
- "or with the -w option.")
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- stdin = sys.stdin.readline()
|
|
||||||
+ stdin = sys.stdin.readline()
|
|
||||||
|
|
||||||
+ try:
|
|
||||||
+ kinit_password(principal, stdin, ccache_name,
|
|
||||||
+ config=krb_name)
|
|
||||||
+ except RuntimeError as e:
|
|
||||||
+ print_port_conf_info()
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Kerberos authentication failed: {}".format(e),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ elif options.keytab:
|
|
||||||
+ join_args.append("-f")
|
|
||||||
+ if os.path.exists(options.keytab):
|
|
||||||
try:
|
|
||||||
- kinit_password(principal, stdin, ccache_name,
|
|
||||||
- config=krb_name)
|
|
||||||
- except RuntimeError as e:
|
|
||||||
+ kinit_keytab(host_principal,
|
|
||||||
+ options.keytab,
|
|
||||||
+ ccache_name,
|
|
||||||
+ config=krb_name,
|
|
||||||
+ attempts=options.kinit_attempts)
|
|
||||||
+ except gssapi.exceptions.GSSError as e:
|
|
||||||
print_port_conf_info()
|
|
||||||
raise ScriptError(
|
|
||||||
"Kerberos authentication failed: {}".format(e),
|
|
||||||
rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- elif options.keytab:
|
|
||||||
- join_args.append("-f")
|
|
||||||
- if os.path.exists(options.keytab):
|
|
||||||
- try:
|
|
||||||
- kinit_keytab(host_principal,
|
|
||||||
- options.keytab,
|
|
||||||
- ccache_name,
|
|
||||||
- config=krb_name,
|
|
||||||
- attempts=options.kinit_attempts)
|
|
||||||
- except gssapi.exceptions.GSSError as e:
|
|
||||||
- print_port_conf_info()
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Kerberos authentication failed: {}".format(e),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Keytab file could not be found: {}".format(
|
|
||||||
- options.keytab),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- elif options.password:
|
|
||||||
- nolog = (options.password,)
|
|
||||||
- join_args.append("-w")
|
|
||||||
- join_args.append(options.password)
|
|
||||||
- elif options.prompt_password:
|
|
||||||
- if options.unattended:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided in non-interactive mode",
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- try:
|
|
||||||
- password = getpass.getpass("Password: ")
|
|
||||||
- except EOFError:
|
|
||||||
- password = None
|
|
||||||
- if not password:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided.",
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- join_args.append("-w")
|
|
||||||
- join_args.append(password)
|
|
||||||
- nolog = (password,)
|
|
||||||
-
|
|
||||||
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
|
|
||||||
- # Get the CA certificate
|
|
||||||
+ else:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Keytab file could not be found: {}".format(
|
|
||||||
+ options.keytab),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ elif options.password:
|
|
||||||
+ nolog = (options.password,)
|
|
||||||
+ join_args.append("-w")
|
|
||||||
+ join_args.append(options.password)
|
|
||||||
+ elif options.prompt_password:
|
|
||||||
+ if options.unattended:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided in non-interactive mode",
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
try:
|
|
||||||
- os.environ['KRB5_CONFIG'] = env['KRB5_CONFIG']
|
|
||||||
- get_ca_certs(fstore, options, cli_server[0], cli_basedn,
|
|
||||||
- cli_realm)
|
|
||||||
- del os.environ['KRB5_CONFIG']
|
|
||||||
- except errors.FileError as e:
|
|
||||||
- logger.error('%s', e)
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- except Exception as e:
|
|
||||||
- logger.error("Cannot obtain CA certificate\n%s", e)
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
-
|
|
||||||
- # Now join the domain
|
|
||||||
- result = run(
|
|
||||||
- join_args, raiseonerr=False, env=env, nolog=nolog,
|
|
||||||
- capture_error=True)
|
|
||||||
- stderr = result.error_output
|
|
||||||
+ password = getpass.getpass("Password: ")
|
|
||||||
+ except EOFError:
|
|
||||||
+ password = None
|
|
||||||
+ if not password:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided.",
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ join_args.append("-w")
|
|
||||||
+ join_args.append(password)
|
|
||||||
+ nolog = (password,)
|
|
||||||
|
|
||||||
- if result.returncode != 0:
|
|
||||||
- logger.error("Joining realm failed: %s", stderr)
|
|
||||||
- if not options.force:
|
|
||||||
- if result.returncode == 13:
|
|
||||||
- logger.info(
|
|
||||||
- "Use --force-join option to override the host "
|
|
||||||
- "entry on the server and force client enrollment.")
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- logger.info(
|
|
||||||
- "Use ipa-getkeytab to obtain a host "
|
|
||||||
- "principal for this server.")
|
|
||||||
- else:
|
|
||||||
- logger.info("Enrolled in IPA realm %s", cli_realm)
|
|
||||||
+ env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
|
|
||||||
+ # Get the CA certificate
|
|
||||||
+ try:
|
|
||||||
+ os.environ['KRB5_CONFIG'] = env['KRB5_CONFIG']
|
|
||||||
+ get_ca_certs(fstore, options, cli_server[0], cli_basedn,
|
|
||||||
+ cli_realm)
|
|
||||||
+ except errors.FileError as e:
|
|
||||||
+ logger.error('%s', e)
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ except Exception as e:
|
|
||||||
+ logger.error("Cannot obtain CA certificate\n%s", e)
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
|
|
||||||
- if options.principal is not None:
|
|
||||||
- run([paths.KDESTROY], raiseonerr=False, env=env)
|
|
||||||
+ # Now join the domain
|
|
||||||
+ result = run(
|
|
||||||
+ join_args, raiseonerr=False, env=env, nolog=nolog,
|
|
||||||
+ capture_error=True)
|
|
||||||
+ stderr = result.error_output
|
|
||||||
|
|
||||||
- # Obtain the TGT. We do it with the temporary krb5.conf, so that
|
|
||||||
- # only the KDC we're installing under is contacted.
|
|
||||||
- # Other KDCs might not have replicated the principal yet.
|
|
||||||
- # Once we have the TGT, it's usable on any server.
|
|
||||||
- try:
|
|
||||||
- kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
|
||||||
- config=krb_name,
|
|
||||||
- attempts=options.kinit_attempts)
|
|
||||||
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
|
|
||||||
- except gssapi.exceptions.GSSError as e:
|
|
||||||
- print_port_conf_info()
|
|
||||||
- logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
- # failure to get ticket makes it impossible to login and bind
|
|
||||||
- # from sssd to LDAP, abort installation and rollback changes
|
|
||||||
+ if result.returncode != 0:
|
|
||||||
+ logger.error("Joining realm failed: %s", stderr)
|
|
||||||
+ if not options.force:
|
|
||||||
+ if result.returncode == 13:
|
|
||||||
+ logger.info(
|
|
||||||
+ "Use --force-join option to override the host "
|
|
||||||
+ "entry on the server and force client enrollment.")
|
|
||||||
raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ logger.info(
|
|
||||||
+ "Use ipa-getkeytab to obtain a host "
|
|
||||||
+ "principal for this server.")
|
|
||||||
+ else:
|
|
||||||
+ logger.info("Enrolled in IPA realm %s", cli_realm)
|
|
||||||
|
|
||||||
- finally:
|
|
||||||
- try:
|
|
||||||
- os.remove(krb_name)
|
|
||||||
- except OSError:
|
|
||||||
- logger.error("Could not remove %s", krb_name)
|
|
||||||
- try:
|
|
||||||
- os.rmdir(ccache_dir)
|
|
||||||
- except OSError:
|
|
||||||
- pass
|
|
||||||
- try:
|
|
||||||
- os.remove(krb_name + ".ipabkp")
|
|
||||||
- except OSError:
|
|
||||||
- logger.error("Could not remove %s.ipabkp", krb_name)
|
|
||||||
+ if options.principal is not None:
|
|
||||||
+ run([paths.KDESTROY], raiseonerr=False, env=env)
|
|
||||||
+
|
|
||||||
+ # Obtain the TGT. We do it with the temporary krb5.conf, so that
|
|
||||||
+ # only the KDC we're installing under is contacted.
|
|
||||||
+ # Other KDCs might not have replicated the principal yet.
|
|
||||||
+ # Once we have the TGT, it's usable on any server.
|
|
||||||
+ try:
|
|
||||||
+ kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
|
||||||
+ config=krb_name,
|
|
||||||
+ attempts=options.kinit_attempts)
|
|
||||||
+ env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
|
|
||||||
+ except gssapi.exceptions.GSSError as e:
|
|
||||||
+ print_port_conf_info()
|
|
||||||
+ logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
+ # failure to get ticket makes it impossible to login and bind
|
|
||||||
+ # from sssd to LDAP, abort installation and rollback changes
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
|
|
||||||
# Configure ipa.conf
|
|
||||||
if not options.on_master:
|
|
||||||
@@ -2931,23 +2946,6 @@ def _install(options):
|
|
||||||
except gssapi.exceptions.GSSError as e:
|
|
||||||
logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- # Configure krb5.conf
|
|
||||||
- fstore.backup_file(paths.KRB5_CONF)
|
|
||||||
- configure_krb5_conf(
|
|
||||||
- cli_realm=cli_realm,
|
|
||||||
- cli_domain=cli_domain,
|
|
||||||
- cli_server=cli_server,
|
|
||||||
- cli_kdc=cli_kdc,
|
|
||||||
- dnsok=dnsok,
|
|
||||||
- filename=paths.KRB5_CONF,
|
|
||||||
- client_domain=client_domain,
|
|
||||||
- client_hostname=hostname,
|
|
||||||
- configure_sssd=options.sssd,
|
|
||||||
- force=options.force)
|
|
||||||
-
|
|
||||||
- logger.info(
|
|
||||||
- "Configured /etc/krb5.conf for IPA realm %s", cli_realm)
|
|
||||||
|
|
||||||
# Clear out any current session keyring information
|
|
||||||
try:
|
|
||||||
@@ -3274,6 +3272,23 @@ def _install(options):
|
|
||||||
configure_nisdomain(
|
|
||||||
options=options, domain=cli_domain, statestore=statestore)
|
|
||||||
|
|
||||||
+ # Configure the final krb5.conf
|
|
||||||
+ if not options.on_master:
|
|
||||||
+ fstore.backup_file(paths.KRB5_CONF)
|
|
||||||
+ configure_krb5_conf(
|
|
||||||
+ cli_realm=cli_realm,
|
|
||||||
+ cli_domain=cli_domain,
|
|
||||||
+ cli_server=cli_server,
|
|
||||||
+ cli_kdc=cli_kdc,
|
|
||||||
+ dnsok=dnsok,
|
|
||||||
+ filename=paths.KRB5_CONF,
|
|
||||||
+ client_domain=client_domain,
|
|
||||||
+ client_hostname=hostname,
|
|
||||||
+ configure_sssd=options.sssd,
|
|
||||||
+ force=options.force)
|
|
||||||
+
|
|
||||||
+ logger.info("Configured /etc/krb5.conf for IPA realm %s", cli_realm)
|
|
||||||
+
|
|
||||||
statestore.delete_state('installation', 'complete')
|
|
||||||
statestore.backup_state('installation', 'complete', True)
|
|
||||||
logger.info('Client configuration complete.')
|
|
||||||
--
|
|
||||||
2.38.1
|
|
||||||
|
|
29
SOURCES/0016-ipatests-mark-test_smb-as-xfail.patch
Normal file
29
SOURCES/0016-ipatests-mark-test_smb-as-xfail.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From b5f2b0b1b213149b5bfe2653c9e40de98249dc73 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 11:45:17 +0100
|
||||||
|
Subject: [PATCH] ipatests: mark test_smb as xfail
|
||||||
|
|
||||||
|
Mark the test test_smb.py::TestSMB::test_smb_service_s4u2self as xfail.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9124
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_smb.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_smb.py b/ipatests/test_integration/test_smb.py
|
||||||
|
index eb3981bddb7ca9f72a0d2cb6c46e5c73de8623ac..30f8d5901afbcda95f27cd966ac03d47205dbb26 100644
|
||||||
|
--- a/ipatests/test_integration/test_smb.py
|
||||||
|
+++ b/ipatests/test_integration/test_smb.py
|
||||||
|
@@ -349,6 +349,7 @@ class TestSMB(IntegrationTest):
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
osinfo.id == 'fedora' and osinfo.version_number <= (31,),
|
||||||
|
reason='Test requires krb 1.18')
|
||||||
|
+ @pytest.mark.xfail(reason="Pagure ticket 9124", strict=True)
|
||||||
|
def test_smb_service_s4u2self(self):
|
||||||
|
"""Test S4U2Self operation by IPA service
|
||||||
|
against both AD and IPA users
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
43
SOURCES/0017-Tests-force-key-type-in-ACME-tests.patch
Normal file
43
SOURCES/0017-Tests-force-key-type-in-ACME-tests.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 36cba23f3f671886f5e7fa310c25a6e500c76e0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Mon, 16 Jan 2023 09:31:57 +0100
|
||||||
|
Subject: [PATCH] Tests: force key type in ACME tests
|
||||||
|
|
||||||
|
PKI can issue ACME certs only when the key type is rsa.
|
||||||
|
|
||||||
|
With version 2.0.0, certbot defaults to ecdsa key type,
|
||||||
|
and this causes test failures.
|
||||||
|
For now, force rsa when requesting an ACME certificate.
|
||||||
|
This change can be reverted when PKI fixes the issue
|
||||||
|
on their side (https://github.com/dogtagpki/pki/issues/4273)
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9298
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_acme.py | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||||
|
index a30f2fc756783c0a5c28ecf32c1e40f422c47a19..15d7543cfb0fa0fcb921166f7cd8f13d0535a41d 100644
|
||||||
|
--- a/ipatests/test_integration/test_acme.py
|
||||||
|
+++ b/ipatests/test_integration/test_acme.py
|
||||||
|
@@ -131,6 +131,7 @@ def certbot_standalone_cert(host, acme_server):
|
||||||
|
'certonly',
|
||||||
|
'--domain', host.hostname,
|
||||||
|
'--standalone',
|
||||||
|
+ '--key-type', 'rsa',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -305,6 +306,7 @@ class TestACME(CALessBase):
|
||||||
|
'--manual-public-ip-logging-ok',
|
||||||
|
'--manual-auth-hook', CERTBOT_DNS_IPA_SCRIPT,
|
||||||
|
'--manual-cleanup-hook', CERTBOT_DNS_IPA_SCRIPT,
|
||||||
|
+ '--key-type', 'rsa',
|
||||||
|
])
|
||||||
|
|
||||||
|
##############
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,129 +0,0 @@
|
|||||||
From ba962632cd008edd057f61e7e6fadbf464ff94f2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
Date: Tue, 4 Oct 2022 17:26:51 +0200
|
|
||||||
Subject: [PATCH] Vault: fix interoperability issues with older RHEL systems
|
|
||||||
|
|
||||||
AES-128-CBC was recently enabled as default wrapping algorithm for transport of secrets.
|
|
||||||
This change was done in favor of FIPS as crypto-policies disabled 3DES in RHEL9, but
|
|
||||||
setting AES as default ended-up breaking backwards compatibility with older RHEL systems.
|
|
||||||
|
|
||||||
This commit is tuning some defaults so that interoperability with older RHEL systems
|
|
||||||
works again. The new logic reflects:
|
|
||||||
|
|
||||||
- when an old client is calling a new server, it doesn't send any value for wrapping_algo
|
|
||||||
and the old value is used (3DES), so that the client can decrypt using 3DES.
|
|
||||||
|
|
||||||
- when a new client is calling a new server, it sends wrapping_algo = AES128_CBC
|
|
||||||
|
|
||||||
- when a new client is calling an old server, it doesn't send any value and the default is
|
|
||||||
to use 3DES.
|
|
||||||
|
|
||||||
Finally, as this logic is able to handle overlapping wrapping algorithm between server and
|
|
||||||
client, the Option "--wrapping-algo" is hidden from "ipa vault-archive --help" and "ipa
|
|
||||||
vault-retrieve --help" commands.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9259
|
|
||||||
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
---
|
|
||||||
API.txt | 4 ++--
|
|
||||||
VERSION.m4 | 4 ++--
|
|
||||||
ipaclient/plugins/vault.py | 7 ++++---
|
|
||||||
ipaserver/plugins/vault.py | 4 ++--
|
|
||||||
4 files changed, 10 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/API.txt b/API.txt
|
|
||||||
index 814124f600111e46c117a0c925e33a27a19b38e0..062a6c756babea6b091c5aaec7d0eaa908b41911 100644
|
|
||||||
--- a/API.txt
|
|
||||||
+++ b/API.txt
|
|
||||||
@@ -6667,7 +6667,7 @@ option: Flag('shared?', autofill=True, default=False)
|
|
||||||
option: Str('username?', cli_name='user')
|
|
||||||
option: Bytes('vault_data')
|
|
||||||
option: Str('version?')
|
|
||||||
-option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
output: Entry('result')
|
|
||||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
|
||||||
output: PrimaryKey('value')
|
|
||||||
@@ -6767,7 +6767,7 @@ option: Bytes('session_key')
|
|
||||||
option: Flag('shared?', autofill=True, default=False)
|
|
||||||
option: Str('username?', cli_name='user')
|
|
||||||
option: Str('version?')
|
|
||||||
-option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
output: Entry('result')
|
|
||||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
|
||||||
output: PrimaryKey('value')
|
|
||||||
diff --git a/VERSION.m4 b/VERSION.m4
|
|
||||||
index 0f02d48979e4af3ad737e377545c4951d5dece02..d628c69a09a43b01aad4ac1bd3a6912bef27a7fe 100644
|
|
||||||
--- a/VERSION.m4
|
|
||||||
+++ b/VERSION.m4
|
|
||||||
@@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
|
|
||||||
# #
|
|
||||||
########################################################
|
|
||||||
define(IPA_API_VERSION_MAJOR, 2)
|
|
||||||
-# Last change: add Random Serial Numbers v3
|
|
||||||
-define(IPA_API_VERSION_MINOR, 249)
|
|
||||||
+# Last change: fix vault interoperability issues.
|
|
||||||
+define(IPA_API_VERSION_MINOR, 251)
|
|
||||||
|
|
||||||
########################################################
|
|
||||||
# Following values are auto-generated from values above
|
|
||||||
diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
|
|
||||||
index 115171c7768d44251c17d0bcdac9c37b3a25db99..d4c84eb6bfb4cc119c599d494171b0a2417ce0ba 100644
|
|
||||||
--- a/ipaclient/plugins/vault.py
|
|
||||||
+++ b/ipaclient/plugins/vault.py
|
|
||||||
@@ -687,7 +687,7 @@ class ModVaultData(Local):
|
|
||||||
default_algo = config.get('wrapping_default_algorithm')
|
|
||||||
if default_algo is None:
|
|
||||||
# old server
|
|
||||||
- wrapping_algo = constants.VAULT_WRAPPING_AES128_CBC
|
|
||||||
+ wrapping_algo = constants.VAULT_WRAPPING_3DES
|
|
||||||
elif default_algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
|
|
||||||
# try to use server default
|
|
||||||
wrapping_algo = default_algo
|
|
||||||
@@ -801,7 +801,8 @@ class vault_archive(ModVaultData):
|
|
||||||
if option.name not in ('nonce',
|
|
||||||
'session_key',
|
|
||||||
'vault_data',
|
|
||||||
- 'version'):
|
|
||||||
+ 'version',
|
|
||||||
+ 'wrapping_algo'):
|
|
||||||
yield option
|
|
||||||
for option in super(vault_archive, self).get_options():
|
|
||||||
yield option
|
|
||||||
@@ -1053,7 +1054,7 @@ class vault_retrieve(ModVaultData):
|
|
||||||
|
|
||||||
def get_options(self):
|
|
||||||
for option in self.api.Command.vault_retrieve_internal.options():
|
|
||||||
- if option.name not in ('session_key', 'version'):
|
|
||||||
+ if option.name not in ('session_key', 'version', 'wrapping_algo'):
|
|
||||||
yield option
|
|
||||||
for option in super(vault_retrieve, self).get_options():
|
|
||||||
yield option
|
|
||||||
diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
|
|
||||||
index 4d40f66c6a793a831e91c5fe25c8b5277cbd1972..574c83a9aaa64b6a4774400ea7af25343b445c03 100644
|
|
||||||
--- a/ipaserver/plugins/vault.py
|
|
||||||
+++ b/ipaserver/plugins/vault.py
|
|
||||||
@@ -1051,7 +1051,7 @@ class vault_archive_internal(PKQuery):
|
|
||||||
'wrapping_algo?',
|
|
||||||
doc=_('Key wrapping algorithm'),
|
|
||||||
values=VAULT_WRAPPING_SUPPORTED_ALGOS,
|
|
||||||
- default=VAULT_WRAPPING_DEFAULT_ALGO,
|
|
||||||
+ default=VAULT_WRAPPING_3DES,
|
|
||||||
autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@@ -1130,7 +1130,7 @@ class vault_retrieve_internal(PKQuery):
|
|
||||||
'wrapping_algo?',
|
|
||||||
doc=_('Key wrapping algorithm'),
|
|
||||||
values=VAULT_WRAPPING_SUPPORTED_ALGOS,
|
|
||||||
- default=VAULT_WRAPPING_DEFAULT_ALGO,
|
|
||||||
+ default=VAULT_WRAPPING_3DES,
|
|
||||||
autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
--
|
|
||||||
2.38.1
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From ff31b0c40cc5e046f839b98b80bd16bb649205ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 11:54:36 -0500
|
||||||
|
Subject: [PATCH] tests: Add ipa_ca_name checking to DNS system records
|
||||||
|
|
||||||
|
freeipa-healthcheck 0.12 includes a SUCCESS message if the
|
||||||
|
ipa-ca records are as expected so a user will know they
|
||||||
|
were checked. For that version and beyond test that it
|
||||||
|
is included.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9291
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_ipahealthcheck.py | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
index 49a5779307ef05617fe9ae200f7149d120977355..94b0db0b7869e722955e232e1dddb26a2dc3d41e 100644
|
||||||
|
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
+++ b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
@@ -810,7 +810,9 @@ class TestIpaHealthCheck(IntegrationTest):
|
||||||
|
+ [str(ip) for ip in resolve_ip_addresses_nss(h.external_hostname)]
|
||||||
|
]
|
||||||
|
SYSTEM_RECORDS.append(f'"{self.master.domain.realm.upper()}"')
|
||||||
|
-
|
||||||
|
+ version = tasks.get_healthcheck_version(self.master)
|
||||||
|
+ if parse_version(version) >= parse_version("0.12"):
|
||||||
|
+ SYSTEM_RECORDS.append('ipa_ca_check')
|
||||||
|
|
||||||
|
returncode, data = run_healthcheck(
|
||||||
|
self.master,
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
From 6ca119686aadfa72c0474f72758b63cd671952d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 12:00:03 -0500
|
||||||
|
Subject: [PATCH] tests: Add new ipa-ca error messages to
|
||||||
|
IPADNSSystemRecordsCheck
|
||||||
|
|
||||||
|
freeipa-healthcheck changed some messages related to ipa-ca
|
||||||
|
DNS record validation in IPADNSSystemRecordsCheck. Include support
|
||||||
|
for it and retain backwards compatibility.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9291
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
.../test_integration/test_ipahealthcheck.py | 21 +++++++++++++------
|
||||||
|
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
index 94b0db0b7869e722955e232e1dddb26a2dc3d41e..47f64f2cb36904ef61211423de7cf33d21a199c3 100644
|
||||||
|
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
+++ b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
@@ -1614,12 +1614,21 @@ class TestIpaHealthCheckWithoutDNS(IntegrationTest):
|
||||||
|
Test checks the result of IPADNSSystemRecordsCheck
|
||||||
|
when ipa-server is configured without DNS.
|
||||||
|
"""
|
||||||
|
- expected_msgs = {
|
||||||
|
- "Expected SRV record missing",
|
||||||
|
- "Got {count} ipa-ca A records, expected {expected}",
|
||||||
|
- "Got {count} ipa-ca AAAA records, expected {expected}",
|
||||||
|
- "Expected URI record missing",
|
||||||
|
- }
|
||||||
|
+ version = tasks.get_healthcheck_version(self.master)
|
||||||
|
+ if (parse_version(version) < parse_version('0.12')):
|
||||||
|
+ expected_msgs = {
|
||||||
|
+ "Expected SRV record missing",
|
||||||
|
+ "Got {count} ipa-ca A records, expected {expected}",
|
||||||
|
+ "Got {count} ipa-ca AAAA records, expected {expected}",
|
||||||
|
+ "Expected URI record missing",
|
||||||
|
+ }
|
||||||
|
+ else:
|
||||||
|
+ expected_msgs = {
|
||||||
|
+ "Expected SRV record missing",
|
||||||
|
+ "Unexpected ipa-ca address {ipaddr}",
|
||||||
|
+ "expected ipa-ca to contain {ipaddr} for {server}",
|
||||||
|
+ "Expected URI record missing",
|
||||||
|
+ }
|
||||||
|
|
||||||
|
tasks.install_packages(self.master, HEALTHCHECK_PKG)
|
||||||
|
returncode, data = run_healthcheck(
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
445
SOURCES/0020-ipatests-tests-for-certificate-pruning.patch
Normal file
445
SOURCES/0020-ipatests-tests-for-certificate-pruning.patch
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
From 0f77b359e241fc4055fb8d785e18f96338451ebf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Date: Mon, 6 Feb 2023 15:31:27 +0530
|
||||||
|
Subject: [PATCH] ipatests: tests for certificate pruning
|
||||||
|
|
||||||
|
1. Test to prune the expired certificate by manual run
|
||||||
|
2. Test to prune expired certificate by cron job
|
||||||
|
3. Test to prune expired certificate with retention unit option
|
||||||
|
4. Test to prune expired certificate with search size limit option
|
||||||
|
5. Test to check config-show command shows set param
|
||||||
|
6. Test prune command shows proper status after disabling the pruning
|
||||||
|
|
||||||
|
related: https://pagure.io/freeipa/issue/9294
|
||||||
|
|
||||||
|
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_acme.py | 306 +++++++++++++++++++++----
|
||||||
|
1 file changed, 260 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||||
|
index 5ceba05976059de69414a79634d98045c3ab68bb..1334be52f4530dd8b2a4207744146cd0eb5477a3 100644
|
||||||
|
--- a/ipatests/test_integration/test_acme.py
|
||||||
|
+++ b/ipatests/test_integration/test_acme.py
|
||||||
|
@@ -122,21 +122,23 @@ def certbot_register(host, acme_server):
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-def certbot_standalone_cert(host, acme_server):
|
||||||
|
+def certbot_standalone_cert(host, acme_server, no_of_cert=1):
|
||||||
|
"""method to issue a certbot's certonly standalone cert"""
|
||||||
|
# Get a cert from ACME service using HTTP challenge and Certbot's
|
||||||
|
# standalone HTTP server mode
|
||||||
|
host.run_command(['systemctl', 'stop', 'httpd'])
|
||||||
|
- host.run_command(
|
||||||
|
- [
|
||||||
|
- 'certbot',
|
||||||
|
- '--server', acme_server,
|
||||||
|
- 'certonly',
|
||||||
|
- '--domain', host.hostname,
|
||||||
|
- '--standalone',
|
||||||
|
- '--key-type', 'rsa',
|
||||||
|
- ]
|
||||||
|
- )
|
||||||
|
+ for _i in range(0, no_of_cert):
|
||||||
|
+ host.run_command(
|
||||||
|
+ [
|
||||||
|
+ 'certbot',
|
||||||
|
+ '--server', acme_server,
|
||||||
|
+ 'certonly',
|
||||||
|
+ '--domain', host.hostname,
|
||||||
|
+ '--standalone',
|
||||||
|
+ '--key-type', 'rsa',
|
||||||
|
+ '--force-renewal'
|
||||||
|
+ ]
|
||||||
|
+ )
|
||||||
|
|
||||||
|
|
||||||
|
class TestACME(CALessBase):
|
||||||
|
@@ -573,43 +575,41 @@ class TestACMEwithExternalCA(TestACME):
|
||||||
|
tasks.install_replica(cls.master, cls.replicas[0])
|
||||||
|
|
||||||
|
|
||||||
|
-class TestACMERenew(IntegrationTest):
|
||||||
|
-
|
||||||
|
- num_clients = 1
|
||||||
|
+@pytest.fixture
|
||||||
|
+def issue_and_expire_acme_cert():
|
||||||
|
+ """Fixture to expire cert by moving date past expiry of acme cert"""
|
||||||
|
+ hosts = []
|
||||||
|
|
||||||
|
- @classmethod
|
||||||
|
- def install(cls, mh):
|
||||||
|
-
|
||||||
|
- # install packages before client install in case of IPA DNS problems
|
||||||
|
- cls.acme_server = prepare_acme_client(cls.master, cls.clients[0])
|
||||||
|
+ def _issue_and_expire_acme_cert(
|
||||||
|
+ master, client,
|
||||||
|
+ acme_server_url, no_of_cert=1
|
||||||
|
+ ):
|
||||||
|
|
||||||
|
- tasks.install_master(cls.master, setup_dns=True)
|
||||||
|
- tasks.install_client(cls.master, cls.clients[0])
|
||||||
|
+ hosts.append(master)
|
||||||
|
+ hosts.append(client)
|
||||||
|
|
||||||
|
- @pytest.fixture
|
||||||
|
- def issue_and_expire_cert(self):
|
||||||
|
- """Fixture to expire cert by moving date past expiry of acme cert"""
|
||||||
|
# enable the ACME service on master
|
||||||
|
- self.master.run_command(['ipa-acme-manage', 'enable'])
|
||||||
|
+ master.run_command(['ipa-acme-manage', 'enable'])
|
||||||
|
|
||||||
|
# register the account with certbot
|
||||||
|
- certbot_register(self.clients[0], self.acme_server)
|
||||||
|
+ certbot_register(client, acme_server_url)
|
||||||
|
|
||||||
|
# request a standalone acme cert
|
||||||
|
- certbot_standalone_cert(self.clients[0], self.acme_server)
|
||||||
|
+ certbot_standalone_cert(client, acme_server_url, no_of_cert)
|
||||||
|
|
||||||
|
# move system date to expire acme cert
|
||||||
|
- for host in self.clients[0], self.master:
|
||||||
|
+ for host in hosts:
|
||||||
|
tasks.kdestroy_all(host)
|
||||||
|
tasks.move_date(host, 'stop', '+90days')
|
||||||
|
|
||||||
|
+ time.sleep(10)
|
||||||
|
tasks.get_kdcinfo(host)
|
||||||
|
# Note raiseonerr=False:
|
||||||
|
# the assert is located after kdcinfo retrieval.
|
||||||
|
- result = host.run_command(
|
||||||
|
+ result = master.run_command(
|
||||||
|
"KRB5_TRACE=/dev/stdout kinit admin",
|
||||||
|
stdin_text='{0}\n{0}\n{0}\n'.format(
|
||||||
|
- self.clients[0].config.admin_password
|
||||||
|
+ master.config.admin_password
|
||||||
|
),
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
@@ -618,16 +618,28 @@ class TestACMERenew(IntegrationTest):
|
||||||
|
tasks.get_kdcinfo(host)
|
||||||
|
assert result.returncode == 0
|
||||||
|
|
||||||
|
- yield
|
||||||
|
+ yield _issue_and_expire_acme_cert
|
||||||
|
|
||||||
|
- # move back date
|
||||||
|
- for host in self.clients[0], self.master:
|
||||||
|
- tasks.kdestroy_all(host)
|
||||||
|
- tasks.move_date(host, 'start', '-90days')
|
||||||
|
- tasks.kinit_admin(host)
|
||||||
|
+ # move back date
|
||||||
|
+ for host in hosts:
|
||||||
|
+ tasks.move_date(host, 'start', '-90days')
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestACMERenew(IntegrationTest):
|
||||||
|
+
|
||||||
|
+ num_clients = 1
|
||||||
|
+
|
||||||
|
+ @classmethod
|
||||||
|
+ def install(cls, mh):
|
||||||
|
+
|
||||||
|
+ # install packages before client install in case of IPA DNS problems
|
||||||
|
+ cls.acme_server = prepare_acme_client(cls.master, cls.clients[0])
|
||||||
|
+
|
||||||
|
+ tasks.install_master(cls.master, setup_dns=True)
|
||||||
|
+ tasks.install_client(cls.master, cls.clients[0])
|
||||||
|
|
||||||
|
@pytest.mark.skipif(skip_certbot_tests, reason='certbot not available')
|
||||||
|
- def test_renew(self, issue_and_expire_cert):
|
||||||
|
+ def test_renew(self, issue_and_expire_acme_cert):
|
||||||
|
"""Test if ACME renews the issued cert with cerbot
|
||||||
|
|
||||||
|
This test is to check if ACME certificate renews upon
|
||||||
|
@@ -635,6 +647,8 @@ class TestACMERenew(IntegrationTest):
|
||||||
|
|
||||||
|
related: https://pagure.io/freeipa/issue/4751
|
||||||
|
"""
|
||||||
|
+ issue_and_expire_acme_cert(
|
||||||
|
+ self.master, self.clients[0], self.acme_server)
|
||||||
|
data = self.clients[0].get_file_contents(
|
||||||
|
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||||
|
)
|
||||||
|
@@ -656,6 +670,7 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
"""Validate that ipa-acme-manage configures dogtag for pruning"""
|
||||||
|
|
||||||
|
random_serial = True
|
||||||
|
+ num_clients = 1
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def install(cls, mh):
|
||||||
|
@@ -663,6 +678,8 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
raise pytest.skip("RNSv3 not supported")
|
||||||
|
tasks.install_master(cls.master, setup_dns=True,
|
||||||
|
random_serial=True)
|
||||||
|
+ cls.acme_server = prepare_acme_client(cls.master, cls.clients[0])
|
||||||
|
+ tasks.install_client(cls.master, cls.clients[0])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def uninstall(cls, mh):
|
||||||
|
@@ -718,7 +735,7 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
['ipa-acme-manage', 'pruning',
|
||||||
|
'--requestretention=60',
|
||||||
|
'--requestretentionunit=minute',
|
||||||
|
- '--requestresearchsizelimit=2000',
|
||||||
|
+ '--requestsearchsizelimit=2000',
|
||||||
|
'--requestsearchtimelimit=5',]
|
||||||
|
)
|
||||||
|
cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
@@ -741,7 +758,7 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
|
||||||
|
self.master.run_command(
|
||||||
|
['ipa-acme-manage', 'pruning',
|
||||||
|
- '--cron="0 23 1 * *',]
|
||||||
|
+ '--cron=0 23 1 * *',]
|
||||||
|
)
|
||||||
|
cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||||
|
assert (
|
||||||
|
@@ -760,7 +777,7 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
'--enable', '--disable'],
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
- assert result.returncode == 1
|
||||||
|
+ assert result.returncode == 2
|
||||||
|
assert "Cannot both enable and disable" in result.stderr_text
|
||||||
|
|
||||||
|
for cmd in ('--config-show', '--run'):
|
||||||
|
@@ -769,20 +786,20 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
cmd, '--enable'],
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
- assert result.returncode == 1
|
||||||
|
+ assert result.returncode == 2
|
||||||
|
assert "Cannot change and show config" in result.stderr_text
|
||||||
|
|
||||||
|
result = self.master.run_command(
|
||||||
|
['ipa-acme-manage', 'pruning',
|
||||||
|
- '--cron="* *"'],
|
||||||
|
+ '--cron=* *'],
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
- assert result.returncode == 1
|
||||||
|
- assert "Invalid format format --cron" in result.stderr_text
|
||||||
|
+ assert result.returncode == 2
|
||||||
|
+ assert "Invalid format for --cron" in result.stderr_text
|
||||||
|
|
||||||
|
result = self.master.run_command(
|
||||||
|
['ipa-acme-manage', 'pruning',
|
||||||
|
- '--cron="100 * * * *"'],
|
||||||
|
+ '--cron=100 * * * *'],
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
assert result.returncode == 1
|
||||||
|
@@ -790,8 +807,205 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
|
||||||
|
result = self.master.run_command(
|
||||||
|
['ipa-acme-manage', 'pruning',
|
||||||
|
- '--cron="10 1-5 * * *"'],
|
||||||
|
+ '--cron=10 1-5 * * *'],
|
||||||
|
raiseonerr=False
|
||||||
|
)
|
||||||
|
assert result.returncode == 1
|
||||||
|
assert "1-5 ranges are not supported" in result.stderr_text
|
||||||
|
+
|
||||||
|
+ def test_prune_cert_manual(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test to prune expired certificate by manual run"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ issue_and_expire_acme_cert(
|
||||||
|
+ self.master, self.clients[0], self.acme_server)
|
||||||
|
+
|
||||||
|
+ # check that the certificate issued for the client
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname]
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' in result.stdout_text
|
||||||
|
+
|
||||||
|
+ # run prune command manually
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+ self.master.run_command(['ipactl', 'restart'])
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--run'])
|
||||||
|
+ # wait for cert to get prune
|
||||||
|
+ time.sleep(50)
|
||||||
|
+
|
||||||
|
+ # check if client cert is removed
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' not in result.stdout_text
|
||||||
|
+
|
||||||
|
+ def test_prune_cert_cron(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test to prune expired certificate by cron job"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ issue_and_expire_acme_cert(
|
||||||
|
+ self.master, self.clients[0], self.acme_server)
|
||||||
|
+
|
||||||
|
+ # check that the certificate issued for the client
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname]
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' in result.stdout_text
|
||||||
|
+
|
||||||
|
+ # enable pruning
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+
|
||||||
|
+ # cron would be set to run the next minute
|
||||||
|
+ cron_minute = self.master.run_command(
|
||||||
|
+ [
|
||||||
|
+ "python3",
|
||||||
|
+ "-c",
|
||||||
|
+ (
|
||||||
|
+ "from datetime import datetime; "
|
||||||
|
+ "print(int(datetime.now().strftime('%M')) + 5)"
|
||||||
|
+ ),
|
||||||
|
+ ]
|
||||||
|
+ ).stdout_text.strip()
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ f'--cron={cron_minute} * * * *']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(['ipactl', 'restart'])
|
||||||
|
+ # wait for 5 minutes to cron to execute and 20 sec for just in case
|
||||||
|
+ time.sleep(320)
|
||||||
|
+
|
||||||
|
+ # check if client cert is removed
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' not in result.stdout_text
|
||||||
|
+
|
||||||
|
+ def test_prune_cert_retention_unit(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test to prune expired certificate with retention unit option"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+ issue_and_expire_acme_cert(
|
||||||
|
+ self.master, self.clients[0], self.acme_server)
|
||||||
|
+
|
||||||
|
+ # check that the certificate issued for the client
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname]
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' in result.stdout_text
|
||||||
|
+
|
||||||
|
+ # enable pruning
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+
|
||||||
|
+ # certretention set to 5 min
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--certretention=5', '--certretentionunit=minute']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(['ipactl', 'restart'])
|
||||||
|
+
|
||||||
|
+ # wait for 5 min and check if expired cert is removed
|
||||||
|
+ time.sleep(310)
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--run'])
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname],
|
||||||
|
+ raiseonerr=False
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' not in result.stdout_text
|
||||||
|
+
|
||||||
|
+ def test_prune_cert_search_size_limit(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test to prune expired certificate with search size limit option"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+ no_of_cert = 10
|
||||||
|
+ search_size_limit = 5
|
||||||
|
+ issue_and_expire_acme_cert(
|
||||||
|
+ self.master, self.clients[0], self.acme_server, no_of_cert)
|
||||||
|
+
|
||||||
|
+ # check that the certificate issued for the client
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname]
|
||||||
|
+ )
|
||||||
|
+ assert f'CN={self.clients[0].hostname}' in result.stdout_text
|
||||||
|
+ assert f'Number of entries returned {no_of_cert}'
|
||||||
|
+
|
||||||
|
+ # enable pruning
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+
|
||||||
|
+ # certretention set to 5 min
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ f'--certsearchsizelimit={search_size_limit}',
|
||||||
|
+ '--certsearchtimelimit=100']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(['ipactl', 'restart'])
|
||||||
|
+
|
||||||
|
+ # prune the certificates
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--run'])
|
||||||
|
+
|
||||||
|
+ # check if 5 expired cert is removed
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa', 'cert-find', '--subject', self.clients[0].hostname]
|
||||||
|
+ )
|
||||||
|
+ assert f'Number of entries returned {no_of_cert - search_size_limit}'
|
||||||
|
+
|
||||||
|
+ def test_prune_config_show(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test to check config-show command shows set param"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron=0 0 1 * *']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--certretention=30', '--certretentionunit=day']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--certsearchsizelimit=1000', '--certsearchtimelimit=0']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--requestretention=30', '--requestretentionunit=day']
|
||||||
|
+ )
|
||||||
|
+ self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--requestsearchsizelimit=1000', '--requestsearchtimelimit=0']
|
||||||
|
+ )
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning', '--config-show']
|
||||||
|
+ )
|
||||||
|
+ assert 'Status: enabled' in result.stdout_text
|
||||||
|
+ assert 'Certificate Retention Time: 30' in result.stdout_text
|
||||||
|
+ assert 'Certificate Retention Unit: day' in result.stdout_text
|
||||||
|
+ assert 'Certificate Search Size Limit: 1000' in result.stdout_text
|
||||||
|
+ assert 'Certificate Search Time Limit: 100' in result.stdout_text
|
||||||
|
+ assert 'Request Retention Time: 30' in result.stdout_text
|
||||||
|
+ assert 'Request Retention Unit: day' in result.stdout_text
|
||||||
|
+ assert 'Request Search Size Limit' in result.stdout_text
|
||||||
|
+ assert 'Request Search Time Limit: 100' in result.stdout_text
|
||||||
|
+ assert 'cron Schedule: 0 0 1 * *' in result.stdout_text
|
||||||
|
+
|
||||||
|
+ def test_prune_disable(self, issue_and_expire_acme_cert):
|
||||||
|
+ """Test prune command throw error after disabling the pruning"""
|
||||||
|
+ if (tasks.get_pki_version(self.master)
|
||||||
|
+ < tasks.parse_version('11.3.0')):
|
||||||
|
+ raise pytest.skip("Certificate pruning is not available")
|
||||||
|
+
|
||||||
|
+ self.master.run_command(['ipa-acme-manage', 'pruning', '--disable'])
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
+ ['ipa-acme-manage', 'pruning',
|
||||||
|
+ '--cron=0 0 1 * *']
|
||||||
|
+ )
|
||||||
|
+ assert 'Status: disabled' in result.stdout_text
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
From 88b9be29036a3580a8bccd31986fc30faa9852df Mon Sep 17 00:00:00 2001
|
||||||
|
From: mbhalodi <mbhalodi@redhat.com>
|
||||||
|
Date: Tue, 14 Feb 2023 15:04:58 +0530
|
||||||
|
Subject: [PATCH] ipatests: ensure that ipa automember-rebuild prints a warning
|
||||||
|
|
||||||
|
ipa automember-rebuild now prints a warning about CPU usage.
|
||||||
|
Ensure that the warning is properly displayed.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9320
|
||||||
|
|
||||||
|
Signed-off-by: mbhalodi <mbhalodi@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_automember.py | 13 ++++++++++---
|
||||||
|
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_automember.py b/ipatests/test_integration/test_automember.py
|
||||||
|
index f013964140714db046a1aa6a92409244b2137727..7acd0d7bf895fec970f2bda8b54f4496280525b6 100644
|
||||||
|
--- a/ipatests/test_integration/test_automember.py
|
||||||
|
+++ b/ipatests/test_integration/test_automember.py
|
||||||
|
@@ -10,6 +10,9 @@ from ipapython.dn import DN
|
||||||
|
from ipatests.pytest_ipa.integration import tasks
|
||||||
|
from ipatests.test_integration.base import IntegrationTest
|
||||||
|
|
||||||
|
+msg = ('IMPORTANT: In case of a high number of users, hosts or '
|
||||||
|
+ 'groups, the operation may require high CPU usage.')
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestAutounmembership(IntegrationTest):
|
||||||
|
"""Tests for autounmembership feature.
|
||||||
|
@@ -206,11 +209,13 @@ class TestAutounmembership(IntegrationTest):
|
||||||
|
assert self.is_user_member_of_group(user2, group1)
|
||||||
|
|
||||||
|
# Running automember-build so that user is part of correct group
|
||||||
|
- self.master.run_command(['ipa', 'automember-rebuild',
|
||||||
|
- '--users=%s' % user2])
|
||||||
|
+ result = self.master.run_command(['ipa', 'automember-rebuild',
|
||||||
|
+ '--users=%s' % user2])
|
||||||
|
assert self.is_user_member_of_group(user2, group2)
|
||||||
|
assert not self.is_user_member_of_group(user2, group1)
|
||||||
|
|
||||||
|
+ assert msg in result.stdout_text
|
||||||
|
+
|
||||||
|
finally:
|
||||||
|
# testcase cleanup
|
||||||
|
self.remove_user_automember(user2, raiseonerr=False)
|
||||||
|
@@ -240,12 +245,14 @@ class TestAutounmembership(IntegrationTest):
|
||||||
|
assert self.is_host_member_of_hostgroup(host2, hostgroup1)
|
||||||
|
|
||||||
|
# Running the automember-build so host is part of correct hostgroup
|
||||||
|
- self.master.run_command(
|
||||||
|
+ result = self.master.run_command(
|
||||||
|
['ipa', 'automember-rebuild', '--hosts=%s' % host2]
|
||||||
|
)
|
||||||
|
assert self.is_host_member_of_hostgroup(host2, hostgroup2)
|
||||||
|
assert not self.is_host_member_of_hostgroup(host2, hostgroup1)
|
||||||
|
|
||||||
|
+ assert msg in result.stdout_text
|
||||||
|
+
|
||||||
|
finally:
|
||||||
|
# testcase cleanup
|
||||||
|
self.remove_host_automember(host2, raiseonerr=False)
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
74
SOURCES/0022-ipatests-fix-tests-in-TestACMEPrune.patch
Normal file
74
SOURCES/0022-ipatests-fix-tests-in-TestACMEPrune.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From e76b219c21d53b6bccce4ea3d18e2b61ac835e1f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Date: Mon, 20 Feb 2023 15:33:09 +0530
|
||||||
|
Subject: [PATCH] ipatests: fix tests in TestACMEPrune
|
||||||
|
|
||||||
|
When cron_minute + 5 > 59, cron job throwing error for it.
|
||||||
|
i.e 58 + 5 = 63 which is not acceptable value for cron minute.
|
||||||
|
|
||||||
|
Second fix is related to mismatch of confing setting and corresponding
|
||||||
|
assert.
|
||||||
|
|
||||||
|
Third fix is related to extending time by 60 minutes to properly
|
||||||
|
expire the certs.
|
||||||
|
|
||||||
|
related: https://pagure.io/freeipa/issue/9294
|
||||||
|
|
||||||
|
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_acme.py | 15 ++++++++-------
|
||||||
|
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||||
|
index 1334be52f4530dd8b2a4207744146cd0eb5477a3..49b173060f88d4b8e876d8e3461a935938518b44 100644
|
||||||
|
--- a/ipatests/test_integration/test_acme.py
|
||||||
|
+++ b/ipatests/test_integration/test_acme.py
|
||||||
|
@@ -600,7 +600,7 @@ def issue_and_expire_acme_cert():
|
||||||
|
# move system date to expire acme cert
|
||||||
|
for host in hosts:
|
||||||
|
tasks.kdestroy_all(host)
|
||||||
|
- tasks.move_date(host, 'stop', '+90days')
|
||||||
|
+ tasks.move_date(host, 'stop', '+90days+60minutes')
|
||||||
|
|
||||||
|
time.sleep(10)
|
||||||
|
tasks.get_kdcinfo(host)
|
||||||
|
@@ -622,7 +622,7 @@ def issue_and_expire_acme_cert():
|
||||||
|
|
||||||
|
# move back date
|
||||||
|
for host in hosts:
|
||||||
|
- tasks.move_date(host, 'start', '-90days')
|
||||||
|
+ tasks.move_date(host, 'start', '-90days-60minutes')
|
||||||
|
|
||||||
|
|
||||||
|
class TestACMERenew(IntegrationTest):
|
||||||
|
@@ -866,8 +866,9 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
"python3",
|
||||||
|
"-c",
|
||||||
|
(
|
||||||
|
- "from datetime import datetime; "
|
||||||
|
- "print(int(datetime.now().strftime('%M')) + 5)"
|
||||||
|
+ "from datetime import datetime, timedelta; "
|
||||||
|
+ "print(int((datetime.now() + "
|
||||||
|
+ "timedelta(minutes=5)).strftime('%M')))"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
).stdout_text.strip()
|
||||||
|
@@ -990,11 +991,11 @@ class TestACMEPrune(IntegrationTest):
|
||||||
|
assert 'Certificate Retention Time: 30' in result.stdout_text
|
||||||
|
assert 'Certificate Retention Unit: day' in result.stdout_text
|
||||||
|
assert 'Certificate Search Size Limit: 1000' in result.stdout_text
|
||||||
|
- assert 'Certificate Search Time Limit: 100' in result.stdout_text
|
||||||
|
+ assert 'Certificate Search Time Limit: 0' in result.stdout_text
|
||||||
|
assert 'Request Retention Time: 30' in result.stdout_text
|
||||||
|
assert 'Request Retention Unit: day' in result.stdout_text
|
||||||
|
- assert 'Request Search Size Limit' in result.stdout_text
|
||||||
|
- assert 'Request Search Time Limit: 100' in result.stdout_text
|
||||||
|
+ assert 'Request Search Size Limit: 1000' in result.stdout_text
|
||||||
|
+ assert 'Request Search Time Limit: 0' in result.stdout_text
|
||||||
|
assert 'cron Schedule: 0 0 1 * *' in result.stdout_text
|
||||||
|
|
||||||
|
def test_prune_disable(self, issue_and_expire_acme_cert):
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmK8aYIACgkQaYdvcqbi
|
|
||||||
00/mYQ/9GsTlD3aiAVvkTn+PLngLdsg3zFSDXUUI/I4ylOeoubzYmdWrX2yWJfvk
|
|
||||||
soVcxtHeLkrI/uLo44iiZkxYILxMY56dPzoUn6I46VQFppdoOzwlvdYhlOXYtvtB
|
|
||||||
yYIZhMdCsTkCORMlZ/RR8qNH8iZ1Zjzd4sf6CMWDdxK6ruAfPzaKAMm4EMa1+Rv7
|
|
||||||
67OfSJKqfNksfeKNndYyNki1FmZo7ukKqcA5/lE+ZaN3/yg6IMydqJVD462OJizF
|
|
||||||
aHyYZDEaUQv3Or9d8V5G/qJpUz6wCjvzLGvNp3nn4goyX2RG1yY6AX6W8P5/FGiN
|
|
||||||
A5emCV2LmufWE02CGHZ/9i88BIRqh0laPYJianEw/4iJa3BVYDjnlCTWxjDqVfv/
|
|
||||||
WBlEnZm/bQkHJITEe6hIwmnHJIFPrhuPxsaBIRUNU1oLTIoU+VFnPRyGGeFuKPSX
|
|
||||||
girFx1ip3roB6ChoXhYprS1eJ8CjP61ffjT+GLXl9b8OyqFmbxLCMRp19uFt96L1
|
|
||||||
DHWZv9ytfcwoZW7zzKlCwcGcLsui4PCmriSS8uaGUNvouBfeshHU4OgilwJnjQMP
|
|
||||||
kPvqagQCF7xe1ZoOdgoKgYvhXI+jABrZ0LVQoj4QMHGjCxkdFmhNNM37xtHogae9
|
|
||||||
NwfSWqa9UZO+LHy4tNiHrv9W0WnDoPjLFrod2yxIfhh/reYs3GU=
|
|
||||||
=Zzx6
|
|
||||||
-----END PGP SIGNATURE-----
|
|
16
SOURCES/freeipa-4.10.1.tar.gz.asc
Normal file
16
SOURCES/freeipa-4.10.1.tar.gz.asc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmN/lzsACgkQaYdvcqbi
|
||||||
|
00+f7w//a5Y4tgTD2A52fQdihv/Q2ZZqhPlSt8rP7bTLtGSjvANHpuF2u0FcjmtB
|
||||||
|
tADL4zljBGGMGONGt1qMF3d0BkAXhyVp8YNIBcL+abEhgeKL++3egOrI/8iyl4FB
|
||||||
|
Sr8Gvr1T4AJXjz+yZ/SsPNKerqFrJwi3flavZ7Bk1c2W2V3rJubSAvK9XwO7Cyxs
|
||||||
|
4afYpLAiknPh999q3zt7NyviivBTYXirif2T45Lelln9sQaB1ksqDA7oYYAfhV0B
|
||||||
|
wmUJMTtDoaMAcsLT29aC8wGSB5dttI5GmrF60gnbq/t5Tr+7x9ch8VYE60qkynU9
|
||||||
|
n1WcouuIwvcwfPpYSONak0vFrnMV2USNQj5OnzlKXl1HnHsSqoaQWRUA6bbBPjdb
|
||||||
|
xQLdQRrZiYtjG5YcwuZyg8TRP2ph1aY3yL2gAR1ZI13yJeNV0pwU+IwouJDiVPvS
|
||||||
|
dwiG8en1jUxYCeXFKjPX3A8/2ei+LvLTVY65qZKT+BsXyE2CymmUx7P20lFN5Ksb
|
||||||
|
RN+g37mJI8CwqmlemdTZiF+wJnlswS9SOS5zxhpVRiJHAV1sfxu66515c9+n890A
|
||||||
|
Hlm9sZn9UBQN5nLwuak8jaOr73E+d8uieXsSCA4wTtXKQSJs67fNY6ldeUmNximc
|
||||||
|
fq6Yh+lDau14rDlPZUkXx0Jd/oPEWDrtnJzfHECeoRn3KoNzezU=
|
||||||
|
=pxPY
|
||||||
|
-----END PGP SIGNATURE-----
|
@ -66,33 +66,34 @@
|
|||||||
%if 0%{?rhel}
|
%if 0%{?rhel}
|
||||||
%global package_name ipa
|
%global package_name ipa
|
||||||
%global alt_name freeipa
|
%global alt_name freeipa
|
||||||
%global krb5_version 1.19.1-15
|
%global krb5_version 1.20.1-1
|
||||||
%global krb5_kdb_version 8.0
|
%global krb5_kdb_version 9.0
|
||||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||||
%global python_netaddr_version 0.7.19
|
%global python_netaddr_version 0.7.19
|
||||||
# Require 4.7.0 which brings Python 3 bindings
|
%global samba_version 4.17.4-101
|
||||||
%global samba_version 4.15.2-2
|
|
||||||
%global selinux_policy_version 3.14.3-52
|
|
||||||
%global slapi_nis_version 0.56.4
|
%global slapi_nis_version 0.56.4
|
||||||
%global python_ldap_version 3.1.0-1
|
%global python_ldap_version 3.1.0-1
|
||||||
%if 0%{?rhel} < 9
|
%if 0%{?rhel} < 9
|
||||||
# Bug 1929067 - PKI instance creation failed with new 389-ds-base build
|
# Bug 1929067 - PKI instance creation failed with new 389-ds-base build
|
||||||
%global ds_version 1.4.3.16-12
|
%global ds_version 1.4.3.16-12
|
||||||
|
%global selinux_policy_version 3.14.3-107
|
||||||
%else
|
%else
|
||||||
# DNA interval enabled
|
# DNA interval enabled
|
||||||
%global ds_version 2.0.5-1
|
%global ds_version 2.0.5-1
|
||||||
|
%global selinux_policy_version 38.1.1-1
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# Fix for TLS 1.3 PHA, RHBZ#1775158
|
# Fix for TLS 1.3 PHA, RHBZ#1775158
|
||||||
%global httpd_version 2.4.37-21
|
%global httpd_version 2.4.37-21
|
||||||
%global bind_version 9.11.20-6
|
%global bind_version 9.11.20-6
|
||||||
|
|
||||||
|
# Fix for https://github.com/SSSD/sssd/issues/6331
|
||||||
|
%global sssd_version 2.8.0
|
||||||
|
|
||||||
%else
|
%else
|
||||||
# Fedora
|
# Fedora
|
||||||
%global package_name freeipa
|
%global package_name freeipa
|
||||||
%global alt_name ipa
|
%global alt_name ipa
|
||||||
# Fix for CVE-2020-28196
|
|
||||||
%global krb5_version 1.18.2-29
|
|
||||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||||
%global python_netaddr_version 0.7.16
|
%global python_netaddr_version 0.7.16
|
||||||
# Require 4.7.0 which brings Python 3 bindings
|
# Require 4.7.0 which brings Python 3 bindings
|
||||||
@ -100,10 +101,23 @@
|
|||||||
%global samba_version 2:4.12.10
|
%global samba_version 2:4.12.10
|
||||||
|
|
||||||
# 3.14.5-45 or later includes a number of interfaces fixes for IPA interface
|
# 3.14.5-45 or later includes a number of interfaces fixes for IPA interface
|
||||||
|
# 36.16-1 fixes BZ#2115691
|
||||||
|
%if 0%{?fedora} < 36
|
||||||
%global selinux_policy_version 3.14.5-45
|
%global selinux_policy_version 3.14.5-45
|
||||||
|
%else
|
||||||
|
%global selinux_policy_version 36.16-1
|
||||||
|
%endif
|
||||||
%global slapi_nis_version 0.56.5
|
%global slapi_nis_version 0.56.5
|
||||||
|
|
||||||
|
%if 0%{?fedora} < 38
|
||||||
|
# Fix for CVE-2020-28196
|
||||||
|
%global krb5_version 1.18.2-29
|
||||||
%global krb5_kdb_version 8.0
|
%global krb5_kdb_version 8.0
|
||||||
|
%else
|
||||||
|
# Fix for CVE-2020-28196
|
||||||
|
%global krb5_version 1.20.1-3
|
||||||
|
%global krb5_kdb_version 9.0
|
||||||
|
%endif
|
||||||
|
|
||||||
# fix for segfault in python3-ldap, https://pagure.io/freeipa/issue/7324
|
# fix for segfault in python3-ldap, https://pagure.io/freeipa/issue/7324
|
||||||
%global python_ldap_version 3.1.0-1
|
%global python_ldap_version 3.1.0-1
|
||||||
@ -119,11 +133,25 @@
|
|||||||
# Fix for TLS 1.3 PHA, RHBZ#1775146
|
# Fix for TLS 1.3 PHA, RHBZ#1775146
|
||||||
%global httpd_version 2.4.41-9
|
%global httpd_version 2.4.41-9
|
||||||
|
|
||||||
|
# Fix for RHBZ#2117342
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
%global bind_version 9.11.24-1
|
%global bind_version 9.11.24-1
|
||||||
|
%else
|
||||||
|
%global bind_version 32:9.18.7-1
|
||||||
|
%endif
|
||||||
# Don't use Fedora's Python dependency generator on Fedora 30/rawhide yet.
|
# Don't use Fedora's Python dependency generator on Fedora 30/rawhide yet.
|
||||||
# Some packages don't provide new dist aliases.
|
# Some packages don't provide new dist aliases.
|
||||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/
|
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/
|
||||||
%{?python_disable_dependency_generator}
|
%{?python_disable_dependency_generator}
|
||||||
|
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
# F35+, adds IdP integration
|
||||||
|
%global sssd_version 2.7.0
|
||||||
|
%else
|
||||||
|
# Fix for https://github.com/SSSD/sssd/issues/6331
|
||||||
|
%global sssd_version 2.8.0
|
||||||
|
%endif
|
||||||
|
|
||||||
# Fedora
|
# Fedora
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
@ -150,9 +178,6 @@
|
|||||||
# RHEL 8.2+, F32+ has 3.58
|
# RHEL 8.2+, F32+ has 3.58
|
||||||
%global nss_version 3.44.0-4
|
%global nss_version 3.44.0-4
|
||||||
|
|
||||||
# RHEL 8.7+, F35+, adds IdP integration
|
|
||||||
%global sssd_version 2.7.0
|
|
||||||
|
|
||||||
%define krb5_base_version %(LC_ALL=C /usr/bin/pkgconf --modversion krb5 | grep -Eo '^[^.]+\.[^.]+' || echo %krb5_version)
|
%define krb5_base_version %(LC_ALL=C /usr/bin/pkgconf --modversion krb5 | grep -Eo '^[^.]+\.[^.]+' || echo %krb5_version)
|
||||||
%global kdcproxy_version 0.4-3
|
%global kdcproxy_version 0.4-3
|
||||||
|
|
||||||
@ -185,7 +210,7 @@
|
|||||||
|
|
||||||
# Work-around fact that RPM SPEC parser does not accept
|
# Work-around fact that RPM SPEC parser does not accept
|
||||||
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
||||||
%define IPA_VERSION 4.10.0
|
%define IPA_VERSION 4.10.1
|
||||||
# Release candidate version -- uncomment with one percent for RC versions
|
# Release candidate version -- uncomment with one percent for RC versions
|
||||||
#%%global rc_version %%nil
|
#%%global rc_version %%nil
|
||||||
%define AT_SIGN @
|
%define AT_SIGN @
|
||||||
@ -198,7 +223,7 @@
|
|||||||
|
|
||||||
Name: %{package_name}
|
Name: %{package_name}
|
||||||
Version: %{IPA_VERSION}
|
Version: %{IPA_VERSION}
|
||||||
Release: 8%{?rc_version:.%rc_version}%{?dist}
|
Release: 6%{?rc_version:.%rc_version}%{?dist}
|
||||||
Summary: The Identity, Policy and Audit system
|
Summary: The Identity, Policy and Audit system
|
||||||
|
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
@ -217,32 +242,38 @@ Source1: https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers
|
|||||||
|
|
||||||
# RHEL spec file only: START
|
# RHEL spec file only: START
|
||||||
%if %{NON_DEVELOPER_BUILD}
|
%if %{NON_DEVELOPER_BUILD}
|
||||||
%if 0%{?rhel} >= 8
|
%if 0%{?rhel} == 8
|
||||||
Patch0001: 0001-Only-calculate-LDAP-password-grace-when-the-password.patch
|
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||||
Patch0002: 0002-webui-Do-not-allow-empty-pagination-size.patch
|
Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
|
||||||
Patch0003: 0003-ipatests-add-nightly-definitions-for-ipa-4-10-branch.patch
|
%endif
|
||||||
Patch0004: 0004-Added-a-check-while-removing-cert_dir-.-The-teardown.patch
|
%if 0%{?rhel} == 9
|
||||||
Patch0005: 0005-ipatests-healthcheck-test-if-system-is-FIPS-enabled.patch
|
Patch0001: 0001-updates-fix-memberManager-ACI-to-allow-managers-from.patch
|
||||||
Patch0006: 0006-Disabling-gracelimit-does-not-prevent-LDAP-binds.patch
|
Patch0002: 0002-Spec-file-ipa-client-depends-on-krb5-pkinit-openssl.patch
|
||||||
Patch0007: 0007-ipatests-ipa-client-install-subid-adds-entry-in-nssw.patch
|
Patch0003: 0003-server-install-remove-error-log-about-missing-bkup-f.patch
|
||||||
Patch0008: 0008-webui-Allow-grace-login-limit.patch
|
Patch0004: 0004-ipa-tests-Add-LANG-before-kinit-command-to-fix-issue.patch
|
||||||
Patch0009: 0009-Additional-tests-for-RSN-v3.patch
|
Patch0005: 0005-trust-add-handle-missing-msSFU30MaxGidNumber.patch
|
||||||
Patch0010: 0010-check_repl_update-in-progress-is-a-boolean.patch
|
Patch0006: 0006-doc-Design-for-certificate-pruning.patch
|
||||||
Patch0011: 0011-ipatests-Fix-expected-object-classes.patch
|
Patch0007: 0007-ipa-acme-manage-add-certificate-request-pruning-mana.patch
|
||||||
Patch0012: 0012-doc-Update-LDAP-grace-period-design-with-default-val.patch
|
Patch0008: 0008-doc-add-the-run-command-for-manual-job-execution.patch
|
||||||
Patch0013: 0013-Set-default-gracelimit-on-group-password-policies-to.patch
|
Patch0009: 0009-tests-add-wrapper-around-ACME-RSNv3-test.patch
|
||||||
Patch0014: 0014-Set-default-on-group-pwpolicy-with-no-grace-limit-in.patch
|
Patch0010: 0010-automember-rebuild-add-a-notice-about-high-CPU-usage.patch
|
||||||
Patch0015: 0015-fix-canonicalization-issue-in-Web-UI.patch
|
Patch0011: 0011-Fix-setting-values-of-0-in-ACME-pruning.patch
|
||||||
Patch0016: 0016-Defer-creating-the-final-krb5.conf-on-clients.patch
|
Patch0012: 0012-Wipe-the-ipa-ca-DNS-record-when-updating-system-reco.patch
|
||||||
Patch0017: 0017-Vault-fix-interoperability-issues-with-older-RHEL-sy.patch
|
Patch0013: 0013-ipa-kdb-PAC-consistency-checker-needs-to-handle-chil.patch
|
||||||
|
Patch0014: 0014-Add-test-for-SSH-with-GSSAPI-auth.patch
|
||||||
|
Patch0015: 0015-webui-tests-fix-assertion-in-test_subid.py.patch
|
||||||
|
Patch0016: 0016-ipatests-mark-test_smb-as-xfail.patch
|
||||||
|
Patch0017: 0017-Tests-force-key-type-in-ACME-tests.patch
|
||||||
|
Patch0018: 0018-tests-Add-ipa_ca_name-checking-to-DNS-system-records.patch
|
||||||
|
Patch0019: 0019-tests-Add-new-ipa-ca-error-messages-to-IPADNSSystemR.patch
|
||||||
|
Patch0020: 0020-ipatests-tests-for-certificate-pruning.patch
|
||||||
|
Patch0021: 0021-ipatests-ensure-that-ipa-automember-rebuild-prints-a.patch
|
||||||
|
Patch0022: 0022-ipatests-fix-tests-in-TestACMEPrune.patch
|
||||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
# RHEL spec file only: END
|
# RHEL spec file only: END
|
||||||
|
|
||||||
# For the timestamp trick in patch application
|
|
||||||
BuildRequires: diffstat
|
|
||||||
|
|
||||||
BuildRequires: openldap-devel
|
BuildRequires: openldap-devel
|
||||||
# For KDB DAL version, make explicit dependency so that increase of version
|
# For KDB DAL version, make explicit dependency so that increase of version
|
||||||
# will cause the build to fail due to unsatisfied dependencies.
|
# will cause the build to fail due to unsatisfied dependencies.
|
||||||
@ -379,7 +410,6 @@ BuildRequires: python3-libsss_nss_idmap
|
|||||||
BuildRequires: python3-lxml
|
BuildRequires: python3-lxml
|
||||||
BuildRequires: python3-netaddr >= %{python_netaddr_version}
|
BuildRequires: python3-netaddr >= %{python_netaddr_version}
|
||||||
BuildRequires: python3-netifaces
|
BuildRequires: python3-netifaces
|
||||||
BuildRequires: python3-paste
|
|
||||||
BuildRequires: python3-pki >= %{pki_version}
|
BuildRequires: python3-pki >= %{pki_version}
|
||||||
BuildRequires: python3-polib
|
BuildRequires: python3-polib
|
||||||
BuildRequires: python3-pyasn1
|
BuildRequires: python3-pyasn1
|
||||||
@ -439,7 +469,6 @@ Requires: nss-tools >= %{nss_version}
|
|||||||
Requires(post): krb5-server >= %{krb5_version}
|
Requires(post): krb5-server >= %{krb5_version}
|
||||||
Requires(post): krb5-server >= %{krb5_base_version}
|
Requires(post): krb5-server >= %{krb5_base_version}
|
||||||
Requires: krb5-kdb-version = %{krb5_kdb_version}
|
Requires: krb5-kdb-version = %{krb5_kdb_version}
|
||||||
Requires: krb5-pkinit-openssl >= %{krb5_version}
|
|
||||||
Requires: cyrus-sasl-gssapi%{?_isa}
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
Requires: chrony
|
Requires: chrony
|
||||||
Requires: httpd >= %{httpd_version}
|
Requires: httpd >= %{httpd_version}
|
||||||
@ -665,6 +694,8 @@ Requires: python3-sssdconfig >= %{sssd_version}
|
|||||||
Requires: cyrus-sasl-gssapi%{?_isa}
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
Requires: chrony
|
Requires: chrony
|
||||||
Requires: krb5-workstation >= %{krb5_version}
|
Requires: krb5-workstation >= %{krb5_version}
|
||||||
|
# support pkinit with client install
|
||||||
|
Requires: krb5-pkinit-openssl >= %{krb5_version}
|
||||||
# authselect: sssd profile with-subid
|
# authselect: sssd profile with-subid
|
||||||
%if 0%{?fedora} >= 36
|
%if 0%{?fedora} >= 36
|
||||||
Requires: authselect >= 1.4.0
|
Requires: authselect >= 1.4.0
|
||||||
@ -965,22 +996,7 @@ Custom SELinux policy module for FreeIPA
|
|||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
# Update timestamps on the files touched by a patch, to avoid non-equal
|
%autosetup -n freeipa-%{version}%{?rc_version} -N -p1
|
||||||
# .pyc/.pyo files across the multilib peers within a build, where "Level"
|
|
||||||
# is the patch prefix option (e.g. -p1)
|
|
||||||
# Taken from specfile for sssd and python-simplejson
|
|
||||||
UpdateTimestamps() {
|
|
||||||
Level=$1
|
|
||||||
PatchFile=$2
|
|
||||||
|
|
||||||
# Locate the affected files:
|
|
||||||
for f in $(diffstat $Level -l $PatchFile); do
|
|
||||||
# Set the files to have the same timestamp as that of the patch:
|
|
||||||
touch -c -r $PatchFile $f
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
%setup -n freeipa-%{version}%{?rc_version} -q
|
|
||||||
|
|
||||||
# To allow proper application patches to the stripped po files, strip originals
|
# To allow proper application patches to the stripped po files, strip originals
|
||||||
pushd po
|
pushd po
|
||||||
@ -990,10 +1006,7 @@ for i in *.po ; do
|
|||||||
done
|
done
|
||||||
popd
|
popd
|
||||||
|
|
||||||
for p in %patches ; do
|
%autopatch -p1
|
||||||
%__patch -p1 -i $p
|
|
||||||
UpdateTimestamps -p1 $p
|
|
||||||
done
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# PATH is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1005235
|
# PATH is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1005235
|
||||||
@ -1738,14 +1751,46 @@ fi
|
|||||||
%if %{with selinux}
|
%if %{with selinux}
|
||||||
%files selinux
|
%files selinux
|
||||||
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*
|
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*
|
||||||
%ghost %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
|
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
|
||||||
# with selinux
|
# with selinux
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Fri Dec 2 2022 Florence Blanc-Renaud <flo@redhat.com> - 4.10.0-8
|
* Wed Feb 22 2023 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-6
|
||||||
- Resolves: rhbz#2149274 vault interoperability with older RHEL systems is broken [rhel-9.1.0.z]
|
- Resolves: rhbz#2169632 Backport latest test fixes in python3-ipatests
|
||||||
- Resolves: rhbz#2150270 ipa-client-install does not maintain server affinity during installation [rhel-9.1.0.z]
|
|
||||||
|
* Mon Feb 13 2023 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-5
|
||||||
|
- Resolves: rhbz#2162656 Passwordless (GSSAPI) SSH not working for subdomain
|
||||||
|
- Resolves: rhbz#2166326 Removing the last DNS type for ipa-ca does not work
|
||||||
|
- Resolves: rhbz#2167473 RFE - Add a warning note about possible performance impact of the Auto Member rebuild task
|
||||||
|
- Resolves: rhbz#2168244 requestsearchtimelimit=0 doesn't seems to be work with ipa-acme-manage pruning command
|
||||||
|
|
||||||
|
* Mon Feb 06 2023 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-4
|
||||||
|
- Resolves: rhbz#2161284 'ERROR Could not remove /tmp/tmpbkw6hawo.ipabkp' can be seen prior to 'ipa-client-install' command was successful
|
||||||
|
- Resolves: rhbz#2164403 ipa-trust-add with --range-type=ipa-ad-trust-posix fails while creating an ID range
|
||||||
|
- Resolves: rhbz#2162677 RFE: Implement support for PKI certificate and request pruning
|
||||||
|
- Resolves: rhbz#2167312 - Backport latest test fixes in python3-ipatests
|
||||||
|
|
||||||
|
* Wed Dec 21 2022 Alexander Bokovoy <abokovoy@redhat.com> - 4.10.1-3
|
||||||
|
- Rebuild against krb5 1.20.1 ABI
|
||||||
|
- Resolves: rhbz#2155425
|
||||||
|
|
||||||
|
* Fri Dec 9 2022 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-2
|
||||||
|
- Resolves: rhbz#2148887 MemberManager with groups fails
|
||||||
|
- Resolves: rhbz#2150335 idm:client is missing dependency on krb5-pkinit
|
||||||
|
|
||||||
|
* Fri Nov 25 2022 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-1
|
||||||
|
- Resolves: rhbz#2141315 [Rebase] Rebase ipa to latest 4.10.x release for RHEL 9.2
|
||||||
|
- Resolves: rhbz#2094673 ipa-client-install should just use system wide CA store and do not specify TLS_CACERT in ldap.conf
|
||||||
|
- Resolves: rhbz#2117167 After leapp upgrade on ipa-client ipa-server package installation failed. (`REQ_FULL_WITH_MEMBERS` returns object from wrong domain)
|
||||||
|
- Resolves: rhbz#2127833 Password Policy Grace login limit allows invalid maximum value
|
||||||
|
- Resolves: rhbz#2143224 [RFE] add certificate support to ipa-client instead of one time password
|
||||||
|
- Resolves: rhbz#2144736 vault interoperability with older RHEL systems is broken
|
||||||
|
- Resolves: rhbz#2148258 ipa-client-install does not maintain server affinity during installation
|
||||||
|
- Resolves: rhbz#2148379 Add warning for empty targetattr when creating ACI with RBAC
|
||||||
|
- Resolves: rhbz#2148380 OTP token sync always returns OK even with random numbers
|
||||||
|
- Resolves: rhbz#2148381 Deprecated feature idnssoaserial in IdM appears when creating reverse dns zones
|
||||||
|
- Resolves: rhbz#2148382 Introduction of URI records for kerberos breaks location functionality
|
||||||
|
|
||||||
* Tue Oct 25 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.10.0-7
|
* Tue Oct 25 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.10.0-7
|
||||||
- Resolves: rhbz#2124547 Attempt to log in as "root" user with admin's password in Web UI does not properly fail
|
- Resolves: rhbz#2124547 Attempt to log in as "root" user with admin's password in Web UI does not properly fail
|
||||||
|
Loading…
Reference in New Issue
Block a user