Remove unused patches
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
parent
bb102603da
commit
d118b2bff1
@ -1,33 +0,0 @@
|
||||
From d43b513927d6dd0a12464dd24287ce40ccaf33e4 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Kelley <ckelley@redhat.com>
|
||||
Date: Fri, 10 Sep 2021 16:47:22 +0100
|
||||
Subject: [PATCH] Make Dogtag return XML for ipa cert-find
|
||||
|
||||
Using JSON by default within Dogtag appears to cause ipa cert-find to
|
||||
return JSON, when the request was made with XML. We can request that XML
|
||||
is returned as before by specifying so in the request header.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/8980
|
||||
Signed-off-by: Chris Kelley <ckelley@redhat.com>
|
||||
Reviewed-By: Francois Cami <fcami@redhat.com>
|
||||
---
|
||||
ipaserver/plugins/dogtag.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
|
||||
index be2e4bb4e..b4feddfac 100644
|
||||
--- a/ipaserver/plugins/dogtag.py
|
||||
+++ b/ipaserver/plugins/dogtag.py
|
||||
@@ -1832,7 +1832,8 @@ class ra(rabase.rabase, RestClient):
|
||||
method='POST',
|
||||
headers={'Accept-Encoding': 'gzip, deflate',
|
||||
'User-Agent': 'IPA',
|
||||
- 'Content-Type': 'application/xml'},
|
||||
+ 'Content-Type': 'application/xml',
|
||||
+ 'Accept': 'application/xml'},
|
||||
body=payload
|
||||
)
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 22d1392a8a0d2887c389dcd78be06104cff88d30 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.31.1
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 1bb4ff9ed2313fb3c2bd1418258c5bcec557b6a5 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.1
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 7a1e1d9f1cb13679c28f12d05b156a08bcc4d856 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.1
|
||||
|
@ -1,137 +0,0 @@
|
||||
From 77803587d6e15b41a66fc0ee0a87ad55ee196dfe Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Wed, 3 Aug 2022 18:22:47 +0200
|
||||
Subject: [PATCH] DNSResolver: Fix use of nameservers with ports
|
||||
|
||||
IPA DNS zone and forwardzone commands allow to use nameservers with ports
|
||||
as "SERVER_IP port PORT_NUMBER". bind is supporting this syntax, but the
|
||||
Resolver in dnspython that is used to verify the list of forwarders
|
||||
(nameservers) is only allowing to have IP addresses in this list. With
|
||||
dnspython version 2.20 there is a new validator in dns.resolver.BaseResolver
|
||||
that ensures this.
|
||||
|
||||
Refs:
|
||||
- https://bind9.readthedocs.io/en/v9_18_4/reference.html#zone-statement-grammar
|
||||
- https://github.com/rthalley/dnspython/blob/master/dns/resolver.py#L1094
|
||||
|
||||
ipapython/dnsutil.DNSResolver derives from dns.resolver.Resolver. The setter
|
||||
for nameservers has been overloaded in the DNSResolver class to split out
|
||||
the port numbers into the nameserver_ports dict { SERVER_IP: PORT_NUMBER }.
|
||||
After the setter for nameservers succeeded, nameserver_ports is set.
|
||||
nameserver_ports is used in the resolve() method of dns.resolver.Resolver.
|
||||
|
||||
Additional tests have been added to verify that nameservers and also
|
||||
nameserver_ports are properly set and also valid.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9158
|
||||
|
||||
Signed-off-by: Thomas Woerner <twoerner@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipapython/dnsutil.py | 41 +++++++++++++++++++++++++
|
||||
ipatests/test_ipapython/test_dnsutil.py | 40 ++++++++++++++++++++++++
|
||||
2 files changed, 81 insertions(+)
|
||||
|
||||
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
|
||||
index 4baeaf8cc..58de365ab 100644
|
||||
--- a/ipapython/dnsutil.py
|
||||
+++ b/ipapython/dnsutil.py
|
||||
@@ -144,6 +144,47 @@ 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 5e7a46197..09463c69d 100644
|
||||
--- a/ipatests/test_ipapython/test_dnsutil.py
|
||||
+++ b/ipatests/test_ipapython/test_dnsutil.py
|
||||
@@ -101,3 +101,43 @@ 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.37.1
|
||||
|
@ -1,231 +0,0 @@
|
||||
From 1aa39529cda4ab9620539dbad705cedd23c21b42 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.1
|
||||
|
||||
From 45e6d49b94da78cd82eb016b3266a17a1359a087 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Thu, 4 Aug 2022 12:04:22 -0400
|
||||
Subject: [PATCH 1/2] 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 66929b921..210bfc495 100644
|
||||
--- a/API.txt
|
||||
+++ b/API.txt
|
||||
@@ -4076,7 +4076,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.1
|
||||
|
||||
From de6f074538f6641fd9d84bed204a3d4d50eccbe5 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Thu, 4 Aug 2022 12:04:41 -0400
|
||||
Subject: [PATCH 2/2] 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.1
|
||||
|
@ -1,114 +0,0 @@
|
||||
From 03f7731d39689ee6da7118fa4d5de01b4012c427 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Sat, 10 Apr 2021 15:40:22 +0300
|
||||
Subject: [PATCH] ipaserver/install/dns: handle SERVFAIL when checking reverse
|
||||
zone
|
||||
|
||||
systemd-resolved in Fedora 34+ returns SERVFAIL for reverse zone that
|
||||
does not yet exist when we attempt to look it up before installation.
|
||||
Assume that this is OK -- we are going to create the zone ourselves
|
||||
during installation.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/8794
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipapython/dnsutil.py | 6 ++++++
|
||||
ipaserver/install/bindinstance.py | 12 ++++++++++++
|
||||
ipaserver/install/dns.py | 12 +++++++++++-
|
||||
3 files changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
|
||||
index 63eb64dc1..67a5a5334 100644
|
||||
--- a/ipapython/dnsutil.py
|
||||
+++ b/ipapython/dnsutil.py
|
||||
@@ -125,6 +125,10 @@ class DNSZoneAlreadyExists(dns.exception.DNSException):
|
||||
"and is handled by server(s): {ns}")
|
||||
|
||||
|
||||
+class DNSNoNameservers(dns.resolver.NoNameservers):
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
@six.python_2_unicode_compatible
|
||||
class DNSName(dns.name.Name):
|
||||
labels = None # make pylint happy
|
||||
@@ -447,6 +451,8 @@ def check_zone_overlap(zone, raise_on_error=True):
|
||||
except dns.exception.DNSException as e:
|
||||
msg = ("DNS check for domain %s failed: %s." % (zone, e))
|
||||
if raise_on_error:
|
||||
+ if isinstance(e, dns.resolver.NoNameservers):
|
||||
+ raise DNSNoNameservers(**e.kwargs) from None
|
||||
raise ValueError(msg)
|
||||
else:
|
||||
logger.warning('%s', msg)
|
||||
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
|
||||
index 19941cd00..f1c9e0aa2 100644
|
||||
--- a/ipaserver/install/bindinstance.py
|
||||
+++ b/ipaserver/install/bindinstance.py
|
||||
@@ -312,6 +312,7 @@ def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
|
||||
logger.error("Reverse zone %s will not be used: %s",
|
||||
zone, e)
|
||||
continue
|
||||
+
|
||||
break
|
||||
|
||||
return normalize_zone(zone)
|
||||
@@ -338,6 +339,12 @@ def get_auto_reverse_zones(ip_addresses, allow_zone_overlap=False):
|
||||
default_reverse, ip)
|
||||
logger.debug('%s', e)
|
||||
continue
|
||||
+ except dnsutil.DNSNoNameservers as e:
|
||||
+ # Show warning and continue in case we've got SERVFAIL
|
||||
+ # because we are supposedly going to create this reverse zone
|
||||
+ logger.warning('%s', str(e))
|
||||
+ continue
|
||||
+
|
||||
auto_zones.append((ip, default_reverse))
|
||||
return auto_zones
|
||||
|
||||
@@ -505,6 +512,11 @@ def check_reverse_zones(ip_addresses, reverse_zones, options, unattended,
|
||||
else:
|
||||
logger.warning('%s', msg)
|
||||
continue
|
||||
+ except dnsutil.DNSNoNameservers as e:
|
||||
+ # Show warning and continue in case we've got SERVFAIL
|
||||
+ # because we are supposedly going to create this reverse zone
|
||||
+ logger.warning('%s', str(e))
|
||||
+ continue
|
||||
checked_reverse_zones.append(normalize_zone(rz))
|
||||
|
||||
# check that there is reverse zone for every IP
|
||||
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
|
||||
index b51b92bfd..cbdaf99fd 100644
|
||||
--- a/ipaserver/install/dns.py
|
||||
+++ b/ipaserver/install/dns.py
|
||||
@@ -151,6 +151,10 @@ def install_check(standalone, api, replica, options, hostname):
|
||||
logger.warning('%s', str(e))
|
||||
else:
|
||||
raise e
|
||||
+ except dnsutil.DNSNoNameservers as e:
|
||||
+ # Show warning and continue in case we've got SERVFAIL
|
||||
+ # because we are supposedly going to create this reverse zone
|
||||
+ logger.warning('%s', str(e))
|
||||
|
||||
if standalone:
|
||||
print("==============================================================================")
|
||||
@@ -457,7 +461,13 @@ class DNSInstallInterface(hostname.HostNameInstallInterface):
|
||||
def reverse_zones(self, values):
|
||||
if not self.allow_zone_overlap:
|
||||
for zone in values:
|
||||
- check_zone_overlap(zone)
|
||||
+ try:
|
||||
+ check_zone_overlap(zone)
|
||||
+ except dnsutil.DNSNoNameservers as e:
|
||||
+ # Show warning and continue in case we've got SERVFAIL
|
||||
+ # we are supposedly going to create this reverse zone
|
||||
+ logger.warning('%s', str(e))
|
||||
+ continue
|
||||
|
||||
no_reverse = knob(
|
||||
None,
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,255 +0,0 @@
|
||||
From 4d4931abf0b77c431252389edb6f447b63c91d8c Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Mon, 31 May 2021 12:53:55 +0300
|
||||
Subject: [PATCH] ds: Support renaming of a replication plugin in 389-ds
|
||||
|
||||
IPA topology plugin depends on the replication plugin but
|
||||
389-ds cannot handle older alias querying in the plugin
|
||||
configuration with 'nsslapd-plugin-depends-on-named: ..' attribute
|
||||
|
||||
See https://github.com/389ds/389-ds-base/issues/4786 for details
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/8799
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
.../ipa-version/version-conf.ldif | 2 +-
|
||||
.../topology/ipa-topology-conf.ldif | 2 +-
|
||||
install/updates/10-enable-betxn.update | 2 +-
|
||||
.../updates/20-enable_dirsrv_plugins.update | 4 ++--
|
||||
install/updates/20-replication.update | 2 +-
|
||||
ipaserver/install/dsinstance.py | 8 ++++++-
|
||||
ipaserver/install/replication.py | 24 ++++++++++++++++++-
|
||||
ipaserver/install/upgradeinstance.py | 18 +++++++++++++-
|
||||
.../test_ipaserver/test_topology_plugin.py | 13 +++++++++-
|
||||
9 files changed, 65 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-slapi-plugins/ipa-version/version-conf.ldif b/daemons/ipa-slapi-plugins/ipa-version/version-conf.ldif
|
||||
index 11558834c..6000868e2 100644
|
||||
--- a/daemons/ipa-slapi-plugins/ipa-version/version-conf.ldif
|
||||
+++ b/daemons/ipa-slapi-plugins/ipa-version/version-conf.ldif
|
||||
@@ -13,5 +13,5 @@ nsslapd-pluginversion: 1.0
|
||||
nsslapd-pluginvendor: Red Hat, Inc.
|
||||
nsslapd-plugindescription: IPA Replication version plugin
|
||||
nsslapd-plugin-depends-on-type: database
|
||||
-nsslapd-plugin-depends-on-named: Multimaster Replication Plugin
|
||||
+nsslapd-plugin-depends-on-named: $REPLICATION_PLUGIN
|
||||
|
||||
diff --git a/daemons/ipa-slapi-plugins/topology/ipa-topology-conf.ldif b/daemons/ipa-slapi-plugins/topology/ipa-topology-conf.ldif
|
||||
index 4b3c4ce99..effa38597 100644
|
||||
--- a/daemons/ipa-slapi-plugins/topology/ipa-topology-conf.ldif
|
||||
+++ b/daemons/ipa-slapi-plugins/topology/ipa-topology-conf.ldif
|
||||
@@ -15,7 +15,7 @@ nsslapd-topo-plugin-shared-binddngroup: cn=replication managers,cn=sysaccounts,c
|
||||
nsslapd-topo-plugin-startup-delay: 20
|
||||
nsslapd-pluginId: none
|
||||
nsslapd-plugin-depends-on-named: ldbm database
|
||||
-nsslapd-plugin-depends-on-named: Multimaster Replication Plugin
|
||||
+nsslapd-plugin-depends-on-named: $REPLICATION_PLUGIN
|
||||
nsslapd-pluginVersion: 1.0
|
||||
nsslapd-pluginVendor: none
|
||||
nsslapd-pluginDescription: none
|
||||
diff --git a/install/updates/10-enable-betxn.update b/install/updates/10-enable-betxn.update
|
||||
index 88f584cb3..1f89341c7 100644
|
||||
--- a/install/updates/10-enable-betxn.update
|
||||
+++ b/install/updates/10-enable-betxn.update
|
||||
@@ -18,7 +18,7 @@ only: nsslapd-pluginType: betxnpreoperation
|
||||
dn: cn=MemberOf Plugin,cn=plugins,cn=config
|
||||
only: nsslapd-pluginType: betxnpostoperation
|
||||
|
||||
-dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config
|
||||
+dn: cn=$REPLICATION_PLUGIN,cn=plugins,cn=config
|
||||
only: nsslapd-pluginbetxn: on
|
||||
|
||||
dn: cn=PAM Pass Through Auth,cn=plugins,cn=config
|
||||
diff --git a/install/updates/20-enable_dirsrv_plugins.update b/install/updates/20-enable_dirsrv_plugins.update
|
||||
index dc046f41b..182a8334d 100644
|
||||
--- a/install/updates/20-enable_dirsrv_plugins.update
|
||||
+++ b/install/updates/20-enable_dirsrv_plugins.update
|
||||
@@ -50,8 +50,8 @@ replace: nsslapd-pluginEnabled:off::on
|
||||
dn: cn=Managed Entries,cn=plugins,cn=config
|
||||
replace: nsslapd-pluginEnabled:off::on
|
||||
|
||||
-# Multimaster Replication Plugin, plugins, config
|
||||
-dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config
|
||||
+# Replication Plugin may be Multisupplier or Multimaster
|
||||
+dn: cn=$REPLICATION_PLUGIN,cn=plugins,cn=config
|
||||
replace: nsslapd-pluginEnabled:off::on
|
||||
|
||||
# Roles Plugin, plugins, config
|
||||
diff --git a/install/updates/20-replication.update b/install/updates/20-replication.update
|
||||
index 34beebc10..287148ec8 100644
|
||||
--- a/install/updates/20-replication.update
|
||||
+++ b/install/updates/20-replication.update
|
||||
@@ -58,7 +58,7 @@ default: nsslapd-topo-plugin-shared-binddngroup: cn=replication managers,cn=sysa
|
||||
default: nsslapd-topo-plugin-startup-delay: 20
|
||||
default: nsslapd-pluginId: none
|
||||
default: nsslapd-plugin-depends-on-named: ldbm database
|
||||
-default: nsslapd-plugin-depends-on-named: Multimaster Replication Plugin
|
||||
+default: nsslapd-plugin-depends-on-named: $REPLICATION_PLUGIN
|
||||
default: nsslapd-pluginVersion: 1.0
|
||||
default: nsslapd-pluginVendor: none
|
||||
default: nsslapd-pluginDescription: none
|
||||
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
|
||||
index 622d6a0f5..b0e012ab8 100644
|
||||
--- a/ipaserver/install/dsinstance.py
|
||||
+++ b/ipaserver/install/dsinstance.py
|
||||
@@ -571,6 +571,12 @@ class DsInstance(service.Service):
|
||||
inst.setup_ldapi()
|
||||
inst.open()
|
||||
|
||||
+ def get_entry(dn, attrs):
|
||||
+ return inst.getEntry(dn, attrlist=attrs)
|
||||
+
|
||||
+ self.sub_dict['REPLICATION_PLUGIN'] = (
|
||||
+ replication.get_replication_plugin_name(get_entry))
|
||||
+
|
||||
try:
|
||||
ipadomain = IpaDomain(inst, dn=self.suffix.ldap_text())
|
||||
ipadomain.create(properties={
|
||||
@@ -735,7 +741,7 @@ class DsInstance(service.Service):
|
||||
self._ldap_mod("pw-logging-conf.ldif")
|
||||
|
||||
def __config_version_module(self):
|
||||
- self._ldap_mod("version-conf.ldif")
|
||||
+ self._ldap_mod("version-conf.ldif", self.sub_dict)
|
||||
|
||||
def __config_uuid_module(self):
|
||||
self._ldap_mod("uuid-conf.ldif")
|
||||
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
|
||||
index 5a3e5e565..8fb4fd414 100644
|
||||
--- a/ipaserver/install/replication.py
|
||||
+++ b/ipaserver/install/replication.py
|
||||
@@ -232,6 +232,23 @@ def get_ds_version(conn):
|
||||
return vendor_version
|
||||
|
||||
|
||||
+def get_replication_plugin_name(dirsrv_get_entry):
|
||||
+ # Support renaming of a replication plugin in 389-ds
|
||||
+ # IPA topology plugin depends on the replication plugin but
|
||||
+ # 389-ds cannot handle older alias querying in the plugin
|
||||
+ # configuration with 'nsslapd-plugin-depends-on-named: ..' attribute
|
||||
+ #
|
||||
+ # dirsrv_get_entry: function (dn, attrs) -> str
|
||||
+ # returns entry dictionary
|
||||
+ try:
|
||||
+ entry = dirsrv_get_entry(
|
||||
+ 'cn=Multisupplier Replication Plugin,cn=plugins,cn=config',
|
||||
+ ['cn'])
|
||||
+ return str(entry['cn'], encoding='utf-8')
|
||||
+ except Exception:
|
||||
+ return 'Multimaster Replication Plugin'
|
||||
+
|
||||
+
|
||||
class ReplicationManager:
|
||||
"""Manage replication agreements
|
||||
|
||||
@@ -737,8 +754,13 @@ class ReplicationManager:
|
||||
mtent = self.get_mapping_tree_entry()
|
||||
dn = mtent.dn
|
||||
|
||||
+ def get_entry(dn, attrs):
|
||||
+ return self.conn.get_entry(DN(dn), attrs)
|
||||
+
|
||||
+ replication_plugin_name = get_replication_plugin_name(get_entry)
|
||||
+
|
||||
plgent = self.conn.get_entry(
|
||||
- DN(('cn', 'Multimaster Replication Plugin'), ('cn', 'plugins'),
|
||||
+ DN(('cn', replication_plugin_name), ('cn', 'plugins'),
|
||||
('cn', 'config')),
|
||||
['nsslapd-pluginPath'])
|
||||
path = plgent.single_value.get('nsslapd-pluginPath')
|
||||
diff --git a/ipaserver/install/upgradeinstance.py b/ipaserver/install/upgradeinstance.py
|
||||
index a239dd035..581742d6f 100644
|
||||
--- a/ipaserver/install/upgradeinstance.py
|
||||
+++ b/ipaserver/install/upgradeinstance.py
|
||||
@@ -40,6 +40,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
DSE = 'dse.ldif'
|
||||
COMPAT_DN = "cn=Schema Compatibility,cn=plugins,cn=config"
|
||||
+REPL_PLUGIN_DN_TEMPLATE = "cn=Multi%s Replication Plugin,cn=plugins,cn=config"
|
||||
|
||||
|
||||
class GetEntryFromLDIF(ldif.LDIFParser):
|
||||
@@ -97,6 +98,7 @@ class IPAUpgrade(service.Service):
|
||||
self.modified = False
|
||||
self.serverid = serverid
|
||||
self.schema_files = schema_files
|
||||
+ self.sub_dict = dict()
|
||||
|
||||
def __start(self):
|
||||
srv = services.service(self.service_name, api)
|
||||
@@ -170,6 +172,20 @@ class IPAUpgrade(service.Service):
|
||||
else:
|
||||
self.backup_state('nsslapd-global-backend-lock', global_lock)
|
||||
|
||||
+ # update self.sub_dict with the replication plugin name
|
||||
+ # It may be different depending on 389-ds version
|
||||
+ with open(self.filename, "r") as in_file:
|
||||
+ parser = GetEntryFromLDIF(in_file, entries_dn=[])
|
||||
+ parser.parse()
|
||||
+
|
||||
+ results = parser.get_results()
|
||||
+
|
||||
+ dn = REPL_PLUGIN_DN_TEMPLATE % "supplier"
|
||||
+ if dn not in results:
|
||||
+ dn = REPL_PLUGIN_DN_TEMPLATE % "master"
|
||||
+
|
||||
+ self.sub_dict['REPLICATION_PLUGIN'] = results[dn].get('cn')
|
||||
+
|
||||
with open(self.filename, "r") as in_file:
|
||||
parser = GetEntryFromLDIF(in_file, entries_dn=[COMPAT_DN])
|
||||
parser.parse()
|
||||
@@ -284,7 +300,7 @@ class IPAUpgrade(service.Service):
|
||||
|
||||
def __upgrade(self):
|
||||
try:
|
||||
- ld = ldapupdate.LDAPUpdate(api=self.api)
|
||||
+ ld = ldapupdate.LDAPUpdate(api=self.api, sub_dict=self.sub_dict)
|
||||
if len(self.files) == 0:
|
||||
self.files = ld.get_all_files(ldapupdate.UPDATES_DIR)
|
||||
self.modified = (ld.update(self.files) or self.modified)
|
||||
diff --git a/ipatests/test_ipaserver/test_topology_plugin.py b/ipatests/test_ipaserver/test_topology_plugin.py
|
||||
index ca68a8905..be24ac5c1 100644
|
||||
--- a/ipatests/test_ipaserver/test_topology_plugin.py
|
||||
+++ b/ipatests/test_ipaserver/test_topology_plugin.py
|
||||
@@ -10,6 +10,8 @@ from ipapython.dn import DN
|
||||
import pytest
|
||||
|
||||
|
||||
+REPL_PLUGIN_NAME_TEMPLATE = 'Multi%s Replication Plugin'
|
||||
+
|
||||
@pytest.mark.tier1
|
||||
class TestTopologyPlugin:
|
||||
"""
|
||||
@@ -35,12 +37,13 @@ class TestTopologyPlugin:
|
||||
@pytest.mark.skipif(os.path.isfile(pwfile) is False,
|
||||
reason="You did not provide a .dmpw file with the DM password")
|
||||
def test_topologyplugin(self):
|
||||
+ supplier = REPL_PLUGIN_NAME_TEMPLATE % 'supplier'
|
||||
pluginattrs = {
|
||||
u'nsslapd-pluginPath': [u'libtopology'],
|
||||
u'nsslapd-pluginVendor': [u'freeipa'],
|
||||
u'cn': [u'IPA Topology Configuration'],
|
||||
u'nsslapd-plugin-depends-on-named':
|
||||
- [u'Multimaster Replication Plugin', u'ldbm database'],
|
||||
+ [supplier, u'ldbm database'],
|
||||
u'nsslapd-topo-plugin-shared-replica-root': [u'dc=example,dc=com'],
|
||||
u'nsslapd-pluginVersion': [u'1.0'],
|
||||
u'nsslapd-topo-plugin-shared-config-base':
|
||||
@@ -72,5 +75,13 @@ class TestTopologyPlugin:
|
||||
bind_pw=dm_password)
|
||||
entry = self.conn.get_entry(topoplugindn)
|
||||
assert(set(entry.keys()) == set(pluginattrs.keys()))
|
||||
+
|
||||
+ # Handle different names for replication plugin
|
||||
+ key = 'nsslapd-plugin-depends-on-named'
|
||||
+ plugin_dependencies = entry[key]
|
||||
+ if supplier not in plugin_dependencies:
|
||||
+ mm = REPL_PLUGIN_NAME_TEMPLATE % 'master'
|
||||
+ pluginattrs[key] = [mm, 'ldbm database']
|
||||
+
|
||||
for i in checkvalues:
|
||||
assert(set(pluginattrs[i]) == set(entry[i]))
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 5238651da06547bb004de2434ae7d357422ba735 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Fri, 4 Jun 2021 15:35:58 +0300
|
||||
Subject: [PATCH] get_credentials: return ValueError for missing creds
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/8873
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipalib/krb_utils.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipalib/krb_utils.py b/ipalib/krb_utils.py
|
||||
index 1002bbaa6..21078ef3e 100644
|
||||
--- a/ipalib/krb_utils.py
|
||||
+++ b/ipalib/krb_utils.py
|
||||
@@ -153,7 +153,7 @@ def get_credentials(name=None, ccache_name=None):
|
||||
return gssapi.Credentials(usage='initiate', name=name, store=store)
|
||||
except gssapi.exceptions.GSSError as e:
|
||||
if e.min_code in ( # pylint: disable=no-member
|
||||
- KRB5_FCC_NOFILE, GSSPROXY_KRB5_FCC_NOFILE,
|
||||
+ KRB5_FCC_NOFILE, GSSPROXY_KRB5_FCC_NOFILE, KRB5_CC_NOTFOUND,
|
||||
):
|
||||
raise ValueError('"%s", ccache="%s"' % (e, ccache_name))
|
||||
raise
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,222 +0,0 @@
|
||||
From fe59e6a0b06926a3d71c6b6f361714d1422d5b0f Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Thu, 11 Nov 2021 09:58:09 +0200
|
||||
Subject: [PATCH 1/2] ipa-kdb: honor SID from the host or service entry
|
||||
|
||||
If the SID was explicitly set for the host or service entry, honor it
|
||||
when issuing PAC. For normal services and hosts we don't allocate
|
||||
individual SIDs but for cifs/... principals on domain members we do as
|
||||
they need to login to Samba domain controller.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9031
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
daemons/ipa-kdb/ipa_kdb_mspac.c | 46 ++++++++++++++++++++-------------
|
||||
1 file changed, 28 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
index 0e0ee3616..6f272f9fe 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
@@ -653,6 +653,28 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
|
||||
* clear it after detecting the changes */
|
||||
info3->base.acct_flags = ACB_USE_AES_KEYS;
|
||||
|
||||
+ ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
|
||||
+ "ipaNTSecurityIdentifier", &strres);
|
||||
+ if (ret) {
|
||||
+ /* SID is mandatory for all but host/services */
|
||||
+ if (!(is_host || is_service)) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ info3->base.rid = 0;
|
||||
+ } else {
|
||||
+ ret = ipadb_string_to_sid(strres, &sid);
|
||||
+ free(strres);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = sid_split_rid(&sid, &info3->base.rid);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* If SID was present prefer using it even for hosts and services
|
||||
+ * but we still need to set the account flags correctly */
|
||||
if ((is_host || is_service)) {
|
||||
/* it is either host or service, so get the hostname first */
|
||||
char *sep = strchr(info3->base.account_name.string, '/');
|
||||
@@ -661,29 +683,17 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
|
||||
sep ? sep + 1 : info3->base.account_name.string);
|
||||
if (is_master) {
|
||||
/* Well known RID of domain controllers group */
|
||||
- info3->base.rid = 516;
|
||||
+ if (info3->base.rid == 0) {
|
||||
+ info3->base.rid = 516;
|
||||
+ }
|
||||
info3->base.acct_flags |= ACB_SVRTRUST;
|
||||
} else {
|
||||
/* Well known RID of domain computers group */
|
||||
- info3->base.rid = 515;
|
||||
+ if (info3->base.rid == 0) {
|
||||
+ info3->base.rid = 515;
|
||||
+ }
|
||||
info3->base.acct_flags |= ACB_WSTRUST;
|
||||
}
|
||||
- } else {
|
||||
- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
|
||||
- "ipaNTSecurityIdentifier", &strres);
|
||||
- if (ret) {
|
||||
- /* SID is mandatory */
|
||||
- return ret;
|
||||
- }
|
||||
- ret = ipadb_string_to_sid(strres, &sid);
|
||||
- free(strres);
|
||||
- if (ret) {
|
||||
- return ret;
|
||||
- }
|
||||
- ret = sid_split_rid(&sid, &info3->base.rid);
|
||||
- if (ret) {
|
||||
- return ret;
|
||||
- }
|
||||
}
|
||||
|
||||
ret = ipadb_ldap_deref_results(ipactx->lcontext, lentry, &deref_results);
|
||||
--
|
||||
2.33.1
|
||||
|
||||
|
||||
From 21af43550aa0a31e1ec5240578bd64fcbdd4ee24 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Thu, 11 Nov 2021 10:16:47 +0200
|
||||
Subject: [PATCH 2/2] ipa-kdb: validate domain SID in incoming PAC for trusted
|
||||
domains for S4U
|
||||
|
||||
Previously, ipadb_check_logon_info() was called only for cross-realm
|
||||
case. Now we call it for both in-realm and cross-realm cases. In case of
|
||||
the S4U2Proxy, we would be passed a PAC of the original caller which
|
||||
might be a principal from the trusted realm. We cannot validate that PAC
|
||||
against our local client DB entry because this is the proxy entry which
|
||||
is guaranteed to have different SID.
|
||||
|
||||
In such case, validate the SID of the domain in PAC against our realm
|
||||
and any trusted doman but skip an additional check of the DB entry in
|
||||
the S4U2Proxy case.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9031
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
daemons/ipa-kdb/ipa_kdb_mspac.c | 54 ++++++++++++++++++++++++++-------
|
||||
1 file changed, 43 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
index 6f272f9fe..6f7d1ac15 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
@@ -1637,11 +1637,13 @@ static void filter_logon_info_log_message_rid(struct dom_sid *sid, uint32_t rid)
|
||||
static krb5_error_code check_logon_info_consistent(krb5_context context,
|
||||
TALLOC_CTX *memctx,
|
||||
krb5_const_principal client_princ,
|
||||
+ krb5_boolean is_s4u,
|
||||
struct PAC_LOGON_INFO_CTR *info)
|
||||
{
|
||||
krb5_error_code kerr = 0;
|
||||
struct ipadb_context *ipactx;
|
||||
bool result;
|
||||
+ bool is_from_trusted_domain = false;
|
||||
krb5_db_entry *client_actual = NULL;
|
||||
struct ipadb_e_data *ied = NULL;
|
||||
int flags = 0;
|
||||
@@ -1671,14 +1673,36 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
|
||||
result = dom_sid_check(&ipactx->mspac->domsid,
|
||||
info->info->info3.base.domain_sid, true);
|
||||
if (!result) {
|
||||
- /* memctx is freed by the caller */
|
||||
- char *sid = dom_sid_string(memctx, info->info->info3.base.domain_sid);
|
||||
- char *dom = dom_sid_string(memctx, &ipactx->mspac->domsid);
|
||||
- krb5_klog_syslog(LOG_ERR, "PAC issue: PAC record claims domain SID different "
|
||||
- "to local domain SID: local [%s], PAC [%s]",
|
||||
- dom ? dom : "<failed to display>",
|
||||
- sid ? sid : "<failed to display>");
|
||||
- return KRB5KDC_ERR_POLICY;
|
||||
+ /* In S4U case we might be dealing with the PAC issued by the trusted domain */
|
||||
+ if (is_s4u && (ipactx->mspac->trusts != NULL)) {
|
||||
+ /* Iterate through list of trusts and check if this SID belongs to
|
||||
+ * one of the domains we trust */
|
||||
+ for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
|
||||
+ result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
|
||||
+ info->info->info3.base.domain_sid, true);
|
||||
+ if (result) {
|
||||
+ is_from_trusted_domain = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!result) {
|
||||
+ /* memctx is freed by the caller */
|
||||
+ char *sid = dom_sid_string(memctx, info->info->info3.base.domain_sid);
|
||||
+ char *dom = dom_sid_string(memctx, &ipactx->mspac->domsid);
|
||||
+ krb5_klog_syslog(LOG_ERR, "PAC issue: PAC record claims domain SID different "
|
||||
+ "to local domain SID or any trusted domain SID: "
|
||||
+ "local [%s], PAC [%s]",
|
||||
+ dom ? dom : "<failed to display>",
|
||||
+ sid ? sid : "<failed to display>");
|
||||
+ return KRB5KDC_ERR_POLICY;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (is_s4u && is_from_trusted_domain) {
|
||||
+ /* If the PAC belongs to a user from the trusted domain, we cannot compare SIDs */
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
kerr = ipadb_get_principal(context, client_princ, flags, &client_actual);
|
||||
@@ -1703,6 +1727,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+
|
||||
kerr = ipadb_get_sid_from_pac(memctx, info->info, &client_sid);
|
||||
if (kerr) {
|
||||
goto done;
|
||||
@@ -1956,6 +1981,7 @@ krb5_error_code filter_logon_info(krb5_context context,
|
||||
static krb5_error_code ipadb_check_logon_info(krb5_context context,
|
||||
krb5_const_principal client_princ,
|
||||
krb5_boolean is_cross_realm,
|
||||
+ krb5_boolean is_s4u,
|
||||
krb5_data *pac_blob,
|
||||
struct dom_sid *requester_sid)
|
||||
{
|
||||
@@ -1999,8 +2025,11 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
|
||||
|
||||
if (!is_cross_realm) {
|
||||
/* For local realm case we need to check whether the PAC is for our user
|
||||
- * but we don't need to process further */
|
||||
- kerr = check_logon_info_consistent(context, tmpctx, client_princ, &info);
|
||||
+ * but we don't need to process further. In S4U2Proxy case when the client
|
||||
+ * is ours but operates on behalf of the cross-realm principal, we will
|
||||
+ * search through the trusted domains but otherwise skip the exact SID check
|
||||
+ * as we are not responsible for the principal from the trusted domain */
|
||||
+ kerr = check_logon_info_consistent(context, tmpctx, client_princ, is_s4u, &info);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2251,7 +2280,10 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
|
||||
#endif
|
||||
|
||||
kerr = ipadb_check_logon_info(context,
|
||||
- client_princ, is_cross_realm, &pac_blob,
|
||||
+ client_princ,
|
||||
+ is_cross_realm,
|
||||
+ (flags & KRB5_KDB_FLAGS_S4U),
|
||||
+ &pac_blob,
|
||||
requester_sid);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
--
|
||||
2.33.1
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user