import CS ipa-4.13.2-2.el9
This commit is contained in:
parent
ffd58edc3c
commit
4128cf0f37
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/freeipa-4.13.1.tar.gz
|
||||
SOURCES/freeipa-4.13.2.tar.gz
|
||||
|
||||
@ -1 +1 @@
|
||||
bc82618e66b45376464cd2206bf6e7a02f766a11 SOURCES/freeipa-4.13.1.tar.gz
|
||||
1b1aa6194b4d2cc3efdcc2e8aaa1e5063c6afe3b SOURCES/freeipa-4.13.2.tar.gz
|
||||
|
||||
@ -32,10 +32,10 @@ This reverts commit e98a80827bcc42dc16b516355077fed844220107.
|
||||
create mode 100644 ipaserver/install/plugins/update_nis.py
|
||||
|
||||
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index b93199a5783a89e0ff58affd3d416556f72dd00c..6ee0f43f059dad4bba2288b1b0d3a63437371861 100644
|
||||
index 36cf4f185c5d269b485e08a57641c33986876daa..42bcd57e64b6d8de3ac457e9d2faa4925d29250c 100644
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -1619,6 +1619,7 @@ fi
|
||||
@@ -1607,6 +1607,7 @@ fi
|
||||
%{_sbindir}/ipa-ldap-updater
|
||||
%{_sbindir}/ipa-otptoken-import
|
||||
%{_sbindir}/ipa-compat-manage
|
||||
@ -43,7 +43,7 @@ index b93199a5783a89e0ff58affd3d416556f72dd00c..6ee0f43f059dad4bba2288b1b0d3a634
|
||||
%{_sbindir}/ipa-managed-entries
|
||||
%{_sbindir}/ipactl
|
||||
%{_sbindir}/ipa-advise
|
||||
@@ -1694,6 +1695,7 @@ fi
|
||||
@@ -1682,6 +1683,7 @@ fi
|
||||
%{_mandir}/man1/ipa-ca-install.1*
|
||||
%{_mandir}/man1/ipa-kra-install.1*
|
||||
%{_mandir}/man1/ipa-compat-manage.1*
|
||||
@ -591,7 +591,7 @@ index 5bc0e3ac3eed257fd7fa6a0830e3e2dbeb3d01d2..b84925bfc7d9af8584d9d4b185aa04b6
|
||||
SCHEMA_COMPAT_POST_ULDIF = "/usr/share/ipa/schema_compat_post.uldif"
|
||||
SUBID_GENERATORS_ULDIF = "/usr/share/ipa/subid-generators.uldif"
|
||||
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
|
||||
index f07a878e739002346df894f93745ea60345e0557..b0a27de5dd40aa661271faa3a8a0855226b5892f 100644
|
||||
index 9f909a2e70ed7f7b7bf52001950c6a504f78f3cd..126a3c7618c4dd2a5a0b7ee6056a1d31c3a2c3da 100644
|
||||
--- a/ipaserver/install/ipa_migrate.py
|
||||
+++ b/ipaserver/install/ipa_migrate.py
|
||||
@@ -32,7 +32,7 @@ from ipapython.admintool import admin_cleanup_global_argv
|
||||
@ -600,7 +600,7 @@ index f07a878e739002346df894f93745ea60345e0557..b0a27de5dd40aa661271faa3a8a08552
|
||||
STRIP_OP_ATTRS, STRIP_ATTRS, STRIP_OC, PROD_ATTRS,
|
||||
- DNA_REGEN_VAL, DNA_REGEN_ATTRS, IGNORE_ATTRS,
|
||||
+ DNA_REGEN_VAL, DNA_REGEN_ATTRS, NIS_PLUGIN, IGNORE_ATTRS,
|
||||
DB_EXCLUDE_TREES, POLICY_OP_ATTRS, STATE_OPTIONS
|
||||
DB_EXCLUDE_TREES, POLICY_OP_ATTRS, STATE_OPTIONS, REDACTED_ATTRS,
|
||||
)
|
||||
|
||||
@@ -749,7 +749,8 @@ class IPAMigrate():
|
||||
@ -613,7 +613,7 @@ index f07a878e739002346df894f93745ea60345e0557..b0a27de5dd40aa661271faa3a8a08552
|
||||
logged_something = True
|
||||
if not self.log_stats(DS_INDEXES) and not logged_something:
|
||||
self.log_info(" - No updates")
|
||||
@@ -1983,6 +1984,28 @@ class IPAMigrate():
|
||||
@@ -2063,6 +2064,28 @@ class IPAMigrate():
|
||||
add_missing=True)
|
||||
stats['config_processed'] += 1
|
||||
|
||||
@ -643,10 +643,10 @@ index f07a878e739002346df894f93745ea60345e0557..b0a27de5dd40aa661271faa3a8a08552
|
||||
# Migration
|
||||
#
|
||||
diff --git a/ipaserver/install/ipa_migrate_constants.py b/ipaserver/install/ipa_migrate_constants.py
|
||||
index 65e920d4bdc7511adb60bbdf87db88beb2630645..4fe8b467978936e4f8d621b7297ff577127c7298 100644
|
||||
index 64dd11cd1244ee30a2eceea3ef823e9092035738..e2f97e6d38c4d47553b854e29b8e0e8903477639 100644
|
||||
--- a/ipaserver/install/ipa_migrate_constants.py
|
||||
+++ b/ipaserver/install/ipa_migrate_constants.py
|
||||
@@ -527,6 +527,30 @@ DS_CONFIG = {
|
||||
@@ -542,6 +542,30 @@ DS_CONFIG = {
|
||||
},
|
||||
}
|
||||
|
||||
@ -788,10 +788,10 @@ index 6c86bbb657a0d9a7b74ef34ad20a796a10073315..4acf8dd5290c687723a9c43a21e194bf
|
||||
(['ipa-replica-manage', 'list'], 1, IPA_NOT_CONFIGURED, None),
|
||||
(['ipa-server-certinstall'], 2, None, IPA_NOT_CONFIGURED),
|
||||
diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py
|
||||
index 5bc871ab71bc05ec1c26df8352e996a9e627b466..8f8548494eaec3afd00961c096772b9d0b1ab3a4 100644
|
||||
index 5021747b67e0b97d322b13261f7e90e688f50cfe..bcd4e2aeb30f45b2a5f2713d213f077b571b6191 100644
|
||||
--- a/ipatests/test_integration/test_commands.py
|
||||
+++ b/ipatests/test_integration/test_commands.py
|
||||
@@ -1382,6 +1382,93 @@ class TestIPACommand(IntegrationTest):
|
||||
@@ -1480,6 +1480,93 @@ class TestIPACommand(IntegrationTest):
|
||||
serverid = realm_to_serverid(self.master.domain.realm)
|
||||
return ("dirsrv@%s.service" % serverid)
|
||||
|
||||
|
||||
31
SOURCES/0004-Change-u-to-u-for-sysusersd.patch
Normal file
31
SOURCES/0004-Change-u-to-u-for-sysusersd.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From c1f9626a4b2b42cade05f83bd5699418e60767a4 Mon Sep 17 00:00:00 2001
|
||||
From: David Hanina <dhanina@redhat.com>
|
||||
Date: Tue, 21 Jul 2026 15:10:49 +0200
|
||||
Subject: [PATCH] Change u! to u for sysusersd
|
||||
|
||||
Adapts the sysusersd settings for RHEL9 to only use u, instead of u!,
|
||||
which errors out.
|
||||
|
||||
Signed-off-by: David Hanina <dhanina@redhat.com>
|
||||
---
|
||||
init/sysusersd/ipa.conf.in | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/init/sysusersd/ipa.conf.in b/init/sysusersd/ipa.conf.in
|
||||
index dcddfc2fc..0955fd341 100644
|
||||
--- a/init/sysusersd/ipa.conf.in
|
||||
+++ b/init/sysusersd/ipa.conf.in
|
||||
@@ -1,8 +1,8 @@
|
||||
# IPA KDC Proxy user and group
|
||||
-u! kdcproxy - "IPA KDC Proxy User"
|
||||
+u kdcproxy - "IPA KDC Proxy User"
|
||||
|
||||
# IPA API user and group
|
||||
-u! ipaapi - "IPA API User"
|
||||
+u ipaapi - "IPA API User"
|
||||
|
||||
# - add Apache system account to ipaapi group (platform-specific)
|
||||
m @HTTPD_USER@ ipaapi
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -29,7 +29,7 @@ diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index b93199a5783a89e0ff58affd3d416556f72dd00c..bf6fa216dcc4cfbac903aad43c6219f1e57db4dd 100644
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -983,7 +983,6 @@ Requires: python3-jwcrypto >= 0.4.2
|
||||
@@ -977,7 +977,6 @@ Requires: python3-jwcrypto >= 0.4.2
|
||||
Requires: python3-libipa_hbac
|
||||
Requires: python3-netaddr >= %{python_netaddr_version}
|
||||
Requires: python3-netifaces >= 0.10.4
|
||||
@ -37,7 +37,7 @@ index b93199a5783a89e0ff58affd3d416556f72dd00c..bf6fa216dcc4cfbac903aad43c6219f1
|
||||
Requires: python3-pyasn1 >= 0.3.2-2
|
||||
Requires: python3-pyasn1-modules >= 0.3.2-2
|
||||
Requires: python3-pyusb
|
||||
@@ -992,6 +991,11 @@ Requires: python3-requests
|
||||
@@ -986,6 +985,11 @@ Requires: python3-requests
|
||||
Requires: python3-six
|
||||
Requires: python3-sss-murmur
|
||||
Requires: python3-yubico >= 1.3.2-7
|
||||
@ -269,15 +269,14 @@ diff --git a/ipatests/test_integration/test_idp.py b/ipatests/test_integration/t
|
||||
index 9983b3c9d62826afa395c2739b4fb9945afed80d..a29333ef232b0ae8229484e404866d8bb720554a 100644
|
||||
--- a/ipatests/test_integration/test_idp.py
|
||||
+++ b/ipatests/test_integration/test_idp.py
|
||||
@@ -12,7 +12,7 @@ from ipatests.pytest_ipa.integration import tasks, create_keycloak
|
||||
user_code_script = textwrap.dedent("""
|
||||
from selenium import webdriver
|
||||
from datetime import datetime
|
||||
-from packaging.version import parse as parse_version
|
||||
+from pkg_resources import parse_version
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
@@ -36,6 +36,6 @@ SELENIUM_REMOTE_HEAD = textwrap.dedent(
|
||||
from selenium import webdriver
|
||||
from datetime import datetime
|
||||
- from packaging.version import parse as parse_version
|
||||
+ from pkg_resources import parse_version
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
||||
index 47392cec9345b6d2447b728fc21050edabe8f0cd..15fc38a6e155b343259ee61c6c7c5c561c7f6410 100644
|
||||
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
||||
|
||||
@ -1,120 +0,0 @@
|
||||
From 1c86c973c8dc778a71c8e2abf54ff37ececdd696 Mon Sep 17 00:00:00 2001
|
||||
From: PRANAV THUBE <pthube@redhat.com>
|
||||
Date: Tue, 13 Jan 2026 19:30:09 +0530
|
||||
Subject: [PATCH] ipatests: Move expire_password fixture into TestIPACommand
|
||||
class
|
||||
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
.../nightly_ipa-4-13_latest.yaml | 2 +-
|
||||
.../nightly_ipa-4-13_latest_selinux.yaml | 2 +-
|
||||
ipatests/test_integration/test_commands.py | 59 +++++++++----------
|
||||
3 files changed, 31 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
index 210739d4b576882ee43e06d85bce819ff30d2357..aff55727e463207fb235ff340989491e62162149 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
@@ -1914,7 +1914,7 @@ jobs:
|
||||
class: RunPytest
|
||||
args:
|
||||
build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
- test_suite: test_integration/test_random_serial_numbers.py::TestIPACommand_RSN::test_certificate_out_write_to_file
|
||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestIPACommand_RSN
|
||||
template: *ci-ipa-4-13-latest
|
||||
timeout: 5400
|
||||
topology: *master_1repl_1client
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
index 0fb7c050b97bf66645599fbff46b53c048211f96..e6c57ea060b3bb8bfdf8b6f981f8fd28e4a7d320 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
@@ -2066,7 +2066,7 @@ jobs:
|
||||
args:
|
||||
build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
selinux_enforcing: True
|
||||
- test_suite: test_integration/test_random_serial_numbers.py::TestIPACommand_RSN::test_certificate_out_write_to_file
|
||||
+ test_suite: test_integration/test_random_serial_numbers.py::TestIPACommand_RSN
|
||||
template: *ci-ipa-4-13-latest
|
||||
timeout: 5400
|
||||
topology: *master_1repl_1client
|
||||
diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py
|
||||
index 01001e4c92037599b075e9bca3ddda7d0c8e8ffa..eda98e92b6b494752d74c6381bdcb6d5c47a26d1 100644
|
||||
--- a/ipatests/test_integration/test_commands.py
|
||||
+++ b/ipatests/test_integration/test_commands.py
|
||||
@@ -199,36 +199,6 @@ duplicatesubject = (
|
||||
duplicate_serial = "4097"
|
||||
|
||||
|
||||
-@pytest.fixture()
|
||||
-def expire_password():
|
||||
- """
|
||||
- Fixture to expire a user's password far into the future past
|
||||
- 2038, then revert time back.
|
||||
- """
|
||||
- hosts = dict()
|
||||
-
|
||||
- def _expire_password(host):
|
||||
- hosts['host'] = host
|
||||
- tasks.move_date(host, 'stop', '+20Years')
|
||||
- host.run_command(
|
||||
- ['ipactl', 'restart', '--ignore-service-failures']
|
||||
- )
|
||||
-
|
||||
- yield _expire_password
|
||||
-
|
||||
- host = hosts.pop('host')
|
||||
- # Prior to uninstall remove all the cert tracking to prevent
|
||||
- # errors from certmonger trying to check the status of certs
|
||||
- # that don't matter because we are uninstalling.
|
||||
- host.run_command(['systemctl', 'stop', 'certmonger'])
|
||||
- # Important: run_command with a str argument is able to
|
||||
- # perform shell expansion but run_command with a list of
|
||||
- # arguments is not
|
||||
- host.run_command('rm -fv ' + paths.CERTMONGER_REQUESTS_DIR + '*')
|
||||
- tasks.uninstall_master(host)
|
||||
- tasks.move_date(host, 'start', '-20Years')
|
||||
-
|
||||
-
|
||||
class TestIPACommand(IntegrationTest):
|
||||
"""
|
||||
A lot of commands can be executed against a single IPA installation
|
||||
@@ -239,6 +209,35 @@ class TestIPACommand(IntegrationTest):
|
||||
num_replicas = 1
|
||||
num_clients = 1
|
||||
|
||||
+ @pytest.fixture
|
||||
+ def expire_password(self):
|
||||
+ """
|
||||
+ Fixture to expire a user's password far into the future past
|
||||
+ 2038, then revert time back.
|
||||
+ """
|
||||
+ hosts = dict()
|
||||
+
|
||||
+ def _expire_password(host):
|
||||
+ hosts['host'] = host
|
||||
+ tasks.move_date(host, 'stop', '+20Years')
|
||||
+ host.run_command(
|
||||
+ ['ipactl', 'restart', '--ignore-service-failures']
|
||||
+ )
|
||||
+
|
||||
+ yield _expire_password
|
||||
+
|
||||
+ host = hosts.pop('host')
|
||||
+ # Prior to uninstall remove all the cert tracking to prevent
|
||||
+ # errors from certmonger trying to check the status of certs
|
||||
+ # that don't matter because we are uninstalling.
|
||||
+ host.run_command(['systemctl', 'stop', 'certmonger'])
|
||||
+ # Important: run_command with a str argument is able to
|
||||
+ # perform shell expansion but run_command with a list of
|
||||
+ # arguments is not
|
||||
+ host.run_command('rm -fv ' + paths.CERTMONGER_REQUESTS_DIR + '*')
|
||||
+ tasks.uninstall_master(host)
|
||||
+ tasks.move_date(host, 'start', '-20Years')
|
||||
+
|
||||
@pytest.fixture
|
||||
def pwpolicy_global(self):
|
||||
"""Fixture to change global password history policy and reset it"""
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
From ecc0efa96e3c446586425d470657de7f2d5376bf Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Mon, 19 Jan 2026 17:00:41 +0100
|
||||
Subject: [PATCH] ipatests: Fix xfail assertion for sssd 2.12.0
|
||||
|
||||
SSSD 2.12.0 provides fixes for
|
||||
https://github.com/SSSD/sssd/issues/5989
|
||||
https://github.com/SSSD/sssd/issues/7169
|
||||
|
||||
Update the condition expecting test failures in test_trust.py
|
||||
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_trust.py | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
|
||||
index 13ad0afa4c1fb032d50f40cf7cb9b79283203225..0cab277c910a6d35f35b57e3068ee6f38706af59 100644
|
||||
--- a/ipatests/test_integration/test_trust.py
|
||||
+++ b/ipatests/test_integration/test_trust.py
|
||||
@@ -1219,9 +1219,10 @@ class TestNonPosixAutoPrivateGroup(BaseTestTrust):
|
||||
assert (uid == self.uid_override and gid == self.gid_override)
|
||||
test_group = self.clients[0].run_command(
|
||||
["id", nonposixuser]).stdout_text
|
||||
- cond2 = ((type == 'false'
|
||||
- and sssd_version >= tasks.parse_version("2.9.4"))
|
||||
- or type == 'hybrid')
|
||||
+ cond2 = (((type == 'false'
|
||||
+ and sssd_version >= tasks.parse_version("2.9.4"))
|
||||
+ or type == 'hybrid')
|
||||
+ and sssd_version < tasks.parse_version("2.12.0"))
|
||||
with xfail_context(cond2,
|
||||
'https://github.com/SSSD/sssd/issues/5989 '
|
||||
'and 7169'):
|
||||
@@ -1347,7 +1348,8 @@ class TestPosixAutoPrivateGroup(BaseTestTrust):
|
||||
and gid == self.gid_override)
|
||||
result = self.clients[0].run_command(['id', posixuser])
|
||||
sssd_version = tasks.get_sssd_version(self.clients[0])
|
||||
- bad_version = sssd_version >= tasks.parse_version("2.9.4")
|
||||
+ bad_version = (tasks.parse_version("2.9.4") <= sssd_version
|
||||
+ < tasks.parse_version("2.12.0"))
|
||||
with xfail_context(bad_version and type in ('false', 'hybrid'),
|
||||
"https://github.com/SSSD/sssd/issues/7169"):
|
||||
assert "10047(testgroup@{0})".format(
|
||||
--
|
||||
2.52.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,99 +0,0 @@
|
||||
From 5756ed2af940378c16d9d52e083b8c4005d41a13 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Wed, 21 Jan 2026 17:19:18 +0100
|
||||
Subject: [PATCH] ipa-advise: smart card client script does not need krb ticket
|
||||
|
||||
The script generated by ipa-advise config-client-for-smart-card-auth
|
||||
currently requires a kerberos ticket because it calls ipa-certupdate.
|
||||
|
||||
Since IPA 4.9.0 and commit 1a09ce9, ipa-certupdate can be called
|
||||
without a ticket. Update the script so that it detects if it gets
|
||||
executed on a client recent enough to skip that requirement.
|
||||
|
||||
Update the test for config-client-for-smart-card-auth, do not
|
||||
call kinit admin on the client.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9923
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipaserver/advise/plugins/smart_card_auth.py | 22 ++++++++++++++++++++-
|
||||
ipatests/test_integration/test_advise.py | 10 +++++++---
|
||||
2 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
|
||||
index b79797dcaee0c881d3ef752a268ed520d96b433b..a0e50e9806f7843d2981141d8941d5e37f53c0cd 100644
|
||||
--- a/ipaserver/advise/plugins/smart_card_auth.py
|
||||
+++ b/ipaserver/advise/plugins/smart_card_auth.py
|
||||
@@ -34,6 +34,26 @@ class common_smart_card_auth_config(Advice):
|
||||
'Use kinit as privileged user to obtain Kerberos credentials'
|
||||
])
|
||||
|
||||
+ def check_ccache_not_empty_if_old_version(self):
|
||||
+ self.log.comment("On version before IPA 4.9, "
|
||||
+ "check that the credential cache is not empty")
|
||||
+ self.log.command(
|
||||
+ "python3 -c \"from ipapython.version import VERSION;"
|
||||
+ "from ipaplatform.tasks import tasks;"
|
||||
+ "exit(tasks.parse_ipa_version(VERSION) >= "
|
||||
+ "tasks.parse_ipa_version('4.9.0'))\"")
|
||||
+ with self.log.if_branch('[ "$?" -eq "0" ]'):
|
||||
+ self.log.exit_on_failed_command(
|
||||
+ 'klist',
|
||||
+ [
|
||||
+ "Credential cache is empty",
|
||||
+ 'Use kinit as privileged user to obtain Kerberos '
|
||||
+ 'credentials'
|
||||
+ ])
|
||||
+ with self.log.else_branch():
|
||||
+ self.log.command(
|
||||
+ "echo 'Version 4.9.0+ does not require Kerberos credentials'")
|
||||
+
|
||||
def check_and_set_ca_cert_paths(self):
|
||||
ca_paths_variable = self.smart_card_ca_certs_variable_name
|
||||
single_ca_path_variable = self.single_ca_cert_variable_name
|
||||
@@ -260,7 +280,7 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
|
||||
def get_info(self):
|
||||
self.log.exit_on_nonroot_euid()
|
||||
self.check_and_set_ca_cert_paths()
|
||||
- self.check_ccache_not_empty()
|
||||
+ self.check_ccache_not_empty_if_old_version()
|
||||
self.check_and_remove_pam_pkcs11()
|
||||
self.install_opensc_and_dconf_packages()
|
||||
self.install_krb5_client_dependencies()
|
||||
diff --git a/ipatests/test_integration/test_advise.py b/ipatests/test_integration/test_advise.py
|
||||
index 3d5cadee319ebba14ebc43ebb1dc90a502e5d3b8..a336634ae9627133c5ad4dea4b1c43ffd726df10 100644
|
||||
--- a/ipatests/test_integration/test_advise.py
|
||||
+++ b/ipatests/test_integration/test_advise.py
|
||||
@@ -60,13 +60,17 @@ class TestAdvice(IntegrationTest):
|
||||
)
|
||||
tasks.install_client(cls.master, cls.clients[0])
|
||||
|
||||
- def execute_advise(self, host, advice_id, *args):
|
||||
+ def execute_advise(self, host, advice_id, *args, kinit=True):
|
||||
# ipa-advise script is only available on a server
|
||||
tasks.kinit_admin(self.master)
|
||||
advice = self.master.run_command(['ipa-advise', advice_id])
|
||||
# execute script on host (client or master)
|
||||
if host is not self.master:
|
||||
- tasks.kinit_admin(host)
|
||||
+ if kinit:
|
||||
+ tasks.kinit_admin(host)
|
||||
+ else:
|
||||
+ # Make sure we don't have any ticket
|
||||
+ tasks.kdestroy_all(host)
|
||||
filename = tasks.upload_temp_contents(host, advice.stdout_text)
|
||||
cmd = ['sh', filename]
|
||||
cmd.extend(args)
|
||||
@@ -181,7 +185,7 @@ class TestAdvice(IntegrationTest):
|
||||
ca_pem = ExternalCA().create_ca()
|
||||
ca_file = tasks.upload_temp_contents(client, ca_pem)
|
||||
try:
|
||||
- self.execute_advise(client, advice_id, ca_file)
|
||||
+ self.execute_advise(client, advice_id, ca_file, kinit=False)
|
||||
finally:
|
||||
client.run_command(['rm', '-f', ca_file])
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,177 +0,0 @@
|
||||
From fd84cec77d18e0e608285ab712f8211b0b49a7fe Mon Sep 17 00:00:00 2001
|
||||
From: PRANAV THUBE <pthube@redhat.com>
|
||||
Date: Thu, 18 Dec 2025 17:13:29 +0530
|
||||
Subject: [PATCH] ipatests: Fix resolver state tracking in enforced DNS policy
|
||||
tests.
|
||||
|
||||
Use resolver.setup_resolver() instead of direct file manipulation to
|
||||
prevent state tracking failures in IDM-CI. Remove redundant manual
|
||||
resolv.conf changes and fix operation order.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9904
|
||||
Reviewed-By: Antonio Torres <antorres@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_edns.py | 70 ++++++++++++++++++--------
|
||||
1 file changed, 50 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_edns.py b/ipatests/test_integration/test_edns.py
|
||||
index d02ce45a1f9c0b04332e4ff4a055ab4c61b35eb4..54b7859da1b9fa320c07bdf29f79d2fdb292c337 100644
|
||||
--- a/ipatests/test_integration/test_edns.py
|
||||
+++ b/ipatests/test_integration/test_edns.py
|
||||
@@ -15,6 +15,9 @@ from ipatests.test_integration.test_dns import TestDNS
|
||||
from ipatests.pytest_ipa.integration.firewall import Firewall
|
||||
from ipaplatform.osinfo import osinfo
|
||||
from ipaplatform.paths import paths
|
||||
+from ipatests.pytest_ipa.integration.resolver import (
|
||||
+ resolver as detect_resolver
|
||||
+)
|
||||
|
||||
|
||||
def apply_enforced_dns_preconfig(host, master_ip, master_host,
|
||||
@@ -30,6 +33,9 @@ def apply_enforced_dns_preconfig(host, master_ip, master_host,
|
||||
ca_cert_path: Path to the CA certificate on the master
|
||||
dest_cert_name: Destination certificate filename in trust anchors
|
||||
"""
|
||||
+ # Backup resolver before making any changes (with original resolver type)
|
||||
+ host.resolver.backup()
|
||||
+
|
||||
# Get the network interface for routing
|
||||
iface_cmd = host.run_command([
|
||||
"bash", "-c",
|
||||
@@ -43,7 +49,8 @@ def apply_enforced_dns_preconfig(host, master_ip, master_host,
|
||||
host.put_file_contents(dest_ca_path, ca_cert_data)
|
||||
host.run_command(["update-ca-trust", "extract"])
|
||||
|
||||
- if osinfo.id in ['rhel', 'centos']:
|
||||
+ platform = tasks.get_platform(host)
|
||||
+ if platform in ['rhel', 'centos']:
|
||||
# RHEL/CentOS configuration
|
||||
# Install and configure dnsconfd
|
||||
tasks.install_packages(host, ['dnsconfd'])
|
||||
@@ -51,31 +58,60 @@ def apply_enforced_dns_preconfig(host, master_ip, master_host,
|
||||
host.run_command(["systemctl", "enable", "--now", "dnsconfd"])
|
||||
host.run_command(["nmcli", "g", "reload"])
|
||||
|
||||
- # Configure DNS over TLS via NetworkManager
|
||||
+ # Configure DNS over TLS via NetworkManager device-specific settings.
|
||||
+ # Device-specific DNS settings work alongside global resolver config.
|
||||
host.run_command([
|
||||
"nmcli", "device", "modify", iface,
|
||||
"ipv4.dns", f"dns+tls://{master_ip}"
|
||||
])
|
||||
|
||||
- elif osinfo.id == 'fedora':
|
||||
- # Fedora configuration
|
||||
+ elif platform == 'fedora':
|
||||
# Configure systemd-resolved for DNS over TLS
|
||||
host.run_command([
|
||||
- "ln", "-sf", "../run/systemd/resolve/stub-resolv.conf",
|
||||
+ "ln", "-sf", "/run/systemd/resolve/stub-resolv.conf",
|
||||
"/etc/resolv.conf"
|
||||
])
|
||||
+ # Restart systemd-resolved to ensure DoT settings are fully applied
|
||||
+ # and resolv.conf is updated
|
||||
host.run_command(["systemctl", "restart", "systemd-resolved"])
|
||||
-
|
||||
- # Configure DNS over TLS via systemd-resolve
|
||||
+ # Configure DNS over TLS via systemd-resolve per-interface settings
|
||||
+ # Per-interface DNS settings work alongside the global resolver config
|
||||
host.run_command([
|
||||
"systemd-resolve", "--set-dns", master_ip,
|
||||
"--set-dnsovertls=yes", f"--interface={iface}"
|
||||
])
|
||||
else:
|
||||
raise ValueError(
|
||||
- f"Unsupported OS for enforced DNS policy: {osinfo.id}"
|
||||
+ f"Unsupported OS for enforced DNS policy: {platform}"
|
||||
)
|
||||
|
||||
+ # Re-detect resolver since we may have changed the resolver type
|
||||
+ # (e.g., from PlainFileResolver to ResolvedResolver on Fedora)
|
||||
+ # This ensures state tracking works correctly with the new resolver type
|
||||
+ # Store the original resolver so we can restore from it during uninstall
|
||||
+ host._enforced_dns_original_resolver = host.resolver
|
||||
+ host.resolver = detect_resolver(host)
|
||||
+ host.resolver.current_state = host.resolver._get_state()
|
||||
+
|
||||
+
|
||||
+def restore_enforced_dns_resolver(host):
|
||||
+ """
|
||||
+ Restore resolver state after enforced DNS preconfig.
|
||||
+
|
||||
+ This restores the original resolver backup created by
|
||||
+ apply_enforced_dns_preconfig() and syncs host.resolver state.
|
||||
+ """
|
||||
+ if not hasattr(host, '_enforced_dns_original_resolver'):
|
||||
+ return
|
||||
+ original_resolver = host._enforced_dns_original_resolver
|
||||
+ if original_resolver.has_backups():
|
||||
+ original_resolver.current_state = original_resolver._get_state()
|
||||
+ original_resolver.restore()
|
||||
+ # Sync host.resolver state since original_resolver changed the config
|
||||
+ host.resolver.backups.clear()
|
||||
+ host.resolver.current_state = host.resolver._get_state()
|
||||
+ delattr(host, '_enforced_dns_original_resolver')
|
||||
+
|
||||
|
||||
def setup_dns_over_tls_environment(cls):
|
||||
"""
|
||||
@@ -451,17 +487,12 @@ class TestDNSOverTLS_EnforcedPolicy_IPA_CA(IntegrationTest):
|
||||
tasks.install_master(self.master, extra_args=args)
|
||||
|
||||
# Apply pre-configuration on client before installation
|
||||
+ # This configures the resolver with master IP and domain
|
||||
apply_enforced_dns_preconfig(
|
||||
self.clients[0], self.master.ip, self.master,
|
||||
paths.IPA_CA_CRT, "ca.crt"
|
||||
)
|
||||
|
||||
- # Configure client nameserver
|
||||
- self.clients[0].put_file_contents(
|
||||
- paths.RESOLV_CONF,
|
||||
- "nameserver %s" % self.master.ip
|
||||
- )
|
||||
-
|
||||
# Install client with enforced policy
|
||||
args = [
|
||||
"--dns-over-tls",
|
||||
@@ -506,6 +537,8 @@ class TestDNSOverTLS_EnforcedPolicy_IPA_CA(IntegrationTest):
|
||||
"""
|
||||
This test ensures that all hosts can be uninstalled correctly.
|
||||
"""
|
||||
+ for host in [self.clients[0], self.replicas[0]]:
|
||||
+ restore_enforced_dns_resolver(host)
|
||||
tasks.uninstall_client(self.clients[0])
|
||||
tasks.uninstall_replica(self.master, self.replicas[0])
|
||||
tasks.uninstall_master(self.master)
|
||||
@@ -559,17 +592,12 @@ class TestDNSOverTLS_EnforcedPolicy_External_CA(IntegrationTest):
|
||||
|
||||
# Apply pre-configuration on client before installation
|
||||
# (includes CA cert setup)
|
||||
+ # This configures the resolver with master IP and domain
|
||||
apply_enforced_dns_preconfig(
|
||||
self.clients[0], self.master.ip, self.master,
|
||||
cert_dest, "certificate.pem"
|
||||
)
|
||||
|
||||
- # Configure client nameserver
|
||||
- self.clients[0].put_file_contents(
|
||||
- paths.RESOLV_CONF,
|
||||
- "nameserver %s" % self.master.ip
|
||||
- )
|
||||
-
|
||||
# Install client with enforced policy
|
||||
args = [
|
||||
"--dns-over-tls",
|
||||
@@ -615,6 +643,8 @@ class TestDNSOverTLS_EnforcedPolicy_External_CA(IntegrationTest):
|
||||
"""
|
||||
This test ensures that all hosts can be uninstalled correctly.
|
||||
"""
|
||||
+ for host in [self.clients[0], self.replicas[0]]:
|
||||
+ restore_enforced_dns_resolver(host)
|
||||
tasks.uninstall_client(self.clients[0])
|
||||
tasks.uninstall_replica(self.master, self.replicas[0])
|
||||
tasks.uninstall_master(self.master)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,224 +0,0 @@
|
||||
From 0800065ac5555dba102f05c947ca47b5dc9a81af Mon Sep 17 00:00:00 2001
|
||||
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
Date: Fri, 23 Jan 2026 16:49:31 -0300
|
||||
Subject: [PATCH] freeipa.spec.in: Use systemd-sysusers to setup users and
|
||||
groups
|
||||
|
||||
System accounts for `kdcproxy` and `ipaapi` are now created with
|
||||
sysusers configuration and macros. User `apache` is updated, by
|
||||
adding it to group `ipaapi` using sysusers configuration.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9572
|
||||
|
||||
AI agent usage info:
|
||||
|
||||
The initial changes were created by Claude by providing the following
|
||||
context:
|
||||
|
||||
>> Add support for creating users through systemd-sysusers by creating
|
||||
>> a folder init/sysusersd, similar to init/tmpfilesd, changing install
|
||||
>> paths in init/sysusersd/Makefile.am, adding configure option
|
||||
>> --with-systemdsysusersdir similar to --with-systemdtmpfilesdir, and
|
||||
>> adding a new file init/sysusersd/freeeipo.sysusers.in with the
|
||||
>> contents:
|
||||
>> ```
|
||||
>> # system accounts for IPA
|
||||
>> u! kdcproxy - "IPA KDC Proxy Uer"
|
||||
>> u! ipaapi - "IPA Framework User"
|
||||
>> # - add Apache HTTPd user to ipaapi group
|
||||
>> m apache ipaapi
|
||||
>> ```
|
||||
>> and updating de spec file freeipa.spec.in
|
||||
|
||||
LLM model used was Claude Sonnet 4.5, and a CLAUDE.md file was
|
||||
automatically created by claude based on the freeipa repository.
|
||||
No custom context was available for the agent.
|
||||
|
||||
Assisted-by: Claude <noreply@anthropic.com>
|
||||
Signed-off-by: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
configure.ac | 42 ++++++++++++++++++++++++++------------
|
||||
freeipa.spec.in | 16 +++------------
|
||||
init/Makefile.am | 2 +-
|
||||
init/sysusersd/Makefile.am | 12 +++++++++++
|
||||
init/sysusersd/ipa.conf.in | 8 ++++++++
|
||||
5 files changed, 53 insertions(+), 27 deletions(-)
|
||||
create mode 100644 init/sysusersd/Makefile.am
|
||||
create mode 100644 init/sysusersd/ipa.conf.in
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 8b9adec1559c8831ef39c27860c1d31496ec5474..b0462bf779dedb7c2fe59494d4eb64a6dd121b1a 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -267,6 +267,13 @@ AC_ARG_WITH([systemdtmpfilesdir],
|
||||
[systemdtmpfilesdir=$($PKG_CONFIG --define-variable=prefix='${prefix}' --variable=tmpfilesdir systemd)])
|
||||
AC_SUBST([systemdtmpfilesdir])
|
||||
|
||||
+AC_ARG_WITH([systemdsysusersdir],
|
||||
+ AS_HELP_STRING([--with-systemdsysusersdir=DIR],
|
||||
+ [Directory for systemd-sysusers configuration files]),
|
||||
+ [systemdsysusersdir=$with_systemdsysusersdir],
|
||||
+ [systemdsysusersdir=$($PKG_CONFIG --define-variable=prefix='${prefix}' --variable=sysusersdir systemd)])
|
||||
+AC_SUBST([systemdsysusersdir])
|
||||
+
|
||||
AC_ARG_WITH([systemdcatalogdir],
|
||||
AS_HELP_STRING([--with-systemdcatalogdir=DIR],
|
||||
[Directory for systemd journal catalog files]),
|
||||
@@ -398,22 +405,29 @@ AC_SUBST([IPAPLATFORM])
|
||||
AC_MSG_RESULT([${IPAPLATFORM}])
|
||||
|
||||
if test "x${IPAPLATFORM}" == "xdebian"; then
|
||||
- HTTPD_GROUP="www-data"
|
||||
- KRB5KDC_SERVICE="krb5-kdc.service"
|
||||
- NAMED_GROUP="bind"
|
||||
- ODS_USER="opendnssec"
|
||||
- ODS_GROUP="opendnssec"
|
||||
- # see https://www.debian.org/doc/packaging-manuals/python-policy/ap-packaging_tools.html
|
||||
- PYTHON_INSTALL_EXTRA_OPTIONS="--install-layout=deb"
|
||||
+ dnl Ubuntu http user is www-data
|
||||
+ HTTPD_USER="www-data"
|
||||
+ HTTPD_GROUP="www-data"
|
||||
+ KRB5KDC_SERVICE="krb5-kdc.service"
|
||||
+ NAMED_GROUP="bind"
|
||||
+ ODS_USER="opendnssec"
|
||||
+ ODS_GROUP="opendnssec"
|
||||
+ # see https://www.debian.org/doc/packaging-manuals/python-policy/ap-packaging_tools.html
|
||||
+ PYTHON_INSTALL_EXTRA_OPTIONS="--install-layout=deb"
|
||||
else
|
||||
- HTTPD_GROUP="apache"
|
||||
- KRB5KDC_SERVICE="krb5kdc.service"
|
||||
- NAMED_GROUP="named"
|
||||
- ODS_USER="ods"
|
||||
- ODS_GROUP="ods"
|
||||
- PYTHON_INSTALL_EXTRA_OPTIONS=""
|
||||
+ HTTPD_USER="apache"
|
||||
+ HTTPD_GROUP="apache"
|
||||
+ KRB5KDC_SERVICE="krb5kdc.service"
|
||||
+ NAMED_GROUP="named"
|
||||
+ ODS_USER="ods"
|
||||
+ ODS_GROUP="ods"
|
||||
+ PYTHON_INSTALL_EXTRA_OPTIONS=""
|
||||
fi
|
||||
|
||||
+AC_MSG_CHECKING([HTTPD_USER])
|
||||
+AC_SUBST([HTTPD_USER])
|
||||
+AC_MSG_RESULT([${HTTPD_USER}])
|
||||
+
|
||||
AC_MSG_CHECKING([HTTPD_GROUP])
|
||||
AC_SUBST([HTTPD_GROUP])
|
||||
AC_MSG_RESULT([${HTTPD_GROUP}])
|
||||
@@ -654,6 +668,7 @@ AC_CONFIG_FILES([
|
||||
daemons/ipa-slapi-plugins/topology/Makefile
|
||||
init/systemd/Makefile
|
||||
init/tmpfilesd/Makefile
|
||||
+ init/sysusersd/Makefile
|
||||
init/Makefile
|
||||
install/Makefile
|
||||
install/certmonger/Makefile
|
||||
@@ -736,6 +751,7 @@ AM_COND_IF([ENABLE_SERVER], [
|
||||
KRAD libs: ${KRAD_LIBS}
|
||||
krb5rundir: ${krb5rundir}
|
||||
systemdtmpfilesdir: ${systemdtmpfilesdir}
|
||||
+ systemdsysusersdir: ${systemdsysusersdir}
|
||||
build mode: server & client"
|
||||
], [
|
||||
echo "\
|
||||
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index f3b45a5308f93928a4d4bb4cbb2ae96c487cf88a..48912185073472c11f08d000dacf3a0b7f2ec668 100644
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -620,7 +620,7 @@ Requires: systemd-units >= %{systemd_version}
|
||||
Requires: system-logos-ipa >= 80.4
|
||||
%endif
|
||||
|
||||
-# The list below is automatically generated by `fix-spec.sh -i`
|
||||
+# The list below is automatically generated by `fix-spec.sh -i`
|
||||
# from the install/freeipa-webui
|
||||
Provides: bundled(npm(attr-accept)) = 2.2.5
|
||||
Provides: bundled(npm(cookie)) = 1.0.2
|
||||
@@ -1274,6 +1274,7 @@ fi
|
||||
/bin/systemctl reload-or-try-restart dbus
|
||||
/bin/systemctl reload-or-try-restart oddjobd
|
||||
|
||||
+%sysusers_create %{_sysusersdir}/ipa.conf
|
||||
%tmpfiles_create ipa.conf
|
||||
%journal_catalog_update
|
||||
|
||||
@@ -1331,18 +1332,6 @@ if [ -e /usr/sbin/ipa_kpasswd ]; then
|
||||
fi
|
||||
|
||||
|
||||
-%pre server-common
|
||||
-# create users and groups
|
||||
-# create kdcproxy group and user
|
||||
-getent group kdcproxy >/dev/null || groupadd -f -r kdcproxy
|
||||
-getent passwd kdcproxy >/dev/null || useradd -r -g kdcproxy -s /sbin/nologin -d / -c "IPA KDC Proxy User" kdcproxy
|
||||
-# create ipaapi group and user
|
||||
-getent group ipaapi >/dev/null || groupadd -f -r ipaapi
|
||||
-getent passwd ipaapi >/dev/null || useradd -r -g ipaapi -s /sbin/nologin -d / -c "IPA Framework User" ipaapi
|
||||
-# add apache to ipaaapi group
|
||||
-id -Gn apache | grep '\bipaapi\b' >/dev/null || usermod apache -a -G ipaapi
|
||||
-
|
||||
-
|
||||
%post server-dns
|
||||
%systemd_post ipa-dnskeysyncd.service ipa-ods-exporter.socket ipa-ods-exporter.service
|
||||
|
||||
@@ -1729,6 +1718,7 @@ fi
|
||||
%dir %attr(0755,root,root) %{_sysconfdir}/ipa/kdcproxy
|
||||
%config(noreplace) %{_sysconfdir}/ipa/kdcproxy/kdcproxy.conf
|
||||
# NOTE: systemd specific section
|
||||
+%{_sysusersdir}/ipa.conf
|
||||
%{_tmpfilesdir}/ipa.conf
|
||||
%attr(644,root,root) %{_unitdir}/ipa-custodia.service
|
||||
%ghost %attr(644,root,root) %{etc_systemd_dir}/httpd.d/ipa.conf
|
||||
diff --git a/init/Makefile.am b/init/Makefile.am
|
||||
index 8f4d1d0a8f7e9739cf7587de6e000dd027a85146..1d4a85ab20e892c8a7c428b84a6393d29e9616e5 100644
|
||||
--- a/init/Makefile.am
|
||||
+++ b/init/Makefile.am
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
AUTOMAKE_OPTIONS = 1.7
|
||||
|
||||
-SUBDIRS = systemd tmpfilesd
|
||||
+SUBDIRS = systemd tmpfilesd sysusersd
|
||||
|
||||
dist_sysconfenv_DATA = \
|
||||
ipa-dnskeysyncd \
|
||||
diff --git a/init/sysusersd/Makefile.am b/init/sysusersd/Makefile.am
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8577255a61ac796353995d3d1f99de195f9bd7c0
|
||||
--- /dev/null
|
||||
+++ b/init/sysusersd/Makefile.am
|
||||
@@ -0,0 +1,12 @@
|
||||
+dist_noinst_DATA = \
|
||||
+ ipa.conf.in
|
||||
+
|
||||
+systemdsysusers_DATA = \
|
||||
+ ipa.conf
|
||||
+
|
||||
+CLEANFILES = $(systemdsysusers_DATA)
|
||||
+
|
||||
+%: %.in Makefile
|
||||
+ sed \
|
||||
+ -e 's|@HTTPD_USER[@]|$(HTTPD_USER)|g' \
|
||||
+ '$(srcdir)/$@.in' >$@
|
||||
diff --git a/init/sysusersd/ipa.conf.in b/init/sysusersd/ipa.conf.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..dcddfc2fc7969b86913ffcd8c397152e4f800fda
|
||||
--- /dev/null
|
||||
+++ b/init/sysusersd/ipa.conf.in
|
||||
@@ -0,0 +1,8 @@
|
||||
+# IPA KDC Proxy user and group
|
||||
+u kdcproxy - "IPA KDC Proxy User"
|
||||
+
|
||||
+# IPA API user and group
|
||||
+u ipaapi - "IPA API User"
|
||||
+
|
||||
+# - add Apache system account to ipaapi group (platform-specific)
|
||||
+m @HTTPD_USER@ ipaapi
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,196 +0,0 @@
|
||||
From a55f9185c96457bdffe9099ddde39ec696f1f998 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>
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
---
|
||||
.../nightly_ipa-4-13_latest.yaml | 12 +++
|
||||
.../nightly_ipa-4-13_latest_selinux.yaml | 13 +++
|
||||
ipatests/pytest_ipa/integration/tasks.py | 15 ++++
|
||||
.../test_replica_promotion.py | 87 +++++++++++++++++++
|
||||
4 files changed, 127 insertions(+)
|
||||
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
index aff55727e463207fb235ff340989491e62162149..c61701ef5f88760f1d6fc36d4acce453a22b6f8f 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
@@ -1000,6 +1000,18 @@ jobs:
|
||||
timeout: 7200
|
||||
topology: *ad_master_1repl_1client
|
||||
|
||||
+ fedora-latest-ipa-4-13/test_replica_promotion_TestReplicaPromotionRandomPassword:
|
||||
+ requires: [fedora-latest-ipa-4-13/build]
|
||||
+ priority: 50
|
||||
+ job:
|
||||
+ class: RunPytest
|
||||
+ args:
|
||||
+ build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
+ test_suite: test_integration/test_replica_promotion.py::TestReplicaPromotionRandomPassword
|
||||
+ template: *ci-ipa-4-13-latest
|
||||
+ timeout: 7200
|
||||
+ topology: *master_1repl
|
||||
+
|
||||
fedora-latest-ipa-4-13/test_upgrade:
|
||||
requires: [fedora-latest-ipa-4-13/build]
|
||||
priority: 50
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
index e6c57ea060b3bb8bfdf8b6f981f8fd28e4a7d320..9b96f3e857e2125478b45632d8d58e42b6e92668 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
@@ -1078,6 +1078,19 @@ jobs:
|
||||
timeout: 7200
|
||||
topology: *ad_master_1repl_1client
|
||||
|
||||
+ fedora-latest-ipa-4-13/test_replica_promotion_TestReplicaPromotionRandomPassword:
|
||||
+ requires: [fedora-latest-ipa-4-13/build]
|
||||
+ priority: 50
|
||||
+ job:
|
||||
+ class: RunPytest
|
||||
+ args:
|
||||
+ build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
+ selinux_enforcing: True
|
||||
+ test_suite: test_integration/test_replica_promotion.py::TestReplicaPromotionRandomPassword
|
||||
+ template: *ci-ipa-4-13-latest
|
||||
+ timeout: 7200
|
||||
+ topology: *master_1repl
|
||||
+
|
||||
fedora-latest-ipa-4-13/test_upgrade:
|
||||
requires: [fedora-latest-ipa-4-13/build]
|
||||
priority: 50
|
||||
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
|
||||
index 32ac5cbc2c6fe87850dfb15c1d5beae6fa648dfb..ff2ea9792d04ebd2e6bd7bb3b51d97f35cb3fbfb 100755
|
||||
--- a/ipatests/pytest_ipa/integration/tasks.py
|
||||
+++ b/ipatests/pytest_ipa/integration/tasks.py
|
||||
@@ -3340,3 +3340,18 @@ def service_control_dirsrv(host, function='restart'):
|
||||
instance = realm_to_serverid(host.domain.realm)
|
||||
cmd = host.run_command(['systemctl', function, f"dirsrv@{instance}"])
|
||||
assert cmd.returncode == 0
|
||||
+
|
||||
+
|
||||
+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 76d6aa24e2ab3d88b7013e0d107d0e27ae7f3426..f8c8414eefbc015cfc0947de575ea349a65a5e73 100644
|
||||
--- a/ipatests/test_integration/test_replica_promotion.py
|
||||
+++ b/ipatests/test_integration/test_replica_promotion.py
|
||||
@@ -1368,3 +1368,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
|
||||
|
||||
@ -1,760 +0,0 @@
|
||||
From 7cb2c5d38a84eb31aa9ddd20cf9dc0b6d90fa242 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/prci_definitions/gating.yaml | 12 +
|
||||
.../nightly_ipa-4-13_latest.yaml | 12 +
|
||||
.../nightly_ipa-4-13_latest_selinux.yaml | 13 +
|
||||
ipatests/pytest_ipa/integration/tasks.py | 49 ++
|
||||
ipatests/test_integration/test_ipa_join.py | 614 ++++++++++++++++++
|
||||
5 files changed, 700 insertions(+)
|
||||
create mode 100644 ipatests/test_integration/test_ipa_join.py
|
||||
|
||||
diff --git a/ipatests/prci_definitions/gating.yaml b/ipatests/prci_definitions/gating.yaml
|
||||
index 0c2a0dafa9de12add8959d9974f080ba8bec0706..182f2c5a097856d22336fa66a0876bdfcf3f3f8d 100644
|
||||
--- a/ipatests/prci_definitions/gating.yaml
|
||||
+++ b/ipatests/prci_definitions/gating.yaml
|
||||
@@ -394,3 +394,15 @@ jobs:
|
||||
template: *ci-ipa-4-13-latest
|
||||
timeout: 7200
|
||||
topology: *master_3client
|
||||
+
|
||||
+ fedora-latest-ipa-4-13/test_ipa_join:
|
||||
+ requires: [fedora-latest-ipa-4-13/build]
|
||||
+ priority: 100
|
||||
+ job:
|
||||
+ class: RunPytest
|
||||
+ args:
|
||||
+ build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
+ test_suite: test_integration/test_ipa_join.py
|
||||
+ template: *ci-ipa-4-13-latest
|
||||
+ timeout: 3600
|
||||
+ topology: *master_1repl_1client
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
index c61701ef5f88760f1d6fc36d4acce453a22b6f8f..aba33a5a05185460305c7516c93ae25c60f9dda7 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest.yaml
|
||||
@@ -2292,3 +2292,15 @@ jobs:
|
||||
template: *ci-ipa-4-13-latest
|
||||
timeout: 2400
|
||||
topology: *ipaserver
|
||||
+
|
||||
+ fedora-latest-ipa-4-13/test_ipa_join:
|
||||
+ requires: [fedora-latest-ipa-4-13/build]
|
||||
+ priority: 50
|
||||
+ job:
|
||||
+ class: RunPytest
|
||||
+ args:
|
||||
+ build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
+ test_suite: test_integration/test_ipa_join.py
|
||||
+ template: *ci-ipa-4-13-latest
|
||||
+ timeout: 3600
|
||||
+ topology: *master_1repl_1client
|
||||
diff --git a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
index 9b96f3e857e2125478b45632d8d58e42b6e92668..7184b722076ba2cab7d782d990a9bc218158a09f 100644
|
||||
--- a/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
+++ b/ipatests/prci_definitions/nightly_ipa-4-13_latest_selinux.yaml
|
||||
@@ -2476,3 +2476,16 @@ jobs:
|
||||
template: *ci-ipa-4-13-latest
|
||||
timeout: 2400
|
||||
topology: *ipaserver
|
||||
+
|
||||
+ fedora-latest-ipa-4-13/test_ipa_join:
|
||||
+ requires: [fedora-latest-ipa-4-13/build]
|
||||
+ priority: 50
|
||||
+ job:
|
||||
+ class: RunPytest
|
||||
+ args:
|
||||
+ build_url: '{fedora-latest-ipa-4-13/build_url}'
|
||||
+ selinux_enforcing: True
|
||||
+ test_suite: test_integration/test_ipa_join.py
|
||||
+ template: *ci-ipa-4-13-latest
|
||||
+ timeout: 3600
|
||||
+ topology: *master_1repl_1client
|
||||
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
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
From 7f6a2835f0972af5e94b58daf47fa60bfade4279 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Thu, 22 Jan 2026 10:02:11 +0100
|
||||
Subject: [PATCH] fetch_domains: Use case-insensitive comparison for domains
|
||||
names
|
||||
|
||||
The fetch_domains method is using netr_DsRGetForestTrustInformation
|
||||
to retrieve the forest trust information. The returned data contains
|
||||
domain entries, with a DNS domain name that can contain mixed case
|
||||
(for instance adDomain.Test).
|
||||
The method compares the domain name with the provided parameter in a
|
||||
case sensitive comparison, while it should use a case-insensitive
|
||||
method (DNS names are case-insensitive).
|
||||
|
||||
Fix the method and compare the lowercase value instead.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9924
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipaserver/dcerpc.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
|
||||
index 1182f128b4988bc699fe7a40d4834f1bead82cf5..5c05ffedb889e774e342cb6cb85ff954d06ac5e9 100644
|
||||
--- a/ipaserver/dcerpc.py
|
||||
+++ b/ipaserver/dcerpc.py
|
||||
@@ -1635,7 +1635,7 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
|
||||
t.forest_trust_data.netbios_domain_name.string
|
||||
|
||||
tname = unicode(t.forest_trust_data.dns_domain_name.string)
|
||||
- if tname != trustdomain:
|
||||
+ if tname.lower() != trustdomain.lower():
|
||||
result['domains'][tname] = {
|
||||
'cn': tname,
|
||||
'ipantflatname': unicode(
|
||||
@@ -1647,7 +1647,7 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
|
||||
record.data.string = t.forest_trust_data.string
|
||||
|
||||
tname = unicode(t.forest_trust_data.string)
|
||||
- if tname == trustdomain:
|
||||
+ if tname.lower() == trustdomain.lower():
|
||||
continue
|
||||
|
||||
result['suffixes'][tname] = {'cn': tname}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From 8deb4be0962b25dfd43e1245307a8bb9d58cfc48 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Tue, 3 Feb 2026 09:46:25 -0500
|
||||
Subject: [PATCH] Handle IPACertificate types in xmlrpc
|
||||
|
||||
The wrapping code didn't understand the IPACertificate class
|
||||
so retrieving any entry that contained one would fail.
|
||||
|
||||
Treat it the same was as its parent class cryptography.Certificate.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9935
|
||||
|
||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: David Hanina <dhanina@redhat.com>
|
||||
---
|
||||
ipalib/rpc.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
|
||||
index ed35afc965308e03269f05e01400660b207b548d..9773626eb054dd404256267c5fffbba1aa0579dd 100644
|
||||
--- a/ipalib/rpc.py
|
||||
+++ b/ipalib/rpc.py
|
||||
@@ -56,7 +56,7 @@ from ipalib.errors import (errors_by_code, UnknownError, NetworkError,
|
||||
XMLRPCMarshallError, JSONError)
|
||||
from ipalib import errors, capabilities
|
||||
from ipalib.request import context, Connection
|
||||
-from ipalib.x509 import Encoding as x509_Encoding
|
||||
+from ipalib.x509 import Encoding as x509_Encoding, IPACertificate
|
||||
from ipapython import ipautil
|
||||
from ipapython import session_storage
|
||||
from ipapython.cookie import Cookie
|
||||
@@ -220,7 +220,7 @@ def xml_wrap(value, version):
|
||||
if isinstance(value, Principal):
|
||||
return unicode(value)
|
||||
|
||||
- if isinstance(value, crypto_x509.Certificate):
|
||||
+ if isinstance(value, (crypto_x509.Certificate, IPACertificate)):
|
||||
return base64.b64encode(
|
||||
value.public_bytes(x509_Encoding.DER)).decode('ascii')
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,159 +0,0 @@
|
||||
From a583b0dc08536a50e10b76e27861864b61906355 Mon Sep 17 00:00:00 2001
|
||||
From: David Hanina <dhanina@redhat.com>
|
||||
Date: Mon, 2 Feb 2026 11:14:48 +0100
|
||||
Subject: [PATCH] Replace None with '' when uninstalling CA
|
||||
|
||||
At many places we're obtaining records from a config file and expect the
|
||||
config to have those keys, but the user may delete the line instead of
|
||||
setting the value to false, this then leads to failed uninstall. This
|
||||
patch replaces None with '' at some places that do not check for None.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9921
|
||||
Signed-off-by: David Hanina <dhanina@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipaserver/install/ca.py | 12 ++++--
|
||||
ipaserver/install/cainstance.py | 14 ++++++-
|
||||
ipaserver/install/server/upgrade.py | 3 +-
|
||||
.../test_integration/test_crlgen_manage.py | 3 +-
|
||||
.../test_integration/test_uninstallation.py | 41 +++++++++++++++++++
|
||||
5 files changed, 66 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
|
||||
index 5a026aa4c556f7012552052cd08223746f3c39ae..2e953a567a3a230cb2a5e35192af76c61f8c1047 100644
|
||||
--- a/ipaserver/install/ca.py
|
||||
+++ b/ipaserver/install/ca.py
|
||||
@@ -340,14 +340,20 @@ def uninstall_crl_check(options):
|
||||
|
||||
try:
|
||||
crlgen_enabled = ca.is_crlgen_enabled()
|
||||
- except cainstance.InconsistentCRLGenConfigException:
|
||||
+ except cainstance.InconsistentCRLGenConfigException as e:
|
||||
# If config is inconsistent, let's be safe and act as if
|
||||
# crl gen was enabled
|
||||
+ print(e)
|
||||
crlgen_enabled = True
|
||||
|
||||
if crlgen_enabled:
|
||||
- print("Deleting this server will leave your installation "
|
||||
- "without a CRL generation master.")
|
||||
+ if not options.ignore_last_of_role:
|
||||
+ print("Deleting this server will leave your installation "
|
||||
+ "without a CRL generation master. Use --ignore-last-of-role "
|
||||
+ "to bypass this check.")
|
||||
+ else:
|
||||
+ print("Deleting this server will leave your installation "
|
||||
+ "without a CRL generation master.")
|
||||
if (options.unattended and not options.ignore_last_of_role) or \
|
||||
not (options.unattended or ipautil.user_input(
|
||||
"Are you sure you want to continue with the uninstall "
|
||||
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
|
||||
index b8267a625554f9375d27160f39b67ee2e64a2dbb..4933ad23d7323859af92bd02f6ae156803e29997 100644
|
||||
--- a/ipaserver/install/cainstance.py
|
||||
+++ b/ipaserver/install/cainstance.py
|
||||
@@ -1421,12 +1421,22 @@ class CAInstance(DogtagInstance):
|
||||
try:
|
||||
cache = directivesetter.get_directive(
|
||||
self.config, 'ca.crl.MasterCRL.enableCRLCache', '=')
|
||||
+
|
||||
+ if cache is None:
|
||||
+ raise InconsistentCRLGenConfigException(
|
||||
+ "Configuration is inconsistent, please check "
|
||||
+ "ca.crl.MasterCRL.enableCRLCache, "
|
||||
+ "ca.crl.MasterCRL.enableCRLUpdates and "
|
||||
+ "ca.listenToCloneModifications in {} and "
|
||||
+ "run ipa-crlgen-manage [enable|disable] to repair".format(
|
||||
+ self.config))
|
||||
+
|
||||
enableCRLCache = cache.lower() == 'true'
|
||||
updates = directivesetter.get_directive(
|
||||
- self.config, 'ca.crl.MasterCRL.enableCRLUpdates', '=')
|
||||
+ self.config, 'ca.crl.MasterCRL.enableCRLUpdates', '=') or ''
|
||||
enableCRLUpdates = updates.lower() == 'true'
|
||||
listen = directivesetter.get_directive(
|
||||
- self.config, 'ca.listenToCloneModifications', '=')
|
||||
+ self.config, 'ca.listenToCloneModifications', '=') or ''
|
||||
enableToClone = listen.lower() == 'true'
|
||||
updateinterval = directivesetter.get_directive(
|
||||
self.config, 'ca.certStatusUpdateInterval', '=')
|
||||
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
|
||||
index 548ee02e1e8524ce0002dca1764d48728eb0509a..8692c983409426193e1746f07fa1a0514621cb4a 100644
|
||||
--- a/ipaserver/install/server/upgrade.py
|
||||
+++ b/ipaserver/install/server/upgrade.py
|
||||
@@ -1712,7 +1712,8 @@ def upgrade_configuration():
|
||||
if ca.is_configured():
|
||||
crl = directivesetter.get_directive(
|
||||
paths.CA_CS_CFG_PATH, 'ca.crl.MasterCRL.enableCRLUpdates', '=')
|
||||
- sub_dict['CLONE']='#' if crl.lower() == 'true' else ''
|
||||
+ sub_dict['CLONE'] = '#' if crl is not None and \
|
||||
+ crl.lower() == 'true' else ''
|
||||
|
||||
ds_dirname = dsinstance.config_dirname(ds.serverid)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_crlgen_manage.py b/ipatests/test_integration/test_crlgen_manage.py
|
||||
index c6f41ebf8939bad8006b1e5eaf37bad30dbfd9d8..8a2a28a75b76158fcc61a8e7612f81343336b64f 100644
|
||||
--- a/ipatests/test_integration/test_crlgen_manage.py
|
||||
+++ b/ipatests/test_integration/test_crlgen_manage.py
|
||||
@@ -302,7 +302,8 @@ class TestCRLGenManage(IntegrationTest):
|
||||
['ipa-server-install', '--uninstall', '-U'], raiseonerr=False)
|
||||
assert result.returncode == 1
|
||||
expected_msg = "Deleting this server will leave your installation " \
|
||||
- "without a CRL generation master"
|
||||
+ "without a CRL generation master. Use " \
|
||||
+ "--ignore-last-of-role to bypass this check."
|
||||
assert expected_msg in result.stdout_text
|
||||
|
||||
def test_uninstall_with_ignore_last_of_role(self):
|
||||
diff --git a/ipatests/test_integration/test_uninstallation.py b/ipatests/test_integration/test_uninstallation.py
|
||||
index 8d83f72868f5c103b0c31d2aa96630c00b2dfbd8..12b10caa60745dcbc2d811bff65d57fb5d865f09 100644
|
||||
--- a/ipatests/test_integration/test_uninstallation.py
|
||||
+++ b/ipatests/test_integration/test_uninstallation.py
|
||||
@@ -237,3 +237,44 @@ class TestUninstallReinstall(IntegrationTest):
|
||||
|
||||
def test_reinstall_server(self):
|
||||
tasks.install_master(self.master, setup_dns=False)
|
||||
+
|
||||
+
|
||||
+class TestUninstallCRLGen(IntegrationTest):
|
||||
+ """Test uninstallation of a replica with broken CRL configuration.
|
||||
+
|
||||
+ Removing ca.crl.MasterCRL.enableCRLCache from CS.cfg crashed.
|
||||
+ https://pagure.io/freeipa/issue/9921
|
||||
+ """
|
||||
+
|
||||
+ num_replicas = 1
|
||||
+ topology = 'line'
|
||||
+
|
||||
+ @classmethod
|
||||
+ def install(cls, mh):
|
||||
+ tasks.install_master(cls.master, setup_dns=False)
|
||||
+ tasks.install_replica(cls.master, cls.replicas[0])
|
||||
+
|
||||
+ def test_uninstall_replica_with_broken_crlgen(self):
|
||||
+ self.replicas[0].run_command(['ipa-crlgen-manage', 'enable'])
|
||||
+
|
||||
+ self.replicas[0].run_command([
|
||||
+ '/bin/sed',
|
||||
+ '-i',
|
||||
+ '/ca.crl.MasterCRL.enableCRLCache=true/d',
|
||||
+ paths.CA_CS_CFG_PATH,
|
||||
+ ])
|
||||
+
|
||||
+ result = self.replicas[0].run_command([
|
||||
+ 'ipa-server-install',
|
||||
+ '--ignore-last-of-role',
|
||||
+ '--uninstall', '-U',
|
||||
+ ])
|
||||
+
|
||||
+ expected_msg = "Configuration is inconsistent, please check " \
|
||||
+ "ca.crl.MasterCRL.enableCRLCache, " \
|
||||
+ "ca.crl.MasterCRL.enableCRLUpdates and " \
|
||||
+ "ca.listenToCloneModifications in {} and run " \
|
||||
+ "ipa-crlgen-manage [enable|disable] to repair".format(
|
||||
+ paths.CA_CS_CFG_PATH)
|
||||
+
|
||||
+ assert expected_msg in result.stdout_text
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,416 +0,0 @@
|
||||
From 91a6618e51b0e767c5cc5e4b1719531dbbd7268d Mon Sep 17 00:00:00 2001
|
||||
From: Sudhir Menon <sumenon@redhat.com>
|
||||
Date: Thu, 22 Jan 2026 12:43:56 +0530
|
||||
Subject: [PATCH] ipatests: Add xmlrpc tests for ipa-delegation-cli
|
||||
|
||||
This patch adds below test cases to the the XML-RPC delegation plugin test suite
|
||||
coverage of delegation operations and important bug regressions.
|
||||
|
||||
Test cases added:
|
||||
|
||||
Test basic delegation creation with write permission
|
||||
Test delegation creation with --all flag
|
||||
Test delegation creation with --raw flag (ACI format)
|
||||
Test deletion of delegation with ipausers group
|
||||
Test finding delegation by name criteria
|
||||
Test finding delegation by membergroup filter
|
||||
Test showing delegation by name
|
||||
Test modifying delegation attrs
|
||||
Test modifying delegation permissions
|
||||
BZ 783548: Verify mod fails when membergroup doesn't exist
|
||||
BZ 783554: Verify mod with empty attrs fails properly
|
||||
BZ 888524: Verify find --group option works correctly
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9931
|
||||
Assisted-by: Claude <noreply@anthropic.com>
|
||||
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Anuja More <amore@redhat.com>
|
||||
---
|
||||
.../test_xmlrpc/test_delegation_plugin.py | 371 ++++++++++++++++++
|
||||
1 file changed, 371 insertions(+)
|
||||
|
||||
diff --git a/ipatests/test_xmlrpc/test_delegation_plugin.py b/ipatests/test_xmlrpc/test_delegation_plugin.py
|
||||
index b3d2aadbddbaaff6f40e1046e4df32bcc9ee7e2d..9245f259e21cad166c3c5b0565da3bb56a341e6b 100644
|
||||
--- a/ipatests/test_xmlrpc/test_delegation_plugin.py
|
||||
+++ b/ipatests/test_xmlrpc/test_delegation_plugin.py
|
||||
@@ -333,4 +333,375 @@ class test_delegation(Declarative):
|
||||
summary=u'Deleted delegation "%s"' % delegation1,
|
||||
)
|
||||
),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation with mobile attr and write permission',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'test_mobile_delegation'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=u'write',
|
||||
+ group=u'editors',
|
||||
+ memberof=u'admins',
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'test_mobile_delegation',
|
||||
+ summary=u'Added delegation "test_mobile_delegation"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'test_mobile_delegation',
|
||||
+ group=u'editors',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation with --all flag',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'test_all_flag'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=u'write',
|
||||
+ group=u'editors',
|
||||
+ memberof=u'admins',
|
||||
+ all=True,
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'test_all_flag',
|
||||
+ summary=u'Added delegation "test_all_flag"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'test_all_flag',
|
||||
+ group=u'editors',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation with --raw flag',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'test_raw_flag'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=u'write',
|
||||
+ group=u'editors',
|
||||
+ memberof=u'admins',
|
||||
+ raw=True,
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'test_raw_flag',
|
||||
+ summary=u'Added delegation "test_raw_flag"',
|
||||
+ result={
|
||||
+ 'aci': u'(targetattr = "mobile")(targetfilter = '
|
||||
+ u'"(memberOf=%s)")(version 3.0;acl '
|
||||
+ u'"delegation:test_raw_flag";allow (write) '
|
||||
+ u'groupdn = "ldap:///%s";)' % (
|
||||
+ DN(('cn', 'admins'), ('cn', 'groups'),
|
||||
+ ('cn', 'accounts'), api.env.basedn),
|
||||
+ DN(('cn', 'editors'), ('cn', 'groups'),
|
||||
+ ('cn', 'accounts'), api.env.basedn))
|
||||
+ },
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete test_mobile_delegation',
|
||||
+ command=('delegation_del', [u'test_mobile_delegation'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'test_mobile_delegation',
|
||||
+ summary=u'Deleted delegation "test_mobile_delegation"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete test_all_flag',
|
||||
+ command=('delegation_del', [u'test_all_flag'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'test_all_flag',
|
||||
+ summary=u'Deleted delegation "test_all_flag"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete test_raw_flag',
|
||||
+ command=('delegation_del', [u'test_raw_flag'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'test_raw_flag',
|
||||
+ summary=u'Deleted delegation "test_raw_flag"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation for ipausers group',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'delegation_del_positive_1001'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ group=u'ipausers',
|
||||
+ memberof=u'admins',
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_del_positive_1001',
|
||||
+ summary=u'Added delegation "delegation_del_positive_1001"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'delegation_del_positive_1001',
|
||||
+ group=u'ipausers',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete delegation_del_positive_1001',
|
||||
+ command=('delegation_del', [u'delegation_del_positive_1001'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'delegation_del_positive_1001',
|
||||
+ summary=u'Deleted delegation "delegation_del_positive_1001"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation for find, show, and mod tests',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'delegation_find_show_mod_test'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=u'write',
|
||||
+ group=u'editors',
|
||||
+ memberof=u'admins',
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_find_show_mod_test',
|
||||
+ summary=u'Added delegation "delegation_find_show_mod_test"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'delegation_find_show_mod_test',
|
||||
+ group=u'editors',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Find delegation by name',
|
||||
+ command=('delegation_find', [u'delegation_find_show_mod_test'], {}),
|
||||
+ expected=dict(
|
||||
+ count=1,
|
||||
+ truncated=False,
|
||||
+ summary=u'1 delegation matched',
|
||||
+ result=[
|
||||
+ {
|
||||
+ 'attrs': [u'mobile'],
|
||||
+ 'permissions': [u'write'],
|
||||
+ 'aciname': u'delegation_find_show_mod_test',
|
||||
+ 'group': u'editors',
|
||||
+ 'memberof': member1,
|
||||
+ },
|
||||
+ ],
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Find delegation by membergroup',
|
||||
+ command=('delegation_find', [], {'memberof': member1}),
|
||||
+ expected=dict(
|
||||
+ count=1,
|
||||
+ truncated=False,
|
||||
+ summary=u'1 delegation matched',
|
||||
+ result=[
|
||||
+ {
|
||||
+ 'attrs': [u'mobile'],
|
||||
+ 'permissions': [u'write'],
|
||||
+ 'aciname': u'delegation_find_show_mod_test',
|
||||
+ 'group': u'editors',
|
||||
+ 'memberof': member1,
|
||||
+ },
|
||||
+ ],
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Show delegation by name',
|
||||
+ command=('delegation_show', [u'delegation_find_show_mod_test'], {}),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_find_show_mod_test',
|
||||
+ summary=None,
|
||||
+ result={
|
||||
+ 'attrs': [u'mobile'],
|
||||
+ 'permissions': [u'write'],
|
||||
+ 'aciname': u'delegation_find_show_mod_test',
|
||||
+ 'group': u'editors',
|
||||
+ 'memberof': member1,
|
||||
+ },
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Modify delegation attrs',
|
||||
+ command=(
|
||||
+ 'delegation_mod', [u'delegation_find_show_mod_test'],
|
||||
+ dict(attrs=[u'l'])
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_find_show_mod_test',
|
||||
+ summary=u'Modified delegation "delegation_find_show_mod_test"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'l'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'delegation_find_show_mod_test',
|
||||
+ group=u'editors',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Modify delegation permissions',
|
||||
+ command=(
|
||||
+ 'delegation_mod', [u'delegation_find_show_mod_test'],
|
||||
+ dict(permissions=u'read')
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_find_show_mod_test',
|
||||
+ summary=u'Modified delegation "delegation_find_show_mod_test"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'l'],
|
||||
+ permissions=[u'read'],
|
||||
+ aciname=u'delegation_find_show_mod_test',
|
||||
+ group=u'editors',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete delegation_find_show_mod_test',
|
||||
+ command=('delegation_del', [u'delegation_find_show_mod_test'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'delegation_find_show_mod_test',
|
||||
+ summary=u'Deleted delegation "delegation_find_show_mod_test"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Create delegation for BZ tests',
|
||||
+ command=(
|
||||
+ 'delegation_add', [u'delegation_bz_test'], dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=u'write',
|
||||
+ group=u'ipausers',
|
||||
+ memberof=u'admins',
|
||||
+ )
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_bz_test',
|
||||
+ summary=u'Added delegation "delegation_bz_test"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'mobile'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'delegation_bz_test',
|
||||
+ group=u'ipausers',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Try to modify with non-existent membergroup (BZ 783548)',
|
||||
+ command=(
|
||||
+ 'delegation_mod', [u'delegation_bz_test'],
|
||||
+ dict(memberof=u'badmembergroup')
|
||||
+ ),
|
||||
+ expected=errors.NotFound(
|
||||
+ reason=u'badmembergroup: group not found'),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Try to modify attrs with empty value (BZ 783554)',
|
||||
+ command=(
|
||||
+ 'delegation_mod', [u'delegation_bz_test'], dict(attrs=u'')
|
||||
+ ),
|
||||
+ expected=errors.RequirementError(name='attrs'),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Modify attrs to prepare for next BZ test',
|
||||
+ command=(
|
||||
+ 'delegation_mod', [u'delegation_bz_test'], dict(attrs=[u'l'])
|
||||
+ ),
|
||||
+ expected=dict(
|
||||
+ value=u'delegation_bz_test',
|
||||
+ summary=u'Modified delegation "delegation_bz_test"',
|
||||
+ result=dict(
|
||||
+ attrs=[u'l'],
|
||||
+ permissions=[u'write'],
|
||||
+ aciname=u'delegation_bz_test',
|
||||
+ group=u'ipausers',
|
||||
+ memberof=member1,
|
||||
+ ),
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Find delegation by group filter (BZ 888524)',
|
||||
+ command=('delegation_find', [], {'group': u'ipausers'}),
|
||||
+ expected=dict(
|
||||
+ count=1,
|
||||
+ truncated=False,
|
||||
+ summary=u'1 delegation matched',
|
||||
+ result=[
|
||||
+ {
|
||||
+ 'attrs': [u'l'],
|
||||
+ 'permissions': [u'write'],
|
||||
+ 'aciname': u'delegation_bz_test',
|
||||
+ 'group': u'ipausers',
|
||||
+ 'memberof': member1,
|
||||
+ },
|
||||
+ ],
|
||||
+ ),
|
||||
+ ),
|
||||
+
|
||||
+
|
||||
+ dict(
|
||||
+ desc='Delete delegation_bz_test',
|
||||
+ command=('delegation_del', [u'delegation_bz_test'], {}),
|
||||
+ expected=dict(
|
||||
+ result=True,
|
||||
+ value=u'delegation_bz_test',
|
||||
+ summary=u'Deleted delegation "delegation_bz_test"',
|
||||
+ )
|
||||
+ ),
|
||||
+
|
||||
]
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From 7cc96e42683a6d3ec9f2dc2a19e99330b6f3ce58 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Wed, 4 Feb 2026 09:21:14 +0100
|
||||
Subject: [PATCH] ipa-join: initialize pointer
|
||||
|
||||
OpenScanHub detected an uninitialized pointer in ipa_join:
|
||||
Slapi_DN *sdn;
|
||||
...
|
||||
if (sdn) slapi_sdn_free(&sdn);
|
||||
|
||||
Initialize to NULL
|
||||
Also initialize Slapi_Backend *be=NULL and char * filter=NULL
|
||||
to avoid potential issues.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9936
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
---
|
||||
daemons/ipa-slapi-plugins/ipa-enrollment/ipa_enrollment.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-slapi-plugins/ipa-enrollment/ipa_enrollment.c b/daemons/ipa-slapi-plugins/ipa-enrollment/ipa_enrollment.c
|
||||
index 3a70dd0a5594fc623e7e808ab8a734349a748a49..2f8923e10310a8a6e19ac701070d6451915c3be3 100644
|
||||
--- a/daemons/ipa-slapi-plugins/ipa-enrollment/ipa_enrollment.c
|
||||
+++ b/daemons/ipa-slapi-plugins/ipa-enrollment/ipa_enrollment.c
|
||||
@@ -129,8 +129,8 @@ ipa_join(Slapi_PBlock *pb)
|
||||
Slapi_PBlock *pbte = NULL;
|
||||
Slapi_PBlock *pbtm = NULL;
|
||||
Slapi_Entry *targetEntry=NULL;
|
||||
- Slapi_DN *sdn;
|
||||
- Slapi_Backend *be;
|
||||
+ Slapi_DN *sdn=NULL;
|
||||
+ Slapi_Backend *be=NULL;
|
||||
Slapi_Entry **es = NULL;
|
||||
int rc=0, ret=0, res;
|
||||
size_t i;
|
||||
@@ -139,7 +139,7 @@ ipa_join(Slapi_PBlock *pb)
|
||||
char *fqdn = NULL;
|
||||
Slapi_Mods *smods = NULL;
|
||||
char *attrlist[] = {"fqdn", "krbPrincipalKey", "krbLastPwdChange", "krbPrincipalName", NULL };
|
||||
- char * filter;
|
||||
+ char * filter=NULL;
|
||||
|
||||
int scope = LDAP_SCOPE_SUBTREE;
|
||||
char *principal = NULL;
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
From d5efb4decb74b50c05b1d252add1c075e660d154 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Wed, 11 Feb 2026 10:23:36 +0100
|
||||
Subject: [PATCH] ipatests: pruning is enabled when RSN is enabled
|
||||
|
||||
The test TestACMEPrune installs the server with --random-serial-numbers
|
||||
but expects pruning to be disabled if the 389ds backend is BDB.
|
||||
|
||||
This is a wrong expectation as pruning is enabled as soon as RSN
|
||||
are enabled (since commit 3777d2b).
|
||||
Fix the test expectation.
|
||||
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_acme.py | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||
index 4c66e4348beeaca95577a786a46e53fdc1532ef7..bedec9d1f9f0c168c11aceb155978b6a0dae8dd7 100644
|
||||
--- a/ipatests/test_integration/test_acme.py
|
||||
+++ b/ipatests/test_integration/test_acme.py
|
||||
@@ -718,12 +718,8 @@ class TestACMEPrune(IntegrationTest):
|
||||
< tasks.parse_version('11.3.0')):
|
||||
raise pytest.skip("Certificate pruning is not available")
|
||||
|
||||
- # Pruning is enabled by default when the host supports lmdb
|
||||
- if get_389ds_backend(self.master) == 'bdb':
|
||||
- cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||
- assert "jobsScheduler.job.pruning.enabled=false".encode() in cs_cfg
|
||||
- self.master.run_command(['ipa-acme-manage', 'pruning', '--enable'])
|
||||
-
|
||||
+ # Pruning is enabled by default when server is installed
|
||||
+ # with --random-serial-numbers
|
||||
cs_cfg = self.master.get_file_contents(paths.CA_CS_CFG_PATH)
|
||||
assert "jobsScheduler.enabled=true".encode() in cs_cfg
|
||||
assert "jobsScheduler.job.pruning.enabled=true".encode() in cs_cfg
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmlqBAcACgkQaYdvcqbi
|
||||
009J4Q//cZi2ZS9RNBkU/v7v7Uvfb7WbsTAUQ2V5EJlqQ7BXbn2tkLtACbzeRn6X
|
||||
aLECdZK+0etdyjbFlb7CvR6GUKw3BCZXpV62XXSQ3/EOhGRtGbrzRiIgaYOmFjzb
|
||||
Hs4Ini6x/QClb0iA478ajG3YHrNYJhy3fFj+s3xzNGZuhJLvhlg3C2VDG7AgrzEx
|
||||
RPiK7DIPY3SVUayxGuPLkNxsZiEQ1IcYtIu++Wp9QHmgPlAdP5aZ2TcEeotgUq4Z
|
||||
+1LXEsDywEdQpg2iO92rja01q+zlcxzuQVjgdEh0G9lIw6f/GtB5WTdm2SER26oq
|
||||
tld6MI6vrWZY+zMSc6FVjy0UB1Tk1kjjp7dp8OQhgzpe2i7LLKZl8bwRhvV6XlZT
|
||||
+ylGHNK5cFglgtOjxIyLVGy6p6PIM+FtEFigUHB5faH+UrWTIL1+zrqWEhhiykI+
|
||||
TT7/plOxG+tALr3ZDOZVqn1Idh9UQNQ8YdPzzKQMKAx5bbm5uHJXR6FQWt/P1QVc
|
||||
S2N1Jlgi8IzbrnVPqN04BDCKsbOOWK6hP8a/SxoGW2IgTd7QWXalfRkeD4vdnM/1
|
||||
9RRWRGuWWKuk2EUlKK202za+wJ7oOY4JSLXC3zxo1bTsHnUN+SYun+5BgYaiKLbM
|
||||
dXZ4K+9Fs4clmT38W3I2LWPFoKcZVczN6/3MpQbTvmgEOkx8LZ0=
|
||||
=jpva
|
||||
-----END PGP SIGNATURE-----
|
||||
16
SOURCES/freeipa-4.13.2.tar.gz.asc
Normal file
16
SOURCES/freeipa-4.13.2.tar.gz.asc
Normal file
@ -0,0 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmpYqDYACgkQaYdvcqbi
|
||||
008XZw//bTJT+5DkI/fFA9YrZJ7aHDdiV59NmaY9p8vsONL93ZeZ1CObKsywCrMN
|
||||
4lSEZ+/SANF+LHqjnXViYtctsOR0jYxwEiJxVcMJU/YkZwOJwnwp3C9vPA9OO/9Y
|
||||
MXW/QYMDGGAPAtDwXqMAsZTP9JRrljw7dvdJtjK5Eq4MUoYFnrBLUXH8XYZq6UoO
|
||||
X+z9hkfDVDqzGginPd+hautapF5TgN07tUBQCx4GIW9Y+4CgtnJSUTMoDo/c42AF
|
||||
zy2VmPnRsHb7XIVw4nQW/ZGVq0e13C2Os11JRKWk6yd3xBLEewgSjvEWhJi4wXik
|
||||
e6G1fSoIX2zl7q5cxiIlvJZv+qja3FGKYmrBC0fdVtFaBqnOJNuSm49vVz2LcB9R
|
||||
VJdWWXksE+A3MEyCKE4haiMhVj9BpEaT6DUEAksQPAAXyLiOoZLIln+XHk56tTPg
|
||||
1EFeUrhnrJj4s5Mo3ODxRU+VtCi+VAfvClXNuxHQBfGajO35OVeqS1Ioe4H/f4YI
|
||||
YazMSSGdlfQbSeKt8n98C0QOTq7jxSnHgeUilpGC3Eum1J59jb5swGbT/yJ/5haU
|
||||
PaY6kkNxoY5AzxjbcSA/k9Uw/wJF4I9IsfHuBY0ISN150amqAE1IlQzqphjTCV3o
|
||||
x/Z3GT9uOqBWr4JewvpA5DpwX/bD2N+57vqWiRGXACVZnN2PwwU=
|
||||
=H7LS
|
||||
-----END PGP SIGNATURE-----
|
||||
@ -69,7 +69,7 @@
|
||||
%global krb5_kdb_version 9.0
|
||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||
%global python_netaddr_version 0.7.19
|
||||
%global samba_version 4.23.0
|
||||
%global samba_version 4.24.5
|
||||
%global slapi_nis_version 0.60.0
|
||||
%global python_ldap_version 3.1.0-1
|
||||
# version supporting Allow Uniqueness plugin to search uniqueness attributes
|
||||
@ -79,12 +79,12 @@
|
||||
%else
|
||||
%global ds_version 3.1.3-5
|
||||
%endif
|
||||
%global selinux_policy_version 38.1.1-1
|
||||
%global selinux_policy_version 38.1.83-1
|
||||
|
||||
%if 0%{?rhel} >= 10
|
||||
%global krb5_version 1.21.3-6
|
||||
%elif 0%{?rhel} == 9
|
||||
%global krb5_version 1.21.1-5
|
||||
%global krb5_version 1.21.1-10
|
||||
%else
|
||||
%global krb5_version 1.18.2-31
|
||||
%endif
|
||||
@ -93,7 +93,7 @@
|
||||
%global httpd_version 2.4.37-21
|
||||
|
||||
# support for passkey
|
||||
%global sssd_version 2.9.7
|
||||
%global sssd_version 2.9.9-3
|
||||
|
||||
%else
|
||||
# Fedora
|
||||
@ -164,7 +164,7 @@
|
||||
# BIND employs 'pkcs11' OpenSSL engine instead of native PKCS11
|
||||
# Fedora 31+ uses OpenSSL engine, as well as Fedora ELN (RHEL9)
|
||||
%if 0%{?fedora} || 0%{?rhel} >= 9
|
||||
%global openssl_pkcs11_version 0.4.10-6
|
||||
%global openssl_pkcs11_version 0.4.11-9
|
||||
%global softhsm_version 2.5.0-4
|
||||
%else
|
||||
%global with_bind_pkcs11 1
|
||||
@ -216,7 +216,7 @@
|
||||
|
||||
# Work-around fact that RPM SPEC parser does not accept
|
||||
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
||||
%define IPA_VERSION 4.13.1
|
||||
%define IPA_VERSION 4.13.2
|
||||
# Release candidate version -- uncomment with one percent for RC versions
|
||||
#%%global rc_version
|
||||
%define AT_SIGN @
|
||||
@ -229,7 +229,7 @@
|
||||
|
||||
Name: %{package_name}
|
||||
Version: %{IPA_VERSION}
|
||||
Release: 3%{?rc_version:.%rc_version}%{?dist}
|
||||
Release: 2%{?rc_version:.%rc_version}%{?dist}
|
||||
Summary: The Identity, Policy and Audit system
|
||||
|
||||
License: GPL-3.0-or-later
|
||||
@ -252,21 +252,8 @@ Source1: https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers
|
||||
Patch0001: 0001-Revert-Replace-netifaces-with-ifaddr.patch
|
||||
Patch0002: 0002-Revert-custodia-do-not-use-deprecated-jwcrypto-wrapp.patch
|
||||
Patch0003: 0003-Revert-Remove-NIS-server-support.patch
|
||||
Patch0004: 0004-Change-u-to-u-for-sysusersd.patch
|
||||
Patch0006: 0006-Revert-Stop-using-deprecated-pkg_resources.patch
|
||||
Patch0007: 0007-ipatests-Move-expire_password-fixture-into-TestIPACo.patch
|
||||
Patch0008: 0008-ipatests-Fix-xfail-assertion-for-sssd-2.12.0.patch
|
||||
Patch0009: 0009-ipatests-Add-DNS-functional-integration-tests.patch
|
||||
Patch0010: 0010-ipa-advise-smart-card-client-script-does-not-need-kr.patch
|
||||
Patch0011: 0011-ipatests-Fix-resolver-state-tracking-in-enforced-DNS.patch
|
||||
Patch0012: 0012-freeipa.spec.in-Use-systemd-sysusers-to-setup-users-.patch
|
||||
Patch0013: 0013-ipatests-add-Random-Password-based-replica-promotion.patch
|
||||
Patch0014: 0014-ipatests-Add-integration-tests-for-ipa-join-command.patch
|
||||
Patch0015: 0015-fetch_domains-Use-case-insensitive-comparison-for-do.patch
|
||||
Patch0016: 0016-Handle-IPACertificate-types-in-xmlrpc.patch
|
||||
Patch0017: 0017-Replace-None-with-when-uninstalling-CA.patch
|
||||
Patch0018: 0018-ipatests-Add-xmlrpc-tests-for-ipa-delegation-cli.patch
|
||||
Patch0019: 0019-ipa-join-initialize-pointer.patch
|
||||
Patch0020: 0020-ipatests-pruning-is-enabled-when-RSN-is-enabled.patch
|
||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||
%endif
|
||||
%endif
|
||||
@ -324,7 +311,7 @@ BuildRequires: libsss_nss_idmap-devel >= %{sssd_version}
|
||||
BuildRequires: nodejs(abi) == 127
|
||||
%elif 0%{?fedora} >= 39
|
||||
# Do not use nodejs20 on fedora < 39, https://pagure.io/freeipa/issue/9374
|
||||
BuildRequires: nodejs(abi) < 127
|
||||
BuildRequires: nodejs(abi) < 127, /usr/bin/node, /usr/bin/npm
|
||||
%else
|
||||
BuildRequires: nodejs(abi) < 111
|
||||
%endif
|
||||
@ -1405,8 +1392,8 @@ if [ $1 -gt 1 ] ; then
|
||||
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
|
||||
fi
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -1478,9 +1465,9 @@ if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
|
||||
GLOBALKNOWNHOSTFILE="GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts/"
|
||||
grep -qF '$GLOBALKNOWNHOSTFILE' $SSH_CLIENT_SYSTEM_CONF
|
||||
if [ $? -ne 0 ]; then
|
||||
sed -E --in-place=.orig '/(# IPA-related configuration changes to ssh_config)/a # added by ipa-client update\n'"$GLOBALKNOWNHOSTFILE"'' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig '/(# IPA-related configuration changes to ssh_config)/a # added by ipa-client update\n'"$GLOBALKNOWNHOSTFILE"'' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
fi
|
||||
sed -E --in-place=.orig 's/(KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H)/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/(KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H)/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h/' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -1499,8 +1486,8 @@ if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
|
||||
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
|
||||
fi
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF || :
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -1735,6 +1722,8 @@ fi
|
||||
%dir %{_usr}/share/ipa/ui/css
|
||||
%{_usr}/share/ipa/ui/css/*.css
|
||||
%dir %{_usr}/share/ipa/ui/js
|
||||
%dir %{_usr}/share/ipa/ui/js/inline
|
||||
%{_usr}/share/ipa/ui/js/inline/*.js
|
||||
%dir %{_usr}/share/ipa/ui/js/dojo
|
||||
%{_usr}/share/ipa/ui/js/dojo/dojo.js
|
||||
%dir %{_usr}/share/ipa/ui/js/libs
|
||||
@ -1765,8 +1754,6 @@ fi
|
||||
%ghost %attr(0640,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-pki-proxy.conf
|
||||
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/kdcproxy/ipa-kdc-proxy.conf
|
||||
%ghost %attr(0644,root,root) %config(noreplace) %{_usr}/share/ipa/html/ca.crt
|
||||
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-ext.conf
|
||||
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-options-ext.conf
|
||||
%dir %{_usr}/share/ipa/updates/
|
||||
%{_usr}/share/ipa/updates/*
|
||||
%dir %{_localstatedir}/lib/ipa
|
||||
@ -1779,7 +1766,6 @@ fi
|
||||
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/private
|
||||
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/passwds
|
||||
%ghost %attr(775,root,pkiuser) %{_localstatedir}/lib/ipa/pki-ca/publish
|
||||
%ghost %attr(770,named,named) %{_localstatedir}/named/dyndb-ldap/ipa
|
||||
%dir %attr(0700,root,root) %{_sysconfdir}/ipa/custodia
|
||||
%dir %{_usr}/share/ipa/schema.d
|
||||
%attr(0644,root,root) %{_usr}/share/ipa/schema.d/README
|
||||
@ -1801,6 +1787,9 @@ fi
|
||||
%attr(644,root,root) %{_unitdir}/ipa-dnskeysyncd.service
|
||||
%attr(644,root,root) %{_unitdir}/ipa-ods-exporter.socket
|
||||
%attr(644,root,root) %{_unitdir}/ipa-ods-exporter.service
|
||||
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-ext.conf
|
||||
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-options-ext.conf
|
||||
%ghost %attr(770,named,named) %{_localstatedir}/named/dyndb-ldap/ipa
|
||||
|
||||
%files server-encrypted-dns
|
||||
%doc README.md Contributors.txt
|
||||
@ -1979,6 +1968,40 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Aug 03 2026 Florence Blanc-Renaud <flo@redhat.com> - 4.13.2-2
|
||||
- Resolves: RHEL-222583 ipa-server-trust-ad package installation failing for samba dependency
|
||||
|
||||
* Mon Jul 20 2026 David Hanina <dhanina@redhat.com> - 4.13.2-1
|
||||
- Resolves: RHEL-166742 [Cursor Automated] Include latest fixes in python3-ipatests package [RHEL9.9]
|
||||
- Resolves: RHEL-151581 Pagure #9948: Extend SELinux policy to allow use of SSSD authentication helpers on non-enrolled hosts [rhel-9]
|
||||
- Resolves: RHEL-151560 ipa-migrate doesn't process users' sshpublickeys [rhel-9]
|
||||
- Resolves: RHEL-179216 ipa-migrate tool is renaming host records & host info in automount information [RHEL 9.9]
|
||||
- Resolves: RHEL-212442 freeipa-client %triggerin and %post can fail (rpm scriptlets should never fail, by policy) [rhel-9]
|
||||
- Resolves: RHEL-212443 ipa-migrate doesn't properly handle replication conflicts [rhel-9]
|
||||
- Resolves: RHEL-212444 ipa-migrate doesn't migrate IPA locations [rhel-9]
|
||||
- Resolves: RHEL-212445 Pagure #9948: Extend SELinux policy to allow use of SSSD authentication helpers on non-enrolled hosts [rhel-9]
|
||||
- Resolves: RHEL-212446 [RFE] X-Content-Type-Options header in IdM WebUI [rhel-9]
|
||||
- Resolves: RHEL-212447 [RFE] Implement Referrer-Policy on IdM WebUI [rhel-9]
|
||||
- Resolves: RHEL-212448 [RFE] CSP not implemented in IdM WebUI [rhel-9]
|
||||
- Resolves: RHEL-212449 IPA compatibility with tomcat 10 [rhel-9]
|
||||
- Resolves: RHEL-212450 Webui 3007 Requirement error "userCertificate" is required (not allowing certificate management for idview) [rhel-9]
|
||||
- Resolves: RHEL-212451 To add "SameSite" flag to ipa_session cookies [rhel-9]
|
||||
- Resolves: RHEL-212452 FreeIPA JSON-RPC CSRF Referer Validation Uses Naive Prefix Match - [rhel-9]
|
||||
- Resolves: RHEL-212471 Pagure #9820: ipalockout_postop is incorrectly warning about locked user [rhel-9]
|
||||
- Resolves: RHEL-178920 Rebase ipa to latest version for RHEL 9.9
|
||||
|
||||
* Tue Jun 02 2026 Florence Blanc-Renaud <flo@redhat.com> - 4.13.1-4
|
||||
- Related: RHEL-175124 Rebuilt for samba 4.24.3
|
||||
|
||||
* Thu Apr 16 2026 David Hanina <dhanina@redhat.com> - 4.13.1-3.2
|
||||
- Related: RHEL-166865 Include latest fixes in python3-ipatests package [rhel-9.8.z]
|
||||
|
||||
* Mon Apr 13 2026 David Hanina <dhanina@redhat.com> - 4.13.1-3.1
|
||||
- Resolves: RHEL-166865 Include latest fixes in python3-ipatests package [rhel-9.8.z]
|
||||
- Resolves: RHEL-155037 Pagure #9953: Adding a group with 32Bit Idrange fails. [rhel-9.8.z]
|
||||
- Resolves: RHEL-153146 IdM password policy Min lifetime is not enforced when high minlife is set [rhel-9.8.z]
|
||||
- Resolves: RHEL-168047 ipa ca-show ipa --all failing to list RSN version
|
||||
|
||||
* Tue Feb 10 2026 Florence Blanc-Renaud <flo@redhat.com> - 4.13.1-3
|
||||
- RHEL-148282 ipa-replica-conncheck fails with "an internal error has occured"
|
||||
- RHEL-148481 Pruning is enabled by default with RSN on RHEL 9.8
|
||||
|
||||
Loading…
Reference in New Issue
Block a user