ipa-4.12.0-6

- Resolves: RHEL-47292 Include latest fixes in python3-ipatests packages
- Resolves: RHEL-47146 Syntax error uninstalling the selinux-luna subpackage
- Resolves: RHEL-46009 ipa-migrate with -Z option fails with ValueError: option error
- Resolves: RHEL-46003 ipa-migrate -V options fails to display version
- Resolves: RHEL-45463 ipa-migrate stage-mode is failing with error: Modifying a mapped attribute in a managed entry is not allowed
- Resolves: RHEL-40890 ipa-server-install: token_password_file read in kra.install_check after calling hsm_validator in ca.install_check
- Resolves: RHEL-40661 Adjust "ipa config-mod --addattr ipaconfigstring=EnforceLDAPOTP" to allow for non OTP users in some cases

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Florence Blanc-Renaud 2024-07-18 14:24:55 +02:00
parent d0ca280108
commit 8b6d847e67
11 changed files with 1047 additions and 1 deletions

View File

@ -0,0 +1,45 @@
From 4521fe5f9125c74b4ad6e4e51f8c66c009079281 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 13 Jun 2024 10:39:54 +0200
Subject: [PATCH] ipatests: mark test_ca_show_error_handling as xfail
With PKI 11.5.0, the test
test_cert.py::TestCAShowErrorHandling::test_ca_show_error_handling
is failing with an exception and a different error message.
Mark as xfail until PKI provides a fix
Related: https://pagure.io/freeipa/issue/9606
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/test_integration/test_cert.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py
index 4dd1254a2d16420bb70686f9715497dfb9048ecf..91598b655a8cd6ff92c1a0cf2166c6548a7af758 100644
--- a/ipatests/test_integration/test_cert.py
+++ b/ipatests/test_integration/test_cert.py
@@ -25,6 +25,7 @@ from pkg_resources import parse_version
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.base import IntegrationTest
+from ipatests.util import xfail_context
DEFAULT_RA_AGENT_SUBMITTED_VAL = '19700101000000'
@@ -555,7 +556,11 @@ class TestCAShowErrorHandling(IntegrationTest):
)
error_msg = 'ipa: ERROR: The certificate for ' \
'{} is not available on this server.'.format(lwca)
- assert error_msg in result.stderr_text
+ bad_version = (tasks.get_pki_version(self.master)
+ >= tasks.parse_version('11.5.0'))
+ with xfail_context(bad_version,
+ reason="https://pagure.io/freeipa/issue/9606"):
+ assert error_msg in result.stderr_text
def test_certmonger_empty_cert_not_segfault(self):
"""Test empty cert request doesn't force certmonger to segfault
--
2.45.2

View File

@ -0,0 +1,47 @@
From efa57193630f244185b3f295ed0de17c6d08f75a Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 10:49:49 -0400
Subject: [PATCH] ipa-migrate - remove -V option
The versioning in ipa-migrate was removed, but the "-V" option to display the version was not removed.
Fixes: https://pagure.io/freeipa/issue/9620
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
install/tools/man/ipa-migrate.1 | 3 ---
ipaserver/install/ipa_migrate.py | 3 ---
2 files changed, 6 deletions(-)
diff --git a/install/tools/man/ipa-migrate.1 b/install/tools/man/ipa-migrate.1
index 78881d1f8a9ea91d7824e5f8b13f50aecf5ebd16..2d9d2c650a4c44a2f397d1c2ccb42fb95eea2bae 100644
--- a/install/tools/man/ipa-migrate.1
+++ b/install/tools/man/ipa-migrate.1
@@ -67,9 +67,6 @@ Reset the ID range for migrated users/groups. In "stage-mode" this is done autom
\fB\-F\fR, \fB\-\-force\fR
Ignore any errors and continue to proceed with migration effort.
.TP
-\fB\-V\fR, \fB\-\-version\fR
-Display the version of the migration tool.
-.TP
\fB\-q\fR, \fB\-\-quiet\fR
Only log errors during the migration process.
.TP
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 58351af604b8d6f4ac31432a425718a4d45e0178..6be8d9ba23b36779bf6296df757c1aca551968c0 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -389,9 +389,6 @@ class IPAMigrate():
parser.add_argument('-F', '--force',
help='Ignore errors and continue with migration',
action='store_true', default=False)
- parser.add_argument('-V', '--version',
- help='Display verison of the migration tool',
- action='store_true', default=False)
parser.add_argument('-q', '--quiet',
help='Only display errors during the migration',
action='store_true', default=False)
--
2.45.2

View File

@ -0,0 +1,37 @@
From 1b278de4ab9c5e00fb48dc2de1ea31d9bdfc94bc Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 9 Jul 2024 14:35:25 -0400
Subject: [PATCH] Fix syntax error in the selinux-luna %postun script
It was missing a trailing fi.
This bad syntax was preventing cleanup of the
{free}ipa-selinux-luna SELinux module:
Running scriptlet: freeipa-selinux-luna-4.12.0.dev202402211727+git0ee 34/44
/var/tmp/rpm-tmp.qoCDFi: line 16: syntax error: unexpected end of file
warning: %postun(freeipa-selinux-luna-4.12.0.dev202402211727+git0eeecdcec-0.fc37.noarch) scriptlet failed, exit status
Fixes: https://pagure.io/freeipa/issue/9629
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
freeipa.spec.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 1e1a0c04728972c6c53beb47dafb25d7898ab0ea..b3b19cf8881db97307836513ff2263dc4fe4ca03 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -1367,6 +1367,7 @@ fi
%postun selinux-luna
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna
+fi
%posttrans selinux
%selinux_relabel_post -s %{selinuxtype}
--
2.45.2

View File

@ -0,0 +1,231 @@
From 7ab1bcb2d364c26024db4ec99c707ebefffcd3e7 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 5 Jul 2024 15:00:59 -0400
Subject: [PATCH] Re-organize HSM validation to be more consistent/less
duplication
hsm_validator() was more or less bolted in place late in the
development cycle in in order to catch some of the more common
problems: bad token name, bad password, etc.
There was a fair bit of duplication and had the side-effect of not
reading in the token password from the --token-password-file option
in some cases.
This patch also re-adds a lost feature where an exception is raised if
both the --token-password and --token-password-file options are passed
in.
This also needs to be enforced on initial server, replica and when
called by ipa-kra-install. Given that each has a unique subject of
options some duplication remains.
Fixes: https://pagure.io/freeipa/issue/9603
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/ca.py | 72 +++++++++++++++--------------
ipaserver/install/kra.py | 56 ++++++++++++++++++++--
ipaserver/install/server/install.py | 2 +
3 files changed, 93 insertions(+), 37 deletions(-)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index dc4b47056f0e327d120ab6dad238deae3c26bbcd..b8155d9965712dbce4076e9d73d6712135309ce2 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -193,6 +193,8 @@ def hsm_validator(token_name, token_library, token_password):
if not token_name:
logger.debug("No token name, assuming not an HSM install")
return
+ if not token_password:
+ raise ValueError("No token password provided")
val, pki_version = hsm_version()
if val is False:
raise ValueError(
@@ -361,17 +363,16 @@ def install_check(standalone, replica_config, options):
host_name = options.host_name
if replica_config is None:
- if options.token_name:
- try:
- hsm_validator(
- options.token_name, options.token_library_path,
- options.token_password)
- except ValueError as e:
- raise ScriptError(str(e))
options._subject_base = options.subject_base
options._ca_subject = options.ca_subject
options._random_serial_numbers = options.random_serial_numbers
token_name = options.token_name
+ token_library_path = options.token_library_path
+ if "setup_ca" in options.__dict__:
+ setup_ca = options.setup_ca
+ else:
+ # We got here through ipa-ca-install
+ setup_ca = True
else:
# during replica install, this gets invoked before local DS is
# available, so use the remote api.
@@ -399,33 +400,36 @@ def install_check(standalone, replica_config, options):
if replica_config.setup_ca and token_name:
if not options.token_library_path:
options.token_library_path = token_library_path
- if (
- not options.token_password_file
- and not options.token_password
- ):
- if options.unattended:
- raise ScriptError("HSM token password required")
- token_password = installutils.read_password(
- f"HSM token '{token_name}'", confirm=False
- )
- if token_password is None:
- raise ScriptError("HSM token password required")
- else:
- options.token_password = token_password
-
- if options.token_password_file:
- with open(options.token_password_file, "r") as fd:
- options.token_password = fd.readline().strip()
- try:
- hsm_validator(
- token_name,
- options.token_library_path
- if options.token_library_path
- else token_library_path,
- options.token_password,
- )
- except ValueError as e:
- raise ScriptError(str(e))
+ setup_ca = replica_config.setup_ca
+
+ if setup_ca and token_name:
+ if (options.token_password_file and options.token_password):
+ raise ScriptError(
+ "token-password and token-password-file are mutually exclusive"
+ )
+ if options.token_password_file:
+ with open(options.token_password_file, "r") as fd:
+ options.token_password = fd.readline().strip()
+ if (
+ not options.token_password_file
+ and not options.token_password
+ ):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
+ token_password = installutils.read_password(
+ f"HSM token '{token_name}'", confirm=False
+ )
+ if token_password is None:
+ raise ScriptError("HSM token password required")
+ else:
+ options.token_password = token_password
+
+ try:
+ hsm_validator(
+ token_name, token_library_path,
+ options.token_password)
+ except ValueError as e:
+ raise ScriptError(str(e))
if replica_config is not None and not replica_config.setup_ca:
return
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
index 2c5b47590c26e37818f055cfd218c85d74e9b46c..dc3bc7c204394187bb7a5c4cc1b863a2091bdc49 100644
--- a/ipaserver/install/kra.py
+++ b/ipaserver/install/kra.py
@@ -16,10 +16,12 @@ from ipalib.kinit import kinit_keytab
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython import ipautil
+from ipapython.admintool import ScriptError
from ipapython.install.core import group
from ipaserver.install import ca, cainstance
from ipaserver.install import krainstance
from ipaserver.install import dsinstance
+from ipaserver.install import installutils
from ipaserver.install import service as _service
from . import dogtag
@@ -58,13 +60,61 @@ def install_check(api, replica_config, options):
"KRA can not be installed when 'ca_host' is overriden in "
"IPA configuration file.")
+ # There are three scenarios for installing a KRA
+ # 1. At install time of the initial server
+ # 2. Using ipa-kra-install
+ # 3. At install time of a replica
+ #
+ # These tests are done in reverse order. If we are doing a
+ # replica install we can check the remote CA.
+ #
+ # If we are running ipa-kra-install then there must be a CA
+ # use that.
+ #
+ # If initial install we either have the token options or we don't.
+
+ cai = cainstance.CAInstance()
+ if replica_config is not None:
+ (token_name, token_library_path) = ca.lookup_hsm_configuration(api)
+ elif cai.is_configured() and cai.hsm_enabled:
+ (token_name, token_library_path) = ca.lookup_hsm_configuration(api)
+ elif 'token_name' in options.__dict__:
+ token_name = options.token_name
+ token_library_path = options.token_library_path
+ else:
+ token_name = None
+
+ if replica_config is not None:
+ if (
+ token_name
+ and options.token_password_file
+ and options.token_password
+ ):
+ raise ScriptError(
+ "token-password and token-password-file are mutually exclusive"
+ )
+
if options.token_password_file:
with open(options.token_password_file, "r") as fd:
options.token_password = fd.readline().strip()
- if replica_config is not None:
- (token_name, token_library) = ca.lookup_hsm_configuration(api)
- ca.hsm_validator(token_name, token_library, options.token_password)
+ if (
+ token_name
+ and not options.token_password_file
+ and not options.token_password
+ ):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
+ token_password = installutils.read_password(
+ f"HSM token '{token_name}'", confirm=False
+ )
+ if token_password is None:
+ raise ScriptError("HSM token password required")
+ else:
+ options.token_password = token_password
+
+ if token_name:
+ ca.hsm_validator(token_name, token_library_path, options.token_password)
def install(api, replica_config, options, custodia):
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 1b18873363cece5e187a7c772acfcbc6c565ee97..47db1314239906a10bb77e5fc0d4c1eddc02e2da 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -663,6 +663,8 @@ def install_check(installer):
options.token_name is not None
)
):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
token_password = read_password(
f"HSM token '{options.token_name}'" , confirm=False)
if token_password is None:
--
2.45.2

View File

@ -0,0 +1,192 @@
From 4ea1ad6acae910574a524403bc82c80d24b525d6 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 13 Jun 2024 14:07:57 +0530
Subject: [PATCH] ipatests: tests related to --token-password-file
Test automation added around the --token-password-file
option for server/replica/kra install.
Related: https://pagure.io/freeipa/issue/9603
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipatests/test_integration/test_hsm.py | 85 ++++++++++++++++++++++++---
1 file changed, 77 insertions(+), 8 deletions(-)
diff --git a/ipatests/test_integration/test_hsm.py b/ipatests/test_integration/test_hsm.py
index b49af12492f7dce4bd41836b220d75d9fc99b5c2..3a33c3bda6d072aa16e361b04ac2d668902bb0e9 100644
--- a/ipatests/test_integration/test_hsm.py
+++ b/ipatests/test_integration/test_hsm.py
@@ -163,6 +163,7 @@ class BaseHSMTest(IntegrationTest):
master_extra_args = []
token_password = None
token_name = None
+ token_password_file = '/tmp/token_password'
random_serial = False
@classmethod
@@ -191,7 +192,7 @@ class BaseHSMTest(IntegrationTest):
delete_hsm_token([cls.master] + cls.replicas, cls.token_name)
@classmethod
- def sync_tokens(cls, source):
+ def sync_tokens(cls, source, token_name=None):
"""Synchronize non-networked HSM tokens between machines
source: source host for the token data
"""
@@ -207,7 +208,8 @@ class BaseHSMTest(IntegrationTest):
for host in [cls.master] + cls.replicas:
if host == source:
continue
- copy_token_files(source, [host], cls.token_name)
+ copy_token_files(source, [host],
+ token_name if token_name else cls.token_name)
class TestHSMInstall(BaseHSMTest):
@@ -218,6 +220,10 @@ class TestHSMInstall(BaseHSMTest):
def test_hsm_install_replica0_ca_less_install(self):
check_version(self.master)
+
+ self.master.put_file_contents(
+ self.token_password_file, self.token_password
+ )
tasks.install_replica(
self.master, self.replicas[0], setup_ca=False,
setup_dns=True,
@@ -307,6 +313,50 @@ class TestHSMInstall(BaseHSMTest):
assert returncode == 0
assert output == "No issues found."
+ def test_hsm_install_server_password_file(self):
+ check_version(self.master)
+ # cleanup before fresh install with password file
+ for client in self.clients:
+ tasks.uninstall_client(client)
+
+ for replica in self.replicas:
+ tasks.uninstall_master(replica)
+
+ tasks.uninstall_master(self.master)
+
+ delete_hsm_token([self.master] + self.replicas, self.token_name)
+ self.token_name, self.token_password = get_hsm_token(self.master)
+ self.master.put_file_contents(self.token_password_file,
+ self.token_password)
+ self.replicas[0].put_file_contents(self.token_password_file,
+ self.token_password)
+
+ tasks.install_master(
+ self.master, setup_dns=self.master_with_dns,
+ setup_kra=self.master_with_kra,
+ setup_adtrust=self.master_with_ad,
+ extra_args=(
+ '--token-name', self.token_name,
+ '--token-library-path', hsm_lib_path,
+ '--token-password-file', self.token_password_file
+ )
+ )
+ self.sync_tokens(self.master, token_name=self.token_name)
+
+ def test_hsm_install_replica0_password_file(self):
+ check_version(self.master)
+ tasks.install_replica(
+ self.master, self.replicas[0], setup_ca=True,
+ extra_args=('--token-password-file', self.token_password_file,)
+ )
+
+ def test_hsm_install_replica0_kra_password_file(self):
+ check_version(self.master)
+ tasks.install_kra(
+ self.replicas[0],
+ extra_args=('--token-password-file', self.token_password_file,)
+ )
+
class TestHSMInstallADTrustBase(BaseHSMTest):
"""
@@ -321,7 +371,7 @@ class TestHSMInstallADTrustBase(BaseHSMTest):
check_version(self.master)
tasks.install_replica(
self.master, self.replicas[0], setup_ca=True,
- setup_adtrust=True, setup_kra=True, setup_dns=True,
+ setup_adtrust=False, setup_kra=True, setup_dns=True,
nameservers='master' if self.master_with_dns else None,
extra_args=('--token-password', self.token_password,)
)
@@ -356,7 +406,8 @@ class TestHSMcertRenewal(BaseHSMTest):
'auditSigningCert cert-pki-ca': 'caauditSigningCert'
}
CA_TRACKING_REQS.update(KRA_TRACKING_REQS)
- self.master.put_file_contents('/tmp/token_passwd', self.token_password)
+ self.master.put_file_contents(self.token_password_file,
+ self.token_password)
for nickname in CA_TRACKING_REQS:
cert = tasks.certutil_fetch_cert(
self.master,
@@ -772,6 +823,7 @@ class TestHSMcertFixReplica(BaseHSMTest):
class TestHSMNegative(IntegrationTest):
master_with_dns = False
+ token_password_file = '/tmp/token_password'
@classmethod
def install(cls, mh):
@@ -792,7 +844,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', self.token_password
)
)
- # assert 'error message non existing token name' in result.stderr_text
assert result.returncode != 0
# wrong token password
@@ -804,7 +855,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', 'token_passwd'
)
)
- # assert 'error message wrong passwd' in result.stderr_text
assert result.returncode != 0
# wrong token lib
@@ -816,7 +866,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', self.token_password
)
)
- # assert 'error message non existing token lib' in result.stderr_text
assert result.returncode != 0
def test_hsm_negative_special_char_token_name(self):
@@ -842,7 +891,27 @@ class TestHSMNegative(IntegrationTest):
'--token-password', token_passwd
)
)
- # assert 'error message non existing token lib' in result.stderr_text
+ assert result.returncode != 0
+
+ def test_hsm_negative_token_password_and_file(self):
+ """Test token-password and token-password-file at same time
+
+ Test if command fails when --token-password and --token-password-file
+ provided at the same time results into command failure.
+ """
+ check_version(self.master)
+ self.master.put_file_contents(
+ self.token_password_file, self.token_password
+ )
+ result = tasks.install_master(
+ self.master, raiseonerr=False,
+ extra_args=(
+ '--token-name', self.token_name,
+ '--token-library-path', hsm_lib_path,
+ '--token-password', self.token_password,
+ '--token-password-file', self.token_password_file
+ )
+ )
assert result.returncode != 0
--
2.45.2

