import Oracle_OSS ipa-4.12.2-22.0.1.el9_7.4
This commit is contained in:
parent
68ce206361
commit
e2d33589aa
37
SOURCES/0133-ipatests-remove-xfail-for-PKI-11.7.patch
Normal file
37
SOURCES/0133-ipatests-remove-xfail-for-PKI-11.7.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From b923355ff04dd88b1530d0bb2e032280afc5d315 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Tue, 26 Aug 2025 09:00:48 +0200
|
||||
Subject: [PATCH] ipatests: remove xfail for PKI 11.7
|
||||
|
||||
The test test_ca_show_error_handling is green with PKI 11.7
|
||||
because the PKI regression has been fixed.
|
||||
Update the xfail condition to 11.5 <= version < 11.7.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9606
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_cert.py | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py
|
||||
index 05b20b910b249af24039a497538f96dad07162aa..84adf2ceafe013e6cfc973fb2cb650c40f36971d 100644
|
||||
--- a/ipatests/test_integration/test_cert.py
|
||||
+++ b/ipatests/test_integration/test_cert.py
|
||||
@@ -558,8 +558,10 @@ class TestCAShowErrorHandling(IntegrationTest):
|
||||
)
|
||||
error_msg = 'ipa: ERROR: The certificate for ' \
|
||||
'{} is not available on this server.'.format(lwca)
|
||||
- bad_version = (tasks.get_pki_version(self.master)
|
||||
- >= tasks.parse_version('11.5.0'))
|
||||
+ pki_version = tasks.get_pki_version(self.master)
|
||||
+ # The regression was introduced in 11.5 and fixed in 11.7
|
||||
+ bad_version = (tasks.parse_version('11.5.0') <= pki_version
|
||||
+ < tasks.parse_version('11.7.0'))
|
||||
with xfail_context(bad_version,
|
||||
reason="https://pagure.io/freeipa/issue/9606"):
|
||||
assert error_msg in result.stderr_text
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
From 0a5509665485baa5190f2e3c6fdd765c966a4405 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Mon, 15 Sep 2025 09:41:31 +0300
|
||||
Subject: [PATCH] GetEntryFromLDIF: handle DNs case-insensitive
|
||||
|
||||
LDAP expects case-insensitive DNs, so modify LDIF parser to
|
||||
compare DNs as case-insensitive strings and use case-preserving but
|
||||
case-insensitive dictionary.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9854
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
---
|
||||
ipaserver/install/upgradeinstance.py | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/install/upgradeinstance.py b/ipaserver/install/upgradeinstance.py
|
||||
index b84f50b059c5d9b19719495ec10f06f67e4a7c8a..ecd0a08ea1ef18bf1225ef339ed0e17a9666e4f3 100644
|
||||
--- a/ipaserver/install/upgradeinstance.py
|
||||
+++ b/ipaserver/install/upgradeinstance.py
|
||||
@@ -29,7 +29,7 @@ import traceback
|
||||
from ipalib import api
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform import services
|
||||
-from ipapython import ipaldap
|
||||
+from ipapython import ipaldap, ipautil
|
||||
|
||||
from ipaserver.install import installutils
|
||||
from ipaserver.install import schemaupdate
|
||||
@@ -57,8 +57,8 @@ class GetEntryFromLDIF(ldif.LDIFParser):
|
||||
returned if list is empty.
|
||||
"""
|
||||
ldif.LDIFParser.__init__(self, input_file)
|
||||
- self.entries_dn = entries_dn
|
||||
- self.results = {}
|
||||
+ self.entries_dn = [e.lower() for e in entries_dn]
|
||||
+ self.results = ipautil.CIDict()
|
||||
|
||||
def get_results(self):
|
||||
"""
|
||||
@@ -67,7 +67,7 @@ class GetEntryFromLDIF(ldif.LDIFParser):
|
||||
return self.results
|
||||
|
||||
def handle(self, dn, entry):
|
||||
- if self.entries_dn and dn not in self.entries_dn:
|
||||
+ if self.entries_dn and dn.lower() not in self.entries_dn:
|
||||
return
|
||||
|
||||
self.results[dn] = entry
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From a1f2fef8c9f1c61392faf3e96a9e89b124221ba9 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Tue, 30 Sep 2025 09:46:09 +0200
|
||||
Subject: [PATCH] Tests xmlrpc: mark xfail tests requesting cert with subca
|
||||
|
||||
With PKI 11.7, requesting a cert with a subca fails.
|
||||
Mark the tests as xfail for now.
|
||||
|
||||
Related: RHEL-108293
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
---
|
||||
ipatests/test_xmlrpc/test_caacl_profile_enforcement.py | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
|
||||
index 98653904f91d6b2d670f04f32de9849250c1cb25..df20c55c5a62394eb085ea0bcca04a33e03a1fe9 100644
|
||||
--- a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
|
||||
+++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
|
||||
@@ -306,6 +306,7 @@ class TestCertSignMIMEwithSubCA(XMLRPC_test):
|
||||
def test_add_group_to_acl(self, smime_group, smime_acl):
|
||||
smime_acl.add_user(group=smime_group)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_sign_smime_csr(self, smime_profile, smime_user, smime_signing_ca):
|
||||
csr = generate_user_csr(smime_user)
|
||||
with change_principal(smime_user, SMIME_USER_PW):
|
||||
@@ -313,6 +314,7 @@ class TestCertSignMIMEwithSubCA(XMLRPC_test):
|
||||
profile_id=smime_profile.name,
|
||||
cacn=smime_signing_ca.name)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_sign_smime_csr_full_principal(
|
||||
self, smime_profile, smime_user, smime_signing_ca):
|
||||
csr = generate_user_csr(smime_user)
|
||||
@@ -322,6 +324,7 @@ class TestCertSignMIMEwithSubCA(XMLRPC_test):
|
||||
profile_id=smime_profile.name,
|
||||
cacn=smime_signing_ca.name)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_verify_cert_issuer_dn_is_subca(
|
||||
self, smime_profile, smime_user, smime_signing_ca):
|
||||
csr = generate_user_csr(smime_user)
|
||||
@@ -541,6 +544,7 @@ class TestPrincipalAliasForSubjectAltNameDnsName(SubjectAltNameOneServiceBase):
|
||||
santest_service_host_1.name,
|
||||
santest_service_host_2.name)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_request_cert_with_SAN_matching_principal_alias(
|
||||
self, santest_subca, santest_host_1,
|
||||
santest_service_host_1, santest_csr):
|
||||
@@ -604,6 +608,7 @@ class TestSignServiceCertManagedByMultipleHosts(CAACLEnforcementOnCertBase):
|
||||
santest_subca_acl.add_host(santest_host_2.name)
|
||||
santest_subca_acl.add_service(santest_service_host_2.name)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_request_cert_with_additional_host(
|
||||
self, santest_subca, santest_host_1, santest_host_2,
|
||||
santest_service_host_1, santest_csr):
|
||||
@@ -696,6 +701,7 @@ class TestManagedByACIOnCertRequest(CAACLEnforcementOnCertBase):
|
||||
cacn=santest_subca.name
|
||||
)
|
||||
|
||||
+ @pytest.mark.xfail(reason='pki RHEL-108293')
|
||||
def test_issuing_service_cert_by_related_host(self,
|
||||
santest_subca,
|
||||
santest_host_1,
|
||||
--
|
||||
2.52.0
|
||||
|
||||
3762
SOURCES/0136-Manual-backport-of-8002.patch
Normal file
3762
SOURCES/0136-Manual-backport-of-8002.patch
Normal file
File diff suppressed because it is too large
Load Diff
1279
SOURCES/0137-ipatests-Add-DNS-functional-integration-tests.patch
Normal file
1279
SOURCES/0137-ipatests-Add-DNS-functional-integration-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,145 @@
|
||||
From 55b01956676add56e1660b23317107f3010fdf5d Mon Sep 17 00:00:00 2001
|
||||
From: Anuja More <amore@redhat.com>
|
||||
Date: Tue, 6 Jan 2026 18:30:06 +0530
|
||||
Subject: [PATCH] ipatests: add Random Password based replica promotion
|
||||
coverage
|
||||
|
||||
Added missing test coverage for :
|
||||
- Installing IPA replica server using random password.
|
||||
- Installing IPA replica server using random password installed client
|
||||
|
||||
- Automated with Cursor+Claude
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9922
|
||||
|
||||
Signed-off-by: Anuja More <amore@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipatests/pytest_ipa/integration/tasks.py | 15 ++++
|
||||
.../test_replica_promotion.py | 87 +++++++++++++++++++
|
||||
2 files changed, 102 insertions(+)
|
||||
|
||||
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
|
||||
index 561e021..c7b4f97 100755
|
||||
--- a/ipatests/pytest_ipa/integration/tasks.py
|
||||
+++ b/ipatests/pytest_ipa/integration/tasks.py
|
||||
@@ -3260,3 +3260,18 @@ def check_journal_does_not_contain_secret(host, cmd):
|
||||
result = host.run_command(journalctl_cmd, raiseonerr=False)
|
||||
assert (host.config.admin_password not in result.stdout_text)
|
||||
assert (host.config.dirman_password not in result.stdout_text)
|
||||
+
|
||||
+
|
||||
+def host_add_with_random_password(host, new_host):
|
||||
+ """
|
||||
+ Add a new host with a random password and return the generated password.
|
||||
+ """
|
||||
+ kinit_admin(host)
|
||||
+ cmd = host.run_command(
|
||||
+ ['ipa', 'host-add', new_host.hostname, '--random']
|
||||
+ )
|
||||
+ result = re.search("Random password: (?P<password>.*$)",
|
||||
+ cmd.stdout_text,
|
||||
+ re.MULTILINE)
|
||||
+ randpasswd1 = result.group('password')
|
||||
+ return randpasswd1
|
||||
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
|
||||
index 3c67833..7859b56 100644
|
||||
--- a/ipatests/test_integration/test_replica_promotion.py
|
||||
+++ b/ipatests/test_integration/test_replica_promotion.py
|
||||
@@ -1367,3 +1367,90 @@ class TestReplicaConn(IntegrationTest):
|
||||
logs = self.replica.get_file_contents(paths.IPAREPLICA_CONNCHECK_LOG)
|
||||
error = "not allowed to perform server connection check"
|
||||
assert error.encode() not in logs
|
||||
+
|
||||
+
|
||||
+class TestReplicaPromotionRandomPassword(IntegrationTest):
|
||||
+ """
|
||||
+ Test installation of a replica using Random Password
|
||||
+ (one step install and two-steps installation
|
||||
+ with client and promotion).
|
||||
+ """
|
||||
+ num_replicas = 1
|
||||
+
|
||||
+ @classmethod
|
||||
+ def install(cls, mh):
|
||||
+ tasks.install_master(cls.master, setup_dns=True)
|
||||
+ cls.replicas[0].resolver.backup()
|
||||
+ nameservers = cls.master.ip
|
||||
+ cls.replicas[0].resolver.setup_resolver(
|
||||
+ nameservers, cls.master.domain.name
|
||||
+ )
|
||||
+
|
||||
+ @replicas_cleanup
|
||||
+ def test_replica_random_password_install(self):
|
||||
+ """
|
||||
+ Installing IPA replica server using Random Password.
|
||||
+
|
||||
+ Steps:
|
||||
+ 1. Ensure replica host/server entries are clean and add DNS A record.
|
||||
+ 2. Add the replica host with a random password and add it to
|
||||
+ the ipaservers hostgroup.
|
||||
+ 3. Install the replica using random password.
|
||||
+ """
|
||||
+ replica = self.replicas[0]
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.add_a_record(self.master, replica)
|
||||
+ randpasswd = tasks.host_add_with_random_password(self.master,
|
||||
+ replica)
|
||||
+ self.master.run_command([
|
||||
+ 'ipa', 'hostgroup-add-member', '--hosts',
|
||||
+ replica.hostname, 'ipaservers'
|
||||
+ ])
|
||||
+ replica.run_command(
|
||||
+ ['ipa-replica-install', '-p', randpasswd, '-U']
|
||||
+ )
|
||||
+
|
||||
+ @replicas_cleanup
|
||||
+ def test_replica_two_step_install(self):
|
||||
+ """
|
||||
+ Installing IPA replica server using Random Password installed client
|
||||
+
|
||||
+ Steps:
|
||||
+ 1. Ensure replica host/server entries are clean and add DNS A record.
|
||||
+ 2. Add the replica host with a random password and add it to
|
||||
+ the ipaservers hostgroup.
|
||||
+ 3. Install the IPA client using the Random Password.
|
||||
+ 4. Promote the client to a replica.
|
||||
+ 5. Install CA on the replica and verify the server role.
|
||||
+ """
|
||||
+ replica = self.replicas[0]
|
||||
+ replica.resolver.backup()
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.add_a_record(self.master, replica)
|
||||
+ randpasswd = tasks.host_add_with_random_password(self.master,
|
||||
+ replica)
|
||||
+ self.master.run_command([
|
||||
+ 'ipa', 'hostgroup-add-member', '--hosts',
|
||||
+ replica.hostname, 'ipaservers'
|
||||
+ ])
|
||||
+ replica.resolver.setup_resolver(
|
||||
+ self.master.ip, self.master.domain.name
|
||||
+ )
|
||||
+ replica.run_command(
|
||||
+ ['ipa-client-install', '-w', randpasswd, '-U']
|
||||
+ )
|
||||
+ Firewall(replica).enable_services(["freeipa-ldap",
|
||||
+ "freeipa-ldaps"])
|
||||
+ replica.run_command(['ipa-replica-install', '-U'])
|
||||
+ tasks.kinit_admin(replica)
|
||||
+ replica.run_command([
|
||||
+ 'ipa-ca-install', '-p',
|
||||
+ self.master.config.admin_password,
|
||||
+ '-w', self.master.config.admin_password
|
||||
+ ])
|
||||
+ result = self.replicas[0].run_command([
|
||||
+ 'ipa', 'server-role-find',
|
||||
+ '--server', self.replicas[0].hostname,
|
||||
+ '--role', 'CA server'
|
||||
+ ])
|
||||
+ assert 'Role status: enabled' in result.stdout_text
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,696 @@
|
||||
From 05198e8fcf3410d4f8a97e8c6282cbabef193980 Mon Sep 17 00:00:00 2001
|
||||
From: PRANAV THUBE <pthube@redhat.com>
|
||||
Date: Tue, 27 Jan 2026 18:45:53 +0530
|
||||
Subject: [PATCH] ipatests: Add integration tests for ipa-join command
|
||||
|
||||
Add tests for ipa-join command covering hostname, server, keytab,
|
||||
and bindpw options with positive and negative scenarios.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9930
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipatests/pytest_ipa/integration/tasks.py | 49 ++
|
||||
ipatests/test_integration/test_ipa_join.py | 614 +++++++++++++++++++++
|
||||
2 files changed, 663 insertions(+)
|
||||
create mode 100644 ipatests/test_integration/test_ipa_join.py
|
||||
|
||||
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
|
||||
index ff2ea9792d04ebd2e6bd7bb3b51d97f35cb3fbfb..47330d6d93401485e4eb7b2501cf5ea37498d719 100755
|
||||
--- a/ipatests/pytest_ipa/integration/tasks.py
|
||||
+++ b/ipatests/pytest_ipa/integration/tasks.py
|
||||
@@ -3355,3 +3355,52 @@ def host_add_with_random_password(host, new_host):
|
||||
re.MULTILINE)
|
||||
randpasswd1 = result.group('password')
|
||||
return randpasswd1
|
||||
+
|
||||
+
|
||||
+def ipa_join(host, *extra_args, raiseonerr=True):
|
||||
+ """Run ipa-join command.
|
||||
+
|
||||
+ :param host: The host to run command on
|
||||
+ :param extra_args: Additional arguments (variable positional args)
|
||||
+ e.g., '--hostname=client.example.com',
|
||||
+ '--server=master.example.com',
|
||||
+ '--keytab=/tmp/test.keytab',
|
||||
+ '--bindpw=password',
|
||||
+ '-u' (for unenroll)
|
||||
+ :param raiseonerr: If True, raise exception on command failure
|
||||
+ :return: Command result object
|
||||
+ """
|
||||
+ command = ['ipa-join']
|
||||
+ command.extend(extra_args)
|
||||
+ return host.run_command(command, raiseonerr=raiseonerr)
|
||||
+
|
||||
+
|
||||
+def host_del(host, hostname, *extra_args, raiseonerr=True):
|
||||
+ """Delete a host from IPA.
|
||||
+
|
||||
+ :param host: The IPA host to run command on
|
||||
+ :param hostname: Hostname to delete
|
||||
+ :param extra_args: Additional arguments (variable positional args)
|
||||
+ :param raiseonerr: If True, raise exception on command failure
|
||||
+ :return: Command result object
|
||||
+ """
|
||||
+ command = ['ipa', 'host-del', hostname]
|
||||
+ command.extend(extra_args)
|
||||
+ return host.run_command(command, raiseonerr=raiseonerr)
|
||||
+
|
||||
+
|
||||
+def host_add(host, hostname, *extra_args, password=None, raiseonerr=True):
|
||||
+ """Add a host to IPA.
|
||||
+
|
||||
+ :param host: The IPA host to run command on
|
||||
+ :param hostname: Hostname to add
|
||||
+ :param extra_args: Additional arguments (variable positional args)
|
||||
+ :param password: OTP/enrollment password for the host (optional)
|
||||
+ :param raiseonerr: If True, raise exception on command failure
|
||||
+ :return: Command result object
|
||||
+ """
|
||||
+ command = ['ipa', 'host-add', hostname]
|
||||
+ if password:
|
||||
+ command.append(f'--password={password}')
|
||||
+ command.extend(extra_args)
|
||||
+ return host.run_command(command, raiseonerr=raiseonerr)
|
||||
diff --git a/ipatests/test_integration/test_ipa_join.py b/ipatests/test_integration/test_ipa_join.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1f7592aec8db1bfd048ec574d06d25bc24373499
|
||||
--- /dev/null
|
||||
+++ b/ipatests/test_integration/test_ipa_join.py
|
||||
@@ -0,0 +1,614 @@
|
||||
+#
|
||||
+# Copyright (C) 2026 FreeIPA Contributors see COPYING for license
|
||||
+#
|
||||
+
|
||||
+"""
|
||||
+Tests for ipa-join command functionality.
|
||||
+
|
||||
+This module tests various combinations of ipa-join options including:
|
||||
+- hostname
|
||||
+- server
|
||||
+- keytab
|
||||
+- bindpw (OTP/enrollment password)
|
||||
+- unenroll
|
||||
+
|
||||
+Ported from the shell-based test suite (t.ipajoin.sh and t.ipaotp.sh).
|
||||
+"""
|
||||
+
|
||||
+from __future__ import absolute_import
|
||||
+
|
||||
+from ipapython.ipautil import ipa_generate_password
|
||||
+from ipatests.pytest_ipa.integration import tasks
|
||||
+from ipatests.test_integration.base import IntegrationTest
|
||||
+
|
||||
+
|
||||
+# Constants
|
||||
+OTP = ipa_generate_password(special=None)
|
||||
+INVALID_PASSWORD = "WrongPassword"
|
||||
+INVALID_SERVER = "No.Such.IPA.Server.Domain.com"
|
||||
+TEST_KEYTAB = "/tmp/ipajoin.test.keytab"
|
||||
+
|
||||
+# Error messages
|
||||
+ERR_SASL_BIND_FAILED = "SASL Bind failed"
|
||||
+ERR_UNAUTHENTICATED_BIND = "Unauthenticated binds are not allowed"
|
||||
+ERR_COULD_NOT_RESOLVE = "JSON-RPC call failed: Could not resolve hostname"
|
||||
+ERR_UNABLE_ROOT_DN = "Unable to determine root DN"
|
||||
+ERR_NO_CONFIG = "Unable to determine IPA server from /etc/ipa/default.conf"
|
||||
+ERR_PREAUTH_FAILED = "Generic preauthentication failure"
|
||||
+
|
||||
+# Exit codes
|
||||
+EXIT_SUCCESS = 0
|
||||
+EXIT_GENERAL_ERROR = 1
|
||||
+EXIT_PREAUTH_ERROR = 19
|
||||
+EXIT_ROOT_DN_ERROR = 14
|
||||
+EXIT_SASL_BIND_FAILED = 15
|
||||
+EXIT_RESOLVE_ERROR = 17
|
||||
+
|
||||
+
|
||||
+class TestIPAJoin(IntegrationTest):
|
||||
+ """Tests for ipa-join command functionality.
|
||||
+
|
||||
+ This test class covers various ipa-join scenarios including:
|
||||
+ - Basic enrollment and unenrollment
|
||||
+ - Using hostname, server, keytab, and bindpw options
|
||||
+ - Positive and negative test cases
|
||||
+ - OTP (one-time password) enrollment tests
|
||||
+
|
||||
+ Tests require one master and one client.
|
||||
+ """
|
||||
+
|
||||
+ topology = 'line'
|
||||
+ num_clients = 1
|
||||
+
|
||||
+ @classmethod
|
||||
+ def install(cls, mh):
|
||||
+ tasks.install_master(cls.master, setup_dns=True)
|
||||
+ tasks.install_client(cls.master, cls.clients[0])
|
||||
+
|
||||
+ @classmethod
|
||||
+ def uninstall(cls, mh):
|
||||
+ # Cleanup test keytab if exists
|
||||
+ cls.clients[0].run_command(
|
||||
+ ['rm', '-f', TEST_KEYTAB],
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+ tasks.uninstall_client(cls.clients[0])
|
||||
+ tasks.uninstall_master(cls.master)
|
||||
+
|
||||
+ # =========================================================================
|
||||
+ # ipa-join basic tests
|
||||
+ # =========================================================================
|
||||
+
|
||||
+ def test_unenroll(self):
|
||||
+ """Test ipa-join --unenroll option."""
|
||||
+ result = tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+
|
||||
+ def test_unenroll_already_unenrolled(self):
|
||||
+ """Test ipa-join -u on an already unenrolled client.
|
||||
+
|
||||
+ When trying to unenroll a client that is not enrolled,
|
||||
+ ipa-join should fail with a preauthentication error.
|
||||
+ """
|
||||
+ # Client is already unenrolled from previous test
|
||||
+ result = tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ assert result.returncode == EXIT_PREAUTH_ERROR
|
||||
+ assert ERR_PREAUTH_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_with_kerberos(self):
|
||||
+ """Test ipa-join with --hostname using Kerberos auth."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_bindpw_invalid(self):
|
||||
+ """Test ipa-join with hostname and invalid bindpw."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname and valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_keytab_with_kerberos(self):
|
||||
+ """Test ipa-join with hostname and keytab using Kerberos."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_keytab_bindpw_invalid(self):
|
||||
+ """Test ipa-join with hostname, keytab, and invalid bindpw."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_keytab_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname, keytab, and valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_invalid_with_kerberos(self):
|
||||
+ """Test ipa-join with hostname and invalid server."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_RESOLVE_ERROR
|
||||
+ assert ERR_COULD_NOT_RESOLVE in result.stderr_text
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_invalid_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname, invalid server, and valid OTP."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ f'--bindpw={OTP}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_ROOT_DN_ERROR
|
||||
+ assert ERR_UNABLE_ROOT_DN in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_server_invalid_keytab_with_kerberos(self):
|
||||
+ """Test ipa-join with hostname, invalid server, keytab."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_RESOLVE_ERROR
|
||||
+ assert ERR_COULD_NOT_RESOLVE in result.stderr_text
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_invalid_keytab_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname, invalid server, keytab, valid OTP."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={OTP}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_ROOT_DN_ERROR
|
||||
+ assert ERR_UNABLE_ROOT_DN in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_server_valid_with_kerberos(self):
|
||||
+ """Test ipa-join with hostname and valid server."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_valid_bindpw_invalid(self):
|
||||
+ """Test ipa-join with hostname, valid server, invalid bindpw."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_server_valid_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname, valid server, valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_valid_keytab_with_kerberos(self):
|
||||
+ """Test ipa-join with hostname, valid server, keytab."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_hostname_server_valid_keytab_bindpw_invalid(self):
|
||||
+ """Test ipa-join with hostname, valid server, keytab, bad bindpw."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ # Note: Original test had "SASL Bind Failed" (capital F), checking both
|
||||
+ assert "SASL Bind" in result.stderr_text
|
||||
+ assert "ailed" in result.stderr_text
|
||||
+
|
||||
+ def test_hostname_server_valid_keytab_bindpw_valid(self):
|
||||
+ """Test ipa-join with hostname, valid server, keytab, valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_keytab_only_with_kerberos(self):
|
||||
+ """Test ipa-join with keytab only using Kerberos."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--keytab={TEST_KEYTAB}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_keytab_bindpw_invalid(self):
|
||||
+ """Test ipa-join with keytab and invalid bindpw."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_keytab_bindpw_valid(self):
|
||||
+ """Test ipa-join with keytab and valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_server_invalid_only_with_kerberos(self):
|
||||
+ """Test ipa-join with invalid server only."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_RESOLVE_ERROR
|
||||
+ assert ERR_COULD_NOT_RESOLVE in result.stderr_text
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+
|
||||
+ def test_server_invalid_bindpw_valid(self):
|
||||
+ """Test ipa-join with invalid server and valid OTP."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ f'--bindpw={OTP}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_ROOT_DN_ERROR
|
||||
+ assert ERR_UNABLE_ROOT_DN in result.stderr_text
|
||||
+
|
||||
+ def test_server_invalid_keytab_with_kerberos(self):
|
||||
+ """Test ipa-join with invalid server and keytab."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={INVALID_SERVER}',
|
||||
+ f'--keytab={TEST_KEYTAB}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_RESOLVE_ERROR
|
||||
+ assert ERR_COULD_NOT_RESOLVE in result.stderr_text
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+
|
||||
+ def test_server_valid_only_with_kerberos(self):
|
||||
+ """Test ipa-join with valid server only."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={self.master.hostname}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_server_valid_bindpw_invalid(self):
|
||||
+ """Test ipa-join with valid server and invalid bindpw."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_server_valid_bindpw_valid(self):
|
||||
+ """Test ipa-join with valid server and valid OTP."""
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_server_valid_keytab_with_kerberos(self):
|
||||
+ """Test ipa-join with valid server and keytab."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname)
|
||||
+
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--server={self.master.hostname}',
|
||||
+ f'--keytab={TEST_KEYTAB}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_bindpw_invalid_only(self):
|
||||
+ """Test ipa-join with invalid bindpw only."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ # =========================================================================
|
||||
+ # OTP (One-Time Password) tests
|
||||
+ # =========================================================================
|
||||
+
|
||||
+ def test_otp_empty_password(self):
|
||||
+ """Test ipa-join with empty OTP password (ipa_otp_1001)."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ '--bindpw=',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_ROOT_DN_ERROR
|
||||
+ assert ERR_UNAUTHENTICATED_BIND in result.stderr_text
|
||||
+
|
||||
+ def test_otp_wrong_password(self):
|
||||
+ """Test ipa-join with wrong OTP password (ipa_otp_1002)."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={INVALID_PASSWORD}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
+
|
||||
+ def test_otp_valid_password(self):
|
||||
+ """Test ipa-join with valid OTP password (ipa_otp_1003)."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+ try:
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ def test_otp_reuse_fails(self):
|
||||
+ """Test that reusing the same OTP fails (ipa_otp_1004)."""
|
||||
+ tasks.kinit_admin(self.clients[0])
|
||||
+ tasks.kinit_admin(self.master)
|
||||
+ tasks.host_del(self.master, self.clients[0].hostname, raiseonerr=False)
|
||||
+ tasks.host_add(self.master, self.clients[0].hostname, password=OTP)
|
||||
+ try:
|
||||
+ # First use should succeed
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={OTP}'
|
||||
+ )
|
||||
+ assert result.returncode == EXIT_SUCCESS
|
||||
+ finally:
|
||||
+ self.clients[0].run_command(['kdestroy', '-A'], raiseonerr=False)
|
||||
+ tasks.ipa_join(self.clients[0], '-u', raiseonerr=False)
|
||||
+
|
||||
+ # Second use of same OTP should fail
|
||||
+ result = tasks.ipa_join(
|
||||
+ self.clients[0],
|
||||
+ f'--hostname={self.clients[0].hostname}',
|
||||
+ f'--bindpw={OTP}',
|
||||
+ raiseonerr=False
|
||||
+ )
|
||||
+
|
||||
+ assert result.returncode == EXIT_SASL_BIND_FAILED
|
||||
+ assert ERR_SASL_BIND_FAILED in result.stderr_text
|
||||
--
|
||||
2.52.0
|
||||
|
||||
1627
SOURCES/0140-ipatests-Add-DNS-bugzilla-integration-tests.patch
Normal file
1627
SOURCES/0140-ipatests-Add-DNS-bugzilla-integration-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
1122
SOURCES/0141-ipatests-Add-DNS-integration-tests.patch
Normal file
1122
SOURCES/0141-ipatests-Add-DNS-integration-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
38
SOURCES/0142-Allow-32bit-gid.patch
Normal file
38
SOURCES/0142-Allow-32bit-gid.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From a5ff0a2261e2df7b2157e6509cdbecf65033e578 Mon Sep 17 00:00:00 2001
|
||||
From: David Hanina <dhanina@redhat.com>
|
||||
Date: Tue, 10 Mar 2026 10:26:33 +0100
|
||||
Subject: [PATCH] Allow 32bit gid
|
||||
|
||||
We should allow 32bit groups, by setting maxvalue we allow that.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9953
|
||||
Signed-off-by: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
|
||||
---
|
||||
ipaserver/plugins/group.py | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/ipaserver/plugins/group.py b/ipaserver/plugins/group.py
|
||||
index f05a39f69ec3eb3257909bd61b42a9a21212c14d..308e5458c1d00be34753f42675367a7307331514 100644
|
||||
--- a/ipaserver/plugins/group.py
|
||||
+++ b/ipaserver/plugins/group.py
|
||||
@@ -26,6 +26,7 @@ import re
|
||||
from ipalib import api
|
||||
from ipalib import Int, Str, Flag
|
||||
from ipalib.constants import PATTERN_GROUPUSER_NAME, ERRMSG_GROUPUSER_NAME
|
||||
+from ipalib.parameters import MAX_UINT32
|
||||
from ipalib.plugable import Registry
|
||||
from .baseldap import (
|
||||
add_external_post_callback,
|
||||
@@ -354,6 +355,7 @@ class group(LDAPObject):
|
||||
label=_('GID'),
|
||||
doc=_('GID (use this option to set it manually)'),
|
||||
minvalue=1,
|
||||
+ maxvalue=MAX_UINT32,
|
||||
),
|
||||
ipaexternalmember_param,
|
||||
)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
From 7de7c0e2ed1afb2887bc7adeb7363109cbc5f3f9 Mon Sep 17 00:00:00 2001
|
||||
From: PRANAV THUBE <pthube@redhat.com>
|
||||
Date: Wed, 11 Mar 2026 20:13:31 +0530
|
||||
Subject: [PATCH] ipatests: Fix test_allow_query_transfer_ipv6 when IPv6 is
|
||||
disabled
|
||||
|
||||
The test was failing in environments where IPv6 is disabled at the
|
||||
kernel level because it attempted to add a temporary IPv6 address
|
||||
without first checking if IPv6 is enabled on the interface.
|
||||
|
||||
This fix restructures the test to:
|
||||
- Check if IPv6 is disabled via sysctl before attempting IPv6 setup
|
||||
- Always run IPv4 allow-query and allow-transfer tests
|
||||
- Only run IPv6-related tests when IPv6 is available
|
||||
|
||||
This ensures the test passes in IPv4-only environments while still
|
||||
providing full coverage when IPv6 is enabled.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9944
|
||||
Signed-off-by: Pranav Thube pthube@redhat.com
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_dns.py | 62 ++++++---------------------
|
||||
1 file changed, 14 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_dns.py b/ipatests/test_integration/test_dns.py
|
||||
index 4b9ab1fe8d7b8884760ed637cb2fcc5d5a060df0..947cff5c02ea2662cc2de88860cfa294e396792d 100644
|
||||
--- a/ipatests/test_integration/test_dns.py
|
||||
+++ b/ipatests/test_integration/test_dns.py
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
+import pytest
|
||||
import time
|
||||
import dns.exception
|
||||
import dns.resolver
|
||||
@@ -1714,13 +1715,12 @@ class TestDNSMisc(IntegrationTest):
|
||||
tasks.del_dns_zone(self.master, zone, raiseonerr=False)
|
||||
|
||||
def test_allow_query_transfer_ipv6(self):
|
||||
- """Test allow-query and allow-transfer with IPv4 and IPv6.
|
||||
+ """Test allow-query and allow-transfer with IPv6.
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=701677
|
||||
"""
|
||||
tasks.kinit_admin(self.master)
|
||||
- zone = "example.com"
|
||||
- ipv4 = self.master.ip
|
||||
+ zone = "example6.com"
|
||||
ipv6_added = False
|
||||
temp_ipv6 = '2001:0db8:0:f101::1/64'
|
||||
|
||||
@@ -1732,6 +1732,13 @@ class TestDNSMisc(IntegrationTest):
|
||||
])
|
||||
eth = result.stdout_text.strip()
|
||||
|
||||
+ # Check if IPv6 is disabled on the interface
|
||||
+ result = self.master.run_command([
|
||||
+ 'sysctl', '-n', f'net.ipv6.conf.{eth}.disable_ipv6'
|
||||
+ ])
|
||||
+ if result.stdout_text.strip() == '1':
|
||||
+ pytest.skip(f"IPv6 is disabled on interface {eth}")
|
||||
+
|
||||
# Add temporary IPv6 if none exists
|
||||
result = self.master.run_command(
|
||||
['ip', 'addr', 'show', 'scope', 'global'], raiseonerr=False
|
||||
@@ -1754,62 +1761,21 @@ class TestDNSMisc(IntegrationTest):
|
||||
tasks.add_dns_zone(self.master, zone, skip_overlap_check=True,
|
||||
admin_email=self.EMAIL)
|
||||
|
||||
- # Test allow-query: IPv4 allowed, IPv6 denied
|
||||
- tasks.mod_dns_zone(
|
||||
- self.master, zone,
|
||||
- f"--allow-query={ipv4};!{ipv6};"
|
||||
- )
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv4}', '-t', 'soa', zone], raiseonerr=False
|
||||
- )
|
||||
- assert 'ANSWER SECTION' in result.stdout_text
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv6}', '-t', 'soa', zone], raiseonerr=False
|
||||
- )
|
||||
- assert 'ANSWER SECTION' not in result.stdout_text
|
||||
-
|
||||
- # Test allow-query: IPv6 allowed, IPv4 denied
|
||||
+ # Test allow-query: IPv6 allowed
|
||||
tasks.mod_dns_zone(
|
||||
self.master, zone,
|
||||
- f"--allow-query={ipv6};!{ipv4};"
|
||||
- )
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv4}', '-t', 'soa', zone], raiseonerr=False
|
||||
+ f"--allow-query={ipv6};"
|
||||
)
|
||||
- assert 'ANSWER SECTION' not in result.stdout_text
|
||||
result = self.master.run_command(
|
||||
['dig', f'@{ipv6}', '-t', 'soa', zone], raiseonerr=False
|
||||
)
|
||||
assert 'ANSWER SECTION' in result.stdout_text
|
||||
|
||||
- # Reset allow-query to any
|
||||
- tasks.mod_dns_zone(
|
||||
- self.master, zone, "--allow-query=any;"
|
||||
- )
|
||||
-
|
||||
- # Test allow-transfer: IPv4 allowed, IPv6 denied
|
||||
- tasks.mod_dns_zone(
|
||||
- self.master, zone,
|
||||
- f"--allow-transfer={ipv4};!{ipv6};"
|
||||
- )
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv4}', zone, 'axfr'], raiseonerr=False
|
||||
- )
|
||||
- assert 'Transfer failed' not in result.stdout_text
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv6}', zone, 'axfr'], raiseonerr=False
|
||||
- )
|
||||
- assert 'Transfer failed' in result.stdout_text
|
||||
-
|
||||
- # Test allow-transfer: IPv6 allowed, IPv4 denied
|
||||
+ # Test allow-transfer: IPv6 allowed
|
||||
tasks.mod_dns_zone(
|
||||
self.master, zone,
|
||||
- f"--allow-transfer={ipv6};!{ipv4};"
|
||||
- )
|
||||
- result = self.master.run_command(
|
||||
- ['dig', f'@{ipv4}', zone, 'axfr'], raiseonerr=False
|
||||
+ f"--allow-transfer={ipv6};"
|
||||
)
|
||||
- assert 'Transfer failed' in result.stdout_text
|
||||
result = self.master.run_command(
|
||||
['dig', f'@{ipv6}', zone, 'axfr'], raiseonerr=False
|
||||
)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -232,7 +232,7 @@
|
||||
|
||||
Name: %{package_name}
|
||||
Version: %{IPA_VERSION}
|
||||
Release: 22%{?rc_version:.%rc_version}%{?dist}.3
|
||||
Release: 22%{?rc_version:.%rc_version}.0.1%{?dist}.4
|
||||
Summary: The Identity, Policy and Audit system
|
||||
|
||||
License: GPL-3.0-or-later
|
||||
@ -388,6 +388,17 @@ Patch0129: 0129-ipa-pwd-extop-Don-t-manipulate-the-config-if-not-ret.patch
|
||||
Patch0130: 0130-ipatests-fix-kdcproxy-tests-against-AD.patch
|
||||
Patch0131: 0131-ipatests-update-the-Let-s-Encrypt-cert-chain.patch
|
||||
Patch0132: 0132-ipa-join-initialize-pointer.patch
|
||||
Patch0133: 0133-ipatests-remove-xfail-for-PKI-11.7.patch
|
||||
Patch0134: 0134-GetEntryFromLDIF-handle-DNs-case-insensitive.patch
|
||||
Patch0135: 0135-Tests-xmlrpc-mark-xfail-tests-requesting-cert-with-s.patch
|
||||
Patch0136: 0136-Manual-backport-of-8002.patch
|
||||
Patch0137: 0137-ipatests-Add-DNS-functional-integration-tests.patch
|
||||
Patch0138: 0138-ipatests-add-Random-Password-based-replica-promotion.patch
|
||||
Patch0139: 0139-ipatests-Add-integration-tests-for-ipa-join-command.patch
|
||||
Patch0140: 0140-ipatests-Add-DNS-bugzilla-integration-tests.patch
|
||||
Patch0141: 0141-ipatests-Add-DNS-integration-tests.patch
|
||||
Patch0142: 0142-Allow-32bit-gid.patch
|
||||
Patch0143: 0143-ipatests-Fix-test_allow_query_transfer_ipv6-when-IPv.patch
|
||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||
%endif
|
||||
%endif
|
||||
@ -716,6 +727,7 @@ BuildArch: noarch
|
||||
Requires: %{name}-client-common = %{version}-%{release}
|
||||
Requires: httpd >= %{httpd_version}
|
||||
Requires: systemd-units >= %{systemd_version}
|
||||
Requires: bind >= %{bind_version}
|
||||
%if 0%{?rhel} >= 8 && ! 0%{?eln}
|
||||
Requires: system-logos-ipa >= 80.4
|
||||
%endif
|
||||
@ -1191,7 +1203,8 @@ autoreconf -ivf
|
||||
%{enable_server_option} \
|
||||
%{with_ipatests_option} \
|
||||
%{with_ipa_join_xml_option} \
|
||||
%{linter_options}
|
||||
%{linter_options} \
|
||||
--with-ipaplatform=rhel
|
||||
|
||||
# run build in default dir
|
||||
# -Onone is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1398405
|
||||
@ -2041,6 +2054,15 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Apr 22 2026 EL Errata <el-errata_ww@oracle.com> - 4.12.2-22.0.1.el9_7.4
|
||||
- Set IPAPLATFORM=rhel when build on Oracle Linux [Orabug: 29516674]
|
||||
- Add bind to ipa-server-common Requires [Orabug: 36518596]
|
||||
|
||||
* Mon Mar 16 2026 David Hanina <dhanina@redhat.com> - 4.12.2-22.4
|
||||
- Resolves: RHEL-155038 Pagure #9953: Adding a group with 32Bit Idrange fails.
|
||||
- Resolves: RHEL-153628 Include latest fixes in python3-ipatests package
|
||||
- Resolves: RHEL-153621 Pagure #9854: Erroneous case-sensitivity in offline DSE lookup
|
||||
|
||||
* Thu Feb 5 2026 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-22.3
|
||||
- Resolves: RHEL-141322 Memory leaks in IPA plugins
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user