ipa-4.12.2-4
- Related: RHEL-59777 Rebase Samba to the latest 4.21.x release - Resolves: RHEL-59659 ipa dns-zone --allow-query '!198.18.2.0/24;any;' fails with Unrecognized IPAddress flags - Resolves: RHEL-61636 Uninstall ACME separately during PKI uninstallation - Resolves: RHEL-61723 Include latest fixes in python3-ipatests packages - Resolves: RHEL-63325 Last expired OTP token would be considered as still assigned to the user Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
parent
c94e6ae745
commit
66cc1eaeec
34
0013-UnsafeIPAddress-pass-flag-0-to-IPNetwork.patch
Normal file
34
0013-UnsafeIPAddress-pass-flag-0-to-IPNetwork.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From a9e653ca36a0829ae59cd204e7388d7a6c91e082 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Fri, 13 Sep 2024 09:58:36 +0200
|
||||||
|
Subject: [PATCH] UnsafeIPAddress: pass flag=0 to IPNetwork
|
||||||
|
|
||||||
|
When parsing a string, the constructor tries to parse the value
|
||||||
|
as an IP Address first, or falls back to an IPNetwork with the
|
||||||
|
flags INET_PTON.
|
||||||
|
|
||||||
|
Use the flag 0 instead for an IPNetwork.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9645
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
ipapython/ipautil.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
|
||||||
|
index 3e98bfd6a66f24933e7e4de8efb79f4f5bf8bd0e..c237d59fb4b8be4187fb0efb04b097ff4df6c182 100644
|
||||||
|
--- a/ipapython/ipautil.py
|
||||||
|
+++ b/ipapython/ipautil.py
|
||||||
|
@@ -119,7 +119,7 @@ class UnsafeIPAddress(netaddr.IPAddress):
|
||||||
|
if addr.version != 6:
|
||||||
|
raise
|
||||||
|
except ValueError:
|
||||||
|
- self._net = netaddr.IPNetwork(addr, flags=self.netaddr_ip_flags)
|
||||||
|
+ self._net = netaddr.IPNetwork(addr, flags=0)
|
||||||
|
addr = self._net.ip
|
||||||
|
super(UnsafeIPAddress, self).__init__(addr,
|
||||||
|
flags=self.netaddr_ip_flags)
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
@ -0,0 +1,67 @@
|
|||||||
|
From a343c149838a3058794f33c75c58b75bc1748f7f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 17:00:49 +0200
|
||||||
|
Subject: [PATCH] ipatests: provide a ccache to rpcclient deletetrustdom
|
||||||
|
|
||||||
|
With samba update to samba-4.20.4, rpcclient now needs a
|
||||||
|
ccache otherwise it prompts for a password.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9667
|
||||||
|
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/pytest_ipa/integration/tasks.py | 23 ++++++++++++++++++++---
|
||||||
|
1 file changed, 20 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
|
||||||
|
index 9d6b5f67a311a28c335801d59e0ff0f0c7faccdd..677fb7534256a65940fb5280fa6412789dcba54f 100755
|
||||||
|
--- a/ipatests/pytest_ipa/integration/tasks.py
|
||||||
|
+++ b/ipatests/pytest_ipa/integration/tasks.py
|
||||||
|
@@ -795,15 +795,22 @@ def remove_trust_info_from_ad(master, ad_domain, ad_hostname):
|
||||||
|
kinit_as_user(master,
|
||||||
|
'Administrator@{}'.format(ad_domain.upper()),
|
||||||
|
master.config.ad_admin_password)
|
||||||
|
+ # Find cache for the user
|
||||||
|
+ cache_args = []
|
||||||
|
+ cache = get_credential_cache(master)
|
||||||
|
+ if cache:
|
||||||
|
+ cache_args = ["--use-krb5-ccache", cache]
|
||||||
|
+
|
||||||
|
# Detect whether rpcclient supports -k or --use-kerberos option
|
||||||
|
res = master.run_command(['rpcclient', '-h'], raiseonerr=False)
|
||||||
|
if "--use-kerberos" in res.stderr_text:
|
||||||
|
rpcclient_krb5_knob = "--use-kerberos=desired"
|
||||||
|
else:
|
||||||
|
rpcclient_krb5_knob = "-k"
|
||||||
|
- master.run_command(['rpcclient', rpcclient_krb5_knob, ad_hostname,
|
||||||
|
- '-c', 'deletetrustdom {}'.format(master.domain.name)],
|
||||||
|
- raiseonerr=False)
|
||||||
|
+ cmd_args = ['rpcclient', rpcclient_krb5_knob, ad_hostname]
|
||||||
|
+ cmd_args.extend(cache_args)
|
||||||
|
+ cmd_args.extend(['-c', 'deletetrustdom {}'.format(master.domain.name)])
|
||||||
|
+ master.run_command(cmd_args, raiseonerr=False)
|
||||||
|
|
||||||
|
|
||||||
|
def configure_auth_to_local_rule(master, ad):
|
||||||
|
@@ -1086,6 +1093,16 @@ def kinit_admin(host, raiseonerr=True):
|
||||||
|
raiseonerr=raiseonerr)
|
||||||
|
|
||||||
|
|
||||||
|
+def get_credential_cache(host):
|
||||||
|
+ # Return the credential cache currently in use on host or None
|
||||||
|
+ result = host.run_command(["klist"]).stdout_text
|
||||||
|
+ pattern = re.compile(r'Ticket cache: (?P<cache>.*)\n')
|
||||||
|
+ res = pattern.search(result)
|
||||||
|
+ if res:
|
||||||
|
+ return res['cache']
|
||||||
|
+ return None
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def uninstall_master(host, ignore_topology_disconnect=True,
|
||||||
|
ignore_last_of_role=True, clean=True, verbose=False):
|
||||||
|
uninstall_cmd = ['ipa-server-install', '--uninstall', '-U']
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 743c7b46e463bef666dc84e9f513eb7dee7f59f6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 14:48:58 +0200
|
||||||
|
Subject: [PATCH] test_adtrust_install: add --use-krb5-ccache to smbclient
|
||||||
|
command
|
||||||
|
|
||||||
|
With samba 4.20.4 the smbclient commands needs a ccache otherwise it
|
||||||
|
prompts for a password.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9666
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
.../test_integration/test_adtrust_install.py | 28 ++++++++++++-------
|
||||||
|
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_adtrust_install.py b/ipatests/test_integration/test_adtrust_install.py
|
||||||
|
index de252db1705ad940c3b5ee4df967d7c17a4203a7..79a91dfaa61276de74b10777c6d44b5942ed1be0 100644
|
||||||
|
--- a/ipatests/test_integration/test_adtrust_install.py
|
||||||
|
+++ b/ipatests/test_integration/test_adtrust_install.py
|
||||||
|
@@ -873,17 +873,25 @@ class TestIpaAdTrustInstall(IntegrationTest):
|
||||||
|
"path", "/freeipa4234"])
|
||||||
|
self.master.run_command(["touch", "before"])
|
||||||
|
self.master.run_command(["touch", "after"])
|
||||||
|
- self.master.run_command(
|
||||||
|
- ["smbclient", "--use-kerberos=desired",
|
||||||
|
- "-c=put before", "//{}/share".format(
|
||||||
|
- self.master.hostname)]
|
||||||
|
- )
|
||||||
|
+ # Find cache for the admin user
|
||||||
|
+ cache_args = []
|
||||||
|
+ cache = tasks.get_credential_cache(self.master)
|
||||||
|
+ if cache:
|
||||||
|
+ cache_args = ["--use-krb5-ccache", cache]
|
||||||
|
+
|
||||||
|
+ cmd_args = ["smbclient", "--use-kerberos=desired"]
|
||||||
|
+ cmd_args.extend(cache_args)
|
||||||
|
+ cmd_args.extend([
|
||||||
|
+ "-c=put before", "//{}/share".format(self.master.hostname)
|
||||||
|
+ ])
|
||||||
|
+ self.master.run_command(cmd_args)
|
||||||
|
self.master.run_command(
|
||||||
|
["net", "conf", "setparm", "share",
|
||||||
|
"valid users", "@admins"])
|
||||||
|
- result = self.master.run_command(
|
||||||
|
- ["smbclient", "--use-kerberos=desired",
|
||||||
|
- "-c=put after", "//{}/share".format(
|
||||||
|
- self.master.hostname)]
|
||||||
|
- )
|
||||||
|
+ cmd_args = ["smbclient", "--use-kerberos=desired"]
|
||||||
|
+ cmd_args.extend(cache_args)
|
||||||
|
+ cmd_args.extend([
|
||||||
|
+ "-c=put after", "//{}/share".format(self.master.hostname)
|
||||||
|
+ ])
|
||||||
|
+ result = self.master.run_command(cmd_args)
|
||||||
|
assert msg not in result.stdout_text
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
209
0016-Don-t-rely-on-removing-the-CA-to-uninstall-the-ACME-.patch
Normal file
209
0016-Don-t-rely-on-removing-the-CA-to-uninstall-the-ACME-.patch
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
From a785d0c561b8e22bd9d56739481095e07e0a7eb7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Mon, 30 Sep 2024 13:30:46 -0400
|
||||||
|
Subject: [PATCH] Don't rely on removing the CA to uninstall the ACME depoyment
|
||||||
|
|
||||||
|
There has always been a pki-server commnd acme-remove. We were
|
||||||
|
not aware that it should be called prior to removing a CA. In
|
||||||
|
11.5.0 this is strongly encouraged by the PKI team. In 11.6.0
|
||||||
|
ACME is treated as a full subsystem so will be removed in the
|
||||||
|
future using pkidestroy -s ACME
|
||||||
|
|
||||||
|
The new class acmeinstance.ACMEInstance is introduced so its
|
||||||
|
uninstallation can be handled in a similar way as the other
|
||||||
|
PKI services via DogtagInstance. It is, right now, a pretty
|
||||||
|
thin wrapper.
|
||||||
|
|
||||||
|
We can discuss moving the ACME installation routines here at
|
||||||
|
some point. It would be ok as long as we don't have to introduce
|
||||||
|
another PKI restart as part of it.
|
||||||
|
|
||||||
|
In PKI 11.6.0 pkidestroy has new options to ensure a clean
|
||||||
|
uninstall: --remove-conf --remove-logs. Pass those options
|
||||||
|
into pkidestroy calls for 11.6.0+.
|
||||||
|
|
||||||
|
Clean up an additional IPA-generated file that needs to be
|
||||||
|
cleaned up during uninstall: /root/kracert.p12. 11.6.0 is
|
||||||
|
more sensitive to leftover files than previous versions.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9673
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9674
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
ipaserver/install/acmeinstance.py | 31 +++++++++++++
|
||||||
|
ipaserver/install/ca.py | 5 ++-
|
||||||
|
ipaserver/install/cainstance.py | 1 +
|
||||||
|
ipaserver/install/dogtaginstance.py | 44 +++++++++++++------
|
||||||
|
.../test_integration/test_uninstallation.py | 21 +++++++++
|
||||||
|
5 files changed, 87 insertions(+), 15 deletions(-)
|
||||||
|
create mode 100644 ipaserver/install/acmeinstance.py
|
||||||
|
|
||||||
|
diff --git a/ipaserver/install/acmeinstance.py b/ipaserver/install/acmeinstance.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..0027c314545f384d9b6ee24b279479e5360d8bef
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ipaserver/install/acmeinstance.py
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+#
|
||||||
|
+# Copyright (C) 2024 FreeIPA Contributors see COPYING for license
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+import logging
|
||||||
|
+
|
||||||
|
+from ipaserver.install.dogtaginstance import DogtagInstance
|
||||||
|
+
|
||||||
|
+logger = logging.getLogger(__name__)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class ACMEInstance(DogtagInstance):
|
||||||
|
+ """
|
||||||
|
+ ACME is deployed automatically with a CA subsystem but it is the
|
||||||
|
+ responsibility of IPA to uninstall the service.
|
||||||
|
+
|
||||||
|
+ This is mostly a placeholder for the uninstaller. We can
|
||||||
|
+ eventually move the ACME installation routines into this class
|
||||||
|
+ if we want but it might result in an extra PKI restart which
|
||||||
|
+ would be slow.
|
||||||
|
+ """
|
||||||
|
+ def __init__(self, realm=None, host_name=None):
|
||||||
|
+ super(ACMEInstance, self).__init__(
|
||||||
|
+ realm=realm,
|
||||||
|
+ subsystem="ACME",
|
||||||
|
+ service_desc="ACME server",
|
||||||
|
+ host_name=host_name
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ def uninstall(self):
|
||||||
|
+ DogtagInstance.uninstall(self)
|
||||||
|
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
|
||||||
|
index ffcb5268399ce71128fc8de5f54d433d35e99dd2..520e3fc5de1084e7c22c0cf7eaa86e1d3c421373 100644
|
||||||
|
--- a/ipaserver/install/ca.py
|
||||||
|
+++ b/ipaserver/install/ca.py
|
||||||
|
@@ -22,7 +22,7 @@ from ipaplatform.constants import constants
|
||||||
|
from ipaserver.install import sysupgrade
|
||||||
|
from ipapython.install import typing
|
||||||
|
from ipapython.install.core import group, knob, extend_knob
|
||||||
|
-from ipaserver.install import cainstance, bindinstance, dsinstance
|
||||||
|
+from ipaserver.install import acmeinstance, cainstance, bindinstance, dsinstance
|
||||||
|
from ipapython import ipautil, certdb
|
||||||
|
from ipapython import ipaldap
|
||||||
|
from ipapython.admintool import ScriptError
|
||||||
|
@@ -715,6 +715,9 @@ def install_step_1(standalone, replica_config, options, custodia):
|
||||||
|
|
||||||
|
|
||||||
|
def uninstall():
|
||||||
|
+ acme = acmeinstance.ACMEInstance(api.env.realm)
|
||||||
|
+ acme.uninstall()
|
||||||
|
+
|
||||||
|
ca_instance = cainstance.CAInstance(api.env.realm)
|
||||||
|
ca_instance.stop_tracking_certificates()
|
||||||
|
ipautil.remove_file(paths.RA_AGENT_PEM)
|
||||||
|
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
|
||||||
|
index 5dac2c0441752e7bb569cde1fc93bc17c3128cdf..5c2c9f8b981cf5d587865f7680e2b231eae655e2 100644
|
||||||
|
--- a/ipaserver/install/cainstance.py
|
||||||
|
+++ b/ipaserver/install/cainstance.py
|
||||||
|
@@ -1118,6 +1118,7 @@ class CAInstance(DogtagInstance):
|
||||||
|
|
||||||
|
ipautil.remove_file(paths.DOGTAG_ADMIN_P12)
|
||||||
|
ipautil.remove_file(paths.CACERT_P12)
|
||||||
|
+ ipautil.remove_file(paths.ADMIN_CERT_PATH)
|
||||||
|
|
||||||
|
def unconfigure_certmonger_renewal_guard(self):
|
||||||
|
if not self.is_configured():
|
||||||
|
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
|
||||||
|
index e89492312deb8ca20668a62fd7a2a20e2866a3fb..4b0f4d274b0c33140ed6f939f1a3fd8b75930ff9 100644
|
||||||
|
--- a/ipaserver/install/dogtaginstance.py
|
||||||
|
+++ b/ipaserver/install/dogtaginstance.py
|
||||||
|
@@ -304,21 +304,37 @@ class DogtagInstance(service.Service):
|
||||||
|
if self.is_installed():
|
||||||
|
self.print_msg("Unconfiguring %s" % self.subsystem)
|
||||||
|
|
||||||
|
- args = [paths.PKIDESTROY,
|
||||||
|
- "-i", "pki-tomcat", "--force",
|
||||||
|
- "-s", self.subsystem]
|
||||||
|
-
|
||||||
|
- # specify --log-file <path> on PKI 11.0.0 or later
|
||||||
|
-
|
||||||
|
+ args = []
|
||||||
|
pki_version = pki.util.Version(pki.specification_version())
|
||||||
|
- if pki_version >= pki.util.Version("11.0.0"):
|
||||||
|
- timestamp = time.strftime(
|
||||||
|
- "%Y%m%d%H%M%S",
|
||||||
|
- time.localtime(time.time()))
|
||||||
|
- log_file = os.path.join(
|
||||||
|
- paths.VAR_LOG_PKI_DIR,
|
||||||
|
- "pki-%s-destroy.%s.log" % (self.subsystem.lower(), timestamp))
|
||||||
|
- args.extend(["--log-file", log_file])
|
||||||
|
+ if self.subsystem == "ACME":
|
||||||
|
+ if pki_version < pki.util.Version("11.0.0"):
|
||||||
|
+ return
|
||||||
|
+ elif (
|
||||||
|
+ pki.util.Version("11.0.0") <= pki_version
|
||||||
|
+ <= pki.util.Version("11.5.0")
|
||||||
|
+ ):
|
||||||
|
+ args = ['pki-server', 'acme-remove']
|
||||||
|
+ else:
|
||||||
|
+ # fall through for PKI >= 11.6.0
|
||||||
|
+ pass
|
||||||
|
+ if not args:
|
||||||
|
+ args = [paths.PKIDESTROY,
|
||||||
|
+ "-i", "pki-tomcat", "--force",
|
||||||
|
+ "-s", self.subsystem]
|
||||||
|
+
|
||||||
|
+ # specify --log-file <path> on PKI 11.0.0 or later
|
||||||
|
+
|
||||||
|
+ if pki_version >= pki.util.Version("11.0.0"):
|
||||||
|
+ timestamp = time.strftime(
|
||||||
|
+ "%Y%m%d%H%M%S",
|
||||||
|
+ time.localtime(time.time()))
|
||||||
|
+ log_file = os.path.join(
|
||||||
|
+ paths.VAR_LOG_PKI_DIR,
|
||||||
|
+ "pki-%s-destroy.%s.log" %
|
||||||
|
+ (self.subsystem.lower(), timestamp))
|
||||||
|
+ args.extend(["--log-file", log_file])
|
||||||
|
+ if pki_version >= pki.util.Version("11.6.0"):
|
||||||
|
+ args.extend(["--remove-conf", "--remove-logs"])
|
||||||
|
|
||||||
|
try:
|
||||||
|
ipautil.run(args)
|
||||||
|
diff --git a/ipatests/test_integration/test_uninstallation.py b/ipatests/test_integration/test_uninstallation.py
|
||||||
|
index 4f8f17ce3ad8d5376ecba11442f379e5691de7f7..049c50db536ae1070f5f958e76b12a1518da0aba 100644
|
||||||
|
--- a/ipatests/test_integration/test_uninstallation.py
|
||||||
|
+++ b/ipatests/test_integration/test_uninstallation.py
|
||||||
|
@@ -197,6 +197,7 @@ class TestUninstallCleanup(IntegrationTest):
|
||||||
|
'/var/lib/sss/pubconf/krb5.include.d/localauth_plugin',
|
||||||
|
'/var/named/dynamic/managed-keys.bind',
|
||||||
|
'/var/named/dynamic/managed-keys.bind.jnl',
|
||||||
|
+ '/var/lib/systemd/coredump/',
|
||||||
|
]
|
||||||
|
|
||||||
|
leftovers = []
|
||||||
|
@@ -217,3 +218,23 @@ class TestUninstallCleanup(IntegrationTest):
|
||||||
|
leftovers.append(line)
|
||||||
|
|
||||||
|
assert len(leftovers) == 0
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestUninstallReinstall(IntegrationTest):
|
||||||
|
+ """Test install, uninstall, re-install.
|
||||||
|
+
|
||||||
|
+ Reinstall with PKI 11.6.0 was failing
|
||||||
|
+ https://pagure.io/freeipa/issue/9673
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ num_replicas = 0
|
||||||
|
+
|
||||||
|
+ @classmethod
|
||||||
|
+ def install(cls, mh):
|
||||||
|
+ tasks.install_master(cls.master, setup_dns=False)
|
||||||
|
+
|
||||||
|
+ def test_uninstall_server(self):
|
||||||
|
+ tasks.uninstall_master(self.master)
|
||||||
|
+
|
||||||
|
+ def test_reinstall_server(self):
|
||||||
|
+ tasks.install_master(self.master, setup_dns=False)
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
35
0017-ipatests-Fixes-for-ipa-idrange-fix-testsuite.patch
Normal file
35
0017-ipatests-Fixes-for-ipa-idrange-fix-testsuite.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From ae4c2ad6cd966d48c063814f494dcc16cf0ccd4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Date: Tue, 24 Sep 2024 13:46:48 +0530
|
||||||
|
Subject: [PATCH] ipatests: Fixes for ipa-idrange-fix testsuite
|
||||||
|
|
||||||
|
This patch adds the line tasks.install_master(cls.master).
|
||||||
|
The kinit admin command fails with the below error as the
|
||||||
|
IPA is not configured on the test system
|
||||||
|
|
||||||
|
'ipa: ERROR: stderr: kinit: Configuration file does not specify default
|
||||||
|
realm when parsing name admin'
|
||||||
|
|
||||||
|
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_ipa_idrange_fix.py | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_ipa_idrange_fix.py b/ipatests/test_integration/test_ipa_idrange_fix.py
|
||||||
|
index ff8fbdac9d028d26fc55f5e357f89af879a61723..0c915bd0931ed11a3aa86c533ee8748aa8a7ec07 100644
|
||||||
|
--- a/ipatests/test_integration/test_ipa_idrange_fix.py
|
||||||
|
+++ b/ipatests/test_integration/test_ipa_idrange_fix.py
|
||||||
|
@@ -17,6 +17,9 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TestIpaIdrangeFix(IntegrationTest):
|
||||||
|
+
|
||||||
|
+ topology = 'line'
|
||||||
|
+
|
||||||
|
@classmethod
|
||||||
|
def install(cls, mh):
|
||||||
|
super(TestIpaIdrangeFix, cls).install(mh)
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
34
0018-spec-Use-nodejs22-on-RHEL-10-and-ELN.patch
Normal file
34
0018-spec-Use-nodejs22-on-RHEL-10-and-ELN.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 642af014d9e7de8e53934af4ca3970977957cba7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yaakov Selkowitz <yselkowi@redhat.com>
|
||||||
|
Date: Tue, 8 Oct 2024 02:13:00 -0400
|
||||||
|
Subject: [PATCH] spec: Use nodejs22 on RHEL 10 and ELN
|
||||||
|
|
||||||
|
nodejs22 is now the default nodejs version in RHEL 10 as well as ELN.
|
||||||
|
|
||||||
|
Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
freeipa.spec.in | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||||
|
index 171b6ad27b57553fdd46c7d041715949bb00b163..9b3d916f34c10a00070855578a593e299187bc44 100755
|
||||||
|
--- a/freeipa.spec.in
|
||||||
|
+++ b/freeipa.spec.in
|
||||||
|
@@ -308,10 +308,10 @@ BuildRequires: libpwquality-devel
|
||||||
|
BuildRequires: libsss_idmap-devel
|
||||||
|
BuildRequires: libsss_certmap-devel
|
||||||
|
BuildRequires: libsss_nss_idmap-devel >= %{sssd_version}
|
||||||
|
-%if 0%{?fedora} >= 41
|
||||||
|
+%if 0%{?fedora} >= 41 || 0%{?rhel} >= 10
|
||||||
|
# Do not use nodejs22 on fedora < 41, https://pagure.io/freeipa/issue/9643
|
||||||
|
BuildRequires: nodejs(abi)
|
||||||
|
-%elif 0%{?fedora} >= 39 || 0%{?rhel} >= 10
|
||||||
|
+%elif 0%{?fedora} >= 39
|
||||||
|
# Do not use nodejs20 on fedora < 39, https://pagure.io/freeipa/issue/9374
|
||||||
|
BuildRequires: nodejs(abi) < 127
|
||||||
|
%else
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
265
0019-Do-not-let-user-with-an-expired-OTP-token-to-log-in-.patch
Normal file
265
0019-Do-not-let-user-with-an-expired-OTP-token-to-log-in-.patch
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
From 18303b94bea4e08a0c889fc357df6ba2f308fa0d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Wed, 2 Oct 2024 21:26:34 -0400
|
||||||
|
Subject: [PATCH] Do not let user with an expired OTP token to log in if only
|
||||||
|
OTP is allowed
|
||||||
|
|
||||||
|
If only OTP authentication is allowed, and a user tries to login with an
|
||||||
|
expired token, do not let them log in with their password. Forcing the
|
||||||
|
admin to intervene. If the user does not have an OTP token then allow
|
||||||
|
them to log in with a password until an OTP token is configured
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9387
|
||||||
|
|
||||||
|
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Julien Rische <jrische@redhat.com>
|
||||||
|
---
|
||||||
|
daemons/ipa-kdb/ipa_kdb_principals.c | 63 +++++++++++--
|
||||||
|
.../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 3 +-
|
||||||
|
ipatests/test_integration/test_otp.py | 94 ++++++++++++++++++-
|
||||||
|
3 files changed, 151 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||||
|
index 14603e528b43acb29234c425e97ad297ac6724a7..114957b884786dd3ca3b01c47f6bb82e8a040beb 100644
|
||||||
|
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||||
|
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||||
|
@@ -107,7 +107,6 @@ static char *std_principal_obj_classes[] = {
|
||||||
|
"krbprincipal",
|
||||||
|
"krbprincipalaux",
|
||||||
|
"krbTicketPolicyAux",
|
||||||
|
-
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -338,14 +337,16 @@ static void ipadb_validate_otp(struct ipadb_context *ipactx,
|
||||||
|
if (dn == NULL)
|
||||||
|
return;
|
||||||
|
count = asprintf(&filter, ftmpl, dn, datetime, datetime);
|
||||||
|
- ldap_memfree(dn);
|
||||||
|
- if (count < 0)
|
||||||
|
+ if (count < 0) {
|
||||||
|
+ ldap_memfree(dn);
|
||||||
|
return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Fetch the active token list. */
|
||||||
|
kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
|
||||||
|
filter, (char**) attrs, &res);
|
||||||
|
free(filter);
|
||||||
|
+ filter = NULL;
|
||||||
|
if (kerr != 0 || res == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -353,10 +354,60 @@ static void ipadb_validate_otp(struct ipadb_context *ipactx,
|
||||||
|
count = ldap_count_entries(ipactx->lcontext, res);
|
||||||
|
ldap_msgfree(res);
|
||||||
|
|
||||||
|
- /* If the user is configured for OTP, but has no active tokens, remove
|
||||||
|
- * OTP from the list since the user obviously can't log in this way. */
|
||||||
|
- if (count == 0)
|
||||||
|
+ /*
|
||||||
|
+ * If there are no valid tokens then we need to remove the OTP flag,
|
||||||
|
+ * unless OTP is the only auth type allowed...
|
||||||
|
+ */
|
||||||
|
+ if (count == 0) {
|
||||||
|
+ /* Remove the OTP flag for now */
|
||||||
|
*ua &= ~IPADB_USER_AUTH_OTP;
|
||||||
|
+
|
||||||
|
+ if (*ua == 0) {
|
||||||
|
+ /*
|
||||||
|
+ * Ok, we "only" allow OTP, so if there is an expired/disabled
|
||||||
|
+ * token then add back the OTP flag as the server will double
|
||||||
|
+ * check the validity and reject the entire bind. Otherwise, this
|
||||||
|
+ * is the first time the user is authenticating and the user
|
||||||
|
+ * should be allowed to bind using its password
|
||||||
|
+ */
|
||||||
|
+ static const char *expired_ftmpl = "(&"
|
||||||
|
+ "(objectClass=ipaToken)(ipatokenOwner=%s)"
|
||||||
|
+ "(|(ipatokenNotAfter<=%s)(!(ipatokenNotAfter=*))"
|
||||||
|
+ "(ipatokenDisabled=True))"
|
||||||
|
+ ")";
|
||||||
|
+ if (asprintf(&filter, expired_ftmpl, dn, datetime) < 0) {
|
||||||
|
+ ldap_memfree(dn);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ krb5_klog_syslog(LOG_INFO,
|
||||||
|
+ "Entry (%s) does not have a valid token and only OTP "
|
||||||
|
+ "authentication is supported, checking for expired tokens...",
|
||||||
|
+ dn);
|
||||||
|
+
|
||||||
|
+ kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
|
||||||
|
+ filter, (char**) attrs, &res);
|
||||||
|
+ free(filter);
|
||||||
|
+ if (kerr != 0 || res == NULL) {
|
||||||
|
+ ldap_memfree(dn);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ldap_count_entries(ipactx->lcontext, res) > 0) {
|
||||||
|
+ /*
|
||||||
|
+ * Ok we only allow OTP, and there are expired/disabled tokens
|
||||||
|
+ * so add the OTP flag back, and the server will reject the
|
||||||
|
+ * bind
|
||||||
|
+ */
|
||||||
|
+ krb5_klog_syslog(LOG_INFO,
|
||||||
|
+ "Entry (%s) does have an expired/disabled token so this "
|
||||||
|
+ "user can not fall through to password auth", dn);
|
||||||
|
+ *ua |= IPADB_USER_AUTH_OTP;
|
||||||
|
+ }
|
||||||
|
+ ldap_msgfree(res);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ ldap_memfree(dn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipadb_validate_radius(struct ipadb_context *ipactx,
|
||||||
|
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
|
||||||
|
index c967e2cfffbd920280639f3188783ec150523b47..1c1340e31ac30cb01412a7065ea339cb5461e839 100644
|
||||||
|
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
|
||||||
|
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
|
||||||
|
@@ -1528,7 +1528,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||||
|
if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
|
||||||
|
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
|
||||||
|
if (ret != 0) {
|
||||||
|
- LOG_FATAL("ipapwd_gen_checks failed!?\n");
|
||||||
|
+ LOG_FATAL("ipapwd_gen_checks failed for '%s': %s\n",
|
||||||
|
+ slapi_sdn_get_dn(sdn), errMesg);
|
||||||
|
slapi_entry_free(entry);
|
||||||
|
slapi_sdn_free(&sdn);
|
||||||
|
return 0;
|
||||||
|
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
|
||||||
|
index 350371bfe1e4c1cc6dcc89f6584f813fcb0d32a0..878b4fb560ba8d7768ead54b065656462545babd 100644
|
||||||
|
--- a/ipatests/test_integration/test_otp.py
|
||||||
|
+++ b/ipatests/test_integration/test_otp.py
|
||||||
|
@@ -10,6 +10,7 @@ import re
|
||||||
|
import time
|
||||||
|
import textwrap
|
||||||
|
from urllib.parse import urlparse, parse_qs
|
||||||
|
+from paramiko import AuthenticationException
|
||||||
|
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
@@ -83,7 +84,7 @@ def kinit_otp(host, user, *, password, otp, success=True):
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-def ssh_2f(hostname, username, answers_dict, port=22):
|
||||||
|
+def ssh_2f(hostname, username, answers_dict, port=22, unwanted_prompt=""):
|
||||||
|
"""
|
||||||
|
:param hostname: hostname
|
||||||
|
:param username: username
|
||||||
|
@@ -103,6 +104,10 @@ def ssh_2f(hostname, username, answers_dict, port=22):
|
||||||
|
logger.info("Prompt is: '%s'", prmpt_str)
|
||||||
|
logger.info(
|
||||||
|
"Answer to ssh prompt is: '%s'", answers_dict[prmpt_str])
|
||||||
|
+ if unwanted_prompt and prmpt_str == unwanted_prompt:
|
||||||
|
+ # We should not see this prompt
|
||||||
|
+ raise ValueError("We got an unwanted prompt: "
|
||||||
|
+ + answers_dict[prmpt_str])
|
||||||
|
return resp
|
||||||
|
|
||||||
|
import paramiko
|
||||||
|
@@ -193,7 +198,8 @@ class TestOTPToken(IntegrationTest):
|
||||||
|
|
||||||
|
# skipping too many OTP fails
|
||||||
|
otp1 = hotp.generate(10).decode("ascii")
|
||||||
|
- kinit_otp(self.master, USER, password=PASSWORD, otp=otp1, success=False)
|
||||||
|
+ kinit_otp(self.master, USER, password=PASSWORD, otp=otp1,
|
||||||
|
+ success=False)
|
||||||
|
# Now the token is desynchronized
|
||||||
|
yield (otpuid, hotp)
|
||||||
|
|
||||||
|
@@ -536,3 +542,87 @@ class TestOTPToken(IntegrationTest):
|
||||||
|
finally:
|
||||||
|
master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
|
||||||
|
master.run_command(['ipa', 'user-del', USER1])
|
||||||
|
+
|
||||||
|
+ def test_totp_expired_ldap(self):
|
||||||
|
+ master = self.master
|
||||||
|
+ basedn = master.domain.basedn
|
||||||
|
+ USER1 = 'user-expired-otp'
|
||||||
|
+ TMP_PASSWORD = 'Secret1234509'
|
||||||
|
+ binddn = DN(f"uid={USER1},cn=users,cn=accounts,{basedn}")
|
||||||
|
+ controls = [
|
||||||
|
+ BooleanControl(
|
||||||
|
+ controlType="2.16.840.1.113730.3.8.10.7",
|
||||||
|
+ booleanValue=True)
|
||||||
|
+ ]
|
||||||
|
+
|
||||||
|
+ tasks.kinit_admin(master)
|
||||||
|
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '0'])
|
||||||
|
+ tasks.user_add(master, USER1, password=TMP_PASSWORD)
|
||||||
|
+ # Enforce use of OTP token for this user
|
||||||
|
+ master.run_command(['ipa', 'user-mod', USER1,
|
||||||
|
+ '--user-auth-type=otp'])
|
||||||
|
+ try:
|
||||||
|
+ # Change initial password through the IPA endpoint
|
||||||
|
+ url = f'https://{master.hostname}/ipa/session/change_password'
|
||||||
|
+ master.run_command(['curl', '-d', f'user={USER1}',
|
||||||
|
+ '-d', f'old_password={TMP_PASSWORD}',
|
||||||
|
+ '-d', f'new_password={PASSWORD}',
|
||||||
|
+ '--referer', f'https://{master.hostname}/ipa',
|
||||||
|
+ url])
|
||||||
|
+ conn = master.ldap_connect()
|
||||||
|
+ # First, attempt authenticating with a password but without LDAP
|
||||||
|
+ # control to enforce OTP presence and without server-side
|
||||||
|
+ # enforcement of the OTP presence check.
|
||||||
|
+ conn.simple_bind(binddn, f"{PASSWORD}")
|
||||||
|
+
|
||||||
|
+ # Add an OTP token and then modify it to be expired
|
||||||
|
+ otpuid, totp = add_otptoken(master, USER1, otptype="totp")
|
||||||
|
+
|
||||||
|
+ # Make sure OTP auth is working
|
||||||
|
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
|
||||||
|
+ conn = master.ldap_connect()
|
||||||
|
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
|
||||||
|
+ client_controls=controls)
|
||||||
|
+ conn.unbind()
|
||||||
|
+
|
||||||
|
+ # Modfy token so that is now expired
|
||||||
|
+ args = [
|
||||||
|
+ "ipa",
|
||||||
|
+ "otptoken-mod",
|
||||||
|
+ otpuid,
|
||||||
|
+ "--not-after",
|
||||||
|
+ "20241001010000Z",
|
||||||
|
+ ]
|
||||||
|
+ master.run_command(args)
|
||||||
|
+
|
||||||
|
+ # Next, authenticate with Password+OTP again and with the LDAP
|
||||||
|
+ # control this operation should now fail
|
||||||
|
+ time.sleep(45)
|
||||||
|
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
|
||||||
|
+
|
||||||
|
+ conn = master.ldap_connect()
|
||||||
|
+ with pytest.raises(errors.ACIError):
|
||||||
|
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
|
||||||
|
+ client_controls=controls)
|
||||||
|
+
|
||||||
|
+ # Sleep to make sure we are going to use a different token value
|
||||||
|
+ time.sleep(45)
|
||||||
|
+
|
||||||
|
+ # Use OTP token again but authenticate over ssh and make sure it
|
||||||
|
+ # doesn't fallthrough to asking for a password
|
||||||
|
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
|
||||||
|
+ answers = {
|
||||||
|
+ 'Enter first factor:': PASSWORD,
|
||||||
|
+ 'Enter second factor:': otpvalue
|
||||||
|
+ }
|
||||||
|
+ with pytest.raises(AuthenticationException):
|
||||||
|
+ # ssh should fail and NOT ask for a password
|
||||||
|
+ ssh_2f(master.hostname, USER1, answers,
|
||||||
|
+ unwanted_prompt="Password:")
|
||||||
|
+
|
||||||
|
+ # Remove token
|
||||||
|
+ del_otptoken(self.master, otpuid)
|
||||||
|
+
|
||||||
|
+ finally:
|
||||||
|
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
|
||||||
|
+ master.run_command(['ipa', 'user-del', USER1])
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
41
0020-ipatests-Activate-ssh-in-sssd.conf.patch
Normal file
41
0020-ipatests-Activate-ssh-in-sssd.conf.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From 761647f842567713032709753b6d63467d9871a6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Date: Mon, 23 Sep 2024 14:05:43 +0530
|
||||||
|
Subject: [PATCH] ipatests: Activate ssh in sssd.conf
|
||||||
|
|
||||||
|
This testcase checks that services: ssh
|
||||||
|
is included in the sssd.conf file when
|
||||||
|
ipa-client-install is successful.
|
||||||
|
|
||||||
|
Ref: https://pagure.io/freeipa/issue/9649
|
||||||
|
|
||||||
|
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_installation_client.py | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py
|
||||||
|
index f8567b39eead4dffd522aad504fa72a086969257..884bff2f2f3e49f66da391424e128d8e31b82a8a 100644
|
||||||
|
--- a/ipatests/test_integration/test_installation_client.py
|
||||||
|
+++ b/ipatests/test_integration/test_installation_client.py
|
||||||
|
@@ -94,6 +94,16 @@ class TestInstallClient(IntegrationTest):
|
||||||
|
).encode() not in krb5_cfg
|
||||||
|
tasks.uninstall_client(self.clients[0])
|
||||||
|
|
||||||
|
+ def test_check_ssh_service_is_activated(self):
|
||||||
|
+ """
|
||||||
|
+ This test checks all default services are activated
|
||||||
|
+ in sssd.conf including ssh
|
||||||
|
+ """
|
||||||
|
+ tasks.install_client(self.master, self.clients[0])
|
||||||
|
+ sssd_cfg = self.clients[0].get_file_contents(paths.SSSD_CONF)
|
||||||
|
+ assert 'services = nss, pam, ssh, sudo' in sssd_cfg.decode()
|
||||||
|
+ tasks.uninstall_client(self.clients[0])
|
||||||
|
+
|
||||||
|
def test_install_with_automount(self):
|
||||||
|
"""Test that installation with automount is successful"""
|
||||||
|
tasks.install_client(self.master, self.clients[0],
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
131
0021-ipa-migrate-man-page-fix-typos-and-errors.patch
Normal file
131
0021-ipa-migrate-man-page-fix-typos-and-errors.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From f978fa05e3ed9d4ad9d20493c05c77fb9b4976a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Tue, 15 Oct 2024 17:04:55 +0200
|
||||||
|
Subject: [PATCH] ipa-migrate man page: fix typos and errors
|
||||||
|
|
||||||
|
ipa-migrate man page mentions non-existing option --hostname.
|
||||||
|
Fix the SYNOPSIS and various typos.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9681
|
||||||
|
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
---
|
||||||
|
install/tools/man/ipa-migrate.1 | 38 +++++++++++++++------------------
|
||||||
|
1 file changed, 17 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/install/tools/man/ipa-migrate.1 b/install/tools/man/ipa-migrate.1
|
||||||
|
index 47ae47ea4afa3a5a6fe25dd9bbd14c27ab5f1fdb..5106f4f0f5b5928909ccd5abcef3bb6d1586f5df 100644
|
||||||
|
--- a/install/tools/man/ipa-migrate.1
|
||||||
|
+++ b/install/tools/man/ipa-migrate.1
|
||||||
|
@@ -5,11 +5,11 @@
|
||||||
|
.SH "NAME"
|
||||||
|
ipa\-migrate \- Migrate an IPA server from one machine to another
|
||||||
|
.SH "SYNOPSIS"
|
||||||
|
-ipa\-migrate
|
||||||
|
+\fBipa\-migrate\fR [OPTIONS] \fBprod\-mode\fR|\fBstage\-mode\fR \fIhostname\fR
|
||||||
|
.SH "DESCRIPTION"
|
||||||
|
|
||||||
|
Use the \fIipa-migrate\fR command to migrate one
|
||||||
|
-IPA server to an existing local IPA server installation.
|
||||||
|
+IPA server \fIhostname\fR to an existing local IPA server installation.
|
||||||
|
|
||||||
|
Migrate IPA schema, configuration, and database to a local IPA server. This
|
||||||
|
migration can be done online, where the tool will query the remote server. Or,
|
||||||
|
@@ -19,7 +19,6 @@ and then use an exported LDIF file for the database migration portion (this
|
||||||
|
might be more useful for very large databases as you don't need to worry about
|
||||||
|
network interruptions)
|
||||||
|
|
||||||
|
-.SH POSITIONAL ARGUMENTS
|
||||||
|
.TP
|
||||||
|
\fBprod\-mode\fR
|
||||||
|
In this mode everything will be migrated including the current user SIDs and
|
||||||
|
@@ -28,13 +27,10 @@ DNA ranges
|
||||||
|
\fBstage\-mode\fR
|
||||||
|
In this mode, SIDs & DNA ranges are not migrated, and DNA attributes are reset
|
||||||
|
|
||||||
|
-.SH "COMMANDS"
|
||||||
|
+.SH "OPTIONS"
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
|
-Use verbose output while running the migration tool.
|
||||||
|
-.TP
|
||||||
|
-\fB\-e\fR, \fB\-\-hostname=HOSTNAME\fR
|
||||||
|
-The host name of the remote IPA server that is being migrated from.
|
||||||
|
+Use verbose output while running the migration tool
|
||||||
|
.TP
|
||||||
|
\fB\-D\fR, \fB\-\-bind\-dn=BIND_DN\fR
|
||||||
|
The Bind DN (Distinguished Name) or an LDAP entry to bind to the remote IPA server with.
|
||||||
|
@@ -43,10 +39,10 @@ access to read the userPassword attribute. If ommitted the default is "cn=direc
|
||||||
|
.TP
|
||||||
|
\fB\-w\fR, \fB\-\-bind\-pw=PASSWORD\fR
|
||||||
|
The password for the Bind DN that is authenticating against the remote IPA server. If
|
||||||
|
-a password is not provided then the tool with prompt for the password if needed.
|
||||||
|
+a password is not provided then the tool with prompt for the password if needed
|
||||||
|
.TP
|
||||||
|
-\fB\-Just\fR, \fB\-\-bind\-pw\-file=FILE_PATH\fR
|
||||||
|
-Path to a file containing the password for the Bind DN.
|
||||||
|
+\fB\-j\fR, \fB\-\-bind\-pw\-file=FILE_PATH\fR
|
||||||
|
+Path to a file containing the password for the Bind DN
|
||||||
|
.TP
|
||||||
|
\fB\-Z\fR, \fB\-\-cacertfile=FILE_PATH\fR
|
||||||
|
Path to a file containing a CA Certificate that the remote server trusts
|
||||||
|
@@ -55,23 +51,23 @@ Path to a file containing a CA Certificate that the remote server trusts
|
||||||
|
Path to a file containing the migration log. By default the tool will use \fI/var/log/ipa-migrate.log\fR
|
||||||
|
.TP
|
||||||
|
\fB\-x\fR, \fB\-\-dryrun\fR
|
||||||
|
-Go through the migration process but do not write and data to the new IPA server.
|
||||||
|
+Go through the migration process but do not write any data to the new IPA server
|
||||||
|
.TP
|
||||||
|
\fB\-o\fR, \fB\-\-dryrun\-record=FILE_PATH\fR
|
||||||
|
Go through the migration process but do not write any data to the new IPA server. However, write the
|
||||||
|
-migration operations to an LDIF file which can be applied later or reused for multiple migrations.
|
||||||
|
+migration operations to an LDIF file which can be applied later or reused for multiple migrations
|
||||||
|
.TP
|
||||||
|
\fB\-r\fR, \fB\-\-reset\-range\fR
|
||||||
|
Reset the ID range for migrated users/groups. In "stage-mode" this is done automatically
|
||||||
|
.TP
|
||||||
|
\fB\-F\fR, \fB\-\-force\fR
|
||||||
|
-Ignore any errors and continue to proceed with migration effort.
|
||||||
|
+Ignore any errors and continue to proceed with migration effort
|
||||||
|
.TP
|
||||||
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
|
-Only log errors during the migration process.
|
||||||
|
+Only log errors during the migration process
|
||||||
|
.TP
|
||||||
|
\fB\-B\fR, \fB\-\-migrate\-dns\fR
|
||||||
|
-Migrate thr DNS records
|
||||||
|
+Migrate the DNS records
|
||||||
|
.TP
|
||||||
|
\fB\-S\fR, \fB\-\-skip\-schema\fR
|
||||||
|
Do not migrate the database schema
|
||||||
|
@@ -80,21 +76,21 @@ Do not migrate the database schema
|
||||||
|
Do not migrate the database configuration (dse.ldif/cn=config)
|
||||||
|
.TP
|
||||||
|
\fB\-O\fR, \fB\-\-schema\-overwrite\fR
|
||||||
|
-Overwrite existing schema definitions. By default duplicate schema is skipped.
|
||||||
|
+Overwrite existing schema definitions. By default duplicate schema is skipped
|
||||||
|
.TP
|
||||||
|
\fB\-s\fR, \fB\-\-subtree=DN\fR
|
||||||
|
Specifies a custom database subtree that should be included in the migration.
|
||||||
|
This is only needed if non-default subtrees/branches were added to the database
|
||||||
|
-outside of IPA.
|
||||||
|
+outside of IPA
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR, \fB\-\-db\-ldif=FILE_PATH\fR
|
||||||
|
-LDIF file containing the entire backend. If omitted the tool will query the remote IPA server.
|
||||||
|
+LDIF file containing the entire backend. If omitted the tool will query the remote IPA server
|
||||||
|
.TP
|
||||||
|
\fB\-m\fR, \fB\-\-schema\-ldif=FILE_PATH\fR
|
||||||
|
-LDIF file containing the schema. If omitted the tool will query the remote IPA server.
|
||||||
|
+LDIF file containing the schema. If omitted the tool will query the remote IPA server
|
||||||
|
.TP
|
||||||
|
\fB\-g\fR, \fB\-\-config\-ldif=FILE_PATH\fR
|
||||||
|
-LDIF file containing the entire "cn=config" DIT. If omitted the tool will query the remote IPA server.
|
||||||
|
+LDIF file containing the entire "cn=config" DIT. If omitted the tool will query the remote IPA server
|
||||||
|
.TP
|
||||||
|
\fB\-n\fR, \fB\-\-no\-prompt\fR
|
||||||
|
Do not prompt for confirmation before starting migration. Use at your own risk!
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
61
0022-ipatests-Test-for-ipa-hbac-rule-duplication.patch
Normal file
61
0022-ipatests-Test-for-ipa-hbac-rule-duplication.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
From 7f4e7e1d6a2ae9d05a2dfcf620f4df07d09d9d2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Date: Thu, 3 Oct 2024 18:45:31 +0530
|
||||||
|
Subject: [PATCH] ipatests: Test for ipa hbac rule duplication
|
||||||
|
|
||||||
|
This test checks that ipa-migrate is not creating duplicate default hbac rules
|
||||||
|
for allow_all and allow_systemd-user rules.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9640
|
||||||
|
|
||||||
|
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||||
|
---
|
||||||
|
.../test_ipa_ipa_migration.py | 26 +++++++++++++++++++
|
||||||
|
1 file changed, 26 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_ipa_ipa_migration.py b/ipatests/test_integration/test_ipa_ipa_migration.py
|
||||||
|
index 288165e8a83a96e6f6bd4e52866f98617f497c56..70c268951a0d7e40806742b16e62b764b2bae37b 100644
|
||||||
|
--- a/ipatests/test_integration/test_ipa_ipa_migration.py
|
||||||
|
+++ b/ipatests/test_integration/test_ipa_ipa_migration.py
|
||||||
|
@@ -9,6 +9,7 @@ from __future__ import absolute_import
|
||||||
|
from ipatests.test_integration.base import IntegrationTest
|
||||||
|
from ipatests.pytest_ipa.integration import tasks
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
+from collections import Counter
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import textwrap
|
||||||
|
@@ -920,3 +921,28 @@ class TestIPAMigrateScenario1(IntegrationTest):
|
||||||
|
)
|
||||||
|
assert result.returncode == 1
|
||||||
|
assert ERR_MSG in result.stderr_text
|
||||||
|
+
|
||||||
|
+ def test_ipa_hbac_rule_duplication(self):
|
||||||
|
+ """
|
||||||
|
+ This testcase checks that default hbac rules
|
||||||
|
+ are not duplicated on the local server when
|
||||||
|
+ ipa-migrate command is run.
|
||||||
|
+ """
|
||||||
|
+ run_migrate(
|
||||||
|
+ self.replicas[0],
|
||||||
|
+ "prod-mode",
|
||||||
|
+ self.master.hostname,
|
||||||
|
+ "cn=Directory Manager",
|
||||||
|
+ self.master.config.admin_password,
|
||||||
|
+ extra_args=['-n']
|
||||||
|
+ )
|
||||||
|
+ result = self.replicas[0].run_command(
|
||||||
|
+ ['ipa', 'hbacrule-find']
|
||||||
|
+ )
|
||||||
|
+ lines = result.stdout_text.splitlines()
|
||||||
|
+ line = []
|
||||||
|
+ for i in lines:
|
||||||
|
+ line.append(i.strip())
|
||||||
|
+ count = Counter(line)
|
||||||
|
+ assert count.get('Rule name: allow_all') < 2
|
||||||
|
+ assert count.get('Rule name: allow_systemd-user') < 2
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
116
0023-ipatests-refactor-password-file-handling-in-TestHSMI.patch
Normal file
116
0023-ipatests-refactor-password-file-handling-in-TestHSMI.patch
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
From 142f52fc981fe9f1d693b79a7b49506af2e98829 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Date: Mon, 19 Aug 2024 16:08:53 +0530
|
||||||
|
Subject: [PATCH] ipatests: refactor password file handling in TestHSMInstall
|
||||||
|
|
||||||
|
When token and associated certs are not being cleaned
|
||||||
|
up properly, the subsequent installation fails. Hence
|
||||||
|
Password file related scenarios moved out to new test class
|
||||||
|
so that it have fresh installation.
|
||||||
|
|
||||||
|
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||||
|
---
|
||||||
|
.../nightly_ipa-4-12_latest.yaml | 12 ++++++++
|
||||||
|
.../nightly_ipa-4-12_latest_selinux.yaml | 13 ++++++++
|
||||||
|
ipatests/test_integration/test_hsm.py | 30 ++++++++++---------
|
||||||
|
3 files changed, 41 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/prci_definitions/nightly_ipa-4-12_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-12_latest.yaml
|
||||||
|
index 6d18e708fb0512ce21d8db68d4f1ab26849f40b7..07e2a8399ae4cc953adb415b975101ed20c67fd2 100644
|
||||||
|
--- a/ipatests/prci_definitions/nightly_ipa-4-12_latest.yaml
|
||||||
|
+++ b/ipatests/prci_definitions/nightly_ipa-4-12_latest.yaml
|
||||||
|
@@ -1950,6 +1950,18 @@ jobs:
|
||||||
|
timeout: 6300
|
||||||
|
topology: *master_3repl_1client
|
||||||
|
|
||||||
|
+ fedora-latest-ipa-4-12/test_hsm_TestHSMInstallPasswordFile:
|
||||||
|
+ requires: [fedora-latest-ipa-4-12/build]
|
||||||
|
+ priority: 50
|
||||||
|
+ job:
|
||||||
|
+ class: RunPytest
|
||||||
|
+ args:
|
||||||
|
+ build_url: '{fedora-latest-ipa-4-12/build_url}'
|
||||||
|
+ test_suite: test_integration/test_hsm.py::TestHSMInstallPasswordFile
|
||||||
|
+ template: *ci-ipa-4-12-latest
|
||||||
|
+ timeout: 6300
|
||||||
|
+ topology: *master_1repl
|
||||||
|
+
|
||||||
|
fedora-latest-ipa-4-12/test_hsm_TestHSMInstallADTrustBase:
|
||||||
|
requires: [fedora-latest-ipa-4-12/build]
|
||||||
|
priority: 50
|
||||||
|
diff --git a/ipatests/prci_definitions/nightly_ipa-4-12_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-12_latest_selinux.yaml
|
||||||
|
index 52686df9713975c9590b8a99edb7c3442531fecc..11046be13fca1e7403d0fd74329a66ded3927a6c 100644
|
||||||
|
--- a/ipatests/prci_definitions/nightly_ipa-4-12_latest_selinux.yaml
|
||||||
|
+++ b/ipatests/prci_definitions/nightly_ipa-4-12_latest_selinux.yaml
|
||||||
|
@@ -2105,6 +2105,19 @@ jobs:
|
||||||
|
timeout: 6300
|
||||||
|
topology: *master_3repl_1client
|
||||||
|
|
||||||
|
+ fedora-latest-ipa-4-12/test_hsm_TestHSMInstallPasswordFile:
|
||||||
|
+ requires: [fedora-latest-ipa-4-12/build]
|
||||||
|
+ priority: 50
|
||||||
|
+ job:
|
||||||
|
+ class: RunPytest
|
||||||
|
+ args:
|
||||||
|
+ build_url: '{fedora-latest-ipa-4-12/build_url}'
|
||||||
|
+ selinux_enforcing: True
|
||||||
|
+ test_suite: test_integration/test_hsm.py::TestHSMInstallPasswordFile
|
||||||
|
+ template: *ci-ipa-4-12-latest
|
||||||
|
+ timeout: 6300
|
||||||
|
+ topology: *master_1repl
|
||||||
|
+
|
||||||
|
fedora-latest-ipa-4-12/test_hsm_TestHSMInstallADTrustBase:
|
||||||
|
requires: [fedora-latest-ipa-4-12/build]
|
||||||
|
priority: 50
|
||||||
|
diff --git a/ipatests/test_integration/test_hsm.py b/ipatests/test_integration/test_hsm.py
|
||||||
|
index 374f5c25fd3453cd45a15d2b0f20cee424282595..42895fcd60a7c02d3b6103c2f6751a367da30b2f 100644
|
||||||
|
--- a/ipatests/test_integration/test_hsm.py
|
||||||
|
+++ b/ipatests/test_integration/test_hsm.py
|
||||||
|
@@ -312,24 +312,26 @@ class TestHSMInstall(BaseHSMTest):
|
||||||
|
assert returncode == 0
|
||||||
|
assert output == "No issues found."
|
||||||
|
|
||||||
|
- def test_hsm_install_server_password_file(self):
|
||||||
|
- check_version(self.master)
|
||||||
|
- # cleanup before fresh install with password file
|
||||||
|
- for client in self.clients:
|
||||||
|
- tasks.uninstall_client(client)
|
||||||
|
|
||||||
|
- for replica in self.replicas:
|
||||||
|
- tasks.uninstall_master(replica)
|
||||||
|
+class TestHSMInstallPasswordFile(BaseHSMTest):
|
||||||
|
|
||||||
|
- tasks.uninstall_master(self.master)
|
||||||
|
+ num_replicas = 1
|
||||||
|
|
||||||
|
- delete_hsm_token([self.master] + self.replicas, self.token_name)
|
||||||
|
- self.token_name, self.token_password = get_hsm_token(self.master)
|
||||||
|
- self.master.put_file_contents(self.token_password_file,
|
||||||
|
- self.token_password)
|
||||||
|
- self.replicas[0].put_file_contents(self.token_password_file,
|
||||||
|
- self.token_password)
|
||||||
|
+ @classmethod
|
||||||
|
+ def install(cls, mh):
|
||||||
|
+ check_version(cls.master)
|
||||||
|
+ # Enable pkiuser to read softhsm tokens
|
||||||
|
+ cls.master.run_command(['usermod', 'pkiuser', '-a', '-G', 'ods'])
|
||||||
|
+ cls.token_name, cls.token_password = get_hsm_token(cls.master)
|
||||||
|
+ cls.master.put_file_contents(
|
||||||
|
+ cls.token_password_file, cls.token_password
|
||||||
|
+ )
|
||||||
|
+ cls.replicas[0].put_file_contents(
|
||||||
|
+ cls.token_password_file, cls.token_password
|
||||||
|
+ )
|
||||||
|
|
||||||
|
+ def test_hsm_install_server_password_file(self):
|
||||||
|
+ check_version(self.master)
|
||||||
|
tasks.install_master(
|
||||||
|
self.master, setup_dns=self.master_with_dns,
|
||||||
|
setup_kra=self.master_with_kra,
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
276
0024-ipatests-2FA-test-cases.patch
Normal file
276
0024-ipatests-2FA-test-cases.patch
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
From 6ac11ae003740faf19f3c75bf542ec44f717114f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Madhuri Upadhye <mupadhye@redhat.com>
|
||||||
|
Date: Tue, 23 Jul 2024 18:14:36 +0530
|
||||||
|
Subject: [PATCH] ipatests: 2FA test cases
|
||||||
|
|
||||||
|
Added following:
|
||||||
|
|
||||||
|
Added 'ssh_2fa_with_cmd' method for authentication,
|
||||||
|
as for '\n' with paramiko did not work. In a test case
|
||||||
|
need to just press `Enter` for `second factor`.
|
||||||
|
Advantage of above function is no having paramiko
|
||||||
|
dependancy.
|
||||||
|
We can run the any command in same session after
|
||||||
|
authentication of user.
|
||||||
|
|
||||||
|
Test cases:
|
||||||
|
1. Authenticate the user only with password,
|
||||||
|
just press enter at `Second factor` and check tgt after auth.
|
||||||
|
when User authentication types: otp, password
|
||||||
|
2. Authenticate the user with password and otpvalues and
|
||||||
|
check tgt of user after auth when
|
||||||
|
User authentication types: otp, password
|
||||||
|
|
||||||
|
related: https://github.com/SSSD/sssd/pull/7500
|
||||||
|
|
||||||
|
Signed-off-by: Madhuri Upadhye <mupadhye@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_otp.py | 192 ++++++++++++++++++++++++--
|
||||||
|
1 file changed, 181 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
|
||||||
|
index 878b4fb560ba8d7768ead54b065656462545babd..0babb45897c6107bf354477dbb0d3a805a3116f5 100644
|
||||||
|
--- a/ipatests/test_integration/test_otp.py
|
||||||
|
+++ b/ipatests/test_integration/test_otp.py
|
||||||
|
@@ -5,26 +5,27 @@
|
||||||
|
"""
|
||||||
|
import base64
|
||||||
|
import logging
|
||||||
|
-import pytest
|
||||||
|
import re
|
||||||
|
-import time
|
||||||
|
+import tempfile
|
||||||
|
import textwrap
|
||||||
|
-from urllib.parse import urlparse, parse_qs
|
||||||
|
-from paramiko import AuthenticationException
|
||||||
|
+import time
|
||||||
|
+from urllib.parse import parse_qs, urlparse
|
||||||
|
|
||||||
|
+import pytest
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.twofactor.hotp import HOTP
|
||||||
|
from cryptography.hazmat.primitives.twofactor.totp import TOTP
|
||||||
|
-
|
||||||
|
-from ipatests.test_integration.base import IntegrationTest
|
||||||
|
-from ipaplatform.paths import paths
|
||||||
|
-from ipatests.pytest_ipa.integration import tasks
|
||||||
|
-from ipapython.dn import DN
|
||||||
|
-
|
||||||
|
from ldap.controls.simple import BooleanControl
|
||||||
|
+from paramiko import AuthenticationException
|
||||||
|
|
||||||
|
from ipalib import errors
|
||||||
|
+from ipaplatform.osinfo import osinfo
|
||||||
|
+from ipaplatform.paths import paths
|
||||||
|
+from ipapython.dn import DN
|
||||||
|
+from ipatests.pytest_ipa.integration import tasks
|
||||||
|
+from ipatests.test_integration.base import IntegrationTest
|
||||||
|
+from ipatests.util import xfail_context
|
||||||
|
|
||||||
|
PASSWORD = "DummyPassword123"
|
||||||
|
USER = "opttestuser"
|
||||||
|
@@ -84,6 +85,65 @@ def kinit_otp(host, user, *, password, otp, success=True):
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
+def ssh_2fa_with_cmd(host, hostname, username, password, otpvalue,
|
||||||
|
+ command="exit 0"):
|
||||||
|
+ """ ssh to user and in same session pass the command to check tgt of user
|
||||||
|
+ :param host: host to ssh
|
||||||
|
+ :param hostname: hostname to ssh
|
||||||
|
+ :param str username: The name of user
|
||||||
|
+ :param str password: password, usually the first factor
|
||||||
|
+ :param str otpvalue: generated pin of user
|
||||||
|
+ :param str command: command to execute in same session,
|
||||||
|
+ by deafult set to "exit 0"
|
||||||
|
+ :return: object class of expect command run
|
||||||
|
+ """
|
||||||
|
+ temp_conf = tempfile.NamedTemporaryFile(suffix='.exp', delete=False)
|
||||||
|
+ with open(temp_conf.name, 'w') as tfile:
|
||||||
|
+ tfile.write('proc exitmsg { msg code } {\n')
|
||||||
|
+ tfile.write('\t# Close spawned program, if we are in the prompt\n')
|
||||||
|
+ tfile.write('\tcatch close\n\n')
|
||||||
|
+ tfile.write('\t# Wait for the exit code\n')
|
||||||
|
+ tfile.write('\tlassign [wait] pid spawnid os_error_flag rc\n\n')
|
||||||
|
+ tfile.write('\tputs ""\n')
|
||||||
|
+ tfile.write('\tputs "expect result: $msg"\n')
|
||||||
|
+ tfile.write('\tputs "expect exit code: $code"\n')
|
||||||
|
+ tfile.write('\tputs "expect spawn exit code: $rc"\n')
|
||||||
|
+ tfile.write('\texit $code\n')
|
||||||
|
+ tfile.write('}\n')
|
||||||
|
+ tfile.write('set timeout 60\n')
|
||||||
|
+ tfile.write('set prompt ".*\\[#\\$>\\] $"\n')
|
||||||
|
+ tfile.write(f'set password "{password}"\n')
|
||||||
|
+ tfile.write(f'set otpvalue "{otpvalue}"\n')
|
||||||
|
+ tfile.write(f'spawn ssh -o NumberOfPasswordPrompts=1 -o '
|
||||||
|
+ f'StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||||
|
+ f' -l {username} {hostname} {command}\n')
|
||||||
|
+ tfile.write('expect {\n')
|
||||||
|
+ tfile.write('"Enter first factor:*" {send -- "$password\r"}\n')
|
||||||
|
+ tfile.write('timeout {exitmsg "Unexpected output" 201}\n')
|
||||||
|
+ tfile.write('eof {exitmsg "Unexpected end of file" 202}\n')
|
||||||
|
+ tfile.write('}\n')
|
||||||
|
+ tfile.write('expect {\n')
|
||||||
|
+ tfile.write('"Enter second factor:*" {send -- "$otpvalue\r"}\n')
|
||||||
|
+ tfile.write('timeout {exitmsg "Unexpected output" 201}\n')
|
||||||
|
+ tfile.write('eof {exitmsg "Unexpected end of file" 202}\n')
|
||||||
|
+ tfile.write('}\n')
|
||||||
|
+ tfile.write('expect {\n')
|
||||||
|
+ tfile.write('"Authentication failure" '
|
||||||
|
+ '{exitmsg "Authentication failure" 1}\n')
|
||||||
|
+ tfile.write('eof {exitmsg "Authentication successful" 0}\n')
|
||||||
|
+ tfile.write('timeout {exitmsg "Unexpected output" 201}\n')
|
||||||
|
+ tfile.write('}\n')
|
||||||
|
+ tfile.write('expect {\n')
|
||||||
|
+ tfile.write('exitmsg "Unexpected code path" 203\n')
|
||||||
|
+ tfile.write('EOF\n')
|
||||||
|
+ tfile.write('}')
|
||||||
|
+ host.transport.put_file(temp_conf.name, '/tmp/ssh.exp')
|
||||||
|
+ tasks.clear_sssd_cache(host)
|
||||||
|
+ expect_cmd = 'expect -f /tmp/ssh.exp'
|
||||||
|
+ cmd = host.run_command(expect_cmd, raiseonerr=False)
|
||||||
|
+ return cmd
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def ssh_2f(hostname, username, answers_dict, port=22, unwanted_prompt=""):
|
||||||
|
"""
|
||||||
|
:param hostname: hostname
|
||||||
|
@@ -91,6 +151,7 @@ def ssh_2f(hostname, username, answers_dict, port=22, unwanted_prompt=""):
|
||||||
|
:param answers_dict: dictionary of options with prompt_message and value.
|
||||||
|
:param port: port for ssh
|
||||||
|
"""
|
||||||
|
+
|
||||||
|
# Handler for server questions
|
||||||
|
def answer_handler(title, instructions, prompt_list):
|
||||||
|
resp = []
|
||||||
|
@@ -131,8 +192,9 @@ class TestOTPToken(IntegrationTest):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def install(cls, mh):
|
||||||
|
- super(TestOTPToken, cls).install(mh)
|
||||||
|
master = cls.master
|
||||||
|
+ tasks.install_packages(master, ['expect'])
|
||||||
|
+ super(TestOTPToken, cls).install(mh)
|
||||||
|
|
||||||
|
tasks.kinit_admin(master)
|
||||||
|
# create service with OTP auth indicator
|
||||||
|
@@ -398,6 +460,114 @@ class TestOTPToken(IntegrationTest):
|
||||||
|
self.master.run_command(['semanage', 'login', '-D'])
|
||||||
|
sssd_conf_backup.restore()
|
||||||
|
|
||||||
|
+ def test_2fa_only_with_password(self):
|
||||||
|
+ """Test ssh with 2FA only with the password(first factor) when
|
||||||
|
+ user-auth-type is opt and password.
|
||||||
|
+
|
||||||
|
+ Test for : https://github.com/SSSD/sssd/pull/7500
|
||||||
|
+
|
||||||
|
+ Add the IPA user and user-auth-type set to opt and password.
|
||||||
|
+ Authenticate the user only with password, just press enter
|
||||||
|
+ at `Second factor`
|
||||||
|
+ """
|
||||||
|
+ master = self.master
|
||||||
|
+ USER3 = 'sshuser3'
|
||||||
|
+ sssd_conf_backup = tasks.FileBackup(master, paths.SSSD_CONF)
|
||||||
|
+ first_prompt = 'Enter first factor:'
|
||||||
|
+ second_prompt = 'Enter second factor:'
|
||||||
|
+ add_contents = textwrap.dedent('''
|
||||||
|
+ [prompting/2fa/sshd]
|
||||||
|
+ single_prompt = False
|
||||||
|
+ first_prompt = {0}
|
||||||
|
+ second_prompt = {1}
|
||||||
|
+ ''').format(first_prompt, second_prompt)
|
||||||
|
+ set_sssd_conf(master, add_contents)
|
||||||
|
+ tasks.create_active_user(master, USER3, PASSWORD)
|
||||||
|
+ tasks.kinit_admin(master)
|
||||||
|
+ master.run_command(['ipa', 'user-mod', USER3, '--user-auth-type=otp',
|
||||||
|
+ '--user-auth-type=password'])
|
||||||
|
+ try:
|
||||||
|
+ otpuid, totp = add_otptoken(master, USER3, otptype='totp')
|
||||||
|
+ master.run_command(['ipa', 'otptoken-show', otpuid])
|
||||||
|
+ totp.generate(int(time.time())).decode('ascii')
|
||||||
|
+ otpvalue = "\n"
|
||||||
|
+ tasks.clear_sssd_cache(self.master)
|
||||||
|
+ github_ticket = "https://github.com/SSSD/sssd/pull/7500"
|
||||||
|
+ sssd_version = tasks.get_sssd_version(master)
|
||||||
|
+ rhel_fail = (
|
||||||
|
+ osinfo.id == 'rhel'
|
||||||
|
+ and sssd_version < tasks.parse_version("2.9.5")
|
||||||
|
+ )
|
||||||
|
+ fedora_fail = (
|
||||||
|
+ osinfo.id == 'fedora'
|
||||||
|
+ and sssd_version == tasks.parse_version("2.9.5")
|
||||||
|
+ )
|
||||||
|
+ with xfail_context(rhel_fail or fedora_fail, reason=github_ticket):
|
||||||
|
+ result = ssh_2fa_with_cmd(master,
|
||||||
|
+ self.master.external_hostname,
|
||||||
|
+ USER3, PASSWORD, otpvalue=otpvalue,
|
||||||
|
+ command="klist")
|
||||||
|
+ print(result.stdout_text)
|
||||||
|
+ assert ('Authentication successful') in result.stdout_text
|
||||||
|
+ assert USER3 in result.stdout_text
|
||||||
|
+ assert (f'Default principal: '
|
||||||
|
+ f'{USER3}@{self.master.domain.realm}' in
|
||||||
|
+ result.stdout_text)
|
||||||
|
+ cmd = self.master.run_command(['semanage', 'login', '-l'])
|
||||||
|
+ assert USER3 in cmd.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ master.run_command(['ipa', 'user-del', USER3])
|
||||||
|
+ self.master.run_command(['semanage', 'login', '-D'])
|
||||||
|
+ sssd_conf_backup.restore()
|
||||||
|
+
|
||||||
|
+ def test_2fa_with_otp_password(self):
|
||||||
|
+ """Test ssh with 2FA only with password and otpvalue when
|
||||||
|
+ user-auth-type is opt and password.
|
||||||
|
+
|
||||||
|
+ Test for : https://github.com/SSSD/sssd/pull/7500
|
||||||
|
+
|
||||||
|
+ Add the IPA user and user-auth-type set to opt and password.
|
||||||
|
+ Authenticate the user only with password and otpvalue.
|
||||||
|
+ """
|
||||||
|
+ master = self.master
|
||||||
|
+ USER4 = 'sshuser4'
|
||||||
|
+ sssd_conf_backup = tasks.FileBackup(master, paths.SSSD_CONF)
|
||||||
|
+ first_prompt = 'Enter first factor:'
|
||||||
|
+ second_prompt = 'Enter second factor:'
|
||||||
|
+ add_contents = textwrap.dedent('''
|
||||||
|
+ [prompting/2fa/sshd]
|
||||||
|
+ single_prompt = False
|
||||||
|
+ first_prompt = {0}
|
||||||
|
+ second_prompt = {1}
|
||||||
|
+ ''').format(first_prompt, second_prompt)
|
||||||
|
+ set_sssd_conf(master, add_contents)
|
||||||
|
+ tasks.create_active_user(master, USER4, PASSWORD)
|
||||||
|
+ tasks.kinit_admin(master)
|
||||||
|
+
|
||||||
|
+ master.run_command(['ipa', 'user-mod', USER4, '--user-auth-type=otp',
|
||||||
|
+ '--user-auth-type=password'])
|
||||||
|
+ try:
|
||||||
|
+ otpuid, totp = add_otptoken(master, USER4, otptype='totp')
|
||||||
|
+ master.run_command(['ipa', 'otptoken-show', otpuid])
|
||||||
|
+ otpvalue = totp.generate(int(time.time())).decode('ascii')
|
||||||
|
+ tasks.clear_sssd_cache(self.master)
|
||||||
|
+ result = ssh_2fa_with_cmd(master,
|
||||||
|
+ self.master.external_hostname,
|
||||||
|
+ USER4, PASSWORD, otpvalue=otpvalue,
|
||||||
|
+ command="klist")
|
||||||
|
+ print(result.stdout_text)
|
||||||
|
+ cmd = self.master.run_command(['semanage', 'login', '-l'])
|
||||||
|
+ # check the output
|
||||||
|
+ assert ('Authentication successful') in result.stdout_text
|
||||||
|
+ assert USER4 in result.stdout_text
|
||||||
|
+ assert (f'Default principal: {USER4}@'
|
||||||
|
+ f'{self.master.domain.realm}' in result.stdout_text)
|
||||||
|
+ assert USER4 in cmd.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ master.run_command(['ipa', 'user-del', USER4])
|
||||||
|
+ self.master.run_command(['semanage', 'login', '-D'])
|
||||||
|
+ sssd_conf_backup.restore()
|
||||||
|
+
|
||||||
|
@pytest.fixture
|
||||||
|
def setup_otp_nsslapd(self):
|
||||||
|
check_services = self.master.run_command(
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
27
freeipa.spec
27
freeipa.spec
@ -70,7 +70,7 @@
|
|||||||
%global krb5_kdb_version 9.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
|
||||||
%global samba_version 4.20.0
|
%global samba_version 4.21.1
|
||||||
%global slapi_nis_version 0.70.0
|
%global slapi_nis_version 0.70.0
|
||||||
%global python_ldap_version 3.1.0-1
|
%global python_ldap_version 3.1.0-1
|
||||||
%if 0%{?rhel} < 9
|
%if 0%{?rhel} < 9
|
||||||
@ -88,7 +88,7 @@
|
|||||||
%global bind_version 9.11.20-6
|
%global bind_version 9.11.20-6
|
||||||
|
|
||||||
# support for passkey
|
# support for passkey
|
||||||
%global sssd_version 2.9.0
|
%global sssd_version 2.10.0
|
||||||
|
|
||||||
%else
|
%else
|
||||||
# Fedora
|
# Fedora
|
||||||
@ -248,6 +248,18 @@ Patch0009: 0009-ipa-migrate-fix-migration-issues-with-entries-using-.patch
|
|||||||
Patch0010: 0010-ipa-migrate-fix-alternate-entry-search-filter.patch
|
Patch0010: 0010-ipa-migrate-fix-alternate-entry-search-filter.patch
|
||||||
Patch0011: 0011-Custodia-in-fips-mode-add-nomac-or-nomacver-to-opens.patch
|
Patch0011: 0011-Custodia-in-fips-mode-add-nomac-or-nomacver-to-opens.patch
|
||||||
Patch0012: 0012-ipatests-make-TestDuplicates-teardowns-order-agnosti.patch
|
Patch0012: 0012-ipatests-make-TestDuplicates-teardowns-order-agnosti.patch
|
||||||
|
Patch0013: 0013-UnsafeIPAddress-pass-flag-0-to-IPNetwork.patch
|
||||||
|
Patch0014: 0014-ipatests-provide-a-ccache-to-rpcclient-deletetrustdo.patch
|
||||||
|
Patch0015: 0015-test_adtrust_install-add-use-krb5-ccache-to-smbclien.patch
|
||||||
|
Patch0016: 0016-Don-t-rely-on-removing-the-CA-to-uninstall-the-ACME-.patch
|
||||||
|
Patch0017: 0017-ipatests-Fixes-for-ipa-idrange-fix-testsuite.patch
|
||||||
|
Patch0018: 0018-spec-Use-nodejs22-on-RHEL-10-and-ELN.patch
|
||||||
|
Patch0019: 0019-Do-not-let-user-with-an-expired-OTP-token-to-log-in-.patch
|
||||||
|
Patch0020: 0020-ipatests-Activate-ssh-in-sssd.conf.patch
|
||||||
|
Patch0021: 0021-ipa-migrate-man-page-fix-typos-and-errors.patch
|
||||||
|
Patch0022: 0022-ipatests-Test-for-ipa-hbac-rule-duplication.patch
|
||||||
|
Patch0023: 0023-ipatests-refactor-password-file-handling-in-TestHSMI.patch
|
||||||
|
Patch0024: 0024-ipatests-2FA-test-cases.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
|
||||||
@ -300,10 +312,10 @@ BuildRequires: libpwquality-devel
|
|||||||
BuildRequires: libsss_idmap-devel
|
BuildRequires: libsss_idmap-devel
|
||||||
BuildRequires: libsss_certmap-devel
|
BuildRequires: libsss_certmap-devel
|
||||||
BuildRequires: libsss_nss_idmap-devel >= %{sssd_version}
|
BuildRequires: libsss_nss_idmap-devel >= %{sssd_version}
|
||||||
%if 0%{?fedora} >= 41
|
%if 0%{?fedora} >= 41 || 0%{?rhel} >= 10
|
||||||
# Do not use nodejs22 on fedora < 41, https://pagure.io/freeipa/issue/9643
|
# Do not use nodejs22 on fedora < 41, https://pagure.io/freeipa/issue/9643
|
||||||
BuildRequires: nodejs(abi)
|
BuildRequires: nodejs(abi)
|
||||||
%elif 0%{?fedora} >= 39 || 0%{?rhel} >= 10
|
%elif 0%{?fedora} >= 39
|
||||||
# Do not use nodejs20 on fedora < 39, https://pagure.io/freeipa/issue/9374
|
# Do not use nodejs20 on fedora < 39, https://pagure.io/freeipa/issue/9374
|
||||||
BuildRequires: nodejs(abi) < 127
|
BuildRequires: nodejs(abi) < 127
|
||||||
%else
|
%else
|
||||||
@ -1870,6 +1882,13 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Oct 21 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-4
|
||||||
|
- Related: RHEL-59777 Rebase Samba to the latest 4.21.x release
|
||||||
|
- Resolves: RHEL-59659 ipa dns-zone --allow-query '!198.18.2.0/24;any;' fails with Unrecognized IPAddress flags
|
||||||
|
- Resolves: RHEL-61636 Uninstall ACME separately during PKI uninstallation
|
||||||
|
- Resolves: RHEL-61723 Include latest fixes in python3-ipatests packages
|
||||||
|
- Resolves: RHEL-63325 Last expired OTP token would be considered as still assigned to the user
|
||||||
|
|
||||||
* Tue Sep 24 2024 Rafael Guteres Jeffman <rjeffman@redhat.com> - 4.12.2-3
|
* Tue Sep 24 2024 Rafael Guteres Jeffman <rjeffman@redhat.com> - 4.12.2-3
|
||||||
- Resolves: RHEL-33818 Remove python3-ipalib's dependency on python3-netifaces
|
- Resolves: RHEL-33818 Remove python3-ipalib's dependency on python3-netifaces
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user