View File

@ -0,0 +1,36 @@
From 6c53a22a2cacf7807df11e51492d1a2c42aeeda1 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 18 Jun 2024 11:16:07 -0400
Subject: [PATCH] Include token password options in ipa-kra-install man page
Related: https://pagure.io/freeipa/issue/9603
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/tools/man/ipa-kra-install.1 | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/install/tools/man/ipa-kra-install.1 b/install/tools/man/ipa-kra-install.1
index 5476a4e717584cd7c6f823e3c3cb4e4948f14875..955085bf7162863a0567356417a0886e733c0b42 100644
--- a/install/tools/man/ipa-kra-install.1
+++ b/install/tools/man/ipa-kra-install.1
@@ -54,6 +54,15 @@ Log to the given file
.TP
\fB\-\-pki\-config\-override\fR=\fIFILE\fR
File containing overrides for KRA installation.
+.SS "HSM OPTIONS"
+The token name and library path are retrieved from the existing
+installation.
+.TP
+\fB\-\-token\-password\fR=\fITOKEN_PASSWORD\fR
+The PKCS#11 token password for the HSM.
+.TP
+\fB\-\-token\-password\-file\fR=\fITOKEN_PASSWORD_FILE\fR
+The full path to a file containing the PKCS#11 token password.
.SH "EXIT STATUS"
0 if the command was successful
--
2.45.2

