import ipa-4.9.11-5.module+el8.8.0+18147+84fe6ec1
This commit is contained in:
parent
ad479c1a26
commit
a6f738aabe
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/freeipa-4.9.10.tar.gz
|
SOURCES/freeipa-4.9.11.tar.gz
|
||||||
|
@ -1 +1 @@
|
|||||||
8f2b6a7f52348421fa7c67048dd5ae454f2642fb SOURCES/freeipa-4.9.10.tar.gz
|
4ef188d43f5f2a09e214dd2bae68595a5977bb61 SOURCES/freeipa-4.9.11.tar.gz
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
From ff54fe2fdfbab11e08a138cdfd0da900ee865e3d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
|
||||||
Date: Fri, 17 Jun 2022 11:22:32 -0300
|
|
||||||
Subject: [PATCH] ipa-otpd: Fix build on older versions of gcc.
|
|
||||||
|
|
||||||
Older versions of gcc do not support unnamed parameters.
|
|
||||||
|
|
||||||
This patch fixes the build on older gcc by applying the same idiom for
|
|
||||||
unsued parameters as used by other functions in the same module.
|
|
||||||
|
|
||||||
Signed-off-by: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
|
||||||
---
|
|
||||||
daemons/ipa-otpd/oauth2.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/daemons/ipa-otpd/oauth2.c b/daemons/ipa-otpd/oauth2.c
|
|
||||||
index df1ffd50d..11d5c135f 100644
|
|
||||||
--- a/daemons/ipa-otpd/oauth2.c
|
|
||||||
+++ b/daemons/ipa-otpd/oauth2.c
|
|
||||||
@@ -319,8 +319,9 @@ static int check_access_token_reply(struct child_ctx *child_ctx,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void oauth2_on_child_readable(verto_ctx *, verto_ev *ev)
|
|
||||||
+static void oauth2_on_child_readable(verto_ctx *vctx, verto_ev *ev)
|
|
||||||
{
|
|
||||||
+ (void)vctx; /* Unused */
|
|
||||||
static char buf[10240];
|
|
||||||
ssize_t io = 0;
|
|
||||||
struct child_ctx *child_ctx = NULL;
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From 651e28c1fb6b86ad1fbd4ea98644e00b7042499c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Date: Dec 02 2022 12:21:22 +0000
|
||||||
|
Subject: updates: fix memberManager ACI to allow managers from a specified group
|
||||||
|
|
||||||
|
|
||||||
|
The original implementation of the member manager added support for both
|
||||||
|
user and group managers but left out upgrade scenario. This means when
|
||||||
|
upgrading existing installation a manager whose rights defined by the
|
||||||
|
group membership would not be able to add group members until the ACI is
|
||||||
|
fixed.
|
||||||
|
|
||||||
|
Remove old ACI and add a full one during upgrade step.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9286
|
||||||
|
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
|
||||||
|
index a168bb9..4a7ba13 100644
|
||||||
|
--- a/install/updates/20-aci.update
|
||||||
|
+++ b/install/updates/20-aci.update
|
||||||
|
@@ -141,11 +141,13 @@ add:aci:(targetattr = "usercertificate")(version 3.0;acl "selfservice:Users can
|
||||||
|
|
||||||
|
# Allow member managers to modify members of user groups
|
||||||
|
dn: cn=groups,cn=accounts,$SUFFIX
|
||||||
|
-add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+remove:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaUserGroup)")(version 3.0; acl "Allow member managers to modify members of user groups"; allow (write) userattr = "memberManager#USERDN" or userattr = "memberManager#GROUPDN";)
|
||||||
|
|
||||||
|
# Allow member managers to modify members of host groups
|
||||||
|
dn: cn=hostgroups,cn=accounts,$SUFFIX
|
||||||
|
-add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+remove:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN";)
|
||||||
|
+add:aci: (targetattr = "member")(targetfilter = "(objectclass=ipaHostGroup)")(version 3.0; acl "Allow member managers to modify members of host groups"; allow (write) userattr = "memberManager#USERDN" or userattr = "memberManager#GROUPDN";)
|
||||||
|
|
||||||
|
# Hosts can add and delete their own services
|
||||||
|
dn: cn=services,cn=accounts,$SUFFIX
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 703ab8c4dfb7f8fd1540c3849ad469d39695a26f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Jan 25 2023 16:57:02 +0000
|
||||||
|
Subject: trust-add: handle missing msSFU30MaxGidNumber
|
||||||
|
|
||||||
|
|
||||||
|
When ipa trust-add is executed with --range-type ad-trust-posix,
|
||||||
|
the server tries to find the max uidnumber and max gidnumber
|
||||||
|
from AD domain controller.
|
||||||
|
The values are extracted from the entry
|
||||||
|
CN=<domain>,CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System,<AD suffix>
|
||||||
|
in the msSFU30MaxUidNumber and msSFU30MaxGidNumber attributes.
|
||||||
|
|
||||||
|
msSFU30MaxUidNumber is required but not msSFU30MaxGidNumber.
|
||||||
|
In case msSFU30MaxGidNumber is missing, the code is currently assigning
|
||||||
|
a "None" value and later on evaluates the max between this value and
|
||||||
|
msSFU30MaxUidNumber. The max function cannot compare None and a list
|
||||||
|
of string and triggers an exception.
|
||||||
|
|
||||||
|
To avoid the exception, assign [b'0'] to max gid if msSFU30MaxGidNumber
|
||||||
|
is missing. This way, the comparison succeeds and max returns the
|
||||||
|
value from msSFU30MaxUidNumber.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9310
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
|
||||||
|
index c074f6d..79264b8 100644
|
||||||
|
--- a/ipaserver/plugins/trust.py
|
||||||
|
+++ b/ipaserver/plugins/trust.py
|
||||||
|
@@ -379,7 +379,10 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
|
||||||
|
range_type = u'ipa-ad-trust-posix'
|
||||||
|
|
||||||
|
max_uid = info.get('msSFU30MaxUidNumber')
|
||||||
|
- max_gid = info.get('msSFU30MaxGidNumber', None)
|
||||||
|
+ # if max_gid is missing, assume 0 and the max will
|
||||||
|
+ # be obtained from max_uid. We just checked that
|
||||||
|
+ # msSFU30MaxUidNumber is defined
|
||||||
|
+ max_gid = info.get('msSFU30MaxGidNumber', [b'0'])
|
||||||
|
max_id = int(max(max_uid, max_gid)[0])
|
||||||
|
|
||||||
|
base_id = int(info.get('msSFU30OrderNumber')[0])
|
||||||
|
|
@ -0,0 +1,76 @@
|
|||||||
|
From e8ef2c2f226704ce510525f07675107179124a95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sumedh Sidhaye <ssidhaye@redhat.com>
|
||||||
|
Date: Feb 02 2023 06:53:56 +0000
|
||||||
|
Subject: With the commit #99a74d7, 389-ds changed the message returned in ipa-healthcheck.
|
||||||
|
|
||||||
|
|
||||||
|
Previously the message was:
|
||||||
|
|
||||||
|
"\n\nIn Directory Server, we offer one hash suitable for this "
|
||||||
|
"(PBKDF2_SHA256) and one hash\nfor \"legacy\" support (SSHA512)."
|
||||||
|
"\n\nYour configuration does not use these for password storage "
|
||||||
|
"or the root password storage\nscheme.\n"
|
||||||
|
|
||||||
|
but now the message is:
|
||||||
|
|
||||||
|
\n\nIn Directory Server, we offer one hash suitable for this "
|
||||||
|
"(PBKDF2-SHA512) and one hash\nfor \"legacy\" support (SSHA512)."
|
||||||
|
"\n\nYour configuration does not use these for password storage "
|
||||||
|
"or the root password storage\nscheme.\n"
|
||||||
|
|
||||||
|
PBKDF2_SHA256 has been replaced with PBKDF2-SHA512
|
||||||
|
|
||||||
|
Pagure: https://pagure.io/freeipa/issue/9238
|
||||||
|
|
||||||
|
Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
||||||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Reviewed-By: Stanislav Levin <slev@altlinux.org>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
index 18a665e..60e8de9 100644
|
||||||
|
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
+++ b/ipatests/test_integration/test_ipahealthcheck.py
|
||||||
|
@@ -1312,9 +1312,6 @@ class TestIpaHealthCheck(IntegrationTest):
|
||||||
|
"""
|
||||||
|
error_msg = (
|
||||||
|
"\n\nIn Directory Server, we offer one hash suitable for this "
|
||||||
|
- "(PBKDF2_SHA256) and one hash\nfor \"legacy\" support (SSHA512)."
|
||||||
|
- "\n\nYour configuration does not use these for password storage "
|
||||||
|
- "or the root password storage\nscheme.\n"
|
||||||
|
)
|
||||||
|
returncode, data = run_healthcheck(
|
||||||
|
self.master, "ipahealthcheck.ds.config", "ConfigCheck",
|
||||||
|
|
||||||
|
From 1bdd8147e7fa1032025dc6f6868e26f285744ee1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Jan 11 2023 11:56:30 +0000
|
||||||
|
Subject: ipatests: mark test_smb as xfail
|
||||||
|
|
||||||
|
|
||||||
|
Mark the test test_smb.py::TestSMB::test_smb_service_s4u2self as xfail.
|
||||||
|
|
||||||
|
Related: https://pagure.io/freeipa/issue/9124
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_smb.py b/ipatests/test_integration/test_smb.py
|
||||||
|
index eb3981b..30f8d59 100644
|
||||||
|
--- a/ipatests/test_integration/test_smb.py
|
||||||
|
+++ b/ipatests/test_integration/test_smb.py
|
||||||
|
@@ -349,6 +349,7 @@ class TestSMB(IntegrationTest):
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
osinfo.id == 'fedora' and osinfo.version_number <= (31,),
|
||||||
|
reason='Test requires krb 1.18')
|
||||||
|
+ @pytest.mark.xfail(reason="Pagure ticket 9124", strict=True)
|
||||||
|
def test_smb_service_s4u2self(self):
|
||||||
|
"""Test S4U2Self operation by IPA service
|
||||||
|
against both AD and IPA users
|
||||||
|
|
@ -1,131 +0,0 @@
|
|||||||
From ff4152539b96d309dcceaf854a3e0a49f435acff Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Date: Mon, 20 Jun 2022 09:09:11 +0200
|
|
||||||
Subject: [PATCH] Preserve user: fix the confusing summary
|
|
||||||
|
|
||||||
When ipa user-del --preserve is called, the command output
|
|
||||||
prints a summary with:
|
|
||||||
Deleted user: user1
|
|
||||||
although the user was preserved.
|
|
||||||
Replace the summary with
|
|
||||||
Preserved user: user1
|
|
||||||
to reflect what was actually done.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9187
|
|
||||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
---
|
|
||||||
ipaserver/plugins/user.py | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
|
|
||||||
index 25d2bb6aa..fa8a67d3d 100644
|
|
||||||
--- a/ipaserver/plugins/user.py
|
|
||||||
+++ b/ipaserver/plugins/user.py
|
|
||||||
@@ -56,6 +56,7 @@ from .idviews import remove_ipaobject_overrides
|
|
||||||
from ipalib.plugable import Registry
|
|
||||||
from .baseldap import (
|
|
||||||
LDAPObject,
|
|
||||||
+ pkey_to_unicode,
|
|
||||||
pkey_to_value,
|
|
||||||
LDAPCreate,
|
|
||||||
LDAPSearch,
|
|
||||||
@@ -701,6 +702,7 @@ class user_del(baseuser_del):
|
|
||||||
__doc__ = _('Delete a user.')
|
|
||||||
|
|
||||||
msg_summary = _('Deleted user "%(value)s"')
|
|
||||||
+ msg_summary_preserved = _('Preserved user "%(value)s"')
|
|
||||||
|
|
||||||
takes_options = baseuser_del.takes_options + (
|
|
||||||
Bool('preserve?',
|
|
||||||
@@ -831,6 +833,8 @@ class user_del(baseuser_del):
|
|
||||||
failed.append(pkey_to_value(pkey, options))
|
|
||||||
|
|
||||||
val = dict(result=dict(failed=failed), value=preserved)
|
|
||||||
+ val['summary'] = self.msg_summary_preserved % dict(
|
|
||||||
+ value=pkey_to_unicode(preserved))
|
|
||||||
return val
|
|
||||||
else:
|
|
||||||
return super(user_del, self).execute(*keys, **options)
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
||||||
From 4984ff210a169129e4e56b10e54e9c795520855c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Date: Mon, 20 Jun 2022 09:12:14 +0200
|
|
||||||
Subject: [PATCH] xmlrpc tests: updated expected output for preserved user
|
|
||||||
|
|
||||||
Update the expected summary for the command
|
|
||||||
ipa user-del --preserve
|
|
||||||
|
|
||||||
The command now displays: Preserved user: user1
|
|
||||||
instead of Deleted user: user1
|
|
||||||
|
|
||||||
Related: https://pagure.io/freeipa/issue/9187
|
|
||||||
|
|
||||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
---
|
|
||||||
ipatests/test_xmlrpc/test_stageuser_plugin.py | 5 ++++-
|
|
||||||
ipatests/test_xmlrpc/tracker/user_plugin.py | 7 ++++++-
|
|
||||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py
|
|
||||||
index bc606b093..fd146876c 100644
|
|
||||||
--- a/ipatests/test_xmlrpc/test_stageuser_plugin.py
|
|
||||||
+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py
|
|
||||||
@@ -479,11 +479,12 @@ class TestActive(XMLRPC_test):
|
|
||||||
|
|
||||||
def test_delete_preserve(self, user):
|
|
||||||
user.ensure_exists()
|
|
||||||
- user.track_delete()
|
|
||||||
+ user.track_delete(preserve=True)
|
|
||||||
command = user.make_delete_command(no_preserve=False, preserve=True)
|
|
||||||
result = command()
|
|
||||||
user.check_delete(result)
|
|
||||||
|
|
||||||
+ user.track_delete(preserve=False)
|
|
||||||
command = user.make_delete_command()
|
|
||||||
result = command()
|
|
||||||
user.check_delete(result)
|
|
||||||
@@ -622,6 +623,7 @@ class TestCustomAttr(XMLRPC_test):
|
|
||||||
assert 'BusinessCat' in result['result'][u'businesscategory']
|
|
||||||
|
|
||||||
# delete the user with --preserve
|
|
||||||
+ user_customattr.track_delete(preserve=True)
|
|
||||||
command = user_customattr.make_delete_command(no_preserve=False,
|
|
||||||
preserve=True)
|
|
||||||
result = command()
|
|
||||||
@@ -763,6 +765,7 @@ class TestGroups(XMLRPC_test):
|
|
||||||
result = command()
|
|
||||||
group.check_retrieve(result)
|
|
||||||
|
|
||||||
+ user.track_delete(preserve=True)
|
|
||||||
command = user.make_delete_command(no_preserve=False, preserve=True)
|
|
||||||
result = command()
|
|
||||||
user.check_delete(result)
|
|
||||||
diff --git a/ipatests/test_xmlrpc/tracker/user_plugin.py b/ipatests/test_xmlrpc/tracker/user_plugin.py
|
|
||||||
index 03c106250..b04be4c19 100644
|
|
||||||
--- a/ipatests/test_xmlrpc/tracker/user_plugin.py
|
|
||||||
+++ b/ipatests/test_xmlrpc/tracker/user_plugin.py
|
|
||||||
@@ -273,9 +273,14 @@ class UserTracker(CertmapdataMixin, KerberosAliasMixin, Tracker):
|
|
||||||
|
|
||||||
def check_delete(self, result):
|
|
||||||
""" Check 'user-del' command result """
|
|
||||||
+ if u'preserved' in self.attrs and self.attrs[u'preserved']:
|
|
||||||
+ summary = u'Preserved user "%s"' % self.uid
|
|
||||||
+ else:
|
|
||||||
+ summary = u'Deleted user "%s"' % self.uid
|
|
||||||
+
|
|
||||||
assert_deepequal(dict(
|
|
||||||
value=[self.uid],
|
|
||||||
- summary=u'Deleted user "%s"' % self.uid,
|
|
||||||
+ summary=summary,
|
|
||||||
result=dict(failed=[]),
|
|
||||||
), result)
|
|
||||||
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
From 3675bd1d7aca443832bb9bb2f521cc4d3a088aec Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Wed, 29 Jun 2022 13:25:55 +0000
|
|
||||||
Subject: [PATCH] Only calculate LDAP password grace when the password is
|
|
||||||
expired
|
|
||||||
|
|
||||||
The user's pwd expiration was retrieved but inadvertently was never
|
|
||||||
compared to current time. So any LDAP bind, including from the
|
|
||||||
IPA API, counted against the grace period. There is no need to go
|
|
||||||
through the graceperiod code for non-expired passwords.
|
|
||||||
|
|
||||||
https://pagure.io/freeipa/issue/1539
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../ipa-graceperiod/ipa_graceperiod.c | 12 +++++++++---
|
|
||||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
index 0860b5c20..a3f57cb4b 100644
|
|
||||||
--- a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
+++ b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
@@ -359,7 +359,8 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
Slapi_ValueSet *values = NULL;
|
|
||||||
long grace_limit = 0;
|
|
||||||
int grace_user_time;
|
|
||||||
- char *pwd_expiration = NULL;
|
|
||||||
+ char *tmpstr = NULL;
|
|
||||||
+ time_t pwd_expiration;
|
|
||||||
int pwresponse_requested = 0;
|
|
||||||
Slapi_PBlock *pbtm = NULL;
|
|
||||||
Slapi_Mods *smods = NULL;
|
|
||||||
@@ -414,12 +415,17 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
}
|
|
||||||
slapi_value_free(&objectclass);
|
|
||||||
|
|
||||||
- pwd_expiration = slapi_entry_attr_get_charptr(target_entry, "krbPasswordExpiration");
|
|
||||||
- if (pwd_expiration == NULL) {
|
|
||||||
+ tmpstr = slapi_entry_attr_get_charptr(target_entry, "krbPasswordExpiration");
|
|
||||||
+ if (tmpstr == NULL) {
|
|
||||||
/* No expiration means nothing to do */
|
|
||||||
LOG_TRACE("No krbPasswordExpiration for %s, nothing to do\n", dn);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
+ pwd_expiration = ipapwd_gentime_to_time_t(tmpstr);
|
|
||||||
+ if (pwd_expiration > time(NULL)) {
|
|
||||||
+ /* Not expired, nothing to see here */
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
ldrc = ipagraceperiod_getpolicy(target_entry, &policy_entry,
|
|
||||||
&values, &actual_type_name,
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
From 6f50b00953c0000d6da8db0f5e8974ae33d7b5d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Jan 16 2023 07:44:50 +0000
|
||||||
|
Subject: server install: remove error log about missing bkup file
|
||||||
|
|
||||||
|
|
||||||
|
The client installer code can be called in 3 different ways:
|
||||||
|
- from ipa-client-install CLI
|
||||||
|
- from ipa-replica-install CLI if the client is not already installed
|
||||||
|
- from ipa-server-install
|
||||||
|
|
||||||
|
In the last case, the client installer is called with
|
||||||
|
options.on_master=True
|
||||||
|
As a result, it's skipping the part that is creating the krb5
|
||||||
|
configuration:
|
||||||
|
if not options.on_master:
|
||||||
|
nolog = tuple()
|
||||||
|
configure_krb5_conf(...)
|
||||||
|
|
||||||
|
The configure_krb5_conf method is the place where the krb5.conf file is
|
||||||
|
backup'ed with the extention ".ipabkp". For a master installation, this
|
||||||
|
code is not called and the ipabkp file does not exist => delete raises
|
||||||
|
an error.
|
||||||
|
|
||||||
|
When delete fails because the file does not exist, no need to log an
|
||||||
|
error message.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9306
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||||
|
index e5d3e82..6e7f17d 100644
|
||||||
|
--- a/ipaclient/install/client.py
|
||||||
|
+++ b/ipaclient/install/client.py
|
||||||
|
@@ -124,10 +124,9 @@ def cleanup(func):
|
||||||
|
os.rmdir(ccache_dir)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
- try:
|
||||||
|
- os.remove(krb_name + ".ipabkp")
|
||||||
|
- except OSError:
|
||||||
|
- logger.error("Could not remove %s.ipabkp", krb_name)
|
||||||
|
+ # During master installation, the .ipabkp file is not created
|
||||||
|
+ # Ignore the delete error if it is "file does not exist"
|
||||||
|
+ remove_file(krb_name + ".ipabkp")
|
||||||
|
|
||||||
|
return inner
|
||||||
|
|
||||||
|
|
@ -1,346 +0,0 @@
|
|||||||
From 857713c5a9c8e0b62c06dd92e69c09eeb34b2e99 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Anuja More <amore@redhat.com>
|
|
||||||
Date: Mon, 23 May 2022 12:26:34 +0530
|
|
||||||
Subject: [PATCH] Add end to end integration tests for external IdP
|
|
||||||
|
|
||||||
Added tests for HBAC and SUDO rule and other
|
|
||||||
test scenarios.
|
|
||||||
|
|
||||||
Related : https://pagure.io/freeipa/issue/8805
|
|
||||||
Related: https://pagure.io/freeipa/issue/8803
|
|
||||||
Related: https://pagure.io/freeipa/issue/8804
|
|
||||||
|
|
||||||
Signed-off-by: Anuja More <amore@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
---
|
|
||||||
ipatests/test_integration/test_idp.py | 260 ++++++++++++++++++++++----
|
|
||||||
1 file changed, 226 insertions(+), 34 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ipatests/test_integration/test_idp.py b/ipatests/test_integration/test_idp.py
|
|
||||||
index 8f9e92e6a..2ffe6a208 100644
|
|
||||||
--- a/ipatests/test_integration/test_idp.py
|
|
||||||
+++ b/ipatests/test_integration/test_idp.py
|
|
||||||
@@ -1,6 +1,8 @@
|
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import time
|
|
||||||
+import pytest
|
|
||||||
+import re
|
|
||||||
|
|
||||||
import textwrap
|
|
||||||
from ipaplatform.paths import paths
|
|
||||||
@@ -22,12 +24,12 @@ driver.get(verification_uri)
|
|
||||||
try:
|
|
||||||
element = WebDriverWait(driver, 90).until(
|
|
||||||
EC.presence_of_element_located((By.ID, "username")))
|
|
||||||
- driver.find_element_by_id("username").send_keys("testuser1")
|
|
||||||
- driver.find_element_by_id("password").send_keys("{passwd}")
|
|
||||||
- driver.find_element_by_id("kc-login").click()
|
|
||||||
+ driver.find_element(By.ID, "username").send_keys("testuser1")
|
|
||||||
+ driver.find_element(By.ID, "password").send_keys("{passwd}")
|
|
||||||
+ driver.find_element(By.ID, "kc-login").click()
|
|
||||||
element = WebDriverWait(driver, 90).until(
|
|
||||||
EC.presence_of_element_located((By.ID, "kc-login")))
|
|
||||||
- driver.find_element_by_id("kc-login").click()
|
|
||||||
+ driver.find_element(By.ID, "kc-login").click()
|
|
||||||
assert "Device Login Successful" in driver.page_source
|
|
||||||
finally:
|
|
||||||
now = datetime.now().strftime("%M-%S")
|
|
||||||
@@ -39,18 +41,12 @@ finally:
|
|
||||||
def add_user_code(host, verification_uri):
|
|
||||||
contents = user_code_script.format(uri=verification_uri,
|
|
||||||
passwd=host.config.admin_password)
|
|
||||||
- host.put_file_contents("/tmp/add_user_code.py", contents)
|
|
||||||
- tasks.run_repeatedly(
|
|
||||||
- host, ['python3', '/tmp/add_user_code.py'])
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-def get_verification_uri(host, since, keycloak_server_name):
|
|
||||||
- command = textwrap.dedent("""
|
|
||||||
- journalctl -u ipa-otpd\\* --since="%s" | grep "user_code:" | awk '{ print substr($7,2,9) }'""" % since) # noqa: E501
|
|
||||||
- user_code = host.run_command(command).stdout_text.rstrip("\r\n")
|
|
||||||
- uri = ("https://{0}:8443/auth/realms/master/device?user_code={1}".format(
|
|
||||||
- keycloak_server_name, user_code))
|
|
||||||
- return uri
|
|
||||||
+ try:
|
|
||||||
+ host.put_file_contents("/tmp/add_user_code.py", contents)
|
|
||||||
+ tasks.run_repeatedly(
|
|
||||||
+ host, ['python3', '/tmp/add_user_code.py'])
|
|
||||||
+ finally:
|
|
||||||
+ host.run_command(["rm", "-f", "/tmp/add_user_code.py"])
|
|
||||||
|
|
||||||
|
|
||||||
def kinit_idp(host, user, keycloak_server):
|
|
||||||
@@ -58,11 +54,14 @@ def kinit_idp(host, user, keycloak_server):
|
|
||||||
tasks.kdestroy_all(host)
|
|
||||||
# create armor for FAST
|
|
||||||
host.run_command(["kinit", "-n", "-c", ARMOR])
|
|
||||||
- since = time.strftime('%Y-%m-%d %H:%M:%S')
|
|
||||||
cmd = ["kinit", "-T", ARMOR, user]
|
|
||||||
+
|
|
||||||
with host.spawn_expect(cmd, default_timeout=100) as e:
|
|
||||||
- e.expect('Authenticate at .+: ')
|
|
||||||
- uri = get_verification_uri(host, since, keycloak_server.hostname)
|
|
||||||
+ e.expect('Authenticate at (.+) and press ENTER.:')
|
|
||||||
+ prompt = e.get_last_output()
|
|
||||||
+ uri = re.search(r'Authenticate at (.*?) and press ENTER.:', prompt
|
|
||||||
+ ).group(1)
|
|
||||||
+ time.sleep(15)
|
|
||||||
if uri:
|
|
||||||
add_user_code(keycloak_server, uri)
|
|
||||||
e.sendline('\n')
|
|
||||||
@@ -74,21 +73,27 @@ def kinit_idp(host, user, keycloak_server):
|
|
||||||
|
|
||||||
class TestIDPKeycloak(IntegrationTest):
|
|
||||||
|
|
||||||
- num_replicas = 1
|
|
||||||
+ num_replicas = 2
|
|
||||||
topology = 'line'
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def install(cls, mh):
|
|
||||||
- tasks.install_master(cls.master, setup_dns=True)
|
|
||||||
- tasks.install_client(cls.master, cls.replicas[0])
|
|
||||||
- content = cls.master.get_file_contents(paths.IPA_DEFAULT_CONF,
|
|
||||||
- encoding='utf-8')
|
|
||||||
- new_content = content + "\noidc_child_debug_level = 10"
|
|
||||||
- cls.master.put_file_contents(paths.IPA_DEFAULT_CONF, new_content)
|
|
||||||
+ cls.client = cls.replicas[0]
|
|
||||||
+ cls.replica = cls.replicas[1]
|
|
||||||
+ tasks.install_master(cls.master)
|
|
||||||
+ tasks.install_client(cls.master, cls.replicas[0],
|
|
||||||
+ extra_args=["--mkhomedir"])
|
|
||||||
+ tasks.install_replica(cls.master, cls.replicas[1])
|
|
||||||
+ for host in [cls.master, cls.replicas[0], cls.replicas[1]]:
|
|
||||||
+ content = host.get_file_contents(paths.IPA_DEFAULT_CONF,
|
|
||||||
+ encoding='utf-8')
|
|
||||||
+ new_content = content + "\noidc_child_debug_level = 10"
|
|
||||||
+ host.put_file_contents(paths.IPA_DEFAULT_CONF, new_content)
|
|
||||||
with tasks.remote_sssd_config(cls.master) as sssd_config:
|
|
||||||
sssd_config.edit_domain(
|
|
||||||
cls.master.domain, 'krb5_auth_timeout', 1100)
|
|
||||||
tasks.clear_sssd_cache(cls.master)
|
|
||||||
+ tasks.clear_sssd_cache(cls.replicas[0])
|
|
||||||
tasks.kinit_admin(cls.master)
|
|
||||||
cls.master.run_command(["ipa", "config-mod", "--user-auth-type=idp",
|
|
||||||
"--user-auth-type=password"])
|
|
||||||
@@ -97,20 +102,207 @@ class TestIDPKeycloak(IntegrationTest):
|
|
||||||
cls.replicas[0].run_command(xvfb)
|
|
||||||
|
|
||||||
def test_auth_keycloak_idp(self):
|
|
||||||
- keycloak_srv = self.replicas[0]
|
|
||||||
- create_quarkus.setup_keycloakserver(keycloak_srv)
|
|
||||||
+ """
|
|
||||||
+ Test case to check that OAuth 2.0 Device
|
|
||||||
+ Authorization Grant is working as
|
|
||||||
+ expected for user configured with external idp.
|
|
||||||
+ """
|
|
||||||
+ create_quarkus.setup_keycloakserver(self.client)
|
|
||||||
time.sleep(60)
|
|
||||||
- create_quarkus.setup_keycloak_client(keycloak_srv)
|
|
||||||
+ create_quarkus.setup_keycloak_client(self.client)
|
|
||||||
tasks.kinit_admin(self.master)
|
|
||||||
- cmd = ["ipa", "idp-add", "keycloak", "--provider=keycloak",
|
|
||||||
+ cmd = ["ipa", "idp-add", "keycloakidp", "--provider=keycloak",
|
|
||||||
"--client-id=ipa_oidc_client", "--org=master",
|
|
||||||
- "--base-url={0}:8443/auth".format(keycloak_srv.hostname)]
|
|
||||||
+ "--base-url={0}:8443/auth".format(self.client.hostname)]
|
|
||||||
self.master.run_command(cmd, stdin_text="{0}\n{0}".format(
|
|
||||||
- keycloak_srv.config.admin_password))
|
|
||||||
+ self.client.config.admin_password))
|
|
||||||
tasks.user_add(self.master, 'keycloakuser',
|
|
||||||
extra_args=["--user-auth-type=idp",
|
|
||||||
"--idp-user-id=testuser1@ipa.test",
|
|
||||||
- "--idp=keycloak"]
|
|
||||||
+ "--idp=keycloakidp"]
|
|
||||||
)
|
|
||||||
+ list_user = self.master.run_command(
|
|
||||||
+ ["ipa", "user-find", "--idp-user-id=testuser1@ipa.test"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakuser" in list_user.stdout_text
|
|
||||||
+ list_by_idp = self.master.run_command(["ipa", "user-find",
|
|
||||||
+ "--idp=keycloakidp"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakuser" in list_by_idp.stdout_text
|
|
||||||
+ list_by_user = self.master.run_command(
|
|
||||||
+ ["ipa", "user-find", "--idp-user-id=testuser1@ipa.test", "--all"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakidp" in list_by_user.stdout_text
|
|
||||||
+ tasks.clear_sssd_cache(self.master)
|
|
||||||
+ kinit_idp(self.master, 'keycloakuser', keycloak_server=self.client)
|
|
||||||
+
|
|
||||||
+ @pytest.fixture
|
|
||||||
+ def hbac_setup_teardown(self):
|
|
||||||
+ # allow sshd only on given host
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-disable", "allow_all"])
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-add", "rule1"])
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-add-user", "rule1",
|
|
||||||
+ "--users=keycloakuser"]
|
|
||||||
+ )
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-add-host", "rule1",
|
|
||||||
+ "--hosts", self.replica.hostname])
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-add-service", "rule1",
|
|
||||||
+ "--hbacsvcs=sshd"]
|
|
||||||
+ )
|
|
||||||
+ tasks.clear_sssd_cache(self.master)
|
|
||||||
+ tasks.clear_sssd_cache(self.replica)
|
|
||||||
+ yield
|
|
||||||
+
|
|
||||||
+ # cleanup
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-enable", "allow_all"])
|
|
||||||
+ self.master.run_command(["ipa", "hbacrule-del", "rule1"])
|
|
||||||
+
|
|
||||||
+ def test_auth_hbac(self, hbac_setup_teardown):
|
|
||||||
+ """
|
|
||||||
+ Test case to check that hbacrule is working as
|
|
||||||
+ expected for user configured with external idp.
|
|
||||||
+ """
|
|
||||||
+ kinit_idp(self.master, 'keycloakuser', keycloak_server=self.client)
|
|
||||||
+ ssh_cmd = "ssh -q -K -l keycloakuser {0} whoami"
|
|
||||||
+ valid_ssh = self.master.run_command(
|
|
||||||
+ ssh_cmd.format(self.replica.hostname))
|
|
||||||
+ assert "keycloakuser" in valid_ssh.stdout_text
|
|
||||||
+ negative_ssh = self.master.run_command(
|
|
||||||
+ ssh_cmd.format(self.master.hostname), raiseonerr=False
|
|
||||||
+ )
|
|
||||||
+ assert negative_ssh.returncode == 255
|
|
||||||
+
|
|
||||||
+ def test_auth_sudo_idp(self):
|
|
||||||
+ """
|
|
||||||
+ Test case to check that sudorule is working as
|
|
||||||
+ expected for user configured with external idp.
|
|
||||||
+ """
|
|
||||||
+ tasks.kdestroy_all(self.master)
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ # rule: keycloakuser are allowed to execute yum on
|
|
||||||
+ # the client machine as root.
|
|
||||||
+ cmdlist = [
|
|
||||||
+ ["ipa", "sudocmd-add", "/usr/bin/yum"],
|
|
||||||
+ ["ipa", "sudorule-add", "sudorule"],
|
|
||||||
+ ['ipa', 'sudorule-add-user', '--users=keycloakuser',
|
|
||||||
+ 'sudorule'],
|
|
||||||
+ ['ipa', 'sudorule-add-host', '--hosts',
|
|
||||||
+ self.client.hostname, 'sudorule'],
|
|
||||||
+ ['ipa', 'sudorule-add-runasuser',
|
|
||||||
+ '--users=root', 'sudorule'],
|
|
||||||
+ ['ipa', 'sudorule-add-allow-command',
|
|
||||||
+ '--sudocmds=/usr/bin/yum', 'sudorule'],
|
|
||||||
+ ['ipa', 'sudorule-show', 'sudorule', '--all'],
|
|
||||||
+ ['ipa', 'sudorule-add-option',
|
|
||||||
+ 'sudorule', '--sudooption', "!authenticate"]
|
|
||||||
+ ]
|
|
||||||
+ for cmd in cmdlist:
|
|
||||||
+ self.master.run_command(cmd)
|
|
||||||
+ tasks.clear_sssd_cache(self.master)
|
|
||||||
+ tasks.clear_sssd_cache(self.client)
|
|
||||||
+ try:
|
|
||||||
+ cmd = 'sudo -ll -U keycloakuser'
|
|
||||||
+ test = self.client.run_command(cmd).stdout_text
|
|
||||||
+ assert "User keycloakuser may run the following commands" in test
|
|
||||||
+ assert "/usr/bin/yum" in test
|
|
||||||
+ kinit_idp(self.client, 'keycloakuser', self.client)
|
|
||||||
+ test_sudo = 'su -c "sudo yum list wget" keycloakuser'
|
|
||||||
+ self.client.run_command(test_sudo)
|
|
||||||
+ list_fail = self.master.run_command(cmd).stdout_text
|
|
||||||
+ assert "User keycloakuser is not allowed to run sudo" in list_fail
|
|
||||||
+ finally:
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ self.master.run_command(['ipa', 'sudorule-del', 'sudorule'])
|
|
||||||
+ self.master.run_command(["ipa", "sudocmd-del", "/usr/bin/yum"])
|
|
||||||
+
|
|
||||||
+ def test_auth_replica(self):
|
|
||||||
+ """
|
|
||||||
+ Test case to check that OAuth 2.0 Device
|
|
||||||
+ Authorization is working as expected on replica.
|
|
||||||
+ """
|
|
||||||
+ tasks.clear_sssd_cache(self.master)
|
|
||||||
+ tasks.clear_sssd_cache(self.replica)
|
|
||||||
+ tasks.kinit_admin(self.replica)
|
|
||||||
+ list_user = self.master.run_command(
|
|
||||||
+ ["ipa", "user-find", "--idp-user-id=testuser1@ipa.test"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakuser" in list_user.stdout_text
|
|
||||||
+ list_by_idp = self.replica.run_command(["ipa", "user-find",
|
|
||||||
+ "--idp=keycloakidp"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakuser" in list_by_idp.stdout_text
|
|
||||||
+ list_by_user = self.replica.run_command(
|
|
||||||
+ ["ipa", "user-find", "--idp-user-id=testuser1@ipa.test", "--all"]
|
|
||||||
+ )
|
|
||||||
+ assert "keycloakidp" in list_by_user.stdout_text
|
|
||||||
+ kinit_idp(self.replica, 'keycloakuser', keycloak_server=self.client)
|
|
||||||
+
|
|
||||||
+ def test_idp_with_services(self):
|
|
||||||
+ """
|
|
||||||
+ Test case to check that services can be configured
|
|
||||||
+ auth indicator as idp.
|
|
||||||
+ """
|
|
||||||
tasks.clear_sssd_cache(self.master)
|
|
||||||
- kinit_idp(self.master, 'keycloakuser', keycloak_srv)
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ domain = self.master.domain.name.upper()
|
|
||||||
+ services = [
|
|
||||||
+ "DNS/{0}@{1}".format(self.master.hostname, domain),
|
|
||||||
+ "HTTP/{0}@{1}".format(self.client.hostname, domain),
|
|
||||||
+ "dogtag/{0}@{1}".format(self.master.hostname, domain),
|
|
||||||
+ "ipa-dnskeysyncd/{0}@{1}".format(self.master.hostname, domain)
|
|
||||||
+ ]
|
|
||||||
+ try:
|
|
||||||
+ for service in services:
|
|
||||||
+ test = self.master.run_command(["ipa", "service-mod", service,
|
|
||||||
+ "--auth-ind=idp"]
|
|
||||||
+ )
|
|
||||||
+ assert "Authentication Indicators: idp" in test.stdout_text
|
|
||||||
+ finally:
|
|
||||||
+ for service in services:
|
|
||||||
+ self.master.run_command(["ipa", "service-mod", service,
|
|
||||||
+ "--auth-ind="])
|
|
||||||
+
|
|
||||||
+ def test_idp_backup_restore(self):
|
|
||||||
+ """
|
|
||||||
+ Test case to check that after restore data is retrieved
|
|
||||||
+ with related idp configuration.
|
|
||||||
+ """
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ user = "backupuser"
|
|
||||||
+ cmd = ["ipa", "idp-add", "testidp", "--provider=keycloak",
|
|
||||||
+ "--client-id=ipa_oidc_client", "--org=master",
|
|
||||||
+ "--base-url={0}:8443/auth".format(self.client.hostname)]
|
|
||||||
+ self.master.run_command(cmd, stdin_text="{0}\n{0}".format(
|
|
||||||
+ self.client.config.admin_password))
|
|
||||||
+
|
|
||||||
+ tasks.user_add(self.master, user,
|
|
||||||
+ extra_args=["--user-auth-type=idp",
|
|
||||||
+ "--idp-user-id=testuser1@ipa.test",
|
|
||||||
+ "--idp=testidp"]
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ backup_path = tasks.get_backup_dir(self.master)
|
|
||||||
+ # change data after backup
|
|
||||||
+ self.master.run_command(['ipa', 'user-del', user])
|
|
||||||
+ self.master.run_command(['ipa', 'idp-del', 'testidp'])
|
|
||||||
+ dirman_password = self.master.config.dirman_password
|
|
||||||
+ self.master.run_command(['ipa-restore', backup_path],
|
|
||||||
+ stdin_text=dirman_password + '\nyes')
|
|
||||||
+ try:
|
|
||||||
+ list_user = self.master.run_command(
|
|
||||||
+ ['ipa', 'user-show', 'backupuser', '--all']
|
|
||||||
+ ).stdout_text
|
|
||||||
+ assert "External IdP configuration: testidp" in list_user
|
|
||||||
+ assert "User authentication types: idp" in list_user
|
|
||||||
+ assert ("External IdP user identifier: "
|
|
||||||
+ "testuser1@ipa.test") in list_user
|
|
||||||
+ list_idp = self.master.run_command(['ipa', 'idp-find', 'testidp'])
|
|
||||||
+ assert "testidp" in list_idp.stdout_text
|
|
||||||
+ kinit_idp(self.master, user, self.client)
|
|
||||||
+ finally:
|
|
||||||
+ tasks.kdestroy_all(self.master)
|
|
||||||
+ tasks.kinit_admin(self.master)
|
|
||||||
+ self.master.run_command(["rm", "-rf", backup_path])
|
|
||||||
+ self.master.run_command(["ipa", "idp-del", "testidp"])
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From 2deaaa788cbdde22d5b15566599fdcf7a10f02c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Date: Feb 02 2023 10:08:26 +0000
|
||||||
|
Subject: automember-rebuild: add a notice about high CPU usage
|
||||||
|
|
||||||
|
|
||||||
|
The automember-rebuild task may require high CPU usage
|
||||||
|
if many users/hosts/groups are processed.
|
||||||
|
Add a note in the ipa automember-rebuild CLI output
|
||||||
|
and in the WebUI confirmation message.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9320
|
||||||
|
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||||
|
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/install/ui/test/data/i18n_messages.json b/install/ui/test/data/i18n_messages.json
|
||||||
|
index 49d2883..5b73548 100644
|
||||||
|
--- a/install/ui/test/data/i18n_messages.json
|
||||||
|
+++ b/install/ui/test/data/i18n_messages.json
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
"actions": {
|
||||||
|
"apply": "Apply",
|
||||||
|
"automember_rebuild": "Rebuild auto membership",
|
||||||
|
- "automember_rebuild_confirm": "Are you sure you want to rebuild auto membership?",
|
||||||
|
+ "automember_rebuild_confirm": "Are you sure you want to rebuild auto membership? In case of a high number of users, hosts or groups, the operation may require high CPU usage.",
|
||||||
|
"automember_rebuild_success": "Automember rebuild membership task completed",
|
||||||
|
"confirm": "Are you sure you want to proceed with the action?",
|
||||||
|
"delete_confirm": "Are you sure you want to delete ${object}?",
|
||||||
|
diff --git a/ipaclient/plugins/automember.py b/ipaclient/plugins/automember.py
|
||||||
|
index df4a2e5..7108dc9 100644
|
||||||
|
--- a/ipaclient/plugins/automember.py
|
||||||
|
+++ b/ipaclient/plugins/automember.py
|
||||||
|
@@ -34,3 +34,11 @@ class automember_add_condition(MethodOverride):
|
||||||
|
flags=['suppress_empty'],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+@register(override=True, no_fail=True)
|
||||||
|
+class automember_rebuild(MethodOverride):
|
||||||
|
+ def interactive_prompt_callback(self, kw):
|
||||||
|
+ msg = _('IMPORTANT: In case of a high number of users, hosts or '
|
||||||
|
+ 'groups, the operation may require high CPU usage.')
|
||||||
|
+ self.Backend.textui.print_plain(msg)
|
||||||
|
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
|
||||||
|
index 5ffa7a2..e1e920f 100644
|
||||||
|
--- a/ipaserver/plugins/internal.py
|
||||||
|
+++ b/ipaserver/plugins/internal.py
|
||||||
|
@@ -160,7 +160,11 @@ class i18n_messages(Command):
|
||||||
|
"actions": {
|
||||||
|
"apply": _("Apply"),
|
||||||
|
"automember_rebuild": _("Rebuild auto membership"),
|
||||||
|
- "automember_rebuild_confirm": _("Are you sure you want to rebuild auto membership?"),
|
||||||
|
+ "automember_rebuild_confirm": _(
|
||||||
|
+ "Are you sure you want to rebuild auto membership? In case of "
|
||||||
|
+ "a high number of users, hosts or groups, the operation "
|
||||||
|
+ "may require high CPU usage."
|
||||||
|
+ ),
|
||||||
|
"automember_rebuild_success": _("Automember rebuild membership task completed"),
|
||||||
|
"confirm": _("Are you sure you want to proceed with the action?"),
|
||||||
|
"delete_confirm": _("Are you sure you want to delete ${object}?"),
|
||||||
|
|
@ -0,0 +1,185 @@
|
|||||||
|
From 2a0868fccbc9f4dfc540a7d3bb5dfa22c0bdce4e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 14:22:30 +0200
|
||||||
|
Subject: [PATCH 1/2] ipa-kdb: PAC consistency checker needs to handle child
|
||||||
|
domains as well
|
||||||
|
|
||||||
|
When PAC check is performed, we might get a signing TGT instead of the
|
||||||
|
client DB entry. This means it is a principal from a trusted domain but
|
||||||
|
we don't know which one exactly because we only have a krbtgt for the
|
||||||
|
forest root. This happens in MIT Kerberos 1.20 or later where KDB's
|
||||||
|
issue_pac() callback never gets the original client principal directly.
|
||||||
|
|
||||||
|
Look into known child domains as well and make pass the check if both
|
||||||
|
NetBIOS name and SID correspond to one of the trusted domains under this
|
||||||
|
forest root. Move check for the SID before NetBIOS name check because we
|
||||||
|
can use SID of the domain in PAC to find out the right child domain in
|
||||||
|
our trusted domains' topology list.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9316
|
||||||
|
|
||||||
|
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||||
|
---
|
||||||
|
daemons/ipa-kdb/ipa_kdb_mspac.c | 51 +++++++++++++++++++++------------
|
||||||
|
1 file changed, 32 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
index a15050e2166..476d1cb558a 100644
|
||||||
|
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||||
|
@@ -1827,11 +1827,43 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
bool result;
|
||||||
|
char *domstr = NULL;
|
||||||
|
|
||||||
|
+ ipactx = ipadb_get_context(context);
|
||||||
|
+ if (!ipactx || !ipactx->mspac) {
|
||||||
|
+ return KRB5_KDB_DBNOTINITED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
domain = get_domain_from_realm_update(context, realm);
|
||||||
|
if (!domain) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* check exact sid */
|
||||||
|
+ result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
|
||||||
|
+ if (!result) {
|
||||||
|
+ struct ipadb_mspac *mspac_ctx = ipactx->mspac;
|
||||||
|
+ result = FALSE;
|
||||||
|
+ /* Didn't match but perhaps the original PAC was issued by a child domain's DC? */
|
||||||
|
+ for (k = 0; k < mspac_ctx->num_trusts; k++) {
|
||||||
|
+ result = dom_sid_check(&mspac_ctx->trusts[k].domsid,
|
||||||
|
+ info->info->info3.base.domain_sid, true);
|
||||||
|
+ if (result) {
|
||||||
|
+ domain = &mspac_ctx->trusts[k];
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!result) {
|
||||||
|
+ domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
|
||||||
|
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
||||||
|
+ "expected domain SID = %s, "
|
||||||
|
+ "found domain SID = %s",
|
||||||
|
+ domain->domain_name, domain->domain_sid,
|
||||||
|
+ domstr ? domstr : "<failed to display>");
|
||||||
|
+ talloc_free(domstr);
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* At this point we may have changed the domain we look at, */
|
||||||
|
/* check netbios/flat name */
|
||||||
|
if (strcasecmp(info->info->info3.base.logon_domain.string,
|
||||||
|
domain->flat_name) != 0) {
|
||||||
|
@@ -1843,21 +1875,6 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* check exact sid */
|
||||||
|
- result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
|
||||||
|
- if (!result) {
|
||||||
|
- domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
|
||||||
|
- if (!domstr) {
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
- krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
||||||
|
- "expected domain SID = %s, "
|
||||||
|
- "found domain SID = %s",
|
||||||
|
- domain->domain_name, domain->domain_sid, domstr);
|
||||||
|
- talloc_free(domstr);
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* Check if this domain has been filtered out by the trust itself*/
|
||||||
|
if (domain->parent != NULL) {
|
||||||
|
for(k = 0; k < domain->parent->len_sid_blocklist_incoming; k++) {
|
||||||
|
@@ -1944,10 +1961,6 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||||
|
* should include different possibilities into account
|
||||||
|
* */
|
||||||
|
if (info->info->info3.sidcount != 0) {
|
||||||
|
- ipactx = ipadb_get_context(context);
|
||||||
|
- if (!ipactx || !ipactx->mspac) {
|
||||||
|
- return KRB5_KDB_DBNOTINITED;
|
||||||
|
- }
|
||||||
|
count = info->info->info3.sidcount;
|
||||||
|
i = 0;
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
From 1a4f2597253c750696f6cd34613b375dc30fe456 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anuja More <amore@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2023 19:27:49 +0530
|
||||||
|
Subject: [PATCH 2/2] Add test for SSH with GSSAPI auth.
|
||||||
|
|
||||||
|
Added test for aduser with GSSAPI authentication.
|
||||||
|
|
||||||
|
Related : https://pagure.io/freeipa/issue/9316
|
||||||
|
|
||||||
|
Signed-off-by: Anuja More <amore@redhat.com>
|
||||||
|
---
|
||||||
|
ipatests/test_integration/test_trust.py | 46 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 46 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
|
||||||
|
index 21c814ff1a9..a1ed906c6ae 100644
|
||||||
|
--- a/ipatests/test_integration/test_trust.py
|
||||||
|
+++ b/ipatests/test_integration/test_trust.py
|
||||||
|
@@ -527,6 +527,35 @@ def test_subordinate_suffix(self):
|
||||||
|
.format(self.ad_domain, subordinate_suffix))
|
||||||
|
self.ad.run_command(['powershell', '-c', cmd])
|
||||||
|
|
||||||
|
+ def test_ssh_aduser(self):
|
||||||
|
+ """Test ssh with GSSAPI is working with aduser
|
||||||
|
+
|
||||||
|
+ When kerberos ticket is obtained for child domain user
|
||||||
|
+ and ssh with this ticket should be successful
|
||||||
|
+ with no password prompt.
|
||||||
|
+
|
||||||
|
+ Related : https://pagure.io/freeipa/issue/9316
|
||||||
|
+ """
|
||||||
|
+ testuser = 'testuser@{0}'.format(self.ad_domain)
|
||||||
|
+ testusersub = 'subdomaintestuser@{0}'.format(self.ad_subdomain)
|
||||||
|
+
|
||||||
|
+ def sshuser(host, user):
|
||||||
|
+ tasks.kdestroy_all(host)
|
||||||
|
+ try:
|
||||||
|
+ tasks.kinit_as_user(host, user,
|
||||||
|
+ host.config.ad_admin_password
|
||||||
|
+ )
|
||||||
|
+ ssh_cmd = "ssh -q -K -l {user} {host} hostname"
|
||||||
|
+ valid_ssh = host.run_command(
|
||||||
|
+ ssh_cmd.format(user=user, host=host.hostname)
|
||||||
|
+ )
|
||||||
|
+ assert host.hostname in valid_ssh.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ tasks.kdestroy_all(host)
|
||||||
|
+
|
||||||
|
+ sshuser(self.master, testuser)
|
||||||
|
+ sshuser(self.master, testusersub)
|
||||||
|
+
|
||||||
|
def test_remove_nonposix_trust(self):
|
||||||
|
self.remove_trust(self.ad)
|
||||||
|
tasks.unconfigure_dns_for_trust(self.master, self.ad)
|
||||||
|
@@ -784,6 +813,23 @@ def test_user_gid_uid_resolution_in_external_treedomain_trust(self):
|
||||||
|
assert re.search(
|
||||||
|
testuser_regex, result.stdout_text), result.stdout_text
|
||||||
|
|
||||||
|
+ def test_ssh_adtreeuser(self):
|
||||||
|
+ testuser = 'treetestuser@{0}'.format(self.ad_treedomain)
|
||||||
|
+ self.master.run_command(["id", testuser])
|
||||||
|
+ tasks.clear_sssd_cache(self.master)
|
||||||
|
+ tasks.kdestroy_all(self.master)
|
||||||
|
+ try:
|
||||||
|
+ tasks.kinit_as_user(self.master, testuser,
|
||||||
|
+ password="Secret123456"
|
||||||
|
+ )
|
||||||
|
+ ssh_cmd = "ssh -q -K -l {user} {host} hostname"
|
||||||
|
+ valid_ssh = self.master.run_command(
|
||||||
|
+ ssh_cmd.format(user=testuser, host=self.master.hostname)
|
||||||
|
+ )
|
||||||
|
+ assert self.master.hostname in valid_ssh.stdout_text
|
||||||
|
+ finally:
|
||||||
|
+ tasks.kdestroy_all(self.master)
|
||||||
|
+
|
||||||
|
def test_remove_external_treedomain_trust(self):
|
||||||
|
self.remove_trust(self.tree_ad)
|
||||||
|
tasks.unconfigure_dns_for_trust(self.master, self.ad, self.tree_ad)
|
@ -1,67 +0,0 @@
|
|||||||
From 991849cf58fa990ad4540a61214b5ab4fcd4baa1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Armando Neto <abiagion@redhat.com>
|
|
||||||
Date: Fri, 8 Jul 2022 15:56:31 -0300
|
|
||||||
Subject: [PATCH] webui: Do not allow empty pagination size
|
|
||||||
|
|
||||||
Pagination size must be required, the current validators are triggered after
|
|
||||||
form is submitted, thus the only way for check if data is not empty is by making
|
|
||||||
the field required.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9192
|
|
||||||
|
|
||||||
Signed-off-by: Armando Neto <abiagion@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../ui/src/freeipa/Application_controller.js | 1 +
|
|
||||||
ipatests/test_webui/test_misc_cases.py | 19 +++++++++++++++++++
|
|
||||||
2 files changed, 20 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
|
|
||||||
index 46aabc9c4..140ee8fe0 100644
|
|
||||||
--- a/install/ui/src/freeipa/Application_controller.js
|
|
||||||
+++ b/install/ui/src/freeipa/Application_controller.js
|
|
||||||
@@ -318,6 +318,7 @@ define([
|
|
||||||
$type: 'text',
|
|
||||||
name: 'pagination_size',
|
|
||||||
label: '@i18n:customization.table_pagination',
|
|
||||||
+ required: true,
|
|
||||||
validators: ['positive_integer']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/ipatests/test_webui/test_misc_cases.py b/ipatests/test_webui/test_misc_cases.py
|
|
||||||
index 5f7ffb54e..aca9e1a99 100644
|
|
||||||
--- a/ipatests/test_webui/test_misc_cases.py
|
|
||||||
+++ b/ipatests/test_webui/test_misc_cases.py
|
|
||||||
@@ -11,6 +11,11 @@ from ipatests.test_webui.ui_driver import screenshot
|
|
||||||
import pytest
|
|
||||||
import re
|
|
||||||
|
|
||||||
+try:
|
|
||||||
+ from selenium.webdriver.common.by import By
|
|
||||||
+except ImportError:
|
|
||||||
+ pass
|
|
||||||
+
|
|
||||||
|
|
||||||
@pytest.mark.tier1
|
|
||||||
class TestMiscCases(UI_driver):
|
|
||||||
@@ -26,3 +31,17 @@ class TestMiscCases(UI_driver):
|
|
||||||
ver_re = re.compile('version: .*')
|
|
||||||
assert re.search(ver_re, about_text), 'Version not found'
|
|
||||||
self.dialog_button_click('ok')
|
|
||||||
+
|
|
||||||
+ @screenshot
|
|
||||||
+ def test_customization_pagination_input_required(self):
|
|
||||||
+ """Test if 'pagination size' is required when submitting the form."""
|
|
||||||
+ self.init_app()
|
|
||||||
+
|
|
||||||
+ self.profile_menu_action('configuration')
|
|
||||||
+ self.fill_input('pagination_size', '')
|
|
||||||
+ self.dialog_button_click('save')
|
|
||||||
+
|
|
||||||
+ pagination_size_elem = self.find(
|
|
||||||
+ ".widget[name='pagination_size']", By.CSS_SELECTOR)
|
|
||||||
+
|
|
||||||
+ self.assert_field_validation_required(parent=pagination_size_elem)
|
|
||||||
--
|
|
||||||
2.36.1
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From b35c75d864040b98ed3f9214d5d17d32f06d6ee1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
Date: Mon, 11 Jul 2022 14:20:32 -0400
|
||||||
|
Subject: [PATCH] Wipe the ipa-ca DNS record when updating system records
|
||||||
|
|
||||||
|
If a server with a CA has been marked as hidden and
|
||||||
|
contains the last A or AAAA address then that address
|
||||||
|
would remain in the ipa-ca entry.
|
||||||
|
|
||||||
|
This is because update-dns-system-records did not delete
|
||||||
|
values, it just re-computed them. So if no A or AAAA
|
||||||
|
records were found then the existing value was left.
|
||||||
|
|
||||||
|
Fixes: https://pagure.io/freeipa/issue/9195
|
||||||
|
|
||||||
|
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
---
|
||||||
|
ipaserver/dns_data_management.py | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py
|
||||||
|
index e2bc530ee8a..aaae5446856 100644
|
||||||
|
--- a/ipaserver/dns_data_management.py
|
||||||
|
+++ b/ipaserver/dns_data_management.py
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
from time import sleep, time
|
||||||
|
|
||||||
|
from ipalib import errors
|
||||||
|
+from ipalib.constants import IPA_CA_RECORD
|
||||||
|
from ipalib.dns import record_name_format
|
||||||
|
from ipapython.dnsutil import DNSName
|
||||||
|
from ipaserver.install import installutils
|
||||||
|
@@ -187,7 +188,7 @@ def __add_uri_records(
|
||||||
|
|
||||||
|
def __add_ca_records_from_hostname(self, zone_obj, hostname):
|
||||||
|
assert isinstance(hostname, DNSName) and hostname.is_absolute()
|
||||||
|
- r_name = DNSName('ipa-ca') + self.domain_abs
|
||||||
|
+ r_name = DNSName(IPA_CA_RECORD) + self.domain_abs
|
||||||
|
rrsets = None
|
||||||
|
end_time = time() + CA_RECORDS_DNS_TIMEOUT
|
||||||
|
while True:
|
||||||
|
@@ -210,6 +211,7 @@ def __add_ca_records_from_hostname(self, zone_obj, hostname):
|
||||||
|
|
||||||
|
for rrset in rrsets:
|
||||||
|
for rd in rrset:
|
||||||
|
+ logger.debug("Adding CA IP %s for %s", rd.to_text(), hostname)
|
||||||
|
rdataset = zone_obj.get_rdataset(
|
||||||
|
r_name, rd.rdtype, create=True)
|
||||||
|
rdataset.add(rd, ttl=self.TTL)
|
||||||
|
@@ -461,6 +463,14 @@ def update_base_records(self):
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
+ # Remove the ipa-ca record(s). They will be reconstructed in
|
||||||
|
+ # get_base_records().
|
||||||
|
+ r_name = DNSName(IPA_CA_RECORD) + self.domain_abs
|
||||||
|
+ try:
|
||||||
|
+ self.api_instance.Command.dnsrecord_del(
|
||||||
|
+ self.domain_abs, r_name, del_all=True)
|
||||||
|
+ except errors.NotFound:
|
||||||
|
+ pass
|
||||||
|
base_zone = self.get_base_records()
|
||||||
|
for record_name, node in base_zone.items():
|
||||||
|
set_cname_template = record_name in names_requiring_cname_templates
|
@ -1,56 +0,0 @@
|
|||||||
From ade5093b08f92b279c200f341e96972a74f644d8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Carla Martinez <carlmart@redhat.com>
|
|
||||||
Date: Fri, 29 Jul 2022 13:16:16 +0200
|
|
||||||
Subject: [PATCH] webui: Allow grace login limit
|
|
||||||
|
|
||||||
There was no support for setting the grace login limit on the WebUI. The
|
|
||||||
only way to so was only via CLI:
|
|
||||||
|
|
||||||
`ipa pwpolicy-mod --gracelimit=2 global_policy`
|
|
||||||
|
|
||||||
Thus, the grace login limit must be updated from the policy section and
|
|
||||||
this will reflect also on the user settings (under the 'Password Policy'
|
|
||||||
section)
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9211
|
|
||||||
|
|
||||||
Signed-off-by: Carla Martinez <carlmart@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
---
|
|
||||||
install/ui/src/freeipa/policy.js | 3 +++
|
|
||||||
install/ui/src/freeipa/user.js | 5 +++++
|
|
||||||
2 files changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/policy.js b/install/ui/src/freeipa/policy.js
|
|
||||||
index fa2028a52..7ec103636 100644
|
|
||||||
--- a/install/ui/src/freeipa/policy.js
|
|
||||||
+++ b/install/ui/src/freeipa/policy.js
|
|
||||||
@@ -72,6 +72,9 @@ return {
|
|
||||||
{
|
|
||||||
name: 'cospriority',
|
|
||||||
required: true
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: 'passwordgracelimit'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
|
|
||||||
index a580db035..b47c97f72 100644
|
|
||||||
--- a/install/ui/src/freeipa/user.js
|
|
||||||
+++ b/install/ui/src/freeipa/user.js
|
|
||||||
@@ -318,6 +318,11 @@ return {
|
|
||||||
label: '@mo-param:pwpolicy:krbpwdlockoutduration:label',
|
|
||||||
read_only: true,
|
|
||||||
measurement_unit: 'seconds'
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: 'passwordgracelimit',
|
|
||||||
+ label: '@mo-param:pwpolicy:passwordgracelimit:label',
|
|
||||||
+ read_only: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 05a298f56485222583cb7dd4f6a3a4c5c77fc8cf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Date: Sun, 7 Aug 2022 12:44:47 +0200
|
|
||||||
Subject: [PATCH] check_repl_update: in progress is a boolean
|
|
||||||
|
|
||||||
With the fix for https://pagure.io/freeipa/issue/9171,
|
|
||||||
nsds5replicaUpdateInProgress is now handled as a boolean.
|
|
||||||
One remaining occurrence was still handling it as a string
|
|
||||||
and calling lower() on its value.
|
|
||||||
|
|
||||||
Replace with direct boolean comparison.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9218
|
|
||||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
---
|
|
||||||
ipaserver/install/replication.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
|
|
||||||
index 16be3760c..9d9aa1c4b 100644
|
|
||||||
--- a/ipaserver/install/replication.py
|
|
||||||
+++ b/ipaserver/install/replication.py
|
|
||||||
@@ -1152,7 +1152,7 @@ class ReplicationManager:
|
|
||||||
except (ValueError, TypeError, KeyError):
|
|
||||||
end = 0
|
|
||||||
# incremental update is done if inprogress is false and end >= start
|
|
||||||
- done = inprogress and inprogress.lower() == 'false' and start <= end
|
|
||||||
+ done = inprogress is not None and not inprogress and start <= end
|
|
||||||
logger.info("Replication Update in progress: %s: status: %s: "
|
|
||||||
"start: %d: end: %d",
|
|
||||||
inprogress, status, start, end)
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
|||||||
From 1316cd8b2252c2543cf2ef2186956a8833037b1e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 21 Jul 2022 09:28:46 -0400
|
|
||||||
Subject: [PATCH] Disabling gracelimit does not prevent LDAP binds
|
|
||||||
|
|
||||||
Originally the code treated 0 as disabled. This was
|
|
||||||
changed during the review process to -1 but one remnant
|
|
||||||
was missed effetively allowing gracelimit 0 to also mean
|
|
||||||
disabled.
|
|
||||||
|
|
||||||
Add explicit tests for testing with gracelimit = 0 and
|
|
||||||
gracelimit = -1.
|
|
||||||
|
|
||||||
Also remove some extranous "str(self.master.domain.basedn)"
|
|
||||||
lines from some of the tests.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9206
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
---
|
|
||||||
.../ipa-graceperiod/ipa_graceperiod.c | 2 +-
|
|
||||||
ipatests/test_integration/test_pwpolicy.py | 55 ++++++++++++++++++-
|
|
||||||
2 files changed, 53 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
index a3f57cb4b..345e1dee7 100644
|
|
||||||
--- a/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
+++ b/daemons/ipa-slapi-plugins/ipa-graceperiod/ipa_graceperiod.c
|
|
||||||
@@ -479,7 +479,7 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
|
|
||||||
if (pwresponse_requested) {
|
|
||||||
slapi_pwpolicy_make_response_control(pb, -1, grace_limit - grace_user_time , -1);
|
|
||||||
}
|
|
||||||
- } else if ((grace_limit > 0) && (grace_user_time >= grace_limit)) {
|
|
||||||
+ } else if (grace_user_time >= grace_limit) {
|
|
||||||
LOG_TRACE("%s password is expired and out of grace limit\n", dn);
|
|
||||||
errstr = "Password is expired.\n";
|
|
||||||
ret = LDAP_INVALID_CREDENTIALS;
|
|
||||||
diff --git a/ipatests/test_integration/test_pwpolicy.py b/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
index 6d6698284..41d6e9070 100644
|
|
||||||
--- a/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
+++ b/ipatests/test_integration/test_pwpolicy.py
|
|
||||||
@@ -36,7 +36,7 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
cls.master.run_command(['ipa', 'group-add-member', POLICY,
|
|
||||||
'--users', USER])
|
|
||||||
cls.master.run_command(['ipa', 'pwpolicy-add', POLICY,
|
|
||||||
- '--priority', '1'])
|
|
||||||
+ '--priority', '1', '--gracelimit', '-1'])
|
|
||||||
cls.master.run_command(['ipa', 'passwd', USER],
|
|
||||||
stdin_text='{password}\n{password}\n'.format(
|
|
||||||
password=PASSWORD
|
|
||||||
@@ -265,7 +265,6 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
|
|
||||||
def test_graceperiod_expired(self):
|
|
||||||
"""Test the LDAP bind grace period"""
|
|
||||||
- str(self.master.domain.basedn)
|
|
||||||
dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
|
|
||||||
@@ -308,7 +307,6 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
|
|
||||||
def test_graceperiod_not_replicated(self):
|
|
||||||
"""Test that the grace period is reset on password reset"""
|
|
||||||
- str(self.master.domain.basedn)
|
|
||||||
dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
|
|
||||||
@@ -341,3 +339,54 @@ class TestPWPolicy(IntegrationTest):
|
|
||||||
)
|
|
||||||
assert 'passwordgraceusertime: 0' in result.stdout_text.lower()
|
|
||||||
self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ def test_graceperiod_zero(self):
|
|
||||||
+ """Test the LDAP bind with zero grace period"""
|
|
||||||
+ dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
+ user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
+
|
|
||||||
+ self.master.run_command(
|
|
||||||
+ ["ipa", "pwpolicy-mod", POLICY, "--gracelimit", "0", ],
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # Resetting the password will mark it as expired
|
|
||||||
+ self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ # Now grace is done and binds should fail.
|
|
||||||
+ result = self.master.run_command(
|
|
||||||
+ ["ldapsearch", "-e", "ppolicy", "-D", dn,
|
|
||||||
+ "-w", PASSWORD, "-b", dn], raiseonerr=False
|
|
||||||
+ )
|
|
||||||
+ assert result.returncode == 49
|
|
||||||
+
|
|
||||||
+ assert 'Password is expired' in result.stderr_text
|
|
||||||
+ assert 'Password expired, 0 grace logins remain' in result.stderr_text
|
|
||||||
+
|
|
||||||
+ def test_graceperiod_disabled(self):
|
|
||||||
+ """Test the LDAP bind with grace period disabled (-1)"""
|
|
||||||
+ str(self.master.domain.basedn)
|
|
||||||
+ dn = "uid={user},cn=users,cn=accounts,{base_dn}".format(
|
|
||||||
+ user=USER, base_dn=str(self.master.domain.basedn))
|
|
||||||
+
|
|
||||||
+ # This can fail if gracelimit is already -1 so ignore it
|
|
||||||
+ self.master.run_command(
|
|
||||||
+ ["ipa", "pwpolicy-mod", POLICY, "--gracelimit", "-1",],
|
|
||||||
+ raiseonerr=False,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # Ensure the password is expired
|
|
||||||
+ self.reset_password(self.master)
|
|
||||||
+
|
|
||||||
+ result = self.kinit_as_user(self.master, PASSWORD, PASSWORD)
|
|
||||||
+
|
|
||||||
+ for _i in range(0, 10):
|
|
||||||
+ result = self.master.run_command(
|
|
||||||
+ ["ldapsearch", "-e", "ppolicy", "-D", dn,
|
|
||||||
+ "-w", PASSWORD, "-b", dn]
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ # With graceperiod disabled it should not increment
|
|
||||||
+ result = tasks.ldapsearch_dm(
|
|
||||||
+ self.master, dn, ['passwordgraceusertime',],
|
|
||||||
+ )
|
|
||||||
+ assert 'passwordgraceusertime: 0' in result.stdout_text.lower()
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
|||||||
From 434620ee342ac4767beccec647a318bfa7743dfa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 18 Aug 2022 08:21:58 -0400
|
|
||||||
Subject: [PATCH] doc: Update LDAP grace period design with default values
|
|
||||||
|
|
||||||
New group password policies will get -1 (unlimited) on creation
|
|
||||||
by default.
|
|
||||||
|
|
||||||
Existing group password policies will remain untouched and
|
|
||||||
those created prior will be treated as no BIND allowed.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
doc/designs/ldap_grace_period.md | 17 ++++++++++++++++-
|
|
||||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/doc/designs/ldap_grace_period.md b/doc/designs/ldap_grace_period.md
|
|
||||||
index 4b9db3424..e26aedda9 100644
|
|
||||||
--- a/doc/designs/ldap_grace_period.md
|
|
||||||
+++ b/doc/designs/ldap_grace_period.md
|
|
||||||
@@ -51,7 +51,22 @@ The basic flow is:
|
|
||||||
|
|
||||||
On successful password reset (by anyone) reset the user's passwordGraceUserTime to 0.
|
|
||||||
|
|
||||||
-The default value on install/upgrade will be -1 to retail existing behavior.
|
|
||||||
+Range values for passwordgracelimit are:
|
|
||||||
+
|
|
||||||
+-1 : password grace checking is disabled
|
|
||||||
+ 0 : no grace BIND are allowed at all post-expiration
|
|
||||||
+ 1..MAXINT: the number of BIND allowed post-expiration
|
|
||||||
+
|
|
||||||
+The default value for the global policy on install/upgrade will be -1 to
|
|
||||||
+retain existing behavior.
|
|
||||||
+
|
|
||||||
+New group password policies will default to -1 to retain previous
|
|
||||||
+behavior.
|
|
||||||
+
|
|
||||||
+Existing group policies with no grace limit set are updated to use
|
|
||||||
+the default unlimited value, -1. This is done because lack of value in
|
|
||||||
+LDAP is treated as 0 so any existing group policies would not allow
|
|
||||||
+post-expiration BIND so this will avoid confusion.
|
|
||||||
|
|
||||||
The per-user attempts will not be replicated.
|
|
||||||
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
||||||
From 497a57e7a6872fa30d1855a1d91a455bfdbf9300 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 4 Aug 2022 12:04:22 -0400
|
|
||||||
Subject: [PATCH] Set default gracelimit on group password policies to -1
|
|
||||||
|
|
||||||
This will retain previous behavior of unlimited LDAP BIND
|
|
||||||
post-expiration.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
API.txt | 2 +-
|
|
||||||
ipaserver/plugins/pwpolicy.py | 2 ++
|
|
||||||
ipatests/test_xmlrpc/test_pwpolicy_plugin.py | 2 ++
|
|
||||||
3 files changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/API.txt b/API.txt
|
|
||||||
index 5ba9add13..d7ea74f08 100644
|
|
||||||
--- a/API.txt
|
|
||||||
+++ b/API.txt
|
|
||||||
@@ -4075,7 +4075,7 @@ option: Int('krbpwdlockoutduration?', cli_name='lockouttime')
|
|
||||||
option: Int('krbpwdmaxfailure?', cli_name='maxfail')
|
|
||||||
option: Int('krbpwdmindiffchars?', cli_name='minclasses')
|
|
||||||
option: Int('krbpwdminlength?', cli_name='minlength')
|
|
||||||
-option: Int('passwordgracelimit?', cli_name='gracelimit', default=-1)
|
|
||||||
+option: Int('passwordgracelimit?', autofill=True, cli_name='gracelimit', default=-1)
|
|
||||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
|
||||||
option: Str('setattr*', cli_name='setattr')
|
|
||||||
option: Str('version?')
|
|
||||||
diff --git a/ipaserver/plugins/pwpolicy.py b/ipaserver/plugins/pwpolicy.py
|
|
||||||
index 4428aede2..f4ebffd5c 100644
|
|
||||||
--- a/ipaserver/plugins/pwpolicy.py
|
|
||||||
+++ b/ipaserver/plugins/pwpolicy.py
|
|
||||||
@@ -408,6 +408,7 @@ class pwpolicy(LDAPObject):
|
|
||||||
minvalue=-1,
|
|
||||||
maxvalue=Int.MAX_UINT32,
|
|
||||||
default=-1,
|
|
||||||
+ autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@@ -539,6 +540,7 @@ class pwpolicy_add(LDAPCreate):
|
|
||||||
keys[-1], krbpwdpolicyreference=dn,
|
|
||||||
cospriority=options.get('cospriority')
|
|
||||||
)
|
|
||||||
+
|
|
||||||
return dn
|
|
||||||
|
|
||||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
|
||||||
diff --git a/ipatests/test_xmlrpc/test_pwpolicy_plugin.py b/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
index 8eee69c18..fc785223b 100644
|
|
||||||
--- a/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
+++ b/ipatests/test_xmlrpc/test_pwpolicy_plugin.py
|
|
||||||
@@ -387,6 +387,7 @@ class test_pwpolicy_mod_cospriority(Declarative):
|
|
||||||
krbpwdhistorylength=[u'10'],
|
|
||||||
krbpwdmindiffchars=[u'3'],
|
|
||||||
krbpwdminlength=[u'8'],
|
|
||||||
+ passwordgracelimit=[u'-1'],
|
|
||||||
objectclass=objectclasses.pwpolicy,
|
|
||||||
),
|
|
||||||
summary=None,
|
|
||||||
@@ -417,6 +418,7 @@ class test_pwpolicy_mod_cospriority(Declarative):
|
|
||||||
krbpwdhistorylength=[u'10'],
|
|
||||||
krbpwdmindiffchars=[u'3'],
|
|
||||||
krbpwdminlength=[u'8'],
|
|
||||||
+ passwordgracelimit=[u'-1'],
|
|
||||||
),
|
|
||||||
summary=None,
|
|
||||||
value=u'ipausers',
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
||||||
From a4ddaaf3048c4e8d78a1807af7266ee40ab3a30b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Thu, 4 Aug 2022 12:04:41 -0400
|
|
||||||
Subject: [PATCH] Set default on group pwpolicy with no grace limit in upgrade
|
|
||||||
|
|
||||||
If an existing group policy lacks a password grace limit
|
|
||||||
update it to -1 on upgrade.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9212
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
---
|
|
||||||
.../updates/90-post_upgrade_plugins.update | 1 +
|
|
||||||
ipaserver/install/plugins/update_pwpolicy.py | 66 +++++++++++++++++++
|
|
||||||
2 files changed, 67 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
|
|
||||||
index c7ec71d49..6fe91aa6c 100644
|
|
||||||
--- a/install/updates/90-post_upgrade_plugins.update
|
|
||||||
+++ b/install/updates/90-post_upgrade_plugins.update
|
|
||||||
@@ -26,6 +26,7 @@ plugin: update_ra_cert_store
|
|
||||||
plugin: update_mapping_Guests_to_nobody
|
|
||||||
plugin: fix_kra_people_entry
|
|
||||||
plugin: update_pwpolicy
|
|
||||||
+plugin: update_pwpolicy_grace
|
|
||||||
|
|
||||||
# last
|
|
||||||
# DNS version 1
|
|
||||||
diff --git a/ipaserver/install/plugins/update_pwpolicy.py b/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
index dca44ce43..4185f0343 100644
|
|
||||||
--- a/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
+++ b/ipaserver/install/plugins/update_pwpolicy.py
|
|
||||||
@@ -78,3 +78,69 @@ class update_pwpolicy(Updater):
|
|
||||||
return False, []
|
|
||||||
|
|
||||||
return False, []
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+@register()
|
|
||||||
+class update_pwpolicy_grace(Updater):
|
|
||||||
+ """
|
|
||||||
+ Ensure all group policies have a grace period set.
|
|
||||||
+ """
|
|
||||||
+
|
|
||||||
+ def execute(self, **options):
|
|
||||||
+ ldap = self.api.Backend.ldap2
|
|
||||||
+
|
|
||||||
+ base_dn = DN(('cn', self.api.env.realm), ('cn', 'kerberos'),
|
|
||||||
+ self.api.env.basedn)
|
|
||||||
+ search_filter = (
|
|
||||||
+ "(&(objectClass=krbpwdpolicy)(!(passwordgracelimit=*)))"
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ while True:
|
|
||||||
+ # Run the search in loop to avoid issues when LDAP limits are hit
|
|
||||||
+ # during update
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ (entries, truncated) = ldap.find_entries(
|
|
||||||
+ search_filter, ['objectclass'], base_dn, time_limit=0,
|
|
||||||
+ size_limit=0)
|
|
||||||
+
|
|
||||||
+ except errors.EmptyResult:
|
|
||||||
+ logger.debug("update_pwpolicy: no policies without "
|
|
||||||
+ "passwordgracelimit set")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ except errors.ExecutionError as e:
|
|
||||||
+ logger.error("update_pwpolicy: cannot retrieve list "
|
|
||||||
+ "of policies missing passwordgracelimit: %s", e)
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ logger.debug("update_pwpolicy: found %d "
|
|
||||||
+ "policies to update, truncated: %s",
|
|
||||||
+ len(entries), truncated)
|
|
||||||
+
|
|
||||||
+ error = False
|
|
||||||
+
|
|
||||||
+ for entry in entries:
|
|
||||||
+ # Set unlimited BIND by default
|
|
||||||
+ entry['passwordgracelimit'] = -1
|
|
||||||
+ try:
|
|
||||||
+ ldap.update_entry(entry)
|
|
||||||
+ except (errors.EmptyModlist, errors.NotFound):
|
|
||||||
+ pass
|
|
||||||
+ except errors.ExecutionError as e:
|
|
||||||
+ logger.debug("update_pwpolicy: cannot "
|
|
||||||
+ "update policy: %s", e)
|
|
||||||
+ error = True
|
|
||||||
+
|
|
||||||
+ if error:
|
|
||||||
+ # Exit loop to avoid infinite cycles
|
|
||||||
+ logger.error("update_pwpolicy: error(s) "
|
|
||||||
+ "detected during pwpolicy update")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ elif not truncated:
|
|
||||||
+ # All affected entries updated, exit the loop
|
|
||||||
+ logger.debug("update_pwpolicy: all policies updated")
|
|
||||||
+ return False, []
|
|
||||||
+
|
|
||||||
+ return False, []
|
|
||||||
--
|
|
||||||
2.37.2
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
From 109cd579e3b089b7fad4c92bf25594eba1af8a21 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
Date: Tue, 23 Aug 2022 16:58:07 +0300
|
|
||||||
Subject: [PATCH] fix canonicalization issue in Web UI
|
|
||||||
|
|
||||||
When Kerberos principal alias is used to login to a Web UI, we end up
|
|
||||||
with a request that is authenticated by a ticket issued in the alias
|
|
||||||
name but metadata processed for the canonical user name. This confuses
|
|
||||||
RPC layer of Web UI code and causes infinite loop to reload the page.
|
|
||||||
|
|
||||||
Fix it by doing two things:
|
|
||||||
|
|
||||||
- force use of canonicalization of an enterprise principal on server
|
|
||||||
side, not just specifying that the principal is an enterprise one;
|
|
||||||
|
|
||||||
- recognize that a principal in the whoami()-returned object can have
|
|
||||||
aliases and the principal returned by the server in the JSON response
|
|
||||||
may be one of those aliases.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9226
|
|
||||||
|
|
||||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
|
||||||
Reviewed-By: Armando Neto <abiagion@redhat.com>
|
|
||||||
---
|
|
||||||
install/ui/src/freeipa/ipa.js | 8 +++++++-
|
|
||||||
ipaserver/rpcserver.py | 1 +
|
|
||||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
|
|
||||||
index 758db1b00..a08d632e9 100644
|
|
||||||
--- a/install/ui/src/freeipa/ipa.js
|
|
||||||
+++ b/install/ui/src/freeipa/ipa.js
|
|
||||||
@@ -271,7 +271,13 @@ var IPA = function () {
|
|
||||||
var cn = that.whoami.data.krbcanonicalname;
|
|
||||||
if (cn) that.principal = cn[0];
|
|
||||||
if (!that.principal) {
|
|
||||||
- that.principal = that.whoami.data.krbprincipalname[0];
|
|
||||||
+ var principal = data.principal;
|
|
||||||
+ var idx = that.whoami.data.krbprincipalname.indexOf(principal);
|
|
||||||
+ if (idx > -1) {
|
|
||||||
+ that.principal = principal;
|
|
||||||
+ } else {
|
|
||||||
+ that.principal = that.whoami.data.krbprincipalname[0];
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
} else if (entity === 'idoverrideuser') {
|
|
||||||
that.principal = that.whoami.data.ipaoriginaluid[0];
|
|
||||||
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
|
|
||||||
index 1f85e9898..4e8a08b66 100644
|
|
||||||
--- a/ipaserver/rpcserver.py
|
|
||||||
+++ b/ipaserver/rpcserver.py
|
|
||||||
@@ -1109,6 +1109,7 @@ class login_password(Backend, KerberosSession):
|
|
||||||
ccache_name,
|
|
||||||
armor_ccache_name=armor_path,
|
|
||||||
enterprise=True,
|
|
||||||
+ canonicalize=True,
|
|
||||||
lifetime=self.api.env.kinit_lifetime)
|
|
||||||
|
|
||||||
if armor_path:
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
@ -1,473 +0,0 @@
|
|||||||
From 69413325158a3ea06d1491acd77ee6e0955ee89a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Date: Sep 26 2022 11:48:47 +0000
|
|
||||||
Subject: Defer creating the final krb5.conf on clients
|
|
||||||
|
|
||||||
|
|
||||||
A temporary krb5.conf is created early during client enrollment
|
|
||||||
and was previously used only during the initial ipa-join call.
|
|
||||||
The final krb5.conf was written soon afterward.
|
|
||||||
|
|
||||||
If there are multiple servers it is possible that the client
|
|
||||||
may then choose a different KDC to connect. If the client
|
|
||||||
is faster than replication then the client may not exist
|
|
||||||
on all servers and therefore enrollment will fail.
|
|
||||||
|
|
||||||
This was seen in performance testing of how many simultaneous
|
|
||||||
client enrollments are possible.
|
|
||||||
|
|
||||||
Use a decorator to wrap the _install() method to ensure the
|
|
||||||
temporary files created during installation are cleaned up.
|
|
||||||
|
|
||||||
https://pagure.io/freeipa/issue/9228
|
|
||||||
|
|
||||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
|
||||||
index 920c517..93bc740 100644
|
|
||||||
--- a/ipaclient/install/client.py
|
|
||||||
+++ b/ipaclient/install/client.py
|
|
||||||
@@ -101,6 +101,37 @@ cli_basedn = None
|
|
||||||
# end of global variables
|
|
||||||
|
|
||||||
|
|
||||||
+def cleanup(func):
|
|
||||||
+ def inner(options, tdict):
|
|
||||||
+ # Add some additional options which contain the temporary files
|
|
||||||
+ # needed during installation.
|
|
||||||
+ fd, krb_name = tempfile.mkstemp()
|
|
||||||
+ os.close(fd)
|
|
||||||
+ ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
|
||||||
+
|
|
||||||
+ tdict['krb_name'] = krb_name
|
|
||||||
+ tdict['ccache_dir'] = ccache_dir
|
|
||||||
+
|
|
||||||
+ func(options, tdict)
|
|
||||||
+
|
|
||||||
+ os.environ.pop('KRB5_CONFIG', None)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ os.remove(krb_name)
|
|
||||||
+ except OSError:
|
|
||||||
+ logger.error("Could not remove %s", krb_name)
|
|
||||||
+ try:
|
|
||||||
+ os.rmdir(ccache_dir)
|
|
||||||
+ except OSError:
|
|
||||||
+ pass
|
|
||||||
+ try:
|
|
||||||
+ os.remove(krb_name + ".ipabkp")
|
|
||||||
+ except OSError:
|
|
||||||
+ logger.error("Could not remove %s.ipabkp", krb_name)
|
|
||||||
+
|
|
||||||
+ return inner
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def remove_file(filename):
|
|
||||||
"""
|
|
||||||
Deletes a file. If the file does not exist (OSError 2) does nothing.
|
|
||||||
@@ -2652,7 +2683,7 @@ def restore_time_sync(statestore, fstore):
|
|
||||||
|
|
||||||
def install(options):
|
|
||||||
try:
|
|
||||||
- _install(options)
|
|
||||||
+ _install(options, dict())
|
|
||||||
except ScriptError as e:
|
|
||||||
if e.rval == CLIENT_INSTALL_ERROR:
|
|
||||||
if options.force:
|
|
||||||
@@ -2679,7 +2710,8 @@ def install(options):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
-def _install(options):
|
|
||||||
+@cleanup
|
|
||||||
+def _install(options, tdict):
|
|
||||||
env = {'PATH': SECURE_PATH}
|
|
||||||
|
|
||||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
|
||||||
@@ -2687,6 +2719,9 @@ def _install(options):
|
|
||||||
|
|
||||||
statestore.backup_state('installation', 'complete', False)
|
|
||||||
|
|
||||||
+ krb_name = tdict['krb_name']
|
|
||||||
+ ccache_dir = tdict['ccache_dir']
|
|
||||||
+
|
|
||||||
if not options.on_master:
|
|
||||||
# Try removing old principals from the keytab
|
|
||||||
purge_host_keytab(cli_realm)
|
|
||||||
@@ -2719,182 +2754,162 @@ def _install(options):
|
|
||||||
host_principal = 'host/%s@%s' % (hostname, cli_realm)
|
|
||||||
if not options.on_master:
|
|
||||||
nolog = tuple()
|
|
||||||
- # First test out the kerberos configuration
|
|
||||||
- fd, krb_name = tempfile.mkstemp()
|
|
||||||
- os.close(fd)
|
|
||||||
- ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
|
||||||
- try:
|
|
||||||
- configure_krb5_conf(
|
|
||||||
- cli_realm=cli_realm,
|
|
||||||
- cli_domain=cli_domain,
|
|
||||||
- cli_server=cli_server,
|
|
||||||
- cli_kdc=cli_kdc,
|
|
||||||
- dnsok=False,
|
|
||||||
- filename=krb_name,
|
|
||||||
- client_domain=client_domain,
|
|
||||||
- client_hostname=hostname,
|
|
||||||
- configure_sssd=options.sssd,
|
|
||||||
- force=options.force)
|
|
||||||
- env['KRB5_CONFIG'] = krb_name
|
|
||||||
- ccache_name = os.path.join(ccache_dir, 'ccache')
|
|
||||||
- join_args = [
|
|
||||||
- paths.SBIN_IPA_JOIN,
|
|
||||||
- "-s", cli_server[0],
|
|
||||||
- "-b", str(realm_to_suffix(cli_realm)),
|
|
||||||
- "-h", hostname,
|
|
||||||
- "-k", paths.KRB5_KEYTAB
|
|
||||||
- ]
|
|
||||||
- if options.debug:
|
|
||||||
- join_args.append("-d")
|
|
||||||
- env['XMLRPC_TRACE_CURL'] = 'yes'
|
|
||||||
- if options.force_join:
|
|
||||||
- join_args.append("-f")
|
|
||||||
- if options.principal is not None:
|
|
||||||
- stdin = None
|
|
||||||
- principal = options.principal
|
|
||||||
- if principal.find('@') == -1:
|
|
||||||
- principal = '%s@%s' % (principal, cli_realm)
|
|
||||||
- if options.password is not None:
|
|
||||||
- stdin = options.password
|
|
||||||
+ configure_krb5_conf(
|
|
||||||
+ cli_realm=cli_realm,
|
|
||||||
+ cli_domain=cli_domain,
|
|
||||||
+ cli_server=cli_server,
|
|
||||||
+ cli_kdc=cli_kdc,
|
|
||||||
+ dnsok=False,
|
|
||||||
+ filename=krb_name,
|
|
||||||
+ client_domain=client_domain,
|
|
||||||
+ client_hostname=hostname,
|
|
||||||
+ configure_sssd=options.sssd,
|
|
||||||
+ force=options.force)
|
|
||||||
+ env['KRB5_CONFIG'] = krb_name
|
|
||||||
+ ccache_name = os.path.join(ccache_dir, 'ccache')
|
|
||||||
+ join_args = [
|
|
||||||
+ paths.SBIN_IPA_JOIN,
|
|
||||||
+ "-s", cli_server[0],
|
|
||||||
+ "-b", str(realm_to_suffix(cli_realm)),
|
|
||||||
+ "-h", hostname,
|
|
||||||
+ "-k", paths.KRB5_KEYTAB
|
|
||||||
+ ]
|
|
||||||
+ if options.debug:
|
|
||||||
+ join_args.append("-d")
|
|
||||||
+ env['XMLRPC_TRACE_CURL'] = 'yes'
|
|
||||||
+ if options.force_join:
|
|
||||||
+ join_args.append("-f")
|
|
||||||
+ if options.principal is not None:
|
|
||||||
+ stdin = None
|
|
||||||
+ principal = options.principal
|
|
||||||
+ if principal.find('@') == -1:
|
|
||||||
+ principal = '%s@%s' % (principal, cli_realm)
|
|
||||||
+ if options.password is not None:
|
|
||||||
+ stdin = options.password
|
|
||||||
+ else:
|
|
||||||
+ if not options.unattended:
|
|
||||||
+ try:
|
|
||||||
+ stdin = getpass.getpass(
|
|
||||||
+ "Password for %s: " % principal)
|
|
||||||
+ except EOFError:
|
|
||||||
+ stdin = None
|
|
||||||
+ if not stdin:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided for {}.".format(
|
|
||||||
+ principal),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
else:
|
|
||||||
- if not options.unattended:
|
|
||||||
- try:
|
|
||||||
- stdin = getpass.getpass(
|
|
||||||
- "Password for %s: " % principal)
|
|
||||||
- except EOFError:
|
|
||||||
- stdin = None
|
|
||||||
- if not stdin:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided for {}.".format(
|
|
||||||
- principal),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ if sys.stdin.isatty():
|
|
||||||
+ logger.error(
|
|
||||||
+ "Password must be provided in "
|
|
||||||
+ "non-interactive mode.")
|
|
||||||
+ logger.info(
|
|
||||||
+ "This can be done via "
|
|
||||||
+ "echo password | ipa-client-install ... "
|
|
||||||
+ "or with the -w option.")
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
else:
|
|
||||||
- if sys.stdin.isatty():
|
|
||||||
- logger.error(
|
|
||||||
- "Password must be provided in "
|
|
||||||
- "non-interactive mode.")
|
|
||||||
- logger.info(
|
|
||||||
- "This can be done via "
|
|
||||||
- "echo password | ipa-client-install ... "
|
|
||||||
- "or with the -w option.")
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- stdin = sys.stdin.readline()
|
|
||||||
+ stdin = sys.stdin.readline()
|
|
||||||
|
|
||||||
+ try:
|
|
||||||
+ kinit_password(principal, stdin, ccache_name,
|
|
||||||
+ config=krb_name)
|
|
||||||
+ except RuntimeError as e:
|
|
||||||
+ print_port_conf_info()
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Kerberos authentication failed: {}".format(e),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ elif options.keytab:
|
|
||||||
+ join_args.append("-f")
|
|
||||||
+ if os.path.exists(options.keytab):
|
|
||||||
try:
|
|
||||||
- kinit_password(principal, stdin, ccache_name,
|
|
||||||
- config=krb_name)
|
|
||||||
- except RuntimeError as e:
|
|
||||||
+ kinit_keytab(host_principal,
|
|
||||||
+ options.keytab,
|
|
||||||
+ ccache_name,
|
|
||||||
+ config=krb_name,
|
|
||||||
+ attempts=options.kinit_attempts)
|
|
||||||
+ except gssapi.exceptions.GSSError as e:
|
|
||||||
print_port_conf_info()
|
|
||||||
raise ScriptError(
|
|
||||||
"Kerberos authentication failed: {}".format(e),
|
|
||||||
rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- elif options.keytab:
|
|
||||||
- join_args.append("-f")
|
|
||||||
- if os.path.exists(options.keytab):
|
|
||||||
- try:
|
|
||||||
- kinit_keytab(host_principal,
|
|
||||||
- options.keytab,
|
|
||||||
- ccache_name,
|
|
||||||
- config=krb_name,
|
|
||||||
- attempts=options.kinit_attempts)
|
|
||||||
- except gssapi.exceptions.GSSError as e:
|
|
||||||
- print_port_conf_info()
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Kerberos authentication failed: {}".format(e),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Keytab file could not be found: {}".format(
|
|
||||||
- options.keytab),
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- elif options.password:
|
|
||||||
- nolog = (options.password,)
|
|
||||||
- join_args.append("-w")
|
|
||||||
- join_args.append(options.password)
|
|
||||||
- elif options.prompt_password:
|
|
||||||
- if options.unattended:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided in non-interactive mode",
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- try:
|
|
||||||
- password = getpass.getpass("Password: ")
|
|
||||||
- except EOFError:
|
|
||||||
- password = None
|
|
||||||
- if not password:
|
|
||||||
- raise ScriptError(
|
|
||||||
- "Password must be provided.",
|
|
||||||
- rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- join_args.append("-w")
|
|
||||||
- join_args.append(password)
|
|
||||||
- nolog = (password,)
|
|
||||||
-
|
|
||||||
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
|
|
||||||
- # Get the CA certificate
|
|
||||||
+ else:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Keytab file could not be found: {}".format(
|
|
||||||
+ options.keytab),
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ elif options.password:
|
|
||||||
+ nolog = (options.password,)
|
|
||||||
+ join_args.append("-w")
|
|
||||||
+ join_args.append(options.password)
|
|
||||||
+ elif options.prompt_password:
|
|
||||||
+ if options.unattended:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided in non-interactive mode",
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
try:
|
|
||||||
- os.environ['KRB5_CONFIG'] = env['KRB5_CONFIG']
|
|
||||||
- get_ca_certs(fstore, options, cli_server[0], cli_basedn,
|
|
||||||
- cli_realm)
|
|
||||||
- del os.environ['KRB5_CONFIG']
|
|
||||||
- except errors.FileError as e:
|
|
||||||
- logger.error('%s', e)
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- except Exception as e:
|
|
||||||
- logger.error("Cannot obtain CA certificate\n%s", e)
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
-
|
|
||||||
- # Now join the domain
|
|
||||||
- result = run(
|
|
||||||
- join_args, raiseonerr=False, env=env, nolog=nolog,
|
|
||||||
- capture_error=True)
|
|
||||||
- stderr = result.error_output
|
|
||||||
+ password = getpass.getpass("Password: ")
|
|
||||||
+ except EOFError:
|
|
||||||
+ password = None
|
|
||||||
+ if not password:
|
|
||||||
+ raise ScriptError(
|
|
||||||
+ "Password must be provided.",
|
|
||||||
+ rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ join_args.append("-w")
|
|
||||||
+ join_args.append(password)
|
|
||||||
+ nolog = (password,)
|
|
||||||
|
|
||||||
- if result.returncode != 0:
|
|
||||||
- logger.error("Joining realm failed: %s", stderr)
|
|
||||||
- if not options.force:
|
|
||||||
- if result.returncode == 13:
|
|
||||||
- logger.info(
|
|
||||||
- "Use --force-join option to override the host "
|
|
||||||
- "entry on the server and force client enrollment.")
|
|
||||||
- raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- logger.info(
|
|
||||||
- "Use ipa-getkeytab to obtain a host "
|
|
||||||
- "principal for this server.")
|
|
||||||
- else:
|
|
||||||
- logger.info("Enrolled in IPA realm %s", cli_realm)
|
|
||||||
+ env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
|
|
||||||
+ # Get the CA certificate
|
|
||||||
+ try:
|
|
||||||
+ os.environ['KRB5_CONFIG'] = env['KRB5_CONFIG']
|
|
||||||
+ get_ca_certs(fstore, options, cli_server[0], cli_basedn,
|
|
||||||
+ cli_realm)
|
|
||||||
+ except errors.FileError as e:
|
|
||||||
+ logger.error('%s', e)
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ except Exception as e:
|
|
||||||
+ logger.error("Cannot obtain CA certificate\n%s", e)
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
|
|
||||||
- if options.principal is not None:
|
|
||||||
- run([paths.KDESTROY], raiseonerr=False, env=env)
|
|
||||||
+ # Now join the domain
|
|
||||||
+ result = run(
|
|
||||||
+ join_args, raiseonerr=False, env=env, nolog=nolog,
|
|
||||||
+ capture_error=True)
|
|
||||||
+ stderr = result.error_output
|
|
||||||
|
|
||||||
- # Obtain the TGT. We do it with the temporary krb5.conf, so that
|
|
||||||
- # only the KDC we're installing under is contacted.
|
|
||||||
- # Other KDCs might not have replicated the principal yet.
|
|
||||||
- # Once we have the TGT, it's usable on any server.
|
|
||||||
- try:
|
|
||||||
- kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
|
||||||
- config=krb_name,
|
|
||||||
- attempts=options.kinit_attempts)
|
|
||||||
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
|
|
||||||
- except gssapi.exceptions.GSSError as e:
|
|
||||||
- print_port_conf_info()
|
|
||||||
- logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
- # failure to get ticket makes it impossible to login and bind
|
|
||||||
- # from sssd to LDAP, abort installation and rollback changes
|
|
||||||
+ if result.returncode != 0:
|
|
||||||
+ logger.error("Joining realm failed: %s", stderr)
|
|
||||||
+ if not options.force:
|
|
||||||
+ if result.returncode == 13:
|
|
||||||
+ logger.info(
|
|
||||||
+ "Use --force-join option to override the host "
|
|
||||||
+ "entry on the server and force client enrollment.")
|
|
||||||
raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
+ logger.info(
|
|
||||||
+ "Use ipa-getkeytab to obtain a host "
|
|
||||||
+ "principal for this server.")
|
|
||||||
+ else:
|
|
||||||
+ logger.info("Enrolled in IPA realm %s", cli_realm)
|
|
||||||
|
|
||||||
- finally:
|
|
||||||
- try:
|
|
||||||
- os.remove(krb_name)
|
|
||||||
- except OSError:
|
|
||||||
- logger.error("Could not remove %s", krb_name)
|
|
||||||
- try:
|
|
||||||
- os.rmdir(ccache_dir)
|
|
||||||
- except OSError:
|
|
||||||
- pass
|
|
||||||
- try:
|
|
||||||
- os.remove(krb_name + ".ipabkp")
|
|
||||||
- except OSError:
|
|
||||||
- logger.error("Could not remove %s.ipabkp", krb_name)
|
|
||||||
+ if options.principal is not None:
|
|
||||||
+ run([paths.KDESTROY], raiseonerr=False, env=env)
|
|
||||||
+
|
|
||||||
+ # Obtain the TGT. We do it with the temporary krb5.conf, so that
|
|
||||||
+ # only the KDC we're installing under is contacted.
|
|
||||||
+ # Other KDCs might not have replicated the principal yet.
|
|
||||||
+ # Once we have the TGT, it's usable on any server.
|
|
||||||
+ try:
|
|
||||||
+ kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
|
||||||
+ config=krb_name,
|
|
||||||
+ attempts=options.kinit_attempts)
|
|
||||||
+ env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
|
|
||||||
+ except gssapi.exceptions.GSSError as e:
|
|
||||||
+ print_port_conf_info()
|
|
||||||
+ logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
+ # failure to get ticket makes it impossible to login and bind
|
|
||||||
+ # from sssd to LDAP, abort installation and rollback changes
|
|
||||||
+ raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
|
|
||||||
# Configure ipa.conf
|
|
||||||
if not options.on_master:
|
|
||||||
@@ -2931,23 +2946,6 @@ def _install(options):
|
|
||||||
except gssapi.exceptions.GSSError as e:
|
|
||||||
logger.error("Failed to obtain host TGT: %s", e)
|
|
||||||
raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
|
||||||
- else:
|
|
||||||
- # Configure krb5.conf
|
|
||||||
- fstore.backup_file(paths.KRB5_CONF)
|
|
||||||
- configure_krb5_conf(
|
|
||||||
- cli_realm=cli_realm,
|
|
||||||
- cli_domain=cli_domain,
|
|
||||||
- cli_server=cli_server,
|
|
||||||
- cli_kdc=cli_kdc,
|
|
||||||
- dnsok=dnsok,
|
|
||||||
- filename=paths.KRB5_CONF,
|
|
||||||
- client_domain=client_domain,
|
|
||||||
- client_hostname=hostname,
|
|
||||||
- configure_sssd=options.sssd,
|
|
||||||
- force=options.force)
|
|
||||||
-
|
|
||||||
- logger.info(
|
|
||||||
- "Configured /etc/krb5.conf for IPA realm %s", cli_realm)
|
|
||||||
|
|
||||||
# Clear out any current session keyring information
|
|
||||||
try:
|
|
||||||
@@ -3274,6 +3272,23 @@ def _install(options):
|
|
||||||
configure_nisdomain(
|
|
||||||
options=options, domain=cli_domain, statestore=statestore)
|
|
||||||
|
|
||||||
+ # Configure the final krb5.conf
|
|
||||||
+ if not options.on_master:
|
|
||||||
+ fstore.backup_file(paths.KRB5_CONF)
|
|
||||||
+ configure_krb5_conf(
|
|
||||||
+ cli_realm=cli_realm,
|
|
||||||
+ cli_domain=cli_domain,
|
|
||||||
+ cli_server=cli_server,
|
|
||||||
+ cli_kdc=cli_kdc,
|
|
||||||
+ dnsok=dnsok,
|
|
||||||
+ filename=paths.KRB5_CONF,
|
|
||||||
+ client_domain=client_domain,
|
|
||||||
+ client_hostname=hostname,
|
|
||||||
+ configure_sssd=options.sssd,
|
|
||||||
+ force=options.force)
|
|
||||||
+
|
|
||||||
+ logger.info("Configured /etc/krb5.conf for IPA realm %s", cli_realm)
|
|
||||||
+
|
|
||||||
statestore.delete_state('installation', 'complete')
|
|
||||||
statestore.backup_state('installation', 'complete', True)
|
|
||||||
logger.info('Client configuration complete.')
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
|||||||
From c643e56e4c45b7cb61aa53989657143627c23e04 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
Date: Nov 22 2022 06:56:00 +0000
|
|
||||||
Subject: Vault: fix interoperability issues with older RHEL systems
|
|
||||||
|
|
||||||
|
|
||||||
AES-128-CBC was recently enabled as default wrapping algorithm for transport of secrets.
|
|
||||||
This change was done in favor of FIPS as crypto-policies disabled 3DES in RHEL9, but
|
|
||||||
setting AES as default ended-up breaking backwards compatibility with older RHEL systems.
|
|
||||||
|
|
||||||
This commit is tuning some defaults so that interoperability with older RHEL systems
|
|
||||||
works again. The new logic reflects:
|
|
||||||
|
|
||||||
- when an old client is calling a new server, it doesn't send any value for wrapping_algo
|
|
||||||
and the old value is used (3DES), so that the client can decrypt using 3DES.
|
|
||||||
|
|
||||||
- when a new client is calling a new server, it sends wrapping_algo = AES128_CBC
|
|
||||||
|
|
||||||
- when a new client is calling an old server, it doesn't send any value and the default is
|
|
||||||
to use 3DES.
|
|
||||||
|
|
||||||
Finally, as this logic is able to handle overlapping wrapping algorithm between server and
|
|
||||||
client, the Option "--wrapping-algo" is hidden from "ipa vault-archive --help" and "ipa
|
|
||||||
vault-retrieve --help" commands.
|
|
||||||
|
|
||||||
Fixes: https://pagure.io/freeipa/issue/9259
|
|
||||||
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
|
|
||||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
||||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
diff --git a/API.txt b/API.txt
|
|
||||||
index 9892211..2bd1cc2 100644
|
|
||||||
--- a/API.txt
|
|
||||||
+++ b/API.txt
|
|
||||||
@@ -6666,7 +6666,7 @@ option: Flag('shared?', autofill=True, default=False)
|
|
||||||
option: Str('username?', cli_name='user')
|
|
||||||
option: Bytes('vault_data')
|
|
||||||
option: Str('version?')
|
|
||||||
-option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
output: Entry('result')
|
|
||||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
|
||||||
output: PrimaryKey('value')
|
|
||||||
@@ -6766,7 +6766,7 @@ option: Bytes('session_key')
|
|
||||||
option: Flag('shared?', autofill=True, default=False)
|
|
||||||
option: Str('username?', cli_name='user')
|
|
||||||
option: Str('version?')
|
|
||||||
-option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
|
|
||||||
output: Entry('result')
|
|
||||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
|
||||||
output: PrimaryKey('value')
|
|
||||||
diff --git a/VERSION.m4 b/VERSION.m4
|
|
||||||
index 7d60b01..b4b1774 100644
|
|
||||||
--- a/VERSION.m4
|
|
||||||
+++ b/VERSION.m4
|
|
||||||
@@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
|
|
||||||
# #
|
|
||||||
########################################################
|
|
||||||
define(IPA_API_VERSION_MAJOR, 2)
|
|
||||||
-# Last change: add graceperiodlimit
|
|
||||||
-define(IPA_API_VERSION_MINOR, 248)
|
|
||||||
+# Last change: fix vault interoperability issues.
|
|
||||||
+define(IPA_API_VERSION_MINOR, 251)
|
|
||||||
|
|
||||||
########################################################
|
|
||||||
# Following values are auto-generated from values above
|
|
||||||
diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
|
|
||||||
index 115171c..d4c84eb 100644
|
|
||||||
--- a/ipaclient/plugins/vault.py
|
|
||||||
+++ b/ipaclient/plugins/vault.py
|
|
||||||
@@ -687,7 +687,7 @@ class ModVaultData(Local):
|
|
||||||
default_algo = config.get('wrapping_default_algorithm')
|
|
||||||
if default_algo is None:
|
|
||||||
# old server
|
|
||||||
- wrapping_algo = constants.VAULT_WRAPPING_AES128_CBC
|
|
||||||
+ wrapping_algo = constants.VAULT_WRAPPING_3DES
|
|
||||||
elif default_algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
|
|
||||||
# try to use server default
|
|
||||||
wrapping_algo = default_algo
|
|
||||||
@@ -801,7 +801,8 @@ class vault_archive(ModVaultData):
|
|
||||||
if option.name not in ('nonce',
|
|
||||||
'session_key',
|
|
||||||
'vault_data',
|
|
||||||
- 'version'):
|
|
||||||
+ 'version',
|
|
||||||
+ 'wrapping_algo'):
|
|
||||||
yield option
|
|
||||||
for option in super(vault_archive, self).get_options():
|
|
||||||
yield option
|
|
||||||
@@ -1053,7 +1054,7 @@ class vault_retrieve(ModVaultData):
|
|
||||||
|
|
||||||
def get_options(self):
|
|
||||||
for option in self.api.Command.vault_retrieve_internal.options():
|
|
||||||
- if option.name not in ('session_key', 'version'):
|
|
||||||
+ if option.name not in ('session_key', 'version', 'wrapping_algo'):
|
|
||||||
yield option
|
|
||||||
for option in super(vault_retrieve, self).get_options():
|
|
||||||
yield option
|
|
||||||
diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
|
|
||||||
index 4d40f66..574c83a 100644
|
|
||||||
--- a/ipaserver/plugins/vault.py
|
|
||||||
+++ b/ipaserver/plugins/vault.py
|
|
||||||
@@ -1051,7 +1051,7 @@ class vault_archive_internal(PKQuery):
|
|
||||||
'wrapping_algo?',
|
|
||||||
doc=_('Key wrapping algorithm'),
|
|
||||||
values=VAULT_WRAPPING_SUPPORTED_ALGOS,
|
|
||||||
- default=VAULT_WRAPPING_DEFAULT_ALGO,
|
|
||||||
+ default=VAULT_WRAPPING_3DES,
|
|
||||||
autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@@ -1130,7 +1130,7 @@ class vault_retrieve_internal(PKQuery):
|
|
||||||
'wrapping_algo?',
|
|
||||||
doc=_('Key wrapping algorithm'),
|
|
||||||
values=VAULT_WRAPPING_SUPPORTED_ALGOS,
|
|
||||||
- default=VAULT_WRAPPING_DEFAULT_ALGO,
|
|
||||||
+ default=VAULT_WRAPPING_3DES,
|
|
||||||
autofill=True,
|
|
||||||
),
|
|
||||||
)
|
|
@ -15,7 +15,7 @@ diff --git a/freeipa.spec.in b/freeipa.spec.in
|
|||||||
index 8f5c370e5..e20edb7bc 100755
|
index 8f5c370e5..e20edb7bc 100755
|
||||||
--- a/freeipa.spec.in
|
--- a/freeipa.spec.in
|
||||||
+++ b/freeipa.spec.in
|
+++ b/freeipa.spec.in
|
||||||
@@ -576,11 +576,9 @@ Requires: %{name}-server = %{version}-%{release}
|
@@ -585,11 +585,9 @@ Requires: %{name}-server = %{version}-%{release}
|
||||||
Requires: bind-dyndb-ldap >= 11.2-2
|
Requires: bind-dyndb-ldap >= 11.2-2
|
||||||
Requires: bind >= %{bind_version}
|
Requires: bind >= %{bind_version}
|
||||||
Requires: bind-utils >= %{bind_version}
|
Requires: bind-utils >= %{bind_version}
|
||||||
@ -32,15 +32,16 @@ diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
|
|||||||
index 7d21367ec..42a47f1df 100644
|
index 7d21367ec..42a47f1df 100644
|
||||||
--- a/ipaplatform/base/paths.py
|
--- a/ipaplatform/base/paths.py
|
||||||
+++ b/ipaplatform/base/paths.py
|
+++ b/ipaplatform/base/paths.py
|
||||||
@@ -259,7 +259,6 @@ class BasePathNamespace:
|
@@ -258,8 +258,7 @@ class BasePathNamespace:
|
||||||
IPA_PKI_RETRIEVE_KEY = "/usr/libexec/ipa/ipa-pki-retrieve-key"
|
IPA_PKI_RETRIEVE_KEY = "/usr/libexec/ipa/ipa-pki-retrieve-key"
|
||||||
IPA_HTTPD_PASSWD_READER = "/usr/libexec/ipa/ipa-httpd-pwdreader"
|
IPA_HTTPD_PASSWD_READER = "/usr/libexec/ipa/ipa-httpd-pwdreader"
|
||||||
IPA_PKI_WAIT_RUNNING = "/usr/libexec/ipa/ipa-pki-wait-running"
|
IPA_PKI_WAIT_RUNNING = "/usr/libexec/ipa/ipa-pki-wait-running"
|
||||||
- DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
|
- DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
|
||||||
+ DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
|
|
||||||
- DNSSEC_KEYFROMLABEL_9_17 = "/usr/bin/dnssec-keyfromlabel"
|
- DNSSEC_KEYFROMLABEL_9_17 = "/usr/bin/dnssec-keyfromlabel"
|
||||||
|
+ DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
|
||||||
GETSEBOOL = "/usr/sbin/getsebool"
|
GETSEBOOL = "/usr/sbin/getsebool"
|
||||||
GROUPADD = "/usr/sbin/groupadd"
|
GROUPADD = "/usr/sbin/groupadd"
|
||||||
|
USERMOD = "/usr/sbin/usermod"
|
||||||
diff --git a/ipaplatform/fedora/paths.py b/ipaplatform/fedora/paths.py
|
diff --git a/ipaplatform/fedora/paths.py b/ipaplatform/fedora/paths.py
|
||||||
index 4e993c063..92a948966 100644
|
index 4e993c063..92a948966 100644
|
||||||
--- a/ipaplatform/fedora/paths.py
|
--- a/ipaplatform/fedora/paths.py
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
From 9a33838407f244e481523fe643bc0626874e8b1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||||
|
Date: Mon, 19 Dec 2022 14:57:03 -0300
|
||||||
|
Subject: [PATCH] Revert "DNSResolver: Fix use of nameservers with ports"
|
||||||
|
|
||||||
|
This reverts commit 5e2e4664aec641886923c2bec61ce25b96edb62a.
|
||||||
|
---
|
||||||
|
ipapython/dnsutil.py | 41 -------------------------
|
||||||
|
ipatests/test_ipapython/test_dnsutil.py | 40 ------------------------
|
||||||
|
2 files changed, 81 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
|
||||||
|
index 58de365ab..4baeaf8cc 100644
|
||||||
|
--- a/ipapython/dnsutil.py
|
||||||
|
+++ b/ipapython/dnsutil.py
|
||||||
|
@@ -144,47 +144,6 @@ class DNSResolver(dns.resolver.Resolver):
|
||||||
|
nameservers.remove(ipv4_loopback)
|
||||||
|
self.nameservers = nameservers
|
||||||
|
|
||||||
|
- @dns.resolver.Resolver.nameservers.setter
|
||||||
|
- def nameservers(self, nameservers):
|
||||||
|
- """
|
||||||
|
- *nameservers*, a ``list`` of nameservers with optional ports:
|
||||||
|
- "SERVER_IP port PORT_NUMBER".
|
||||||
|
-
|
||||||
|
- Overloads dns.resolver.Resolver.nameservers setter to split off ports
|
||||||
|
- into nameserver_ports after setting nameservers successfully with the
|
||||||
|
- setter in dns.resolver.Resolver.
|
||||||
|
- """
|
||||||
|
- # Get nameserver_ports if it is already set
|
||||||
|
- if hasattr(self, "nameserver_ports"):
|
||||||
|
- nameserver_ports = self.nameserver_ports
|
||||||
|
- else:
|
||||||
|
- nameserver_ports = {}
|
||||||
|
-
|
||||||
|
- # Check nameserver items in list and split out converted port number
|
||||||
|
- # into nameserver_ports: { nameserver: port }
|
||||||
|
- if isinstance(nameservers, list):
|
||||||
|
- _nameservers = []
|
||||||
|
- for nameserver in nameservers:
|
||||||
|
- splits = nameserver.split()
|
||||||
|
- if len(splits) == 3 and splits[1] == "port":
|
||||||
|
- nameserver = splits[0]
|
||||||
|
- try:
|
||||||
|
- port = int(splits[2])
|
||||||
|
- if port < 0 or port > 65535:
|
||||||
|
- raise ValueError()
|
||||||
|
- except ValueError:
|
||||||
|
- raise ValueError(
|
||||||
|
- "invalid nameserver: %s is not a valid port" %
|
||||||
|
- splits[2])
|
||||||
|
- nameserver_ports[nameserver] = port
|
||||||
|
- _nameservers.append(nameserver)
|
||||||
|
- nameservers = _nameservers
|
||||||
|
-
|
||||||
|
- # Call dns.resolver.Resolver.nameservers setter
|
||||||
|
- dns.resolver.Resolver.nameservers.__set__(self, nameservers)
|
||||||
|
- # Set nameserver_ports after successfull call to setter
|
||||||
|
- self.nameserver_ports = nameserver_ports
|
||||||
|
-
|
||||||
|
|
||||||
|
class DNSZoneAlreadyExists(dns.exception.DNSException):
|
||||||
|
supp_kwargs = {'zone', 'ns'}
|
||||||
|
diff --git a/ipatests/test_ipapython/test_dnsutil.py b/ipatests/test_ipapython/test_dnsutil.py
|
||||||
|
index 09463c69d..5e7a46197 100644
|
||||||
|
--- a/ipatests/test_ipapython/test_dnsutil.py
|
||||||
|
+++ b/ipatests/test_ipapython/test_dnsutil.py
|
||||||
|
@@ -101,43 +101,3 @@ class TestSortURI:
|
||||||
|
assert dnsutil.sort_prio_weight([h3, h2, h1]) == [h1, h2, h3]
|
||||||
|
assert dnsutil.sort_prio_weight([h3, h3, h3]) == [h3]
|
||||||
|
assert dnsutil.sort_prio_weight([h2, h2, h1, h1]) == [h1, h2]
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-class TestDNSResolver:
|
||||||
|
- def test_nameservers(self):
|
||||||
|
- res = dnsutil.DNSResolver()
|
||||||
|
- res.nameservers = ["4.4.4.4", "8.8.8.8"]
|
||||||
|
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
|
||||||
|
-
|
||||||
|
- def test_nameservers_with_ports(self):
|
||||||
|
- res = dnsutil.DNSResolver()
|
||||||
|
- res.nameservers = ["4.4.4.4 port 53", "8.8.8.8 port 8053"]
|
||||||
|
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
|
||||||
|
- assert res.nameserver_ports == {"4.4.4.4": 53, "8.8.8.8": 8053}
|
||||||
|
-
|
||||||
|
- res.nameservers = ["4.4.4.4 port 53", "8.8.8.8 port 8053"]
|
||||||
|
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
|
||||||
|
- assert res.nameserver_ports == {"4.4.4.4": 53, "8.8.8.8": 8053}
|
||||||
|
-
|
||||||
|
- def test_nameservers_with_bad_ports(self):
|
||||||
|
- res = dnsutil.DNSResolver()
|
||||||
|
- try:
|
||||||
|
- res.nameservers = ["4.4.4.4 port a"]
|
||||||
|
- except ValueError:
|
||||||
|
- pass
|
||||||
|
- else:
|
||||||
|
- pytest.fail("No fail on bad port a")
|
||||||
|
-
|
||||||
|
- try:
|
||||||
|
- res.nameservers = ["4.4.4.4 port -1"]
|
||||||
|
- except ValueError:
|
||||||
|
- pass
|
||||||
|
- else:
|
||||||
|
- pytest.fail("No fail on bad port -1")
|
||||||
|
-
|
||||||
|
- try:
|
||||||
|
- res.nameservers = ["4.4.4.4 port 65536"]
|
||||||
|
- except ValueError:
|
||||||
|
- pass
|
||||||
|
- else:
|
||||||
|
- pytest.fail("No fail on bad port 65536")
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmKp71wACgkQaYdvcqbi
|
|
||||||
008rbg/9G5w7KXgJcrhwBx5qqd4fqzSnwJdyN5oaBIEKNsAigMD7LIYawqgnO3g/
|
|
||||||
/3FmJTbeCrOj9EoakvE1YNRT+75oxAO+rMFcRvFHlJyfMCa3r3lrS4LrlQiiyNwZ
|
|
||||||
IHovcXr0Q3fizhp/V3acyZqx2pbnSh24CK4q5a1CNUs8SPkEFcOfpAJIMQCHeH6t
|
|
||||||
ScfxuWOp8R1FnaNQc/9x3vy3ySQbHMxIWLSfJy7pk7FhLGAvgVNQBAz70Bg7BfR1
|
|
||||||
R1V6syGeaPmqLOQw0jV05YMxyKwkbnSK/h2DlCg/iNQ/S71rXhOpuk01dDf73CI4
|
|
||||||
Fu1H9TX50Indq31+4qbOlKZqDshhNzRRpn2m2qVvzeTfObHlZMbYNyVamovP9fEZ
|
|
||||||
pfJcppI8aNDURjqpf/sVy4G8mhI5FQS+Q7bKvv9C04iE3XpTutg8q5mLMXGwWekY
|
|
||||||
yeklBAmdygOKsY1uWb7BCH9eoWCVWKIwi4m5uYteZNxBt4aqsa/VFsxCE1P2T7/S
|
|
||||||
+yc1Jo7hXWW8v3wm+dIGJj+Lz9YlJxC9SAiC72a6kTwIe2gnKlxoYbqe/18hEWm6
|
|
||||||
0jESl2LiXfBhXz0YQlv2HjcPWZMMrNuhSCGTMgzP8KfZB258mtxpbBTk5/e9Wgsk
|
|
||||||
29GCfaMWFUqZsrteG10HT/P6cotre6EVffQl9lNlPNQpX+DUKy4=
|
|
||||||
=azus
|
|
||||||
-----END PGP SIGNATURE-----
|
|
16
SOURCES/freeipa-4.9.11.tar.gz.asc
Normal file
16
SOURCES/freeipa-4.9.11.tar.gz.asc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmOA8kcACgkQaYdvcqbi
|
||||||
|
00887g/9GTvueJCypiuTqxKsbkTbWamOyH3W+AqtHw9Ff+wM/hnkSloGizhQ4EZZ
|
||||||
|
4Zs1e6bfM1pGXT7DXU9WbiYtcVtUhY5l9SnT9moCMaG1z4aB7z9UCxsqsSCuy3bG
|
||||||
|
KQq6AO2z4DaqHiz6ez3QXi+MUCNnPziWmS3bLdDCrTK0PNxqiMPIotlXMgVFgDL7
|
||||||
|
go/TAUvUL27zH4ELvG4parSGEKVEqe//RzXklOwGrInyj/4u42x7lUdO2ugOolCI
|
||||||
|
wNod8v+NWQWVgxNyhfTjP5VBZzO9wkGx4xruF2cAjVdjnIUGcG0FR3hI/bpi7Lyv
|
||||||
|
EmIozbQMK92MLel63E7Z/d5Jxfmuw/n1t5NrgSth+9hhWnBEpiaKkD2zAmUATqHf
|
||||||
|
+y4mbrtajmjzewEnfUnQfCvSLDPyTpnQKkRY8hUvk7u/J+/ZFWMQl9RdGNw3M0Zr
|
||||||
|
WrsqkKLK/n5IOHYHb/lBRaUidssKjQYFIvyNfHDP/lu6iiyLOpi5MIdk9BakO5wc
|
||||||
|
oDMk3w9xY7tPPmoesW40BThnAdOR9U4aad8zVvOxhMfzAYRwu95HGQoHnk7/rNut
|
||||||
|
IfzMZVjVTLQ8gyApcBlWzu/buiOoEXTKaMyzs0S9RMptknj5Xf0CGRz3bVrZRfJd
|
||||||
|
umyhD6/rNk3eZW/yEIv3IqFev0h1txTBPSTlczYUIz6uc7nx82E=
|
||||||
|
=8YVm
|
||||||
|
-----END PGP SIGNATURE-----
|
135
SPECS/ipa.spec
135
SPECS/ipa.spec
@ -68,8 +68,7 @@
|
|||||||
%global krb5_kdb_version 8.0
|
%global krb5_kdb_version 8.0
|
||||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||||
%global python_netaddr_version 0.7.19
|
%global python_netaddr_version 0.7.19
|
||||||
# Require 4.14.5-13 which brings CVE-2020-25717 fixes
|
%global samba_version 4.17.2-1
|
||||||
%global samba_version 4.14.5-13
|
|
||||||
%global selinux_policy_version 3.14.3-52
|
%global selinux_policy_version 3.14.3-52
|
||||||
%global slapi_nis_version 0.56.4
|
%global slapi_nis_version 0.56.4
|
||||||
%global python_ldap_version 3.1.0-1
|
%global python_ldap_version 3.1.0-1
|
||||||
@ -93,8 +92,7 @@
|
|||||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||||
%global python_netaddr_version 0.7.16
|
%global python_netaddr_version 0.7.16
|
||||||
|
|
||||||
# Require 4.14.6 which brings CVE-2020-25717 fixes
|
%global samba_version 2:4.17.2
|
||||||
%global samba_version 2:4.14.6
|
|
||||||
|
|
||||||
# 3.14.5-45 or later includes a number of interfaces fixes for IPA interface
|
# 3.14.5-45 or later includes a number of interfaces fixes for IPA interface
|
||||||
%global selinux_policy_version 3.14.5-45
|
%global selinux_policy_version 3.14.5-45
|
||||||
@ -178,7 +176,7 @@
|
|||||||
|
|
||||||
# Work-around fact that RPM SPEC parser does not accept
|
# Work-around fact that RPM SPEC parser does not accept
|
||||||
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
||||||
%define IPA_VERSION 4.9.10
|
%define IPA_VERSION 4.9.11
|
||||||
# Release candidate version -- uncomment with one percent for RC versions
|
# Release candidate version -- uncomment with one percent for RC versions
|
||||||
#%%global rc_version %%nil
|
#%%global rc_version %%nil
|
||||||
%define AT_SIGN @
|
%define AT_SIGN @
|
||||||
@ -191,7 +189,7 @@
|
|||||||
|
|
||||||
Name: %{package_name}
|
Name: %{package_name}
|
||||||
Version: %{IPA_VERSION}
|
Version: %{IPA_VERSION}
|
||||||
Release: 9%{?rc_version:.%rc_version}%{?dist}
|
Release: 5%{?rc_version:.%rc_version}%{?dist}
|
||||||
Summary: The Identity, Policy and Audit system
|
Summary: The Identity, Policy and Audit system
|
||||||
|
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
@ -211,27 +209,28 @@ Source1: https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers
|
|||||||
# RHEL spec file only: START
|
# RHEL spec file only: START
|
||||||
%if %{NON_DEVELOPER_BUILD}
|
%if %{NON_DEVELOPER_BUILD}
|
||||||
%if 0%{?rhel} >= 8
|
%if 0%{?rhel} >= 8
|
||||||
Patch0001: 0001-ipa-otpd-Fix-build-on-older-versions-of-gcc.patch
|
Patch0001: 0001-updates-fix-memberManager-ACI-to-allow-managers-from-a-specified-group_rhbz#2056009.patch
|
||||||
Patch0002: 0002-webui-IdP-Remove-arrow-notation-due-to-uglify-js-lim.patch
|
Patch0002: 0002-trust-add-handle-missing-msSFU30MaxGidNumber_rhbz#2162355.patch
|
||||||
Patch0003: 0003-Preserve-user-fix-the-confusing-summary_rhbz#2022028.patch
|
Patch0003: 0003-Backport-latest-test-fixes-python3-ipatests_rhbz#2166929.patch
|
||||||
Patch0004: 0004-Only-calculate-LDAP-password-grace-when-the-password_rhbz#782917.patch
|
Patch0004: 0004-server-install-remove-error-log-about-missing-bkup-file_rhbz#2160389.patch
|
||||||
Patch0005: 0005-Add-end-to-end-integration-tests-for-external-IdP.patch
|
Patch0005: 0005-automember-rebuild-add-a-notice-about-high-CPU-usage_rhbz#2018198.patch
|
||||||
Patch0006: 0006-webui-Do-not-allow-empty-pagination-size_rhbz#2094672.patch
|
Patch0006: 0006-ipa-kdb-PAC-consistency-checker-needs-to-handle-child-domains-as-well_rhbz#2166324.patch
|
||||||
Patch0007: 0007-webui-Allow-grace-login-limit_rhbz#2109243.patch
|
Patch0007: 0007-Wipe-the-ipa-ca-DNS-record-when-updating-system-records_rhbz#2158775.patch
|
||||||
Patch0008: 0008-check_repl_update-in-progress-is-a-boolean_rhbz#2117303.patch
|
|
||||||
Patch0009: 0009-Disabling-gracelimit-does-not-prevent-LDAP-binds_rhbz#2109236.patch
|
|
||||||
Patch0010: 0010-Set-passwordgracelimit-to-match-global-policy-on-group-pw-policies_rhbz#2115475.patch
|
|
||||||
Patch0011: 0011-fix-canonicalization-issue-in-Web-UI_rhbz#2133050.patch
|
|
||||||
Patch0012: 0012-Defer-creating-the-final-krb5-conf-on-clients_rhbz#2150246.patch
|
|
||||||
Patch0013: 0013-Vault-fix-interoperability-issues-with-older-RHEL-systems_rhbz#2148255.patch
|
|
||||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||||
Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
|
Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
|
||||||
|
Patch1003: 1003-webui-IdP-Remove-arrow-notation-due-to-uglify-js-lim.patch
|
||||||
|
# Due to behavior changes in python3-dns 2.2.0, IPA overrides the setting of the
|
||||||
|
# nameserver property inherited from dns.resolver.Resolver class to allow the
|
||||||
|
# setting of nameservers with custom ports. The method used is only needed, and
|
||||||
|
# only works, on version 2.2.0, or later, of python3-dns. For RHEL 8, which uses
|
||||||
|
# series 1.xx, the method override is not needed to provide the same behavior.
|
||||||
|
Patch1004: 1004-Revert-DNSResolver-Fix-use-of-nameservers-with-ports.patch
|
||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
# RHEL spec file only: END
|
# RHEL spec file only: END
|
||||||
|
|
||||||
# For the timestamp trick in patch application
|
## For the timestamp trick in patch application
|
||||||
BuildRequires: diffstat
|
#BuildRequires: diffstat
|
||||||
|
|
||||||
BuildRequires: openldap-devel
|
BuildRequires: openldap-devel
|
||||||
# For KDB DAL version, make explicit dependency so that increase of version
|
# For KDB DAL version, make explicit dependency so that increase of version
|
||||||
@ -298,6 +297,7 @@ BuildRequires: cracklib-dicts
|
|||||||
# Build dependencies for makeapi/makeaci
|
# Build dependencies for makeapi/makeaci
|
||||||
#
|
#
|
||||||
BuildRequires: python3-cffi
|
BuildRequires: python3-cffi
|
||||||
|
# RHEL 8 packages will not work with python3-dns 2.2.0 or newer.
|
||||||
BuildRequires: python3-dns
|
BuildRequires: python3-dns
|
||||||
BuildRequires: python3-ldap >= %{python_ldap_version}
|
BuildRequires: python3-ldap >= %{python_ldap_version}
|
||||||
BuildRequires: python3-libsss_nss_idmap
|
BuildRequires: python3-libsss_nss_idmap
|
||||||
@ -350,6 +350,7 @@ BuildRequires: python3-cryptography >= 1.6
|
|||||||
BuildRequires: python3-custodia >= 0.3.1
|
BuildRequires: python3-custodia >= 0.3.1
|
||||||
BuildRequires: python3-dateutil
|
BuildRequires: python3-dateutil
|
||||||
BuildRequires: python3-dbus
|
BuildRequires: python3-dbus
|
||||||
|
# RHEL 8 packages will not work with python3-dns 2.2.0 or newer.
|
||||||
BuildRequires: python3-dns >= 1.15
|
BuildRequires: python3-dns >= 1.15
|
||||||
BuildRequires: python3-docker
|
BuildRequires: python3-docker
|
||||||
BuildRequires: python3-gssapi >= 1.2.0
|
BuildRequires: python3-gssapi >= 1.2.0
|
||||||
@ -424,7 +425,6 @@ Requires: nss-tools >= %{nss_version}
|
|||||||
Requires(post): krb5-server >= %{krb5_version}
|
Requires(post): krb5-server >= %{krb5_version}
|
||||||
Requires(post): krb5-server >= %{krb5_base_version}
|
Requires(post): krb5-server >= %{krb5_base_version}
|
||||||
Requires: krb5-kdb-version = %{krb5_kdb_version}
|
Requires: krb5-kdb-version = %{krb5_kdb_version}
|
||||||
Requires: krb5-pkinit-openssl >= %{krb5_version}
|
|
||||||
Requires: cyrus-sasl-gssapi%{?_isa}
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
Requires: chrony
|
Requires: chrony
|
||||||
Requires: httpd >= %{httpd_version}
|
Requires: httpd >= %{httpd_version}
|
||||||
@ -522,6 +522,7 @@ Requires: python3-augeas
|
|||||||
Requires: augeas-libs >= %{augeas_version}
|
Requires: augeas-libs >= %{augeas_version}
|
||||||
Requires: python3-custodia >= 0.3.1
|
Requires: python3-custodia >= 0.3.1
|
||||||
Requires: python3-dbus
|
Requires: python3-dbus
|
||||||
|
# RHEL 8 packages will not work with python3-dns 2.2.0 or newer.
|
||||||
Requires: python3-dns >= 1.15
|
Requires: python3-dns >= 1.15
|
||||||
Requires: python3-gssapi >= 1.2.0
|
Requires: python3-gssapi >= 1.2.0
|
||||||
Requires: python3-ipaclient = %{version}-%{release}
|
Requires: python3-ipaclient = %{version}-%{release}
|
||||||
@ -652,6 +653,8 @@ Requires: python3-sssdconfig >= %{sssd_version}
|
|||||||
Requires: cyrus-sasl-gssapi%{?_isa}
|
Requires: cyrus-sasl-gssapi%{?_isa}
|
||||||
Requires: chrony
|
Requires: chrony
|
||||||
Requires: krb5-workstation >= %{krb5_version}
|
Requires: krb5-workstation >= %{krb5_version}
|
||||||
|
# Support pkinit with client install
|
||||||
|
Requires: krb5-pkinit-openssl >= %{krb5_version}
|
||||||
# authselect: sssd profile with-subid
|
# authselect: sssd profile with-subid
|
||||||
%if 0%{?fedora} >= 36
|
%if 0%{?fedora} >= 36
|
||||||
Requires: authselect >= 1.4.0
|
Requires: authselect >= 1.4.0
|
||||||
@ -751,6 +754,7 @@ Requires: %{name}-common = %{version}-%{release}
|
|||||||
Requires: python3-ipalib = %{version}-%{release}
|
Requires: python3-ipalib = %{version}-%{release}
|
||||||
Requires: python3-augeas
|
Requires: python3-augeas
|
||||||
Requires: augeas-libs >= %{augeas_version}
|
Requires: augeas-libs >= %{augeas_version}
|
||||||
|
# RHEL 8 packages will not work with python3-dns 2.2.0 or newer.
|
||||||
Requires: python3-dns >= 1.15
|
Requires: python3-dns >= 1.15
|
||||||
Requires: python3-jinja2
|
Requires: python3-jinja2
|
||||||
|
|
||||||
@ -831,6 +835,7 @@ Requires: python3-cffi
|
|||||||
Requires: python3-cryptography >= 1.6
|
Requires: python3-cryptography >= 1.6
|
||||||
Requires: python3-dateutil
|
Requires: python3-dateutil
|
||||||
Requires: python3-dbus
|
Requires: python3-dbus
|
||||||
|
# RHEL 8 packages will not work with python3-dns 2.2.0 or newer.
|
||||||
Requires: python3-dns >= 1.15
|
Requires: python3-dns >= 1.15
|
||||||
Requires: python3-gssapi >= 1.2.0
|
Requires: python3-gssapi >= 1.2.0
|
||||||
Requires: python3-jwcrypto >= 0.4.2
|
Requires: python3-jwcrypto >= 0.4.2
|
||||||
@ -947,22 +952,8 @@ Custom SELinux policy module for FreeIPA
|
|||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
# Update timestamps on the files touched by a patch, to avoid non-equal
|
|
||||||
# .pyc/.pyo files across the multilib peers within a build, where "Level"
|
|
||||||
# is the patch prefix option (e.g. -p1)
|
|
||||||
# Taken from specfile for sssd and python-simplejson
|
|
||||||
UpdateTimestamps() {
|
|
||||||
Level=$1
|
|
||||||
PatchFile=$2
|
|
||||||
|
|
||||||
# Locate the affected files:
|
%autosetup -n freeipa-%{version}%{?rc_version} -N -p1
|
||||||
for f in $(diffstat $Level -l $PatchFile); do
|
|
||||||
# Set the files to have the same timestamp as that of the patch:
|
|
||||||
touch -c -r $PatchFile $f
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
%setup -n freeipa-%{version}%{?rc_version} -q
|
|
||||||
|
|
||||||
# To allow proper application patches to the stripped po files, strip originals
|
# To allow proper application patches to the stripped po files, strip originals
|
||||||
pushd po
|
pushd po
|
||||||
@ -972,10 +963,8 @@ for i in *.po ; do
|
|||||||
done
|
done
|
||||||
popd
|
popd
|
||||||
|
|
||||||
for p in %patches ; do
|
%autopatch -p1
|
||||||
%__patch -p1 -i $p
|
|
||||||
UpdateTimestamps -p1 $p
|
|
||||||
done
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# PATH is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1005235
|
# PATH is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1005235
|
||||||
@ -1245,7 +1234,7 @@ if [ $1 -gt 1 ] ; then
|
|||||||
|
|
||||||
%{__python3} -c 'from ipaclient.install.client import configure_krb5_snippet; configure_krb5_snippet()' >>/var/log/ipaupgrade.log 2>&1
|
%{__python3} -c 'from ipaclient.install.client import configure_krb5_snippet; configure_krb5_snippet()' >>/var/log/ipaupgrade.log 2>&1
|
||||||
%{__python3} -c 'from ipaclient.install.client import update_ipa_nssdb; update_ipa_nssdb()' >>/var/log/ipaupgrade.log 2>&1
|
%{__python3} -c 'from ipaclient.install.client import update_ipa_nssdb; update_ipa_nssdb()' >>/var/log/ipaupgrade.log 2>&1
|
||||||
chmod 0600 /var/log/ipaupgrade.lo
|
chmod 0600 /var/log/ipaupgrade.log
|
||||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
|
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
|
||||||
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
|
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
|
||||||
sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
|
sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
|
||||||
@ -1726,19 +1715,63 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Mon Dec 5 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-9
|
* Fri Feb 10 2023 Rafael Jeffman <rjeffman@redhat.com> - 4.9.11-5
|
||||||
- Exclude installed policy module file from RPM verification
|
- Wipe the ipa-ca DNS record when updating system records
|
||||||
Resolves: RHBZ#2150243
|
Resolves: RHBZ#2158775
|
||||||
|
|
||||||
* Fri Dec 2 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-8
|
* Thu Feb 09 2023 Rafael Jeffman <rjeffman@redhat.com> - 4.9.11-4
|
||||||
|
- trust-add: handle missinf msSFU30MaxGidNumber
|
||||||
|
Resolves: RHBZ#2162355
|
||||||
|
- Backport latest test fixes for python3-ipatests
|
||||||
|
Resolves: RHBZ#2166929
|
||||||
|
- server install: remove error log about missing bkup file
|
||||||
|
Resolves: RHBZ#2160389
|
||||||
|
- automember-rebuild: add a notice about high CPU usage
|
||||||
|
Resolves: RHBZ#2018198
|
||||||
|
- ipa-kdb: PAC consistency checker needs to handle child domains as well
|
||||||
|
Resolves: RHBZ#2166324
|
||||||
|
|
||||||
|
* Mon Dec 19 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.11-3
|
||||||
|
- Revert DNSResolver Fix use of nameservers with ports.
|
||||||
|
Related: RHBZ#2141316
|
||||||
|
|
||||||
|
* Fri Dec 16 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.11-2
|
||||||
|
- webui IdP: Remove arrow notation due to uglify-js limitation
|
||||||
|
Related: RHBZ#2141316
|
||||||
|
|
||||||
|
* Wed Dec 14 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.11-1
|
||||||
|
- Rebase ipa to 4.9.11
|
||||||
|
Resolves: RHBZ#2141316
|
||||||
|
- updates: fix memberManager ACI to allow managers from a specified group
|
||||||
|
Resolves: RHBZ#2056009
|
||||||
- Defer creating the final krb5.conf on clients
|
- Defer creating the final krb5.conf on clients
|
||||||
Resolves: RHBZ#2150246
|
Resolves: RHBZ#2148259
|
||||||
- Vault: fix interoperability issues with older RHEL systems
|
- Exclude installed policy module file from RPM verification
|
||||||
Resolves: RHBZ#2148255
|
Resolves: RHBZ#2149567
|
||||||
|
- Spec file: ipa-client depends on krb5-pkinit-openssl
|
||||||
|
Resolves: RHBZ#2149889
|
||||||
|
|
||||||
* Thu Oct 13 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-7
|
* Thu Nov 24 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-8
|
||||||
|
- ipa man page format the EXAMPLES section
|
||||||
|
Resolves: RHBZ#2129895
|
||||||
- Fix canonicalization issue in Web UI
|
- Fix canonicalization issue in Web UI
|
||||||
Resolves: RHBZ#2133050
|
Resolves: RHBZ#2127035
|
||||||
|
- Remove idnssoaserial argument from dns zone API.
|
||||||
|
Resolves: RHBZ#2108630
|
||||||
|
- Warn for permissions with read/write/search/compare and no attrs
|
||||||
|
Resolves: RHBZ#2098187
|
||||||
|
- Add PKINIT support to ipa-client-install
|
||||||
|
Resolves: RHBZ#2075452
|
||||||
|
- Generate CNAMEs for TXT+URI location krb records
|
||||||
|
Resolves: RHBZ#2104185
|
||||||
|
- Vault: fix interoperability issues with older RHEL systems
|
||||||
|
Resolves: RHBZ#2144737
|
||||||
|
- Fix typo on ipaupgrade.log chmod during RPM %post snipppet
|
||||||
|
Resolves: RHBZ#2140994
|
||||||
|
|
||||||
|
* Tue Nov 1 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-7
|
||||||
|
- Rebuild to samba 4.17.2.
|
||||||
|
Related: RHBZ#2132051
|
||||||
|
|
||||||
* Mon Aug 22 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-6
|
* Mon Aug 22 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.10-6
|
||||||
- webui: Allow grace login limit
|
- webui: Allow grace login limit
|
||||||
|
Loading…
Reference in New Issue
Block a user