View File

@ -0,0 +1,86 @@
From eeade50933cb2251b43ee34c642bcae69a216655 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 10:20:47 -0400
Subject: [PATCH] ipa-migrate - starttls does not work
We were previousily taking the provided ca cert and creating a temporary
file from it. This was incorrect and caused the secure connection to
fail. Instead just use the file path provided.
Fixes: https://pagure.io/freeipa/issue/9619
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/tools/man/ipa-migrate.1 | 2 +-
ipaserver/install/ipa_migrate.py | 25 +++++++++++++++++--------
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/install/tools/man/ipa-migrate.1 b/install/tools/man/ipa-migrate.1
index 2d9d2c650a4c44a2f397d1c2ccb42fb95eea2bae..47ae47ea4afa3a5a6fe25dd9bbd14c27ab5f1fdb 100644
--- a/install/tools/man/ipa-migrate.1
+++ b/install/tools/man/ipa-migrate.1
@@ -25,7 +25,7 @@ network interruptions)
In this mode everything will be migrated including the current user SIDs and
DNA ranges
.TP
-\fBstage\-mod\fR
+\fBstage\-mode\fR
In this mode, SIDs & DNA ranges are not migrated, and DNA attributes are reset
.SH "COMMANDS"
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 6be8d9ba23b36779bf6296df757c1aca551968c0..0e19b98b5be532c513876e165561f0af176baa27 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -27,7 +27,6 @@ from ipalib.x509 import IPACertificate
from ipaplatform.paths import paths
from ipapython.dn import DN
from ipapython.ipaldap import LDAPClient, LDAPEntry, realm_to_ldapi_uri
-from ipapython.ipautil import write_tmp_file
from ipapython.ipa_log_manager import standard_logging_setup
from ipaserver.install.ipa_migrate_constants import (
DS_CONFIG, DB_OBJECTS, DS_INDEXES, BIND_DN, LOG_FILE_NAME,
@@ -758,13 +757,19 @@ class IPAMigrate():
insecure_bind = False
if self.args.cacertfile is not None:
- # Store CA cert into file
- tmp_ca_cert_f = write_tmp_file(self.args.cacertfile)
- cacert = tmp_ca_cert_f.name
-
# Start TLS connection (START_TLS)
- ds_conn = LDAPClient(ldapuri, cacert=cacert, start_tls=True)
- tmp_ca_cert_f.close()
+ try:
+ ds_conn = LDAPClient(ldapuri, cacert=self.args.cacertfile,
+ start_tls=True)
+ except (
+ ldap.LDAPError,
+ errors.NetworkError,
+ errors.DatabaseError,
+ IOError
+ ) as e:
+ self.handle_error(
+ f"Failed to connect to remote server: {str(e)}"
+ )
else:
# LDAP (insecure)
ds_conn = LDAPClient(ldapuri)
@@ -773,7 +778,11 @@ class IPAMigrate():
try:
ds_conn.simple_bind(DN(self.args.bind_dn), self.bindpw,
insecure_bind=insecure_bind)
- except (errors.NetworkError, errors.ACIError) as e:
+ except (
+ errors.NetworkError,
+ errors.ACIError,
+ errors.DatabaseError
+ ) as e:
self.handle_error(f"Failed to bind to remote server: {str(e)}")
# All set, stash the remote connection
--
2.45.2

View File

@ -0,0 +1,232 @@
From 051d61fdc301f2768ac78c45e93a5f9eeff8aa28 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 25 Jun 2024 14:27:24 +0300
Subject: [PATCH] ipa-pwd-extop: differentiate OTP requirements in LDAP binds
For users who has no OTP tokens defined (yet), a missing token should
not be seen as a failure. This is needed to allow a basic password
change.
The logic around enforcement of OTP over LDAP bind is the following:
----------------------------------------------------------------------
- when LDAP OTP control is requested by the LDAP client, OTP is
explicitly required
- when EnforceLDAPOTP is set in the IPA configuration, OTP is implicitly
required, regardless of the state of LDAP client
In either case, only users with 'user-auth-type: otp' are allowed to
authenticate.
If these users have no OTP token associated yet, they will be allowed to
authenticate with their password. This is to allow initial password
change and adding an OTP token.
----------------------------------------------------------------------
Implement test that simulates lifecycle for new user who get to change
their password before adding an OTP token.
Related: https://pagure.io/freeipa/issue/5169
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 39 ++++++++++----
ipatests/test_integration/test_otp.py | 52 ++++++++++++++++---
2 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index cc170fc4b81f8ecad88f4ff4401b5651c43aaf55..c967e2cfffbd920280639f3188783ec150523b47 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1212,13 +1212,20 @@ done:
* value at the end. This leaves only the password in creds for later
* validation.
*/
+typedef enum {
+ OTP_IS_NOT_REQUIRED = 0,
+ OTP_IS_REQUIRED_EXPLICITLY,
+ OTP_IS_REQUIRED_IMPLICITLY
+} otp_req_enum;
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
- struct berval *creds, bool otpreq)
+ struct berval *creds, otp_req_enum otpreq,
+ bool *notokens)
{
uint32_t auth_types;
/* Get the configured authentication types. */
auth_types = otp_config_auth_types(otp_config, entry);
+ *notokens = false;
/*
* IMPORTANT SECTION!
@@ -1248,7 +1255,11 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
/* With no tokens, succeed if tokens aren't required. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
- return !otpreq;
+ *notokens = true;
+ if (otpreq != OTP_IS_NOT_REQUIRED)
+ /* DENY: OTP is required, either explicitly or implicitly */
+ return false;
+ return true;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
@@ -1259,7 +1270,8 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
- return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) && !otpreq;
+ return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
+ (otpreq == OTP_IS_NOT_REQUIRED);
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1452,6 +1464,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
struct tm expire_tm;
int rc = LDAP_INVALID_CREDENTIALS;
char *errMesg = NULL;
+ bool notokens = false;
/* get BIND parameters */
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
@@ -1510,8 +1523,9 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Try to do OTP first. */
syncreq = otpctrl_present(pb, OTP_SYNC_REQUEST_OID);
- otpreq = otpctrl_present(pb, OTP_REQUIRED_OID);
- if (!syncreq && !otpreq) {
+ otpreq = otpctrl_present(pb, OTP_REQUIRED_OID) ?
+ OTP_IS_REQUIRED_EXPLICITLY : OTP_IS_NOT_REQUIRED;
+ if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
if (ret != 0) {
LOG_FATAL("ipapwd_gen_checks failed!?\n");
@@ -1520,11 +1534,17 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
return 0;
}
if (krbcfg->enforce_ldap_otp) {
- otpreq = true;
+ otpreq = OTP_IS_REQUIRED_IMPLICITLY;
}
}
- if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials, otpreq))
- goto invalid_creds;
+ if (!syncreq && !ipapwd_pre_bind_otp(dn, entry,
+ credentials, otpreq, &notokens)) {
+ /* We got here because ipapwd_pre_bind_otp() returned false,
+ * it means that either token verification failed or
+ * a rule for empty tokens failed current policy. */
+ if (!(notokens || (otpreq == OTP_IS_NOT_REQUIRED)))
+ goto invalid_creds;
+ }
/* Ensure that there is a password. */
if (credentials->bv_len == 0) {
@@ -1561,7 +1581,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
* for access log to notice multi-factor authentication has happened
* https://www.port389.org/docs/389ds/design/mfa-operation-note-design.html
*/
- if (!syncreq && otpreq) {
+ if (!syncreq &&
+ ((otpreq != OTP_IS_NOT_REQUIRED) && !notokens)) {
slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_MFA_AUTH);
}
#endif
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index d2dfca4cbf8c60955e888b6f92bd88a2608bb265..350371bfe1e4c1cc6dcc89f6584f813fcb0d32a0 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -458,41 +458,81 @@ class TestOTPToken(IntegrationTest):
master = self.master
basedn = master.domain.basedn
USER1 = 'user-forced-otp'
+ TMP_PASSWORD = 'Secret1234509'
binddn = DN(f"uid={USER1},cn=users,cn=accounts,{basedn}")
- tasks.create_active_user(master, USER1, PASSWORD)
tasks.kinit_admin(master)
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '0'])
+ tasks.user_add(master, USER1, password=TMP_PASSWORD)
# Enforce use of OTP token for this user
master.run_command(['ipa', 'user-mod', USER1,
'--user-auth-type=otp'])
try:
+ # Change initial password through the IPA endpoint
+ url = f'https://{master.hostname}/ipa/session/change_password'
+ master.run_command(['curl', '-d', f'user={USER1}',
+ '-d', f'old_password={TMP_PASSWORD}',
+ '-d', f'new_password={PASSWORD}',
+ '--referer', f'https://{master.hostname}/ipa',
+ url])
conn = master.ldap_connect()
# First, attempt authenticating with a password but without LDAP
# control to enforce OTP presence and without server-side
# enforcement of the OTP presence check.
conn.simple_bind(binddn, f"{PASSWORD}")
- # Add an OTP token now
- otpuid, totp = add_otptoken(master, USER1, otptype="totp")
# Next, enforce Password+OTP for a user with OTP token
master.run_command(['ipa', 'config-mod', '--addattr',
'ipaconfigstring=EnforceLDAPOTP'])
+ # Try to bind without OTP because there is no OTP token yet,
+ # the operation should succeed because OTP enforcement is implicit
+ # and there is no token yet, so it is allowed.
+ conn.simple_bind(binddn, f"{PASSWORD}")
+ conn.unbind()
+ # Add an OTP token now
+ otpuid, totp = add_otptoken(master, USER1, otptype="totp")
# Next, authenticate with Password+OTP and with the LDAP control
# this operation should succeed
otpvalue = totp.generate(int(time.time())).decode("ascii")
+ conn = master.ldap_connect()
conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
client_controls=[
BooleanControl(
controlType="2.16.840.1.113730.3.8.10.7",
booleanValue=True)])
- # Remove token
- del_otptoken(self.master, otpuid)
+ conn.unbind()
+ # Sleep to make sure we are going to use a different token value
+ time.sleep(45)
+ # Use OTP token again, without LDAP control, should succeed
+ # because OTP enforcement is implicit
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ conn = master.ldap_connect()
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}")
+ conn.unbind()
# Now, try to authenticate without otp and without control
- # this operation should fail
+ # this operation should fail because we have OTP token associated
+ # with the user account
try:
+ conn = master.ldap_connect()
conn.simple_bind(binddn, f"{PASSWORD}")
+ conn.unbind()
except errors.ACIError:
pass
+ # Sleep to make sure we are going to use a different token value
+ time.sleep(45)
+ # Use OTP token again, without LDAP control, should succeed
+ # because OTP enforcement is implicit
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ # Finally, change password again, now that otp is present
+ master.run_command(['curl', '-d', f'user={USER1}',
+ '-d', f'old_password={PASSWORD}',
+ '-d', f'new_password={TMP_PASSWORD}0',
+ '-d', f'otp={otpvalue}',
+ '--referer', f'https://{master.hostname}/ipa',
+ url])
+ # Remove token
+ del_otptoken(self.master, otpuid)
master.run_command(['ipa', 'config-mod', '--delattr',
'ipaconfigstring=EnforceLDAPOTP'])
finally:
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
master.run_command(['ipa', 'user-del', USER1])
--
2.45.2

View File

@ -0,0 +1,74 @@
From 8b703150a47bf509f37856bdc27cfa99e85e5e6b Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Mon, 24 Jun 2024 13:48:24 +0530
Subject: [PATCH] ipatests: Test replica installation using AD admin.
Test to verify that replica connection check is not failing when
the AD administrator Administrator@AD.EXAMPLE.COM is
used for the deployment or promotion of a replica
Related: https://pagure.io/freeipa/issue/9542
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
.../test_replica_promotion.py | 46 +++++++++++++++++++
1 files changed, 46 insertions(+)
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index 7ef44c571c8a4106577d27f4712f661be873dacc..c754cef88cb275987f5afdaad43f2ea07e3b7476 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -1318,3 +1318,49 @@ class TestHiddenReplicaKRA(IntegrationTest):
self.replicas[0].hostname, '--state=hidden'
])
assert result.returncode == 0
+
+
+class TestReplicaConn(IntegrationTest):
+ num_replicas = 1
+ num_ad_domains = 1
+
+ @classmethod
+ def install(cls, mh):
+ cls.replica = cls.replicas[0]
+ cls.ad = cls.ads[0]
+ ad_domain = cls.ad.domain.name
+ cls.ad_admin = 'Administrator@{}'.format(ad_domain.upper())
+ cls.adview = 'Default Trust View'
+ tasks.install_master(cls.master, setup_adtrust=True)
+ tasks.configure_dns_for_trust(cls.master, cls.ad)
+ tasks.establish_trust_with_ad(cls.master, cls.ad.domain.name)
+ tasks.install_client(cls.master, cls.replica)
+
+ def test_replica_conncheck_ad_admin(self):
+ """
+ Test to verify that replica installation is not failing for
+ replica connection check when AD administrator
+ Administrator@AD.EXAMPLE.COM is used for the deployment
+ or promotion of a replica.
+
+ Related : https://pagure.io/freeipa/issue/9542
+ """
+ self.master.run_command(
+ ['ipa', 'idoverrideuser-add', self.adview, self.ad_admin]
+ )
+ self.master.run_command(
+ ["ipa", "group-add-member", "admins", "--idoverrideusers",
+ self.ad_admin]
+ )
+ tasks.clear_sssd_cache(self.master)
+
+ self.replica.run_command(
+ ["ipa-replica-install", "--setup-ca", "-U", "--ip-address",
+ self.replica.ip, "--realm", self.replica.domain.realm,
+ "--domain", self.replica.domain.name,
+ "--principal={0}".format(self.ad_admin),
+ "--password", self.master.config.ad_admin_password]
+ )
+ logs = self.replica.get_file_contents(paths.IPAREPLICA_CONNCHECK_LOG)
+ error = "not allowed to perform server connection check"
+ assert error.encode() not in logs
--
2.45.2

View File

@ -0,0 +1,46 @@
From 85a853ba93c1d23d5bad13a1ae2bee802dc90131 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 11:25:53 -0400
Subject: [PATCH] Issue 9621 - ipa-migrate - should not update mapped
attributes in managed entries
We should not migrate mmapped attributes (uidNumber, gidNumber) from
managed entries
We should also not migrate DNA ranges in staging mode
Fixes: https://pagure.io/freeipa/issue/9621
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/ipa_migrate.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 0e19b98b5be532c513876e165561f0af176baa27..20f59f84db21022b66c0aa1ffd696d99aef85a44 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -1322,6 +1322,9 @@ class IPAMigrate():
self.args.reset_range
or self.mode == "stage-mode"
) and attr.lower() in DNA_REGEN_ATTRS:
+ # Skip dna attributes from managed entries
+ if 'mepManagedBy' in local_entry:
+ break
# Ok, set the magic regen value
local_entry[attr] = [DNA_REGEN_VAL]
self.log_debug("Resetting the DNA range for: "
@@ -1816,6 +1819,9 @@ class IPAMigrate():
# processing the entries
for entry in remote_dse:
for dse_item in DS_CONFIG.items():
+ if dse_item[0] == "dna" and self.mode == "stage-mode":
+ # Do not migrate DNA ranges in staging mode
+ continue
dse = dse_item[1]
for dn in dse['dn']:
if DN(dn) == DN(entry['dn']):
--
2.45.2

View File

@ -224,7 +224,7 @@
Name: %{package_name}
Version: %{IPA_VERSION}
Release: 5%{?rc_version:.%rc_version}%{?dist}
Release: 6%{?rc_version:.%rc_version}%{?dist}
Summary: The Identity, Policy and Audit system
License: GPL-3.0-or-later
@ -260,6 +260,16 @@ Patch0009: 0009-PKINIT-certificate-fix-renewal-on-hidden-replica.patch
Patch0010: 0010-ipatests-add-test-for-PKINIT-renewal-on-hidden-repli.patch
Patch0011: 0011-ipatests-Tests-for-ipa-ipa-migration-tool.patch
Patch0012: 0012-ipa_sidgen-Allow-sidgen_task-to-continue-after-findi.patch
Patch0013: 0013-ipatests-mark-test_ca_show_error_handling-as-xfail.patch
Patch0014: 0014-ipa-migrate-remove-V-option.patch
Patch0015: 0015-Fix-syntax-error-in-the-selinux-luna-postun-script.patch
Patch0016: 0016-Re-organize-HSM-validation-to-be-more-consistent-les.patch
Patch0017: 0017-ipatests-tests-related-to-token-password-file.patch
Patch0018: 0018-Include-token-password-options-in-ipa-kra-install-ma.patch
Patch0019: 0019-ipa-migrate-starttls-does-not-work.patch
Patch0020: 0020-ipa-pwd-extop-differentiate-OTP-requirements-in-LDAP.patch
Patch0021: 0021-ipatests-Test-replica-installation-using-AD-admin.patch
Patch0022: 0022-Issue-9621-ipa-migrate-should-not-update-mapped-attr.patch
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
%endif
%endif
@ -1359,6 +1369,7 @@ fi
%postun selinux-luna
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna
fi
%posttrans selinux
%selinux_relabel_post -s %{selinuxtype}
@ -1872,6 +1883,15 @@ fi
%endif
%changelog
* Thu Jul 18 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.0-6
- Resolves: RHEL-47292 Include latest fixes in python3-ipatests packages
- Resolves: RHEL-47146 Syntax error uninstalling the selinux-luna subpackage
- Resolves: RHEL-46009 ipa-migrate with -Z option fails with ValueError: option error
- Resolves: RHEL-46003 ipa-migrate -V options fails to display version
- Resolves: RHEL-45463 ipa-migrate stage-mode is failing with error: Modifying a mapped attribute in a managed entry is not allowed
- Resolves: RHEL-40890 ipa-server-install: token_password_file read in kra.install_check after calling hsm_validator in ca.install_check
- Resolves: RHEL-40661 Adjust "ipa config-mod --addattr ipaconfigstring=EnforceLDAPOTP" to allow for non OTP users in some cases
* Mon Jul 08 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.0-5
- Resolves: RHEL-37285 IPA Web UI not showing replication agreement for non-admin users
- Resolves: RHEL-42703 PSKC.xml issues with ipa_otptoken_import.py