ipa-4.12.0-1
- Resolves: RHEL-39144 Rebase ipa to the latest 4.12 version for RHEL 10 - Resolves: RHEL-30537 ipa: freeipa: argument injection into the username field of the /ipa/session/login_password requests
This commit is contained in:
parent
123abb92ab
commit
90dae868c3
2
.gitignore
vendored
2
.gitignore
vendored
@ -132,3 +132,5 @@
|
||||
/freeipa-4.11.0.tar.gz.asc
|
||||
/freeipa-4.11.1.tar.gz
|
||||
/freeipa-4.11.1.tar.gz.asc
|
||||
/freeipa-4.12.0.tar.gz
|
||||
/freeipa-4.12.0.tar.gz.asc
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 499f1e3e996aadbd4f26a90db81a0b1b68b61c57 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Tue, 12 Sep 2023 17:07:52 +0300
|
||||
Subject: [PATCH] Restore selinux states if they exist at uninstall time
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9434
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipaclient/install/client.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||
index 1aaa4ed60..01a5f2339 100644
|
||||
--- a/ipaclient/install/client.py
|
||||
+++ b/ipaclient/install/client.py
|
||||
@@ -3624,7 +3624,7 @@ def uninstall(options):
|
||||
"Failed to disable automatic startup of the SSSD daemon: %s",
|
||||
e)
|
||||
|
||||
- if was_sssd_installed and selinux_works:
|
||||
+ if statestore.has_state('selinux'):
|
||||
# Restore SELinux boolean states
|
||||
boolean_states = {name: statestore.restore_state('selinux', name)
|
||||
for name in constants.SELINUX_BOOLEAN_SSSD}
|
||||
--
|
||||
2.41.0
|
||||
|
238
0001-Revert-Replace-netifaces-with-ifaddr.patch
Normal file
238
0001-Revert-Replace-netifaces-with-ifaddr.patch
Normal file
@ -0,0 +1,238 @@
|
||||
From dfeb01d5e4e8934bae8f495bbbd5b6570f3dc862 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Tue, 4 Jun 2024 13:56:56 +0200
|
||||
Subject: [PATCH] Revert "Replace netifaces with ifaddr"
|
||||
|
||||
This reverts commit 6c6b9354b5f970983655ca5423c726763d9015fa.
|
||||
---
|
||||
doc/requirements.txt | 1 -
|
||||
freeipa.spec.in | 4 +--
|
||||
ipaclient/install/client.py | 43 ++++++++++++++-----------------
|
||||
ipapython/ipautil.py | 51 ++++++++++++++++++++-----------------
|
||||
ipapython/setup.py | 2 +-
|
||||
ipasetup.py.in | 2 +-
|
||||
pylintrc | 1 +
|
||||
7 files changed, 52 insertions(+), 52 deletions(-)
|
||||
|
||||
diff --git a/doc/requirements.txt b/doc/requirements.txt
|
||||
index 8d91b893fbcb5de784f5abdf802b976c6b2ae277..cdaa42658c73e495379d87b7c50195fbd79533ee 100644
|
||||
--- a/doc/requirements.txt
|
||||
+++ b/doc/requirements.txt
|
||||
@@ -11,7 +11,6 @@ m2r2
|
||||
## ipa dependencies
|
||||
dnspython
|
||||
jwcrypto
|
||||
-ifaddr
|
||||
netaddr
|
||||
qrcode
|
||||
six
|
||||
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index 6803de752bc122bf6e1eafd610d399cde994cad5..a532fe85c34a523519187b6fd1297c198d9f4a4e 100755
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -403,7 +403,7 @@ BuildRequires: python3-libipa_hbac
|
||||
BuildRequires: python3-libsss_nss_idmap
|
||||
BuildRequires: python3-lxml
|
||||
BuildRequires: python3-netaddr >= %{python_netaddr_version}
|
||||
-BuildRequires: python3-ifaddr
|
||||
+BuildRequires: python3-netifaces
|
||||
BuildRequires: python3-pki >= %{pki_version}
|
||||
BuildRequires: python3-polib
|
||||
BuildRequires: python3-pyasn1
|
||||
@@ -885,7 +885,7 @@ Requires: python3-gssapi >= 1.2.0
|
||||
Requires: python3-jwcrypto >= 0.4.2
|
||||
Requires: python3-libipa_hbac
|
||||
Requires: python3-netaddr >= %{python_netaddr_version}
|
||||
-Requires: python3-ifaddr
|
||||
+Requires: python3-netifaces >= 0.10.4
|
||||
Requires: python3-pyasn1 >= 0.3.2-2
|
||||
Requires: python3-pyasn1-modules >= 0.3.2-2
|
||||
Requires: python3-pyusb
|
||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||
index 29aff5f413e7f27136e236382031171f068284c5..263dc8e302cccd76412c294e0740af9744a2c62d 100644
|
||||
--- a/ipaclient/install/client.py
|
||||
+++ b/ipaclient/install/client.py
|
||||
@@ -18,7 +18,7 @@ import logging
|
||||
import dns
|
||||
import getpass
|
||||
import gssapi
|
||||
-import ifaddr
|
||||
+import netifaces
|
||||
import os
|
||||
import re
|
||||
import SSSDConfig
|
||||
@@ -1374,36 +1374,31 @@ def unconfigure_nisdomain(statestore):
|
||||
|
||||
|
||||
def get_iface_from_ip(ip_addr):
|
||||
- for adapter in ifaddr.get_adapters():
|
||||
- for ips in adapter.ips:
|
||||
- # IPv6 is reported as a tuple, IPv4 is reported as str
|
||||
- if ip_addr in (ips.ip[0], ips.ip):
|
||||
- return adapter.name
|
||||
+ for interface in netifaces.interfaces():
|
||||
+ if_addrs = netifaces.ifaddresses(interface)
|
||||
+ for family in [netifaces.AF_INET, netifaces.AF_INET6]:
|
||||
+ for ip in if_addrs.get(family, []):
|
||||
+ if ip['addr'] == ip_addr:
|
||||
+ return interface
|
||||
raise RuntimeError("IP %s not assigned to any interface." % ip_addr)
|
||||
|
||||
|
||||
-def __get_ifaddr_adapters(iface=None):
|
||||
+def get_local_ipaddresses(iface=None):
|
||||
if iface:
|
||||
- interfaces = set(iface if isinstance(iface, (list, tuple)) else [iface])
|
||||
+ interfaces = [iface]
|
||||
else:
|
||||
- interfaces = set(adapter.name for adapter in ifaddr.get_adapters())
|
||||
- return [
|
||||
- adapter
|
||||
- for adapter in ifaddr.get_adapters()
|
||||
- if adapter.name in interfaces or adapter.nice_name in interfaces
|
||||
- ]
|
||||
+ interfaces = netifaces.interfaces()
|
||||
|
||||
-
|
||||
-def get_local_ipaddresses(iface=None):
|
||||
ips = []
|
||||
- for adapter in __get_ifaddr_adapters(iface):
|
||||
- for ifip in adapter.ips:
|
||||
- try:
|
||||
- ip_addr = ifip.ip[0] if isinstance(ifip.ip, tuple) else ifip.ip
|
||||
- ips.append(ipautil.CheckedIPAddress(ip_addr))
|
||||
- logger.debug('IP check successful: %s', ip_addr)
|
||||
- except ValueError as e:
|
||||
- logger.debug('IP check failed: %s', e)
|
||||
+ for interface in interfaces:
|
||||
+ if_addrs = netifaces.ifaddresses(interface)
|
||||
+ for family in [netifaces.AF_INET, netifaces.AF_INET6]:
|
||||
+ for ip in if_addrs.get(family, []):
|
||||
+ try:
|
||||
+ ips.append(ipautil.CheckedIPAddress(ip['addr']))
|
||||
+ logger.debug('IP check successful: %s', ip['addr'])
|
||||
+ except ValueError as e:
|
||||
+ logger.debug('IP check failed: %s', e)
|
||||
return ips
|
||||
|
||||
|
||||
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
|
||||
index b02d58839ed74215d7253fc23be94846d689f91e..6802dde574d179b2d4bf868a2c38546cc01fc46b 100644
|
||||
--- a/ipapython/ipautil.py
|
||||
+++ b/ipapython/ipautil.py
|
||||
@@ -48,9 +48,9 @@ import six
|
||||
from six.moves import input
|
||||
|
||||
try:
|
||||
- import ifaddr
|
||||
+ import netifaces
|
||||
except ImportError:
|
||||
- ifaddr = None
|
||||
+ netifaces = None
|
||||
|
||||
from ipapython.dn import DN
|
||||
from ipaplatform.paths import paths
|
||||
@@ -203,37 +203,42 @@ class CheckedIPAddress(UnsafeIPAddress):
|
||||
:return: InterfaceDetails named tuple or None if no interface has
|
||||
this address
|
||||
"""
|
||||
- if ifaddr is None:
|
||||
- raise ImportError("ifaddr")
|
||||
+ if netifaces is None:
|
||||
+ raise ImportError("netifaces")
|
||||
logger.debug("Searching for an interface of IP address: %s", self)
|
||||
-
|
||||
if self.version == 4:
|
||||
- family_ips = (
|
||||
- (ip.ip, ip.network_prefix, ip.nice_name)
|
||||
- for ips in [a.ips for a in ifaddr.get_adapters()]
|
||||
- for ip in ips if not isinstance(ip.ip, tuple)
|
||||
- )
|
||||
+ family = netifaces.AF_INET
|
||||
elif self.version == 6:
|
||||
- family_ips = (
|
||||
- (ip.ip[0], ip.network_prefix, ip.nice_name)
|
||||
- for ips in [a.ips for a in ifaddr.get_adapters()]
|
||||
- for ip in ips if isinstance(ip.ip, tuple)
|
||||
- )
|
||||
+ family = netifaces.AF_INET6
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unsupported address family ({})".format(self.version)
|
||||
)
|
||||
|
||||
- for ip, prefix, ifname in family_ips:
|
||||
- ifaddrmask = "{ip}/{prefix}".format(ip=ip, prefix=prefix)
|
||||
- logger.debug(
|
||||
- "Testing local IP address: %s (interface: %s)",
|
||||
- ifaddrmask, ifname)
|
||||
- ifnet = netaddr.IPNetwork(ifaddrmask)
|
||||
+ for interface in netifaces.interfaces():
|
||||
+ for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
||||
+
|
||||
+ # link-local addresses contain '%suffix' that causes parse
|
||||
+ # errors in IPNetwork
|
||||
+ ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
||||
+
|
||||
+ # newer versions of netifaces provide IPv6 netmask in format
|
||||
+ # 'ffff:ffff:ffff:ffff::/64'. We have to split and use prefix
|
||||
+ # or the netmask with older versions
|
||||
+ ifmask = ifdata['netmask'].split(u'/')[-1]
|
||||
+
|
||||
+ ifaddrmask = '{addr}/{netmask}'.format(
|
||||
+ addr=ifaddr,
|
||||
+ netmask=ifmask
|
||||
+ )
|
||||
+ logger.debug(
|
||||
+ "Testing local IP address: %s (interface: %s)",
|
||||
+ ifaddrmask, interface)
|
||||
|
||||
- if ifnet.ip == self:
|
||||
- return InterfaceDetails(ifname, ifnet)
|
||||
+ ifnet = netaddr.IPNetwork(ifaddrmask)
|
||||
|
||||
+ if ifnet.ip == self:
|
||||
+ return InterfaceDetails(interface, ifnet)
|
||||
return None
|
||||
|
||||
def set_ip_net(self, ifnet):
|
||||
diff --git a/ipapython/setup.py b/ipapython/setup.py
|
||||
index b7b25c8b480f0dc80ae20c4027554b27fe6d87b3..ea55f5c729e8ba65a4436ebf3eb4898870558648 100644
|
||||
--- a/ipapython/setup.py
|
||||
+++ b/ipapython/setup.py
|
||||
@@ -48,6 +48,6 @@ if __name__ == '__main__':
|
||||
extras_require={
|
||||
"ldap": ["python-ldap"], # ipapython.ipaldap
|
||||
# CheckedIPAddress.get_matching_interface
|
||||
- "ifaddr": ["ifaddr"],
|
||||
+ "netifaces": ["netifaces"],
|
||||
},
|
||||
)
|
||||
diff --git a/ipasetup.py.in b/ipasetup.py.in
|
||||
index 56a1f3b066c70385949c86d0d35ce393331ad1c5..25eac3b214b4e6443fe29dd3d656c2fdbe84343a 100644
|
||||
--- a/ipasetup.py.in
|
||||
+++ b/ipasetup.py.in
|
||||
@@ -75,7 +75,7 @@ PACKAGE_VERSION = {
|
||||
'ipaserver': 'ipaserver == {}'.format(VERSION),
|
||||
'jwcrypto': 'jwcrypto >= 0.4.2',
|
||||
'kdcproxy': 'kdcproxy >= 0.3',
|
||||
- 'ifaddr': 'ifaddr >= 0.1.7',
|
||||
+ 'netifaces': 'netifaces >= 0.10.4',
|
||||
'python-ldap': 'python-ldap >= 3.0.0',
|
||||
'python-yubico': 'python-yubico >= 1.2.3',
|
||||
'qrcode': 'qrcode >= 5.0',
|
||||
diff --git a/pylintrc b/pylintrc
|
||||
index 50278cc76031af68959a138f6ea185c4288c7155..22053a9b55e9dc8e71c1835a63c9393e8ad6803d 100644
|
||||
--- a/pylintrc
|
||||
+++ b/pylintrc
|
||||
@@ -13,6 +13,7 @@ extension-pkg-allow-list=
|
||||
_ldap,
|
||||
cryptography,
|
||||
gssapi,
|
||||
+ netifaces,
|
||||
lxml.etree,
|
||||
pysss_murmur,
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
@ -1,107 +0,0 @@
|
||||
From a44fd5a7691d263d670312e0c8e02efd868618c1 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Tue, 6 Jun 2023 17:15:11 +0200
|
||||
Subject: [PATCH] Revert "cert_find: fix call with --all"
|
||||
|
||||
This reverts commit 918b6e011795ba4854d178d18c86ad54f3cf75ab.
|
||||
|
||||
Revert "Use the OpenSSL certificate parser in cert-find"
|
||||
|
||||
This reverts commit 50dd79d1a35549034bc281fbdffea4399baed3c7.
|
||||
---
|
||||
freeipa.spec.in | 2 --
|
||||
ipaserver/plugins/cert.py | 27 +++------------------------
|
||||
2 files changed, 3 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index 3e23bbfe9d054a3a9febf468de0bcb4a6e81bb32..bec9780a82fe0d9bc5a50a93bdce8aa7e27a9f30 100755
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -412,7 +412,6 @@ BuildRequires: python3-pylint
|
||||
BuildRequires: python3-pytest-multihost
|
||||
BuildRequires: python3-pytest-sourceorder
|
||||
BuildRequires: python3-qrcode-core >= 5.0.0
|
||||
-BuildRequires: python3-pyOpenSSL
|
||||
BuildRequires: python3-samba
|
||||
BuildRequires: python3-six
|
||||
BuildRequires: python3-sss
|
||||
@@ -884,7 +883,6 @@ Requires: python3-netifaces >= 0.10.4
|
||||
Requires: python3-pyasn1 >= 0.3.2-2
|
||||
Requires: python3-pyasn1-modules >= 0.3.2-2
|
||||
Requires: python3-pyusb
|
||||
-Requires: python3-pyOpenSSL
|
||||
Requires: python3-qrcode-core >= 5.0.0
|
||||
Requires: python3-requests
|
||||
Requires: python3-six
|
||||
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
|
||||
index 400b1b3cec0aba82e699a4a981516e121f3e0c77..36a0e8cb31b4dbdd9bff09165d1d8aa203936d37 100644
|
||||
--- a/ipaserver/plugins/cert.py
|
||||
+++ b/ipaserver/plugins/cert.py
|
||||
@@ -30,7 +30,6 @@ import cryptography.x509
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from dns import resolver, reversename
|
||||
import six
|
||||
-import sys
|
||||
|
||||
from ipalib import Command, Str, Int, Flag, StrEnum, SerialNumber
|
||||
from ipalib import api
|
||||
@@ -1618,19 +1617,7 @@ class cert_find(Search, CertMethod):
|
||||
)
|
||||
|
||||
def _get_cert_key(self, cert):
|
||||
- # for cert-find with a certificate value
|
||||
- if isinstance(cert, x509.IPACertificate):
|
||||
- return (DN(cert.issuer), cert.serial_number)
|
||||
-
|
||||
- issuer = []
|
||||
- for oid, value in cert.get_issuer().get_components():
|
||||
- issuer.append(
|
||||
- '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8'))
|
||||
- )
|
||||
- issuer = ','.join(issuer)
|
||||
- # Use this to flip from OpenSSL reverse to X500 ordering
|
||||
- issuer = DN(issuer).x500_text()
|
||||
- return (DN(issuer), cert.get_serial_number())
|
||||
+ return (DN(cert.issuer), cert.serial_number)
|
||||
|
||||
def _cert_search(self, pkey_only, **options):
|
||||
result = collections.OrderedDict()
|
||||
@@ -1750,11 +1737,6 @@ class cert_find(Search, CertMethod):
|
||||
return result, False, complete
|
||||
|
||||
def _ldap_search(self, all, pkey_only, no_members, **options):
|
||||
- # defer import of the OpenSSL module to not affect the requests
|
||||
- # module which will use pyopenssl if this is available.
|
||||
- if sys.modules.get('OpenSSL.SSL', False) is None:
|
||||
- del sys.modules["OpenSSL.SSL"]
|
||||
- import OpenSSL.crypto
|
||||
ldap = self.api.Backend.ldap2
|
||||
|
||||
filters = []
|
||||
@@ -1813,21 +1795,18 @@ class cert_find(Search, CertMethod):
|
||||
ca_enabled = getattr(context, 'ca_enabled')
|
||||
for entry in entries:
|
||||
for attr in ('usercertificate', 'usercertificate;binary'):
|
||||
- for der in entry.raw.get(attr, []):
|
||||
- cert = OpenSSL.crypto.load_certificate(
|
||||
- OpenSSL.crypto.FILETYPE_ASN1, der)
|
||||
+ for cert in entry.get(attr, []):
|
||||
cert_key = self._get_cert_key(cert)
|
||||
try:
|
||||
obj = result[cert_key]
|
||||
except KeyError:
|
||||
- obj = {'serial_number': cert.get_serial_number()}
|
||||
+ obj = {'serial_number': cert.serial_number}
|
||||
if not pkey_only and (all or not ca_enabled):
|
||||
# Retrieving certificate details is now deferred
|
||||
# until after all certificates are collected.
|
||||
# For the case of CA-less we need to keep
|
||||
# the certificate because getting it again later
|
||||
# would require unnecessary LDAP searches.
|
||||
- cert = cert.to_cryptography()
|
||||
obj['certificate'] = (
|
||||
base64.b64encode(
|
||||
cert.public_bytes(x509.Encoding.DER))
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,82 +0,0 @@
|
||||
From a96dae1a9918cfc1413e199336eece447920ef8e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
|
||||
Date: Wed, 5 Jul 2023 08:52:59 +0200
|
||||
Subject: [PATCH] Use ssl.match_hostname from urllib3 as it was removed from
|
||||
Python 3.12
|
||||
|
||||
See https://pagure.io/freeipa/issue/9409
|
||||
and https://github.com/python/cpython/pull/94224#issuecomment-1621097418
|
||||
---
|
||||
ipalib/x509.py | 5 +++--
|
||||
ipaserver/install/cainstance.py | 4 +++-
|
||||
ipaserver/install/server/upgrade.py | 4 +++-
|
||||
3 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipalib/x509.py b/ipalib/x509.py
|
||||
index 5adb511..faf62d4 100644
|
||||
--- a/ipalib/x509.py
|
||||
+++ b/ipalib/x509.py
|
||||
@@ -385,6 +385,8 @@ class IPACertificate(crypto_x509.Certificate):
|
||||
return result
|
||||
|
||||
def match_hostname(self, hostname):
|
||||
+ from urllib3.util import ssl_match_hostname
|
||||
+
|
||||
match_cert = {}
|
||||
|
||||
match_cert['subject'] = match_subject = []
|
||||
@@ -401,8 +403,7 @@ class IPACertificate(crypto_x509.Certificate):
|
||||
for value in values:
|
||||
match_san.append(('DNS', value))
|
||||
|
||||
- # deprecated in Python3.7 without replacement
|
||||
- ssl.match_hostname( # pylint: disable=deprecated-method
|
||||
+ ssl_match_hostname.match_hostname(
|
||||
match_cert, DNSName(hostname).ToASCII()
|
||||
)
|
||||
|
||||
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
|
||||
index fa8942d..e9f3ecb 100644
|
||||
--- a/ipaserver/install/cainstance.py
|
||||
+++ b/ipaserver/install/cainstance.py
|
||||
@@ -2373,12 +2373,14 @@ def check_ipa_ca_san(cert):
|
||||
|
||||
On success returns None, on failure raises ValidationError
|
||||
"""
|
||||
+ from urllib3.util import ssl_match_hostname
|
||||
+
|
||||
expect = f'{ipalib.constants.IPA_CA_RECORD}.' \
|
||||
f'{ipautil.format_netloc(api.env.domain)}'
|
||||
|
||||
try:
|
||||
cert.match_hostname(expect)
|
||||
- except ssl.CertificateError:
|
||||
+ except ssl_match_hostname.CertificateError:
|
||||
raise errors.ValidationError(
|
||||
name='certificate',
|
||||
error='Does not have a \'{}\' SAN'.format(expect)
|
||||
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
|
||||
index f8701c8..9e5f5aa 100644
|
||||
--- a/ipaserver/install/server/upgrade.py
|
||||
+++ b/ipaserver/install/server/upgrade.py
|
||||
@@ -710,6 +710,8 @@ def http_certificate_ensure_ipa_ca_dnsname(http):
|
||||
steps.
|
||||
|
||||
"""
|
||||
+ from urllib3.util import ssl_match_hostname
|
||||
+
|
||||
logger.info('[Adding ipa-ca alias to HTTP certificate]')
|
||||
|
||||
expect = f'{IPA_CA_RECORD}.{ipautil.format_netloc(api.env.domain)}'
|
||||
@@ -717,7 +719,7 @@ def http_certificate_ensure_ipa_ca_dnsname(http):
|
||||
|
||||
try:
|
||||
cert.match_hostname(expect)
|
||||
- except ssl.CertificateError:
|
||||
+ except ssl_match_hostname.CertificateError:
|
||||
if certs.is_ipa_issued_cert(api, cert):
|
||||
request_id = certmonger.get_request_id(
|
||||
{'cert-file': paths.HTTPD_CERT_FILE})
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,140 +0,0 @@
|
||||
From d355761f23fae412bb01a1d737cee342c7bd04f9 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Tue, 29 Aug 2023 12:37:57 +0300
|
||||
Subject: [PATCH] ipa-client-install: enable SELinux for SSSD
|
||||
|
||||
For passkeys (FIDO2) support, SSSD uses libfido2 library which needs
|
||||
access to USB devices. Add SELinux booleans handling to ipa-client-install
|
||||
so that correct SELinux booleans can be enabled and disabled during
|
||||
install and uninstall. Ignore and record a warning when SELinux policy
|
||||
does not support the boolean.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9434
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipaclient/install/client.py | 35 ++++++++++++++++++++++++++++++++++-
|
||||
ipaplatform/base/constants.py | 3 +++
|
||||
2 files changed, 37 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||
index 07d62a748..1aaa4ed60 100644
|
||||
--- a/ipaclient/install/client.py
|
||||
+++ b/ipaclient/install/client.py
|
||||
@@ -67,6 +67,7 @@ from ipapython.ipautil import (
|
||||
)
|
||||
from ipapython.ssh import SSHPublicKey
|
||||
from ipapython import version
|
||||
+from ipapython.errors import SetseboolError
|
||||
|
||||
from . import automount, timeconf, sssd
|
||||
from ipaclient import discovery
|
||||
@@ -98,6 +99,7 @@ cli_realm = None
|
||||
cli_kdc = None
|
||||
client_domain = None
|
||||
cli_basedn = None
|
||||
+selinux_works = None
|
||||
# end of global variables
|
||||
|
||||
|
||||
@@ -2153,6 +2155,7 @@ def install_check(options):
|
||||
global cli_kdc
|
||||
global client_domain
|
||||
global cli_basedn
|
||||
+ global selinux_works
|
||||
|
||||
print("This program will set up IPA client.")
|
||||
print("Version {}".format(version.VERSION))
|
||||
@@ -2166,7 +2169,7 @@ def install_check(options):
|
||||
"You must be root to run ipa-client-install.",
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
- tasks.check_selinux_status()
|
||||
+ selinux_works = tasks.check_selinux_status()
|
||||
|
||||
if is_ipa_client_configured(on_master=options.on_master):
|
||||
logger.error("IPA client is already configured on this system.")
|
||||
@@ -2674,6 +2677,20 @@ def restore_time_sync(statestore, fstore):
|
||||
logger.error('Failed to restore time synchronization service: %s', e)
|
||||
|
||||
|
||||
+def configure_selinux_for_client(statestore):
|
||||
+ def backup_state(key, value):
|
||||
+ statestore.backup_state('selinux', key, value)
|
||||
+
|
||||
+ try:
|
||||
+ tasks.set_selinux_booleans(constants.SELINUX_BOOLEAN_SSSD,
|
||||
+ backup_state)
|
||||
+ except SetseboolError as e:
|
||||
+ for c in constants.SELINUX_BOOLEAN_SSSD:
|
||||
+ if c in e.failed:
|
||||
+ logger.warning(
|
||||
+ "SELinux does not support SSSD boolean %s, ignoring", c)
|
||||
+
|
||||
+
|
||||
def install(options):
|
||||
try:
|
||||
_install(options, dict())
|
||||
@@ -3198,6 +3215,9 @@ def _install(options, tdict):
|
||||
logger.info("%s enabled", "SSSD" if options.sssd else "LDAP")
|
||||
|
||||
if options.sssd:
|
||||
+ if selinux_works:
|
||||
+ configure_selinux_for_client(statestore)
|
||||
+
|
||||
sssd = services.service('sssd', api)
|
||||
try:
|
||||
sssd.restart()
|
||||
@@ -3322,6 +3342,8 @@ def _install(options, tdict):
|
||||
|
||||
|
||||
def uninstall_check(options):
|
||||
+ global selinux_works
|
||||
+
|
||||
if not is_ipa_client_configured():
|
||||
if options.on_master:
|
||||
rval = SUCCESS
|
||||
@@ -3337,6 +3359,8 @@ def uninstall_check(options):
|
||||
logger.info("Refer to ipa-server-install for uninstallation.")
|
||||
raise ScriptError(rval=CLIENT_NOT_CONFIGURED)
|
||||
|
||||
+ selinux_works = tasks.check_selinux_status()
|
||||
+
|
||||
|
||||
def uninstall(options):
|
||||
env = {'PATH': SECURE_PATH}
|
||||
@@ -3600,6 +3624,15 @@ def uninstall(options):
|
||||
"Failed to disable automatic startup of the SSSD daemon: %s",
|
||||
e)
|
||||
|
||||
+ if was_sssd_installed and selinux_works:
|
||||
+ # Restore SELinux boolean states
|
||||
+ boolean_states = {name: statestore.restore_state('selinux', name)
|
||||
+ for name in constants.SELINUX_BOOLEAN_SSSD}
|
||||
+ try:
|
||||
+ tasks.set_selinux_booleans(boolean_states)
|
||||
+ except SetseboolError as e:
|
||||
+ logger.warning("Unable to reset SELinux variable: %s", str(e))
|
||||
+
|
||||
tasks.restore_hostname(fstore, statestore)
|
||||
|
||||
if fstore.has_files():
|
||||
diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py
|
||||
index 61b864376..1689efe52 100644
|
||||
--- a/ipaplatform/base/constants.py
|
||||
+++ b/ipaplatform/base/constants.py
|
||||
@@ -151,6 +151,9 @@ class BaseConstantsNamespace:
|
||||
'samba_share_nfs': 'on',
|
||||
},
|
||||
}
|
||||
+ SELINUX_BOOLEAN_SSSD = {
|
||||
+ 'sssd_use_usb': 'on',
|
||||
+ }
|
||||
SELINUX_MCS_MAX = 1023
|
||||
SELINUX_MCS_REGEX = r"^c(\d+)([.,-]c(\d+))*$"
|
||||
SELINUX_MLS_MAX = 15
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 5fe447532f573fc3f73511073070f5dfe6b6535a Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Fri, 15 Sep 2023 10:12:16 +0300
|
||||
Subject: [PATCH] Allow ipa-otpd to access USB devices for passkeys
|
||||
|
||||
Main SELinux policy will allow transition of passkey_child (SSSD) to
|
||||
ipa_otpd_t context to perform FIDO2 operations with USB devices.
|
||||
This means ipa-otpd will need to be able to read data from sysfs and
|
||||
connect to USB devices.
|
||||
|
||||
Add required permissions to IPA subpolicy as well. See rhbz#2238224 for
|
||||
discussion.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9434
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
selinux/ipa.te | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/selinux/ipa.te b/selinux/ipa.te
|
||||
index 92e6b295b19..c8a44b64e82 100644
|
||||
--- a/selinux/ipa.te
|
||||
+++ b/selinux/ipa.te
|
||||
@@ -106,6 +106,8 @@ corenet_tcp_connect_radius_port(ipa_otpd_t)
|
||||
|
||||
dev_read_urand(ipa_otpd_t)
|
||||
dev_read_rand(ipa_otpd_t)
|
||||
+dev_read_sysfs(ipa_otpd_t)
|
||||
+dev_rw_generic_usb_dev(ipa_otpd_t)
|
||||
|
||||
sysnet_dns_name_resolve(ipa_otpd_t)
|
||||
|
@ -1,91 +0,0 @@
|
||||
From 34b58d8ee93ab385c1f3ba1166377fc1008a9c17 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 24 Jan 2024 15:50:17 +0100
|
||||
Subject: [PATCH] ipa-kdb: Fix memory leak during PAC verification
|
||||
|
||||
Commit 0022bd70d93708d325855d5271516d6cd894d6e8 introduced a memory leak
|
||||
during the copy of some PAC buffers, because of an unfreed memory
|
||||
allocation context.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9520
|
||||
|
||||
Signed-off-by: Julien Rische <jrische@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
daemons/ipa-kdb/ipa_kdb_mspac.c | 28 +++++++++++++---------------
|
||||
1 file changed, 13 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
index 1558e2bea..2866304e1 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||||
@@ -2316,6 +2316,7 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
|
||||
size_t i;
|
||||
struct dom_sid *requester_sid = NULL;
|
||||
struct dom_sid req_sid;
|
||||
+ TALLOC_CTX *tmpctx = NULL;
|
||||
|
||||
if (signing_krbtgt != NULL &&
|
||||
ipadb_is_cross_realm_krbtgt(signing_krbtgt->princ)) {
|
||||
@@ -2371,6 +2372,12 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ tmpctx = talloc_new(NULL);
|
||||
+ if (tmpctx == NULL) {
|
||||
+ kerr = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < num_buffers; i++) {
|
||||
if (types[i] == KRB5_PAC_SERVER_CHECKSUM ||
|
||||
types[i] == KRB5_PAC_PRIVSVR_CHECKSUM ||
|
||||
@@ -2398,32 +2405,21 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
|
||||
DATA_BLOB pac_attrs_data;
|
||||
krb5_boolean pac_requested;
|
||||
|
||||
- TALLOC_CTX *tmpctx = talloc_new(NULL);
|
||||
- if (tmpctx == NULL) {
|
||||
- kerr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
kerr = ipadb_client_requested_pac(context, old_pac, tmpctx, &pac_requested);
|
||||
- if (kerr != 0) {
|
||||
- talloc_free(tmpctx);
|
||||
+ if (kerr)
|
||||
goto done;
|
||||
- }
|
||||
|
||||
kerr = ipadb_get_pac_attrs_blob(tmpctx, &pac_requested, &pac_attrs_data);
|
||||
- if (kerr) {
|
||||
- talloc_free(tmpctx);
|
||||
+ if (kerr)
|
||||
goto done;
|
||||
- }
|
||||
+
|
||||
data.magic = KV5M_DATA;
|
||||
data.data = (char *)pac_attrs_data.data;
|
||||
data.length = pac_attrs_data.length;
|
||||
|
||||
kerr = krb5_pac_add_buffer(context, new_pac, PAC_TYPE_ATTRIBUTES_INFO, &data);
|
||||
- if (kerr) {
|
||||
- talloc_free(tmpctx);
|
||||
+ if (kerr)
|
||||
goto done;
|
||||
- }
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -2470,6 +2466,8 @@ done:
|
||||
if (kerr != 0 && (new_pac != *pac)) {
|
||||
krb5_pac_free(context, new_pac);
|
||||
}
|
||||
+ if (tmpctx)
|
||||
+ talloc_free(tmpctx);
|
||||
krb5_free_data_contents(context, &pac_blob);
|
||||
free(types);
|
||||
return kerr;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,247 +0,0 @@
|
||||
From 33638de180a8157e369ad6c61f9e3406d9e85404 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislav Levin <slev@altlinux.org>
|
||||
Date: Tue, 23 Jan 2024 19:12:53 +0300
|
||||
Subject: [PATCH 1/3] ipapython: Clean up krb5_error
|
||||
|
||||
`krb5_error` has different definition in MIT krb.
|
||||
https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/types/krb5_error.html
|
||||
|
||||
> Error message structure.
|
||||
>
|
||||
> Declaration:
|
||||
> typedef struct _krb5_error krb5_error
|
||||
|
||||
While `krb5_error_code`
|
||||
https://web.mit.edu/kerberos/www/krb5-latest/doc/appdev/refs/types/krb5_error_code.html#c.krb5_error_code
|
||||
|
||||
> krb5_error_code
|
||||
> Used to convey an operation status.
|
||||
>
|
||||
> The value 0 indicates success; any other values are com_err codes. Use krb5_get_error_message() to obtain a string describing the error.
|
||||
>
|
||||
> Declaration
|
||||
> typedef krb5_int32 krb5_error_code
|
||||
|
||||
And this is what was actually used.
|
||||
|
||||
To prevent confusion of types `krb5_error` was replaced with
|
||||
`krb5_error_code`.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9519
|
||||
Signed-off-by: Stanislav Levin <slev@altlinux.org>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipapython/session_storage.py | 25 ++++++++++++-------------
|
||||
1 file changed, 12 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
|
||||
index c43ef7d4e..371cf1524 100644
|
||||
--- a/ipapython/session_storage.py
|
||||
+++ b/ipapython/session_storage.py
|
||||
@@ -111,7 +111,7 @@ class KRB5Error(Exception):
|
||||
|
||||
|
||||
def krb5_errcheck(result, func, arguments):
|
||||
- """Error checker for krb5_error return value"""
|
||||
+ """Error checker for krb5_error_code return value"""
|
||||
if result != 0:
|
||||
raise KRB5Error(result, func.__name__, arguments)
|
||||
|
||||
@@ -119,14 +119,13 @@ def krb5_errcheck(result, func, arguments):
|
||||
krb5_context = ctypes.POINTER(_krb5_context)
|
||||
krb5_ccache = ctypes.POINTER(_krb5_ccache)
|
||||
krb5_data_p = ctypes.POINTER(_krb5_data)
|
||||
-krb5_error = ctypes.c_int32
|
||||
krb5_creds = _krb5_creds
|
||||
krb5_pointer = ctypes.c_void_p
|
||||
krb5_cc_cursor = krb5_pointer
|
||||
|
||||
krb5_init_context = LIBKRB5.krb5_init_context
|
||||
krb5_init_context.argtypes = (ctypes.POINTER(krb5_context), )
|
||||
-krb5_init_context.restype = krb5_error
|
||||
+krb5_init_context.restype = krb5_error_code
|
||||
krb5_init_context.errcheck = krb5_errcheck
|
||||
|
||||
krb5_free_context = LIBKRB5.krb5_free_context
|
||||
@@ -143,30 +142,30 @@ krb5_free_data_contents.restype = None
|
||||
|
||||
krb5_cc_default = LIBKRB5.krb5_cc_default
|
||||
krb5_cc_default.argtypes = (krb5_context, ctypes.POINTER(krb5_ccache), )
|
||||
-krb5_cc_default.restype = krb5_error
|
||||
+krb5_cc_default.restype = krb5_error_code
|
||||
krb5_cc_default.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_close = LIBKRB5.krb5_cc_close
|
||||
krb5_cc_close.argtypes = (krb5_context, krb5_ccache, )
|
||||
-krb5_cc_close.restype = krb5_error
|
||||
+krb5_cc_close.restype = krb5_error_code
|
||||
krb5_cc_close.errcheck = krb5_errcheck
|
||||
|
||||
krb5_parse_name = LIBKRB5.krb5_parse_name
|
||||
krb5_parse_name.argtypes = (krb5_context, ctypes.c_char_p,
|
||||
ctypes.POINTER(krb5_principal), )
|
||||
-krb5_parse_name.restype = krb5_error
|
||||
+krb5_parse_name.restype = krb5_error_code
|
||||
krb5_parse_name.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_set_config = LIBKRB5.krb5_cc_set_config
|
||||
krb5_cc_set_config.argtypes = (krb5_context, krb5_ccache, krb5_principal,
|
||||
ctypes.c_char_p, krb5_data_p, )
|
||||
-krb5_cc_set_config.restype = krb5_error
|
||||
+krb5_cc_set_config.restype = krb5_error_code
|
||||
krb5_cc_set_config.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_get_principal = LIBKRB5.krb5_cc_get_principal
|
||||
krb5_cc_get_principal.argtypes = (krb5_context, krb5_ccache,
|
||||
ctypes.POINTER(krb5_principal), )
|
||||
-krb5_cc_get_principal.restype = krb5_error
|
||||
+krb5_cc_get_principal.restype = krb5_error_code
|
||||
krb5_cc_get_principal.errcheck = krb5_errcheck
|
||||
|
||||
# krb5_build_principal is a variadic function but that can't be expressed
|
||||
@@ -177,26 +176,26 @@ krb5_build_principal.argtypes = (krb5_context, ctypes.POINTER(krb5_principal),
|
||||
ctypes.c_uint, ctypes.c_char_p,
|
||||
ctypes.c_char_p, ctypes.c_char_p,
|
||||
ctypes.c_char_p, ctypes.c_char_p, )
|
||||
-krb5_build_principal.restype = krb5_error
|
||||
+krb5_build_principal.restype = krb5_error_code
|
||||
krb5_build_principal.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_start_seq_get = LIBKRB5.krb5_cc_start_seq_get
|
||||
krb5_cc_start_seq_get.argtypes = (krb5_context, krb5_ccache,
|
||||
ctypes.POINTER(krb5_cc_cursor), )
|
||||
-krb5_cc_start_seq_get.restype = krb5_error
|
||||
+krb5_cc_start_seq_get.restype = krb5_error_code
|
||||
krb5_cc_start_seq_get.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_next_cred = LIBKRB5.krb5_cc_next_cred
|
||||
krb5_cc_next_cred.argtypes = (krb5_context, krb5_ccache,
|
||||
ctypes.POINTER(krb5_cc_cursor),
|
||||
ctypes.POINTER(krb5_creds), )
|
||||
-krb5_cc_next_cred.restype = krb5_error
|
||||
+krb5_cc_next_cred.restype = krb5_error_code
|
||||
krb5_cc_next_cred.errcheck = krb5_errcheck
|
||||
|
||||
krb5_cc_end_seq_get = LIBKRB5.krb5_cc_end_seq_get
|
||||
krb5_cc_end_seq_get.argtypes = (krb5_context, krb5_ccache,
|
||||
ctypes.POINTER(krb5_cc_cursor), )
|
||||
-krb5_cc_end_seq_get.restype = krb5_error
|
||||
+krb5_cc_end_seq_get.restype = krb5_error_code
|
||||
krb5_cc_end_seq_get.errcheck = krb5_errcheck
|
||||
|
||||
krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents
|
||||
@@ -212,7 +211,7 @@ krb5_principal_compare.restype = krb5_boolean
|
||||
krb5_unparse_name = LIBKRB5.krb5_unparse_name
|
||||
krb5_unparse_name.argtypes = (krb5_context, krb5_principal,
|
||||
ctypes.POINTER(ctypes.c_char_p), )
|
||||
-krb5_unparse_name.restype = krb5_error
|
||||
+krb5_unparse_name.restype = krb5_error_code
|
||||
krb5_unparse_name.errcheck = krb5_errcheck
|
||||
|
||||
krb5_free_unparsed_name = LIBKRB5.krb5_free_unparsed_name
|
||||
--
|
||||
2.43.0
|
||||
|
||||
|
||||
From f8a616dc6196324145372713da772fe9b2352e53 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislav Levin <slev@altlinux.org>
|
||||
Date: Tue, 23 Jan 2024 19:19:43 +0300
|
||||
Subject: [PATCH 2/3] ipapython: Correct return type of krb5_free_cred_contents
|
||||
|
||||
According to https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/api/krb5_free_cred_contents.html
|
||||
|
||||
> krb5_free_cred_contents - Free the contents of a krb5_creds structure.
|
||||
>
|
||||
> void krb5_free_cred_contents(krb5_context context, krb5_creds * val)
|
||||
> param:
|
||||
> [in] context - Library context
|
||||
>
|
||||
> [in] val - Credential structure to free contents of
|
||||
>
|
||||
> This function frees the contents of val , but not the structure itself.
|
||||
|
||||
https://github.com/krb5/krb5/blob/5b00197227231943bd2305328c8260dd0b0dbcf0/src/lib/krb5/krb/kfree.c#L166
|
||||
|
||||
This leads to undefined behavior and `krb5_free_cred_contents` can
|
||||
raise KRB5Error (because of garbage data) while actually its foreign
|
||||
function doesn't.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9519
|
||||
Signed-off-by: Stanislav Levin <slev@altlinux.org>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipapython/session_storage.py | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
|
||||
index 371cf1524..dc36f5493 100644
|
||||
--- a/ipapython/session_storage.py
|
||||
+++ b/ipapython/session_storage.py
|
||||
@@ -200,8 +200,7 @@ krb5_cc_end_seq_get.errcheck = krb5_errcheck
|
||||
|
||||
krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents
|
||||
krb5_free_cred_contents.argtypes = (krb5_context, ctypes.POINTER(krb5_creds))
|
||||
-krb5_free_cred_contents.restype = krb5_error
|
||||
-krb5_free_cred_contents.errcheck = krb5_errcheck
|
||||
+krb5_free_cred_contents.restype = None
|
||||
|
||||
krb5_principal_compare = LIBKRB5.krb5_principal_compare
|
||||
krb5_principal_compare.argtypes = (krb5_context, krb5_principal,
|
||||
--
|
||||
2.43.0
|
||||
|
||||
|
||||
From 59b8a9fb7169561c7ba9168fe84f47ae94e5ce23 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislav Levin <slev@altlinux.org>
|
||||
Date: Tue, 23 Jan 2024 19:52:34 +0300
|
||||
Subject: [PATCH 3/3] ipapython: Propagate KRB5Error exceptions on iterating
|
||||
ccache
|
||||
|
||||
`ipapython.session_storage.get_data` iterates over
|
||||
credentials in a credential cache till `krb5_cc_next_cred` returns
|
||||
an error. This function doesn't expect any error on calling
|
||||
other kerberos foreign functions during iteration. But that can
|
||||
actually happen and KRB5Error exceptions stop an iteration while
|
||||
they should be propagated.
|
||||
|
||||
With this change iteration will exactly stop on `krb5_cc_next_cred`
|
||||
error as it was supposed to be.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9519
|
||||
Signed-off-by: Stanislav Levin <slev@altlinux.org>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipapython/session_storage.py | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
|
||||
index dc36f5493..e890dc9b1 100644
|
||||
--- a/ipapython/session_storage.py
|
||||
+++ b/ipapython/session_storage.py
|
||||
@@ -312,8 +312,12 @@ def get_data(princ_name, key):
|
||||
checkcreds = krb5_creds()
|
||||
# the next function will throw an error and break out of the
|
||||
# while loop when we try to access past the last cred
|
||||
- krb5_cc_next_cred(context, ccache, ctypes.byref(cursor),
|
||||
- ctypes.byref(checkcreds))
|
||||
+ try:
|
||||
+ krb5_cc_next_cred(context, ccache, ctypes.byref(cursor),
|
||||
+ ctypes.byref(checkcreds))
|
||||
+ except KRB5Error:
|
||||
+ break
|
||||
+
|
||||
if (krb5_principal_compare(context, principal,
|
||||
checkcreds.client) == 1 and
|
||||
krb5_principal_compare(context, srv_princ,
|
||||
@@ -328,8 +332,6 @@ def get_data(princ_name, key):
|
||||
else:
|
||||
krb5_free_cred_contents(context,
|
||||
ctypes.byref(checkcreds))
|
||||
- except KRB5Error:
|
||||
- pass
|
||||
finally:
|
||||
krb5_cc_end_seq_get(context, ccache, ctypes.byref(cursor))
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,424 +0,0 @@
|
||||
From fa46b41af42797dba8dcd04b8cacbc78d602ab80 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <cheimes@redhat.com>
|
||||
Date: Wed, 24 Jan 2024 09:23:22 +0100
|
||||
Subject: [PATCH 1/2] Compatibility fix for PyCA cryptography 42.0.0
|
||||
|
||||
Cryptography 42.0.0 introduced two new abstract properties
|
||||
`not_valid_before_utc` and `not_valid_after_utc`, which are non-naive UTC
|
||||
variants of the `not_valid_before` and `not_valid_after` properties.
|
||||
|
||||
The old properties are deprecated. The changeset also modifies code and
|
||||
tests to use the new `_utc` variants.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9518
|
||||
Signed-off-by: Christian Heimes <cheimes@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
---
|
||||
ipaclient/install/client.py | 4 ++--
|
||||
ipalib/x509.py | 22 +++++++++++++++++++
|
||||
ipapython/certdb.py | 15 +++++++------
|
||||
ipaserver/install/ipa_cacert_manage.py | 2 +-
|
||||
ipaserver/install/ipa_cert_fix.py | 12 +++++-----
|
||||
ipaserver/plugins/cert.py | 4 ++--
|
||||
ipaserver/plugins/dogtag.py | 12 +++++-----
|
||||
ipaserver/plugins/service.py | 5 +++--
|
||||
ipatests/test_integration/test_acme.py | 4 ++--
|
||||
.../test_integration/test_installation.py | 2 +-
|
||||
.../test_integration/test_ipa_cert_fix.py | 2 +-
|
||||
.../test_integration/test_ipahealthcheck.py | 2 +-
|
||||
ipatests/test_ipalib/test_x509.py | 6 +++++
|
||||
13 files changed, 61 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
||||
index 976d3821d..5b97a37f2 100644
|
||||
--- a/ipaclient/install/client.py
|
||||
+++ b/ipaclient/install/client.py
|
||||
@@ -1727,8 +1727,8 @@ def cert_summary(msg, certs, indent=' '):
|
||||
for cert in certs:
|
||||
s += '%sSubject: %s\n' % (indent, DN(cert.subject))
|
||||
s += '%sIssuer: %s\n' % (indent, DN(cert.issuer))
|
||||
- s += '%sValid From: %s\n' % (indent, cert.not_valid_before)
|
||||
- s += '%sValid Until: %s\n' % (indent, cert.not_valid_after)
|
||||
+ s += '%sValid From: %s\n' % (indent, cert.not_valid_before_utc)
|
||||
+ s += '%sValid Until: %s\n' % (indent, cert.not_valid_after_utc)
|
||||
s += '\n'
|
||||
s = s[:-1]
|
||||
|
||||
diff --git a/ipalib/x509.py b/ipalib/x509.py
|
||||
index 769d48007..daeea8195 100644
|
||||
--- a/ipalib/x509.py
|
||||
+++ b/ipalib/x509.py
|
||||
@@ -272,6 +272,28 @@ class IPACertificate(crypto_x509.Certificate):
|
||||
def not_valid_after(self):
|
||||
return self._cert.not_valid_after.replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
+ if hasattr(crypto_x509.Certificate, "not_valid_before_utc"):
|
||||
+ # added in python-cryptography 42.0.0
|
||||
+ @property
|
||||
+ def not_valid_before_utc(self):
|
||||
+ return self._cert.not_valid_before_utc
|
||||
+
|
||||
+ @property
|
||||
+ def not_valid_after_utc(self):
|
||||
+ return self._cert.not_valid_after_utc
|
||||
+ else:
|
||||
+ @property
|
||||
+ def not_valid_before_utc(self):
|
||||
+ return self._cert.not_valid_before.replace(
|
||||
+ tzinfo=datetime.timezone.utc
|
||||
+ )
|
||||
+
|
||||
+ @property
|
||||
+ def not_valid_after_utc(self):
|
||||
+ return self._cert.not_valid_after.replace(
|
||||
+ tzinfo=datetime.timezone.utc
|
||||
+ )
|
||||
+
|
||||
@property
|
||||
def tbs_certificate_bytes(self):
|
||||
return self._cert.tbs_certificate_bytes
|
||||
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
|
||||
index 21af42d23..e3a80bcec 100644
|
||||
--- a/ipapython/certdb.py
|
||||
+++ b/ipapython/certdb.py
|
||||
@@ -944,19 +944,20 @@ class NSSDatabase:
|
||||
"""Common checks for cert validity
|
||||
"""
|
||||
utcnow = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
- if cert.not_valid_before > utcnow:
|
||||
+ if cert.not_valid_before_utc > utcnow:
|
||||
raise ValueError(
|
||||
- f"not valid before {cert.not_valid_before} UTC is in the "
|
||||
- "future."
|
||||
+ f"not valid before {cert.not_valid_before_utc} UTC is in "
|
||||
+ "the future."
|
||||
)
|
||||
- if cert.not_valid_after < utcnow:
|
||||
+ if cert.not_valid_after_utc < utcnow:
|
||||
raise ValueError(
|
||||
- f"has expired {cert.not_valid_after} UTC"
|
||||
+ f"has expired {cert.not_valid_after_utc} UTC"
|
||||
)
|
||||
# make sure the cert does not expire during installation
|
||||
- if cert.not_valid_after + datetime.timedelta(hours=1) < utcnow:
|
||||
+ if cert.not_valid_after_utc + datetime.timedelta(hours=1) < utcnow:
|
||||
raise ValueError(
|
||||
- f"expires in less than one hour ({cert.not_valid_after} UTC)"
|
||||
+ f"expires in less than one hour ({cert.not_valid_after_utc} "
|
||||
+ "UTC)"
|
||||
)
|
||||
|
||||
def verify_server_cert_validity(self, nickname, hostname):
|
||||
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
|
||||
index d371a854b..f6ab736fa 100644
|
||||
--- a/ipaserver/install/ipa_cacert_manage.py
|
||||
+++ b/ipaserver/install/ipa_cacert_manage.py
|
||||
@@ -558,7 +558,7 @@ class CACertManage(admintool.AdminTool):
|
||||
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
for ca_cert, ca_nickname, _ca_trust_flags in ca_certs:
|
||||
- if ca_cert.not_valid_after < now:
|
||||
+ if ca_cert.not_valid_after_utc < now:
|
||||
expired_certs.append(ca_nickname)
|
||||
|
||||
|
||||
diff --git a/ipaserver/install/ipa_cert_fix.py b/ipaserver/install/ipa_cert_fix.py
|
||||
index 834e9557d..8e02d1e75 100644
|
||||
--- a/ipaserver/install/ipa_cert_fix.py
|
||||
+++ b/ipaserver/install/ipa_cert_fix.py
|
||||
@@ -208,7 +208,7 @@ def expired_dogtag_certs(now):
|
||||
except RuntimeError:
|
||||
pass # unfortunately certdb doesn't give us a better exception
|
||||
else:
|
||||
- if cert.not_valid_after <= now:
|
||||
+ if cert.not_valid_after_utc <= now:
|
||||
certs.append((certid, cert))
|
||||
|
||||
return certs
|
||||
@@ -226,12 +226,12 @@ def expired_ipa_certs(now):
|
||||
|
||||
# IPA RA
|
||||
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
|
||||
- if cert.not_valid_after <= now:
|
||||
+ if cert.not_valid_after_utc <= now:
|
||||
certs.append((IPACertType.IPARA, cert))
|
||||
|
||||
# Apache HTTPD
|
||||
cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
|
||||
- if cert.not_valid_after <= now:
|
||||
+ if cert.not_valid_after_utc <= now:
|
||||
if not is_ipa_issued_cert(api, cert):
|
||||
non_renewed.append((IPACertType.HTTPS, cert))
|
||||
else:
|
||||
@@ -244,7 +244,7 @@ def expired_ipa_certs(now):
|
||||
ds_nickname = ds.get_server_cert_nickname(serverid)
|
||||
db = NSSDatabase(nssdir=ds_dbdir)
|
||||
cert = db.get_cert(ds_nickname)
|
||||
- if cert.not_valid_after <= now:
|
||||
+ if cert.not_valid_after_utc <= now:
|
||||
if not is_ipa_issued_cert(api, cert):
|
||||
non_renewed.append((IPACertType.LDAPS, cert))
|
||||
else:
|
||||
@@ -252,7 +252,7 @@ def expired_ipa_certs(now):
|
||||
|
||||
# KDC
|
||||
cert = x509.load_certificate_from_file(paths.KDC_CERT)
|
||||
- if cert.not_valid_after <= now:
|
||||
+ if cert.not_valid_after_utc <= now:
|
||||
if not is_ipa_issued_cert(api, cert):
|
||||
non_renewed.append((IPACertType.HTTPS, cert))
|
||||
else:
|
||||
@@ -286,7 +286,7 @@ def print_cert_info(context, desc, cert):
|
||||
print("{} {} certificate:".format(context, desc))
|
||||
print(" Subject: {}".format(DN(cert.subject)))
|
||||
print(" Serial: {}".format(cert.serial_number))
|
||||
- print(" Expires: {}".format(cert.not_valid_after))
|
||||
+ print(" Expires: {}".format(cert.not_valid_after_utc))
|
||||
print()
|
||||
|
||||
|
||||
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
|
||||
index 4fb85069a..d52cdc1e2 100644
|
||||
--- a/ipaserver/plugins/cert.py
|
||||
+++ b/ipaserver/plugins/cert.py
|
||||
@@ -486,9 +486,9 @@ class BaseCertObject(Object):
|
||||
obj['serial_number'] = str(cert.serial_number)
|
||||
obj['serial_number_hex'] = '0x%X' % cert.serial_number
|
||||
obj['valid_not_before'] = x509.format_datetime(
|
||||
- cert.not_valid_before)
|
||||
+ cert.not_valid_before_utc)
|
||||
obj['valid_not_after'] = x509.format_datetime(
|
||||
- cert.not_valid_after)
|
||||
+ cert.not_valid_after_utc)
|
||||
if full:
|
||||
obj['sha1_fingerprint'] = x509.to_hex_with_colons(
|
||||
cert.fingerprint(hashes.SHA1()))
|
||||
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
|
||||
index 7cd51ae58..23667c3dd 100644
|
||||
--- a/ipaserver/plugins/dogtag.py
|
||||
+++ b/ipaserver/plugins/dogtag.py
|
||||
@@ -1475,14 +1475,14 @@ class ra(rabase.rabase, RestClient):
|
||||
if issuer_dn:
|
||||
response_request['issuer'] = issuer_dn
|
||||
|
||||
- not_valid_before = cert.get('NotValidBefore')
|
||||
- if not_valid_before:
|
||||
+ not_valid_before_utc = cert.get('NotValidBefore')
|
||||
+ if not_valid_before_utc:
|
||||
response_request['valid_not_before'] = (
|
||||
- not_valid_before)
|
||||
+ not_valid_before_utc)
|
||||
|
||||
- not_valid_after = cert.get('NotValidAfter')
|
||||
- if not_valid_after:
|
||||
- response_request['valid_not_after'] = (not_valid_after)
|
||||
+ not_valid_after_utc = cert.get('NotValidAfter')
|
||||
+ if not_valid_after_utc:
|
||||
+ response_request['valid_not_after'] = (not_valid_after_utc)
|
||||
|
||||
status = cert.get('Status')
|
||||
if status:
|
||||
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
|
||||
index f4b107213..075a1be8a 100644
|
||||
--- a/ipaserver/plugins/service.py
|
||||
+++ b/ipaserver/plugins/service.py
|
||||
@@ -303,8 +303,9 @@ def set_certificate_attrs(entry_attrs):
|
||||
entry_attrs['serial_number_hex'] = u'0x%X' % cert.serial_number
|
||||
entry_attrs['issuer'] = unicode(DN(cert.issuer))
|
||||
entry_attrs['valid_not_before'] = x509.format_datetime(
|
||||
- cert.not_valid_before)
|
||||
- entry_attrs['valid_not_after'] = x509.format_datetime(cert.not_valid_after)
|
||||
+ cert.not_valid_before_utc)
|
||||
+ entry_attrs['valid_not_after'] = x509.format_datetime(
|
||||
+ cert.not_valid_after_utc)
|
||||
entry_attrs['sha1_fingerprint'] = x509.to_hex_with_colons(
|
||||
cert.fingerprint(hashes.SHA1()))
|
||||
entry_attrs['sha256_fingerprint'] = x509.to_hex_with_colons(
|
||||
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||
index ee13eb4a0..8e6243d4c 100644
|
||||
--- a/ipatests/test_integration/test_acme.py
|
||||
+++ b/ipatests/test_integration/test_acme.py
|
||||
@@ -670,7 +670,7 @@ class TestACMERenew(IntegrationTest):
|
||||
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||
)
|
||||
cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
- initial_expiry = cert.not_valid_after
|
||||
+ initial_expiry = cert.not_valid_after_utc
|
||||
|
||||
self.clients[0].run_command(['certbot', 'renew'])
|
||||
|
||||
@@ -678,7 +678,7 @@ class TestACMERenew(IntegrationTest):
|
||||
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||
)
|
||||
cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
- renewed_expiry = cert.not_valid_after
|
||||
+ renewed_expiry = cert.not_valid_after_utc
|
||||
|
||||
assert initial_expiry != renewed_expiry
|
||||
|
||||
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
|
||||
index 36142447f..217aae019 100644
|
||||
--- a/ipatests/test_integration/test_installation.py
|
||||
+++ b/ipatests/test_integration/test_installation.py
|
||||
@@ -1565,7 +1565,7 @@ class TestKRAinstallAfterCertRenew(IntegrationTest):
|
||||
certs = x509.load_certificate_list(cmd.stdout_text.encode('utf-8'))
|
||||
|
||||
# get expiry date of agent cert
|
||||
- cert_expiry = certs[0].not_valid_after
|
||||
+ cert_expiry = certs[0].not_valid_after_utc
|
||||
|
||||
# move date to grace period so that certs get renewed
|
||||
self.master.run_command(['systemctl', 'stop', 'chronyd'])
|
||||
diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
index ec9456e51..219e7d0e1 100644
|
||||
--- a/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
+++ b/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
@@ -92,7 +92,7 @@ def get_cert_expiry(host, nssdb_path, cert_nick):
|
||||
])
|
||||
data = host.get_file_contents('/root/cert.pem')
|
||||
cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
- return cert.not_valid_after
|
||||
+ return cert.not_valid_after_utc
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
|
||||
index 40c848988..28200e096 100644
|
||||
--- a/ipatests/test_integration/test_ipahealthcheck.py
|
||||
+++ b/ipatests/test_integration/test_ipahealthcheck.py
|
||||
@@ -1595,7 +1595,7 @@ class TestIpaHealthCheck(IntegrationTest):
|
||||
# Pick a cert to find the upcoming expiration
|
||||
certfile = self.master.get_file_contents(paths.RA_AGENT_PEM)
|
||||
cert = x509.load_certificate_list(certfile)
|
||||
- cert_expiry = cert[0].not_valid_after
|
||||
+ cert_expiry = cert[0].not_valid_after_utc
|
||||
|
||||
# Stop chronyd so it doesn't freak out with time so off
|
||||
restart_service(self.master, 'chronyd')
|
||||
diff --git a/ipatests/test_ipalib/test_x509.py b/ipatests/test_ipalib/test_x509.py
|
||||
index 74287c84a..8ab2ea8c3 100644
|
||||
--- a/ipatests/test_ipalib/test_x509.py
|
||||
+++ b/ipatests/test_ipalib/test_x509.py
|
||||
@@ -246,6 +246,8 @@ class test_x509:
|
||||
assert cert.serial_number == 1093
|
||||
assert cert.not_valid_before == not_before
|
||||
assert cert.not_valid_after == not_after
|
||||
+ assert cert.not_valid_before_utc == not_before
|
||||
+ assert cert.not_valid_after_utc == not_after
|
||||
assert cert.san_general_names == []
|
||||
assert cert.san_a_label_dns_names == []
|
||||
assert cert.extended_key_usage == {'1.3.6.1.5.5.7.3.1'}
|
||||
@@ -277,6 +279,8 @@ class test_x509:
|
||||
# ensure the timezone doesn't mess with not_before and not_after
|
||||
assert cert.not_valid_before == not_before
|
||||
assert cert.not_valid_after == not_after
|
||||
+ assert cert.not_valid_before_utc == not_before
|
||||
+ assert cert.not_valid_after_utc == not_after
|
||||
|
||||
def test_load_pkcs7_pem(self):
|
||||
certlist = x509.pkcs7_to_certs(good_pkcs7, datatype=x509.PEM)
|
||||
@@ -312,6 +316,8 @@ class test_x509:
|
||||
datetime.timezone.utc)
|
||||
assert cert.not_valid_before == not_before
|
||||
assert cert.not_valid_after == not_after
|
||||
+ assert cert.not_valid_before_utc == not_before
|
||||
+ assert cert.not_valid_after_utc == not_after
|
||||
assert cert.san_general_names == [DNSName('ipa.demo1.freeipa.org')]
|
||||
assert cert.san_a_label_dns_names == ['ipa.demo1.freeipa.org']
|
||||
assert cert.extended_key_usage == {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
|
||||
From 18244d7ec1103ec6fba0f94c385e62dba774ed3d Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <cheimes@redhat.com>
|
||||
Date: Thu, 25 Jan 2024 08:56:11 +0100
|
||||
Subject: [PATCH 2/2] test_acme: Use ipalib.x509
|
||||
|
||||
Use IPA's x509 module instead of `cryptography.x509`. This fixes a
|
||||
regression which was introduced in commit a45a7a20.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9518
|
||||
Signed-off-by: Christian Heimes <cheimes@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Mohammad Rizwan Yusuf <myusuf@redhat.com>
|
||||
---
|
||||
ipatests/test_integration/test_acme.py | 9 ++++-----
|
||||
ipatests/test_integration/test_ipa_cert_fix.py | 5 ++---
|
||||
2 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
|
||||
index 8e6243d4c..4032d266a 100644
|
||||
--- a/ipatests/test_integration/test_acme.py
|
||||
+++ b/ipatests/test_integration/test_acme.py
|
||||
@@ -4,11 +4,10 @@
|
||||
|
||||
import time
|
||||
|
||||
-from cryptography.hazmat.backends import default_backend
|
||||
-from cryptography import x509
|
||||
import pytest
|
||||
|
||||
from ipalib.constants import IPA_CA_RECORD
|
||||
+from ipalib import x509
|
||||
from ipatests.test_integration.base import IntegrationTest
|
||||
from ipatests.pytest_ipa.integration.firewall import Firewall
|
||||
from ipatests.pytest_ipa.integration import tasks
|
||||
@@ -278,7 +277,7 @@ class TestACME(CALessBase):
|
||||
cert_path = \
|
||||
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||
data = self.clients[0].get_file_contents(cert_path)
|
||||
- cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
+ cert = x509.load_pem_x509_certificate(data)
|
||||
|
||||
# revoke cert via ACME
|
||||
self.clients[0].run_command(
|
||||
@@ -669,7 +668,7 @@ class TestACMERenew(IntegrationTest):
|
||||
data = self.clients[0].get_file_contents(
|
||||
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||
)
|
||||
- cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
+ cert = x509.load_pem_x509_certificate(data)
|
||||
initial_expiry = cert.not_valid_after_utc
|
||||
|
||||
self.clients[0].run_command(['certbot', 'renew'])
|
||||
@@ -677,7 +676,7 @@ class TestACMERenew(IntegrationTest):
|
||||
data = self.clients[0].get_file_contents(
|
||||
f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem'
|
||||
)
|
||||
- cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
+ cert = x509.load_pem_x509_certificate(data)
|
||||
renewed_expiry = cert.not_valid_after_utc
|
||||
|
||||
assert initial_expiry != renewed_expiry
|
||||
diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
index 219e7d0e1..e6ec30de1 100644
|
||||
--- a/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
+++ b/ipatests/test_integration/test_ipa_cert_fix.py
|
||||
@@ -5,13 +5,12 @@
|
||||
"""
|
||||
Module provides tests for ipa-cert-fix CLI.
|
||||
"""
|
||||
-from cryptography.hazmat.backends import default_backend
|
||||
-from cryptography import x509
|
||||
from datetime import datetime, date
|
||||
import pytest
|
||||
import time
|
||||
|
||||
import logging
|
||||
+from ipalib import x509
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython.ipaldap import realm_to_serverid
|
||||
from ipatests.pytest_ipa.integration import tasks
|
||||
@@ -91,7 +90,7 @@ def get_cert_expiry(host, nssdb_path, cert_nick):
|
||||
'-o', '/root/cert.pem'
|
||||
])
|
||||
data = host.get_file_contents('/root/cert.pem')
|
||||
- cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||||
+ cert = x509.load_pem_x509_certificate(data)
|
||||
return cert.not_valid_after_utc
|
||||
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,69 +0,0 @@
|
||||
From 5dbb3101cee7a96ec8eef40be8e802d456c0d06c Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Mon, 22 Jan 2024 08:36:27 -0500
|
||||
Subject: [PATCH] Server affinity: call ca.install() if there is a CA in the
|
||||
topology
|
||||
|
||||
This should not have been gated on options.setup_ca because we need
|
||||
the RA agent on all servers if there is a CA in the topology otherwise
|
||||
the non-CA servers won't be able to communicate with the CA.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9510
|
||||
|
||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
---
|
||||
ipaserver/install/ca.py | 7 ++++---
|
||||
ipaserver/install/server/replicainstall.py | 7 +++++--
|
||||
2 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
|
||||
index c93ae1fce..187f8032b 100644
|
||||
--- a/ipaserver/install/ca.py
|
||||
+++ b/ipaserver/install/ca.py
|
||||
@@ -387,9 +387,10 @@ def install_step_0(standalone, replica_config, options, custodia):
|
||||
promote = False
|
||||
else:
|
||||
cafile = os.path.join(replica_config.dir, 'cacert.p12')
|
||||
- custodia.get_ca_keys(
|
||||
- cafile,
|
||||
- replica_config.dirman_password)
|
||||
+ if replica_config.setup_ca:
|
||||
+ custodia.get_ca_keys(
|
||||
+ cafile,
|
||||
+ replica_config.dirman_password)
|
||||
|
||||
ca_signing_algorithm = None
|
||||
ca_type = None
|
||||
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
|
||||
index 191913ddb..b3fd27e6a 100644
|
||||
--- a/ipaserver/install/server/replicainstall.py
|
||||
+++ b/ipaserver/install/server/replicainstall.py
|
||||
@@ -1382,11 +1382,13 @@ def install(installer):
|
||||
custodia = custodiainstance.get_custodia_instance(config, mode)
|
||||
custodia.create_instance()
|
||||
|
||||
- if options.setup_ca and ca_enabled:
|
||||
+ if ca_enabled:
|
||||
options.realm_name = config.realm_name
|
||||
options.domain_name = config.domain_name
|
||||
options.host_name = config.host_name
|
||||
options.dm_password = config.dirman_password
|
||||
+ # Always call ca.install() if there is a CA in the topology
|
||||
+ # to ensure the RA agent is present.
|
||||
ca.install(False, config, options, custodia=custodia)
|
||||
|
||||
# configure PKINIT now that all required services are in place
|
||||
@@ -1398,7 +1400,8 @@ def install(installer):
|
||||
service.print_msg("Finalize replication settings")
|
||||
ds.finalize_replica_config()
|
||||
|
||||
- if options.setup_kra and kra_enabled:
|
||||
+ if kra_enabled:
|
||||
+ # The KRA installer checks for itself the status of setup_kra
|
||||
kra.install(api, config, options, custodia=custodia)
|
||||
|
||||
service.print_msg("Restarting the KDC")
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,35 +0,0 @@
|
||||
From eab52d3cda9bbec716008c040551bd11facd0e11 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 12:27:26 +0200
|
||||
Subject: [PATCH] adtrustinstance: make sure NetBIOS name defaults are set
|
||||
properly
|
||||
|
||||
Some tools may pass None as NetBIOS name if not put explicitly by a
|
||||
user. This meant to use default NetBIOS name generator based on the
|
||||
domain (realm) name. However, this wasn't done properly, so None is
|
||||
passed later to python-ldap and it rejects such LDAP entry.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9514
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
---
|
||||
ipaserver/install/adtrustinstance.py | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
|
||||
index d55ba8491..2ff68dfb4 100644
|
||||
--- a/ipaserver/install/adtrustinstance.py
|
||||
+++ b/ipaserver/install/adtrustinstance.py
|
||||
@@ -189,6 +189,8 @@ class ADTRUSTInstance(service.Service):
|
||||
self.fqdn = self.fqdn or api.env.host
|
||||
self.host_netbios_name = make_netbios_name(self.fqdn)
|
||||
self.realm = self.realm or api.env.realm
|
||||
+ if not self.netbios_name:
|
||||
+ self.netbios_name = make_netbios_name(self.realm)
|
||||
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm)
|
||||
self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,101 +0,0 @@
|
||||
From 3842116185de6ae8714f30b57bd75c7eddde53d8 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Thu, 21 Dec 2023 09:38:57 +0200
|
||||
Subject: [PATCH] host: update System: Manage Host Keytab permission
|
||||
|
||||
Since commit 5c0e7a5fb420377dcc06a956695afdcb35196444, a new extended
|
||||
operation to get a keytab is supposed to be used. This keytab
|
||||
setting/retrieval extended operation checks access rights of the bound
|
||||
DN to write to a virtual attribute 'ipaProtectedOperation;write_keys'.
|
||||
|
||||
If the write isn't allowed, the operation is rejected and ipa-getkeytab
|
||||
tool falls back to an older code that generates the keytab on the client
|
||||
and forcibly sets to the LDAP entry. For the latter, a check is done to
|
||||
make sure the bound DN is allowed to write to 'krbPrincipalKey' attribute.
|
||||
|
||||
This fallback should never happen for newer deployments. When enrollemnt
|
||||
operation is delegated to non-administrative user with the help of 'Host
|
||||
Enrollment' role, a host can be pre-created or created at enrollment
|
||||
time, if this non-administrative user has 'Host Administrators' role. In
|
||||
the latter case a system permission 'System: Manage Host Keytab' grants
|
||||
write access to 'krbPrincipalKey' attribute but lacks any access to the
|
||||
virtual attributes expected by the new extended operation.
|
||||
|
||||
There is a second virtual attribute, 'ipaProtectedOperation;read_keys',
|
||||
that allows to retrieve existing keys for a host. However, during
|
||||
initial enrollment we do not allow to retrieve and reuse existing
|
||||
Kerberos key: while 'ipa-getkeytab -r' would give ability to retrieve
|
||||
the existing key, 'ipa-join' has no way to trigger that operation.
|
||||
Hence, permission 'System: Manage Host Keytab' will not grant the right
|
||||
to read the Kerberos key via extended operation used by 'ipa-getkeytab
|
||||
-r'. Such operation can be done later by utilizing 'ipa
|
||||
service/host-allow-retrieve-keytab' commands.
|
||||
|
||||
Fix 'System: Manage Host Keytab' permission and extend a permission test
|
||||
to see that we do not fallback to the old extended operation.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9496
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ACI.txt | 2 +-
|
||||
ipaserver/plugins/host.py | 3 ++-
|
||||
ipatests/test_integration/test_user_permissions.py | 7 +++++++
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ACI.txt b/ACI.txt
|
||||
index e6d6e3d15..236bb4367 100644
|
||||
--- a/ACI.txt
|
||||
+++ b/ACI.txt
|
||||
@@ -147,7 +147,7 @@ aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=ipahost)")(ve
|
||||
dn: cn=computers,cn=accounts,dc=ipa,dc=example
|
||||
aci: (targetattr = "userpassword")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Enrollment Password";allow (write) groupdn = "ldap:///cn=System: Manage Host Enrollment Password,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=computers,cn=accounts,dc=ipa,dc=example
|
||||
-aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
+aci: (targetattr = "ipaprotectedoperation;write_keys || krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=computers,cn=accounts,dc=ipa,dc=example
|
||||
aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Host Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=computers,cn=accounts,dc=ipa,dc=example
|
||||
diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
|
||||
index 3ef510edc..b02c8b55f 100644
|
||||
--- a/ipaserver/plugins/host.py
|
||||
+++ b/ipaserver/plugins/host.py
|
||||
@@ -409,7 +409,8 @@ class host(LDAPObject):
|
||||
api.env.container_hostgroup,
|
||||
api.env.basedn),
|
||||
],
|
||||
- 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey'},
|
||||
+ 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey',
|
||||
+ 'ipaprotectedoperation;write_keys'},
|
||||
'replaces': [
|
||||
'(targetattr = "krbprincipalkey || krblastpwdchange")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Manage host keytab";allow (write) groupdn = "ldap:///cn=Manage host keytab,cn=permissions,cn=pbac,$SUFFIX";)',
|
||||
],
|
||||
diff --git a/ipatests/test_integration/test_user_permissions.py b/ipatests/test_integration/test_user_permissions.py
|
||||
index 3333a4f6b..cd1096ff3 100644
|
||||
--- a/ipatests/test_integration/test_user_permissions.py
|
||||
+++ b/ipatests/test_integration/test_user_permissions.py
|
||||
@@ -277,6 +277,9 @@ class TestInstallClientNoAdmin(IntegrationTest):
|
||||
self.master.run_command(['ipa', 'privilege-add-permission',
|
||||
'--permissions', 'System: Add Hosts',
|
||||
'Add Hosts'])
|
||||
+ self.master.run_command(['ipa', 'privilege-add-permission',
|
||||
+ '--permissions', 'System: Manage Host Keytab',
|
||||
+ 'Add Hosts'])
|
||||
|
||||
self.master.run_command(['ipa', 'role-add-privilege', 'useradmin',
|
||||
'--privileges', 'Host Enrollment'])
|
||||
@@ -301,6 +304,10 @@ class TestInstallClientNoAdmin(IntegrationTest):
|
||||
encoding='utf-8')
|
||||
assert msg in install_log
|
||||
|
||||
+ # Make sure we do not fallback to an old keytab retrieval method anymore
|
||||
+ msg = "Retrying with pre-4.0 keytab retrieval method..."
|
||||
+ assert msg not in install_log
|
||||
+
|
||||
# check that user is able to request a host cert, too
|
||||
result = tasks.run_certutil(client, ['-L'], paths.IPA_NSSDB_DIR)
|
||||
assert 'Local IPA host' in result.stdout_text
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,50 +0,0 @@
|
||||
From f8b444c563094173c17c3327d72ce9b70da254af Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Tue, 30 Jan 2024 19:58:05 +0200
|
||||
Subject: [PATCH] ipa-kdb: support Samba 4.20 private libraries
|
||||
|
||||
Samba 4.20 will change name extension of the private libraries from
|
||||
'samba4' to 'private-samba'. Detect private extension through configure
|
||||
step and make sure to use the right library name in Makefile.
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
daemons/ipa-kdb/Makefile.am | 2 +-
|
||||
server.m4 | 8 ++++++++
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
|
||||
index 777c6b4bd..ca1593bc8 100644
|
||||
--- a/daemons/ipa-kdb/Makefile.am
|
||||
+++ b/daemons/ipa-kdb/Makefile.am
|
||||
@@ -116,7 +116,7 @@ ipa_kdb_tests_LDADD = \
|
||||
$(top_builddir)/util/libutil.la \
|
||||
-lkdb5 \
|
||||
-lsss_idmap \
|
||||
- -lsamba-security-samba4 \
|
||||
+ -l$(SAMBA_SECURITY_LIBS)\
|
||||
-lsamba-errors \
|
||||
$(NULL)
|
||||
|
||||
diff --git a/server.m4 b/server.m4
|
||||
index 2ee2cf519..f97ceddea 100644
|
||||
--- a/server.m4
|
||||
+++ b/server.m4
|
||||
@@ -182,6 +182,14 @@ AC_CHECK_LIB([smbldap],[smbldap_set_bind_callback],
|
||||
[AC_DEFINE([HAVE_SMBLDAP_SET_BIND_CALLBACK], [1], [struct smbldap_state is opaque])],
|
||||
[AC_MSG_WARN([libsmbldap is not opaque, not using smbldap_set_bind_callback])],
|
||||
[$SAMBA40EXTRA_LIBPATH])
|
||||
+AC_CHECK_LIB([samba-security-private-samba],[dom_sid_string],
|
||||
+ [SAMBA_SECURITY_LIBS=samba-security-private-samba],
|
||||
+ [AC_CHECK_LIB([samba-security-samba4],[dom_sid_string],
|
||||
+ [SAMBA_SECURITY_LIBS=samba-security-samba4],
|
||||
+ [AC_MSG_ERROR([Cannot find private samba-security library])],
|
||||
+ [$SAMBA40EXTRA_LIBPATH])],
|
||||
+ [$SAMBA40EXTRA_LIBPATH])
|
||||
+AC_SUBST(SAMBA_SECURITY_LIBS)
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Check for libunistring
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,153 +0,0 @@
|
||||
From d4271391adc45c781092db0fb89b802743a9dda8 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Mon, 11 Sep 2023 21:37:05 +0000
|
||||
Subject: [PATCH 1/2] The PKI JSON API the revocation reason key may be
|
||||
case-sensitive
|
||||
|
||||
PKI 11.4.0 changed the reason keyword in the REST API from lower-case
|
||||
to camel-case in https://github.com/dogtagpki/pki/commit/926eb221ce6
|
||||
|
||||
Use Reason instead of reason as the keyword for revocations
|
||||
for PKI 11.4.0+
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9345
|
||||
|
||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
|
||||
---
|
||||
ipaserver/plugins/dogtag.py | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
|
||||
index 1c2c51824..0036803c8 100644
|
||||
--- a/ipaserver/plugins/dogtag.py
|
||||
+++ b/ipaserver/plugins/dogtag.py
|
||||
@@ -274,6 +274,8 @@ if six.PY3:
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
+pki_version = pki.util.Version(pki.specification_version())
|
||||
+
|
||||
# These are general status return values used when
|
||||
# CMSServlet.outputError() is invoked.
|
||||
CMS_SUCCESS = 0
|
||||
@@ -1130,7 +1132,11 @@ class ra(rabase.rabase, RestClient):
|
||||
serial_number = int(serial_number, 0)
|
||||
|
||||
path = 'agent/certs/{}/revoke'.format(serial_number)
|
||||
- data = '{{"reason":"{}"}}'.format(reasons[revocation_reason])
|
||||
+ if pki_version < pki.util.Version("11.4.0"):
|
||||
+ keyword = "reason"
|
||||
+ else:
|
||||
+ keyword = "Reason"
|
||||
+ data = '{{"{}":"{}"}}'.format(keyword, reasons[revocation_reason])
|
||||
|
||||
http_status, _http_headers, http_body = self._ssldo(
|
||||
'POST', path,
|
||||
--
|
||||
2.41.0
|
||||
|
||||
|
||||
From 0539d97f3e9d2b7d80549ff08d78fe55afcc2dbb Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Thu, 26 Oct 2023 13:59:21 -0400
|
||||
Subject: [PATCH 2/2] WIP: Get the PKI version from the remote to determine the
|
||||
argument
|
||||
|
||||
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
|
||||
---
|
||||
ipaserver/plugins/dogtag.py | 55 ++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 48 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
|
||||
index 0036803c8..7cd51ae58 100644
|
||||
--- a/ipaserver/plugins/dogtag.py
|
||||
+++ b/ipaserver/plugins/dogtag.py
|
||||
@@ -274,8 +274,6 @@ if six.PY3:
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
-pki_version = pki.util.Version(pki.specification_version())
|
||||
-
|
||||
# These are general status return values used when
|
||||
# CMSServlet.outputError() is invoked.
|
||||
CMS_SUCCESS = 0
|
||||
@@ -1059,6 +1057,39 @@ class ra(rabase.rabase, RestClient):
|
||||
|
||||
return cmd_result
|
||||
|
||||
+ def get_pki_version(self):
|
||||
+ """
|
||||
+ Retrieve the version of a remote PKI server.
|
||||
+
|
||||
+ The REST API request is a GET to the info URI:
|
||||
+ GET /pki/rest/info HTTP/1.1
|
||||
+
|
||||
+ The response is: {"Version":"11.5.0","Attributes":{"Attribute":[]}}
|
||||
+ """
|
||||
+ path = "/pki/rest/info"
|
||||
+ logger.debug('%s.get_pki_version()', type(self).__name__)
|
||||
+ http_status, _http_headers, http_body = self._ssldo(
|
||||
+ 'GET', path,
|
||||
+ headers={
|
||||
+ 'Content-Type': 'application/json',
|
||||
+ 'Accept': 'application/json',
|
||||
+ },
|
||||
+ use_session=False,
|
||||
+ )
|
||||
+ if http_status != 200:
|
||||
+ self.raise_certificate_operation_error('get_pki_version',
|
||||
+ detail=http_status)
|
||||
+
|
||||
+ try:
|
||||
+ response = json.loads(ipautil.decode_json(http_body))
|
||||
+ except ValueError as e:
|
||||
+ logger.debug("Response from CA was not valid JSON: %s", e)
|
||||
+ raise errors.RemoteRetrieveError(
|
||||
+ reason=_("Response from CA was not valid JSON")
|
||||
+ )
|
||||
+
|
||||
+ return response.get('Version')
|
||||
+
|
||||
|
||||
def revoke_certificate(self, serial_number, revocation_reason=0):
|
||||
"""
|
||||
@@ -1125,6 +1156,20 @@ class ra(rabase.rabase, RestClient):
|
||||
detail='7 is not a valid revocation reason'
|
||||
)
|
||||
|
||||
+ # dogtag changed the argument case for revocation from
|
||||
+ # "reason" to "Reason" in PKI 11.4.0. Detect that change
|
||||
+ # based on the remote version and pass the expected value
|
||||
+ # in.
|
||||
+ pki_version = pki.util.Version(self.get_pki_version())
|
||||
+ if pki_version is None:
|
||||
+ self.raise_certificate_operation_error('revoke_certificate',
|
||||
+ detail="Remove version not "
|
||||
+ "detected")
|
||||
+ if pki_version < pki.util.Version("11.4.0"):
|
||||
+ reason = "reason"
|
||||
+ else:
|
||||
+ reason = "Reason"
|
||||
+
|
||||
# Convert serial number to integral type from string to properly handle
|
||||
# radix issues. Note: the int object constructor will properly handle
|
||||
# large magnitude integral values by returning a Python long type
|
||||
@@ -1132,11 +1177,7 @@ class ra(rabase.rabase, RestClient):
|
||||
serial_number = int(serial_number, 0)
|
||||
|
||||
path = 'agent/certs/{}/revoke'.format(serial_number)
|
||||
- if pki_version < pki.util.Version("11.4.0"):
|
||||
- keyword = "reason"
|
||||
- else:
|
||||
- keyword = "Reason"
|
||||
- data = '{{"{}":"{}"}}'.format(keyword, reasons[revocation_reason])
|
||||
+ data = '{{"{}":"{}"}}'.format(reason, reasons[revocation_reason])
|
||||
|
||||
http_status, _http_headers, http_body = self._ssldo(
|
||||
'POST', path,
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,135 +0,0 @@
|
||||
From 9b0b723a0e62f18d41be53900ab8a3e710708563 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Thu, 18 May 2023 09:23:32 -0400
|
||||
Subject: [PATCH] Allow password policy minlength to be removed like other
|
||||
values
|
||||
|
||||
This is a side-effect of adding the libpwquality options. It
|
||||
imposes its own hardcoded minimum password length so some care
|
||||
was needed to ensure that it isn't set too low.
|
||||
|
||||
So if there are no libpwquality options used then it's fine to
|
||||
have no minlength in the policy.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9297
|
||||
|
||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
---
|
||||
ipaserver/plugins/pwpolicy.py | 10 +++--
|
||||
ipatests/test_integration/test_pwpolicy.py | 45 +++++++++++++++++++++-
|
||||
2 files changed, 50 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/plugins/pwpolicy.py b/ipaserver/plugins/pwpolicy.py
|
||||
index 5ea3e6b78..15cfef45b 100644
|
||||
--- a/ipaserver/plugins/pwpolicy.py
|
||||
+++ b/ipaserver/plugins/pwpolicy.py
|
||||
@@ -462,6 +462,7 @@ class pwpolicy(LDAPObject):
|
||||
return False
|
||||
|
||||
has_pwquality_value = False
|
||||
+ min_length = 0
|
||||
if not add:
|
||||
if len(keys) > 0:
|
||||
existing_entry = self.api.Command.pwpolicy_show(
|
||||
@@ -470,14 +471,15 @@ class pwpolicy(LDAPObject):
|
||||
existing_entry = self.api.Command.pwpolicy_show(
|
||||
all=True,)['result']
|
||||
existing_entry.update(entry_attrs)
|
||||
- min_length = int(get_val(existing_entry, 'krbpwdminlength'))
|
||||
-
|
||||
+ if existing_entry.get('krbpwdminlength'):
|
||||
+ min_length = int(get_val(existing_entry, 'krbpwdminlength'))
|
||||
has_pwquality_value = has_pwquality_set(existing_entry)
|
||||
else:
|
||||
- min_length = int(get_val(entry_attrs, 'krbpwdminlength'))
|
||||
+ if entry_attrs.get('krbpwdminlength'):
|
||||
+ min_length = int(get_val(entry_attrs, 'krbpwdminlength'))
|
||||
has_pwquality_value = has_pwquality_set(entry_attrs)
|
||||
|
||||
- if min_length and min_length < 6 and has_pwquality_value:
|
||||
+ if min_length < 6 and has_pwquality_value:
|
||||
raise errors.ValidationError(
|
||||
name='minlength',
|
||||
error=_('Minimum length must be >= 6 if maxrepeat, '
|
||||
diff --git a/ipatests/test_integration/test_pwpolicy.py b/ipatests/test_integration/test_pwpolicy.py
|
||||
index 41d6e9070..652c95e47 100644
|
||||
--- a/ipatests/test_integration/test_pwpolicy.py
|
||||
+++ b/ipatests/test_integration/test_pwpolicy.py
|
||||
@@ -36,7 +36,9 @@ class TestPWPolicy(IntegrationTest):
|
||||
cls.master.run_command(['ipa', 'group-add-member', POLICY,
|
||||
'--users', USER])
|
||||
cls.master.run_command(['ipa', 'pwpolicy-add', POLICY,
|
||||
- '--priority', '1', '--gracelimit', '-1'])
|
||||
+ '--priority', '1',
|
||||
+ '--gracelimit', '-1',
|
||||
+ '--minlength', '6'])
|
||||
cls.master.run_command(['ipa', 'passwd', USER],
|
||||
stdin_text='{password}\n{password}\n'.format(
|
||||
password=PASSWORD
|
||||
@@ -92,6 +94,12 @@ class TestPWPolicy(IntegrationTest):
|
||||
"--minlength", "0",
|
||||
"--minclasses", "0",],
|
||||
)
|
||||
+ # minlength => 6 is required for any of the libpwquality settings
|
||||
+ self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--minlength", "6"],
|
||||
+ raiseonerr=False,
|
||||
+ )
|
||||
|
||||
@pytest.fixture
|
||||
def reset_pwpolicy(self):
|
||||
@@ -212,6 +220,7 @@ class TestPWPolicy(IntegrationTest):
|
||||
assert 'Password is too simple' in \
|
||||
result.stdout_text
|
||||
|
||||
+ self.reset_password(self.master)
|
||||
# test with valid password
|
||||
for valid in ('Passw0rd', 'password1!', 'Password!'):
|
||||
self.kinit_as_user(self.master, PASSWORD, valid)
|
||||
@@ -252,6 +261,40 @@ class TestPWPolicy(IntegrationTest):
|
||||
assert result.returncode != 0
|
||||
assert 'minlength' in result.stderr_text
|
||||
|
||||
+ def test_minlength_empty(self, reset_pwpolicy):
|
||||
+ """Test that the pwpolicy minlength can be blank
|
||||
+ """
|
||||
+ # Ensure it is set to a non-zero value to avoid EmptyModlist
|
||||
+ self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--minlength", "10",]
|
||||
+ )
|
||||
+ # Enable one of the libpwquality options, removing minlength
|
||||
+ # should fail.
|
||||
+ self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--maxrepeat", "4",]
|
||||
+ )
|
||||
+ result = self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--minlength", "",], raiseonerr=False
|
||||
+ )
|
||||
+ assert result.returncode != 0
|
||||
+
|
||||
+ # Remove the blocking value
|
||||
+ self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--maxrepeat", "",]
|
||||
+ )
|
||||
+
|
||||
+ # Now erase it
|
||||
+ result = self.master.run_command(
|
||||
+ ["ipa", "pwpolicy-mod", POLICY,
|
||||
+ "--minlength", "",]
|
||||
+ )
|
||||
+ assert result.returncode == 0
|
||||
+ assert 'minlength' not in result.stderr_text
|
||||
+
|
||||
def test_minlength_add(self):
|
||||
"""Test that adding a new policy with minlength is caught.
|
||||
"""
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,88 +0,0 @@
|
||||
From d9ad56155e76f97ad9326d5c1bcc6e19eea3a0da Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Mon, 9 Oct 2023 13:54:17 +0200
|
||||
Subject: [PATCH] ipalib: fix the IPACertificate validity dates
|
||||
|
||||
The class IPACertificate builds objects from x509 Certificate
|
||||
objects and creates the not_valid_before and not_valid_after values
|
||||
by converting to a timestamp + applying timezone delta to UTC + reading
|
||||
from the timestamp. This results in applying twice the delta.
|
||||
|
||||
Use a simpler method that replaces the timezone info with UTC in the
|
||||
datetime object.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9462
|
||||
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipalib/x509.py | 6 ++----
|
||||
ipatests/test_ipalib/test_x509.py | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 27 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipalib/x509.py b/ipalib/x509.py
|
||||
index 7396688ae..769d48007 100644
|
||||
--- a/ipalib/x509.py
|
||||
+++ b/ipalib/x509.py
|
||||
@@ -266,13 +266,11 @@ class IPACertificate(crypto_x509.Certificate):
|
||||
|
||||
@property
|
||||
def not_valid_before(self):
|
||||
- return datetime.datetime.fromtimestamp(
|
||||
- self._cert.not_valid_before.timestamp(), tz=datetime.timezone.utc)
|
||||
+ return self._cert.not_valid_before.replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
@property
|
||||
def not_valid_after(self):
|
||||
- return datetime.datetime.fromtimestamp(
|
||||
- self._cert.not_valid_after.timestamp(), tz=datetime.timezone.utc)
|
||||
+ return self._cert.not_valid_after.replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
@property
|
||||
def tbs_certificate_bytes(self):
|
||||
diff --git a/ipatests/test_ipalib/test_x509.py b/ipatests/test_ipalib/test_x509.py
|
||||
index c25e8a0b5..74287c84a 100644
|
||||
--- a/ipatests/test_ipalib/test_x509.py
|
||||
+++ b/ipatests/test_ipalib/test_x509.py
|
||||
@@ -26,6 +26,7 @@ from binascii import hexlify
|
||||
from configparser import RawConfigParser
|
||||
import datetime
|
||||
from io import StringIO
|
||||
+import os
|
||||
import pickle
|
||||
|
||||
import pytest
|
||||
@@ -253,6 +254,30 @@ class test_x509:
|
||||
b'+\x06\x01\x05\x05\x07\x03\x01'
|
||||
)
|
||||
|
||||
+ def test_cert_with_timezone(self):
|
||||
+ """
|
||||
+ Test the not_before and not_after values in a diffent timezone
|
||||
+
|
||||
+ Test for https://pagure.io/freeipa/issue/9462
|
||||
+ """
|
||||
+ # Store initial timezone, then set to New York
|
||||
+ tz = os.environ.get('TZ', None)
|
||||
+ os.environ['TZ'] = 'America/New_York'
|
||||
+ # Load the cert, extract not before and not after
|
||||
+ cert = x509.load_pem_x509_certificate(goodcert_headers)
|
||||
+ not_before = datetime.datetime(2010, 6, 25, 13, 0, 42, 0,
|
||||
+ datetime.timezone.utc)
|
||||
+ not_after = datetime.datetime(2015, 6, 25, 13, 0, 42, 0,
|
||||
+ datetime.timezone.utc)
|
||||
+ # Reset timezone to previous value
|
||||
+ if tz:
|
||||
+ os.environ['TZ'] = tz
|
||||
+ else:
|
||||
+ del os.environ['TZ']
|
||||
+ # ensure the timezone doesn't mess with not_before and not_after
|
||||
+ assert cert.not_valid_before == not_before
|
||||
+ assert cert.not_valid_after == not_after
|
||||
+
|
||||
def test_load_pkcs7_pem(self):
|
||||
certlist = x509.pkcs7_to_certs(good_pkcs7, datatype=x509.PEM)
|
||||
assert len(certlist) == 1
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,80 +0,0 @@
|
||||
From d50624dce932d02ea03a00d3ac2ec1be69e8d3b6 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Thu, 19 Oct 2023 12:47:03 +0200
|
||||
Subject: [PATCH 1/2] group-add-member fails with an external member
|
||||
|
||||
The command ipa group-add-member --external aduser@addomain.test
|
||||
fails with an internal error when used with samba 4.19.
|
||||
|
||||
The command internally calls samba.security.dom_sid(sid) which
|
||||
used to raise a TypeError but now raises a ValueError
|
||||
(commit 9abdd67 on https://github.com/samba-team/samba).
|
||||
|
||||
IPA source code needs to handle properly both exception types.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9466
|
||||
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipaserver/dcerpc.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
|
||||
index 741f0608f..7e585c876 100644
|
||||
--- a/ipaserver/dcerpc.py
|
||||
+++ b/ipaserver/dcerpc.py
|
||||
@@ -303,7 +303,7 @@ class DomainValidator:
|
||||
# Parse sid string to see if it is really in a SID format
|
||||
try:
|
||||
test_sid = security.dom_sid(sid)
|
||||
- except TypeError:
|
||||
+ except (TypeError, ValueError):
|
||||
raise errors.ValidationError(name='sid',
|
||||
error=_('SID is not valid'))
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
||||
|
||||
From ed6fa6029d863aed1522b449d3360e6c4028e066 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Fri, 20 Oct 2023 10:20:57 +0200
|
||||
Subject: [PATCH 2/2] Handle samba changes in samba.security.dom_sid()
|
||||
|
||||
samba.security.dom_sid() in 4.19 now raises ValueError instead of
|
||||
TypeError. Fix the expected exception.
|
||||
|
||||
Related: https://pagure.io/freeipa/issue/9466
|
||||
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
ipaserver/dcerpc.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
|
||||
index 7e585c876..675572c03 100644
|
||||
--- a/ipaserver/dcerpc.py
|
||||
+++ b/ipaserver/dcerpc.py
|
||||
@@ -97,7 +97,7 @@ logger = logging.getLogger(__name__)
|
||||
def is_sid_valid(sid):
|
||||
try:
|
||||
security.dom_sid(sid)
|
||||
- except TypeError:
|
||||
+ except (TypeError, ValueError):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@@ -457,7 +457,7 @@ class DomainValidator:
|
||||
try:
|
||||
test_sid = security.dom_sid(sid)
|
||||
return unicode(test_sid)
|
||||
- except TypeError:
|
||||
+ except (TypeError, ValueError):
|
||||
raise errors.ValidationError(name=_('trusted domain object'),
|
||||
error=_('Trusted domain did not '
|
||||
'return a valid SID for '
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,83 +0,0 @@
|
||||
From 677d30806662856595289525ef529a77adbf2272 Mon Sep 17 00:00:00 2001
|
||||
From: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Date: Fri, 26 Jan 2024 13:26:48 +0100
|
||||
Subject: [PATCH] ipa-backup: adapt for 389ds switch to LMDB
|
||||
|
||||
ipa-backup is relying on the presence of the directory
|
||||
/var/lib/dirsrv/slapd-<INSTANCE>/db/ipaca/
|
||||
to detect if the CA is installed on the server and backup
|
||||
the ipaca backend.
|
||||
|
||||
With the switch to LMDB, this directory does not exist and the
|
||||
backup is missing ipaca information.
|
||||
|
||||
Use lib389.cli_ctl.dblib.run_dbscan utility instead to
|
||||
check if ipaca backend is present (this method has been
|
||||
introduced in 389ds 2.1.0 and works with Berkeley DB and LMDB).
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9516
|
||||
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
|
||||
---
|
||||
freeipa.spec.in | 7 ++++---
|
||||
ipaserver/install/ipa_backup.py | 8 ++++++--
|
||||
2 files changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
||||
index a091fee68..997a55d8d 100755
|
||||
--- a/freeipa.spec.in
|
||||
+++ b/freeipa.spec.in
|
||||
@@ -78,8 +78,8 @@
|
||||
%global ds_version 1.4.3.16-12
|
||||
%global selinux_policy_version 3.14.3-107
|
||||
%else
|
||||
-# DNA interval enabled
|
||||
-%global ds_version 2.0.5-1
|
||||
+# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility
|
||||
+%global ds_version 2.1.0
|
||||
%global selinux_policy_version 38.1.1-1
|
||||
%endif
|
||||
|
||||
@@ -124,10 +124,11 @@
|
||||
|
||||
# Make sure to use 389-ds-base versions that fix https://github.com/389ds/389-ds-base/issues/4700
|
||||
# and has DNA interval enabled
|
||||
+# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility
|
||||
%if 0%{?fedora} < 34
|
||||
%global ds_version 1.4.4.16-1
|
||||
%else
|
||||
-%global ds_version 2.0.7-1
|
||||
+%global ds_version 2.1.0
|
||||
%endif
|
||||
|
||||
# Fix for TLS 1.3 PHA, RHBZ#1775146
|
||||
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
|
||||
index 2904c9e2e..f4fa73ff5 100644
|
||||
--- a/ipaserver/install/ipa_backup.py
|
||||
+++ b/ipaserver/install/ipa_backup.py
|
||||
@@ -41,6 +41,7 @@ from ipaserver.install import installutils
|
||||
from ipapython import ipaldap
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.tasks import tasks
|
||||
+from lib389.cli_ctl.dblib import run_dbscan
|
||||
|
||||
# pylint: disable=import-error
|
||||
if six.PY3:
|
||||
@@ -337,8 +338,11 @@ class Backup(admintool.AdminTool):
|
||||
instance = ipaldap.realm_to_serverid(api.env.realm)
|
||||
if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
|
||||
instance):
|
||||
- if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
||||
- (instance, 'ipaca')):
|
||||
+ # Check existence of ipaca backend
|
||||
+ dbpath = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
||||
+ (instance, ""))
|
||||
+ output = run_dbscan(['-L', dbpath])
|
||||
+ if 'ipaca/' in output:
|
||||
self.db2ldif(instance, 'ipaca', online=options.online)
|
||||
self.db2ldif(instance, 'userRoot', online=options.online)
|
||||
self.db2bak(instance, online=options.online)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,106 +0,0 @@
|
||||
From cb16071635e8c60faa5b6062ed1dd61c3f133fa3 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Wed, 7 Feb 2024 13:42:11 -0500
|
||||
Subject: ipa-restore: adapt for 389-ds switch to LMDB
|
||||
|
||||
ipa-restore is relying on the presence of specific directories,
|
||||
e.g. /var/lib/dirsrv/slapd-<INSTANCE>/db/ipaca, to detect
|
||||
which backends are in use (userRoot or ipaca).
|
||||
|
||||
With the switch to LMDB, these directories do not exist and the
|
||||
restore fails finding the ipaca backend.
|
||||
|
||||
Use lib389.cli_ctl.dblib.run_dbscan utility instead to
|
||||
check which backends are present.
|
||||
|
||||
This method was been introduced in 389ds 2.1.0 and works with
|
||||
Berkeley DB and LMDB.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9526
|
||||
|
||||
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
|
||||
---
|
||||
ipaserver/install/ipa_restore.py | 45 +++++++++++++++++++++++++++-----
|
||||
1 file changed, 38 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
|
||||
index 5b7ac61d08f..88b34477049 100644
|
||||
--- a/ipaserver/install/ipa_restore.py
|
||||
+++ b/ipaserver/install/ipa_restore.py
|
||||
@@ -50,6 +50,8 @@
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
+from lib389.cli_ctl.dblib import run_dbscan
|
||||
+
|
||||
try:
|
||||
from ipaserver.install import adtrustinstance
|
||||
except ImportError:
|
||||
@@ -65,6 +67,29 @@
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
+backends = [] # global to save running dbscan multiple times
|
||||
+
|
||||
+
|
||||
+def get_backends(db_dir):
|
||||
+ """Retrieve the set of backends directly from the current database"""
|
||||
+ global backends
|
||||
+
|
||||
+ if backends:
|
||||
+ return backends
|
||||
+
|
||||
+ output = run_dbscan(['-L', db_dir])
|
||||
+ output = output.replace(db_dir + '/', '')
|
||||
+ output = output.split('\n')
|
||||
+ for line in output:
|
||||
+ if '/' not in line:
|
||||
+ continue
|
||||
+ backends.append(line.split('/')[0].strip().lower())
|
||||
+ backends = set(backends)
|
||||
+ if 'changelog' in backends:
|
||||
+ backends.remove('changelog')
|
||||
+
|
||||
+ return backends
|
||||
+
|
||||
|
||||
def recursive_chown(path, uid, gid):
|
||||
'''
|
||||
@@ -295,8 +320,9 @@ def run(self):
|
||||
if options.backend:
|
||||
for instance in self.instances:
|
||||
db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
||||
- (instance, options.backend))
|
||||
- if os.path.exists(db_dir):
|
||||
+ (instance, ""))
|
||||
+ backends = get_backends(db_dir)
|
||||
+ if options.backend.lower() in backends:
|
||||
break
|
||||
else:
|
||||
raise admintool.ScriptError(
|
||||
@@ -304,15 +330,20 @@ def run(self):
|
||||
|
||||
self.backends = [options.backend]
|
||||
|
||||
+ missing_backends = []
|
||||
for instance, backend in itertools.product(self.instances,
|
||||
self.backends):
|
||||
db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
||||
- (instance, backend))
|
||||
- if os.path.exists(db_dir):
|
||||
- break
|
||||
- else:
|
||||
+ (instance, ""))
|
||||
+ backends = get_backends(db_dir)
|
||||
+ if backend.lower() not in backends:
|
||||
+ missing_backends.append(backend)
|
||||
+
|
||||
+ if missing_backends:
|
||||
raise admintool.ScriptError(
|
||||
- "Cannot restore a data backup into an empty system")
|
||||
+ "Cannot restore a data backup into an empty system. "
|
||||
+ "Missing backend(s) %s" % ', '.join(missing_backends)
|
||||
+ )
|
||||
|
||||
logger.info("Performing %s restore from %s backup",
|
||||
restore_type, self.backup_type)
|
169
freeipa.spec
169
freeipa.spec
@ -70,7 +70,7 @@
|
||||
%global krb5_kdb_version 9.0
|
||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||
%global python_netaddr_version 0.7.19
|
||||
%global samba_version 4.17.4-101
|
||||
%global samba_version 4.20.0
|
||||
%global slapi_nis_version 0.56.4
|
||||
%global python_ldap_version 3.1.0-1
|
||||
%if 0%{?rhel} < 9
|
||||
@ -111,9 +111,14 @@
|
||||
# fix for segfault in python3-ldap, https://pagure.io/freeipa/issue/7324
|
||||
%global python_ldap_version 3.1.0-1
|
||||
|
||||
# 389-ds-base version that fixes a number of crashes and performance issues
|
||||
# https://bodhi.fedoraproject.org/updates/FEDORA-2023-9133b9b669
|
||||
%global ds_version 2.4.3-1
|
||||
# Make sure to use 389-ds-base versions that fix https://github.com/389ds/389-ds-base/issues/4700
|
||||
# and has DNA interval enabled
|
||||
# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility
|
||||
%if 0%{?fedora} < 34
|
||||
%global ds_version 1.4.4.16-1
|
||||
%else
|
||||
%global ds_version 2.1.0
|
||||
%endif
|
||||
|
||||
# Fix for TLS 1.3 PHA, RHBZ#1775146
|
||||
%global httpd_version 2.4.41-9
|
||||
@ -150,7 +155,7 @@
|
||||
%endif
|
||||
|
||||
# RHEL 8.3+, F32+ has 0.79.13
|
||||
%global certmonger_version 0.79.7-3
|
||||
%global certmonger_version 0.79.17-1
|
||||
|
||||
# RHEL 8.2+, F32+ has 3.58
|
||||
%global nss_version 3.44.0-4
|
||||
@ -187,7 +192,7 @@
|
||||
|
||||
# Work-around fact that RPM SPEC parser does not accept
|
||||
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
|
||||
%define IPA_VERSION 4.11.1
|
||||
%define IPA_VERSION 4.12.0
|
||||
# Release candidate version -- uncomment with one percent for RC versions
|
||||
#%%global rc_version
|
||||
%define AT_SIGN @
|
||||
@ -200,7 +205,7 @@
|
||||
|
||||
Name: %{package_name}
|
||||
Version: %{IPA_VERSION}
|
||||
Release: 4%{?rc_version:.%rc_version}%{?dist}
|
||||
Release: 1%{?rc_version:.%rc_version}%{?dist}
|
||||
Summary: The Identity, Policy and Audit system
|
||||
|
||||
License: GPL-3.0-or-later
|
||||
@ -219,19 +224,6 @@ Source1: https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers
|
||||
Source2: gpgkey-0E63D716D76AC080A4A33513F40800B6298EB963.asc
|
||||
%endif
|
||||
|
||||
Patch0001: freeipa-4.11-samba-changes.patch
|
||||
Patch0002: freeipa-4.11-pki-revocation-changes.patch
|
||||
Patch0003: freeipa-4.11-py3.12-timezone-changes.patch
|
||||
Patch0004: freeipa-4.11-pwpolicy-minlength.patch
|
||||
Patch0005: 0009-host-keytab-permission.patch
|
||||
Patch0006: 0008-netbios-defaults.patch
|
||||
Patch0009: 0005-pyca-42.0.0-support.patch
|
||||
Patch0010: 0004-ipa-cli-krb5-crash.patch
|
||||
Patch0011: 0003-kdb-memory-leak.patch
|
||||
Patch0012: 0010-support-samba-4.20.patch
|
||||
Patch0013: freeipa-support-389-ds-with-lmdb-backup.patch
|
||||
Patch0014: freeipa-support-389-ds-with-lmdb-restore.patch
|
||||
|
||||
# RHEL spec file only: START: Change branding to IPA and Identity Management
|
||||
# Moved branding logos and background to redhat-logos-ipa-80.4:
|
||||
# header-logo.png, login-screen-background.jpg, login-screen-logo.png,
|
||||
@ -244,7 +236,8 @@ Patch0014: freeipa-support-389-ds-with-lmdb-restore.patch
|
||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||
Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
|
||||
%endif
|
||||
%if 0%{?rhel} == 9
|
||||
%if 0%{?rhel} >= 9
|
||||
Patch0001: 0001-Revert-Replace-netifaces-with-ifaddr.patch
|
||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||
%endif
|
||||
%endif
|
||||
@ -279,6 +272,7 @@ BuildRequires: gettext
|
||||
BuildRequires: gettext-devel
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: python3-setuptools
|
||||
BuildRequires: python3-argcomplete
|
||||
BuildRequires: systemd >= %{systemd_version}
|
||||
# systemd-tmpfiles which is executed from make install requires apache user
|
||||
BuildRequires: httpd
|
||||
@ -555,12 +549,8 @@ Requires: python3-pyasn1 >= 0.3.2-2
|
||||
Requires: python3-sssdconfig >= %{sssd_version}
|
||||
Requires: python3-psutil
|
||||
Requires: rpm-libs
|
||||
%if 0%{?rhel}
|
||||
Requires: python3-urllib3 >= 1.24.2-3
|
||||
%else
|
||||
# For urllib3.util.ssl_match_hostname
|
||||
Requires: python3-urllib3 >= 1.25.8
|
||||
%endif
|
||||
|
||||
%description -n python3-ipaserver
|
||||
IPA is an integrated solution to provide centrally managed Identity (users,
|
||||
@ -704,7 +694,7 @@ Requires: oddjob-mkhomedir
|
||||
Requires: libsss_autofs
|
||||
Requires: autofs
|
||||
Requires: libnfsidmap
|
||||
Requires: nfs-utils
|
||||
Requires: (nfs-utils or nfsv4-client-utils)
|
||||
Requires: sssd-tools >= %{sssd_version}
|
||||
Requires(post): policycoreutils
|
||||
|
||||
@ -863,6 +853,7 @@ Requires: %{name}-common = %{version}-%{release}
|
||||
Requires(pre): python3-ldap >= %{python_ldap_version}
|
||||
Requires: gnupg2
|
||||
Requires: keyutils
|
||||
Requires: python3-argcomplete
|
||||
Requires: python3-cffi
|
||||
Requires: python3-cryptography >= 1.6
|
||||
Requires: python3-dateutil
|
||||
@ -886,12 +877,9 @@ Requires: platform-python-setuptools
|
||||
%else
|
||||
Requires: python3-setuptools
|
||||
%endif
|
||||
%if 0%{?rhel}
|
||||
Requires: python3-urllib3 >= 1.24.2-3
|
||||
%else
|
||||
# For urllib3.util.ssl_match_hostname
|
||||
Requires: python3-urllib3 >= 1.25.8
|
||||
%endif
|
||||
Requires: python3-systemd
|
||||
|
||||
%description -n python3-ipalib
|
||||
IPA is an integrated solution to provide centrally managed Identity (users,
|
||||
@ -983,6 +971,26 @@ Requires(post): selinux-policy-%{selinuxtype}
|
||||
|
||||
%description selinux
|
||||
Custom SELinux policy module for FreeIPA
|
||||
|
||||
%package selinux-nfast
|
||||
Summary: FreeIPA SELinux policy for nCipher nfast HSMs
|
||||
BuildArch: noarch
|
||||
Requires: selinux-policy-%{selinuxtype}
|
||||
Requires(post): selinux-policy-%{selinuxtype}
|
||||
%{?selinux_requires}
|
||||
|
||||
%description selinux-nfast
|
||||
Custom SELinux policy module for nCipher nfast HSMs
|
||||
|
||||
%package selinux-luna
|
||||
Summary: FreeIPA SELinux policy for Thales Luna HSMs
|
||||
BuildArch: noarch
|
||||
Requires: selinux-policy-%{selinuxtype}
|
||||
Requires(post): selinux-policy-%{selinuxtype}
|
||||
%{?selinux_requires}
|
||||
|
||||
%description selinux-luna
|
||||
Custom SELinux policy module for Thales Luna HSMs
|
||||
# with selinux
|
||||
%endif
|
||||
|
||||
@ -1069,6 +1077,17 @@ rm -f %{buildroot}%{_usr}/share/ipa/ui/images/product-name.png
|
||||
%endif
|
||||
# RHEL spec file only: END
|
||||
|
||||
%if ! %{ONLY_CLIENT}
|
||||
%if 0%{?fedora} >= 38
|
||||
# Register CLI tools for bash completion (fedora only)
|
||||
for clitool in ipa-migrate
|
||||
do
|
||||
register-python-argcomplete "${clitool}" > "${clitool}"
|
||||
install -p -m 0644 -D -t '%{buildroot}%{bash_completions_dir}' "${clitool}"
|
||||
done
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%find_lang %{gettext_domain}
|
||||
|
||||
%if ! %{ONLY_CLIENT}
|
||||
@ -1132,6 +1151,10 @@ fi
|
||||
/bin/systemctl reload-or-try-restart oddjobd
|
||||
|
||||
%tmpfiles_create ipa.conf
|
||||
%journal_catalog_update
|
||||
|
||||
%postun server
|
||||
%journal_catalog_update
|
||||
|
||||
%posttrans server
|
||||
# don't execute upgrade and restart of IPA when server is not installed
|
||||
@ -1268,13 +1291,21 @@ if [ $1 -gt 1 ] ; then
|
||||
cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/kdc-ca-bundle.pem
|
||||
cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/ca-bundle.pem
|
||||
fi
|
||||
|
||||
%{__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
|
||||
chmod 0600 /var/log/ipaupgrade.log
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
|
||||
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"
|
||||
# https://pagure.io/freeipa/issue/9536
|
||||
# replace sss_ssh_knownhostsproxy with sss_ssh_knownhosts
|
||||
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
|
||||
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
|
||||
fi
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -1290,17 +1321,75 @@ fi
|
||||
semodule -d ipa_custodia &> /dev/null || true;
|
||||
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2
|
||||
|
||||
%post selinux-nfast
|
||||
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.bz2
|
||||
|
||||
%post selinux-luna
|
||||
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.bz2
|
||||
|
||||
%postun selinux
|
||||
if [ $1 -eq 0 ]; then
|
||||
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}
|
||||
semodule -e ipa_custodia &> /dev/null || true;
|
||||
fi
|
||||
|
||||
%postun selinux-nfast
|
||||
if [ $1 -eq 0 ]; then
|
||||
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-nfast
|
||||
fi
|
||||
|
||||
%postun selinux-luna
|
||||
if [ $1 -eq 0 ]; then
|
||||
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna
|
||||
|
||||
%posttrans selinux
|
||||
%selinux_relabel_post -s %{selinuxtype}
|
||||
# with_selinux
|
||||
%endif
|
||||
|
||||
%triggerin client -- sssd-common < 2.10
|
||||
# Has the client been configured?
|
||||
restore=0
|
||||
test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}')
|
||||
|
||||
if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
|
||||
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
|
||||
# https://pagure.io/freeipa/issue/9536
|
||||
# downgrade sss_ssh_knownhosts with sss_ssh_knownhostsproxy
|
||||
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
|
||||
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
|
||||
fi
|
||||
GLOBALKNOWNHOSTFILE="GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts/"
|
||||
grep -qF '$GLOBALKNOWNHOSTFILE' $SSH_CLIENT_SYSTEM_CONF
|
||||
if [ $? -ne 0 ]; then
|
||||
sed -E --in-place=.orig '/(# IPA-related configuration changes to ssh_config)/a # added by ipa-client update\n'"$GLOBALKNOWNHOSTFILE"'' $SSH_CLIENT_SYSTEM_CONF
|
||||
fi
|
||||
sed -E --in-place=.orig 's/(KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H)/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h/' $SSH_CLIENT_SYSTEM_CONF
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
%triggerin client -- sssd-common >= 2.10
|
||||
# Has the client been configured?
|
||||
restore=0
|
||||
test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}')
|
||||
|
||||
if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
|
||||
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
|
||||
# https://pagure.io/freeipa/issue/9536
|
||||
# upgrade sss_ssh_knownhostsproxy with sss_ssh_knownhosts
|
||||
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
|
||||
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
|
||||
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
|
||||
fi
|
||||
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
|
||||
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
%triggerin client -- openssh-server < 8.2
|
||||
# Has the client been configured?
|
||||
@ -1399,6 +1488,10 @@ fi
|
||||
%{_sbindir}/ipa-crlgen-manage
|
||||
%{_sbindir}/ipa-cert-fix
|
||||
%{_sbindir}/ipa-acme-manage
|
||||
%{_sbindir}/ipa-migrate
|
||||
%if 0%{?fedora} >= 38
|
||||
%{bash_completions_dir}/ipa-migrate
|
||||
%endif
|
||||
%{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit
|
||||
%{_libexecdir}/certmonger/ipa-server-guard
|
||||
%dir %{_libexecdir}/ipa
|
||||
@ -1431,6 +1524,7 @@ fi
|
||||
%attr(644,root,root) %{_unitdir}/ipa-otpd@.service
|
||||
%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.service
|
||||
%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.timer
|
||||
%attr(644,root,root) %{_journalcatalogdir}/ipa.catalog
|
||||
# END
|
||||
%attr(755,root,root) %{plugin_dir}/libipa_pwd_extop.so
|
||||
%attr(755,root,root) %{plugin_dir}/libipa_enrollment_extop.so
|
||||
@ -1473,6 +1567,7 @@ fi
|
||||
%{_mandir}/man1/ipa-crlgen-manage.1*
|
||||
%{_mandir}/man1/ipa-cert-fix.1*
|
||||
%{_mandir}/man1/ipa-acme-manage.1*
|
||||
%{_mandir}/man1/ipa-migrate.1*
|
||||
|
||||
|
||||
%files -n python3-ipaserver
|
||||
@ -1747,10 +1842,22 @@ fi
|
||||
%files selinux
|
||||
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
|
||||
|
||||
%files selinux-nfast
|
||||
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.*
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-nfast
|
||||
|
||||
%files selinux-luna
|
||||
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.*
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-luna
|
||||
# with selinux
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Jun 04 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.0-1
|
||||
- Resolves: RHEL-39144 Rebase ipa to the latest 4.12 version for RHEL 10
|
||||
- Resolves: RHEL-30537 ipa: freeipa: argument injection into the username field of the /ipa/session/login_password requests
|
||||
|
||||
* Thu Feb 22 2024 Troy Dawson <tdawson@redhat.com> - 4.11.1-4
|
||||
- Bump release to rebuild on correct samba
|
||||
|
||||
|
4
sources
4
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (freeipa-4.11.1.tar.gz) = 65c3ccc8a6da71b2bad3efdf9e798b0d65e6d1e2c3a6ed6617ab86d7e8a5fa01ba2787714a3004b01e35fe087f464e0ae22d0fe4b254956262e7d96d61b1e84d
|
||||
SHA512 (freeipa-4.11.1.tar.gz.asc) = 31157e852653681d3914aebc4b98babf16c4131f647ed6b4c2b49d07f50ac393f54fb1a9d9fcbcf6772eccf5bae7331912ad3e3508bf8cac7d7e74c676bdbc60
|
||||
SHA512 (freeipa-4.12.0.tar.gz) = 1e95250a6892e85b4782a1f2451a99d21c90ce82db2be369d9e0e1706575229d4539b20f8dd2b97da0d6f73f4fb59168ab6e05eb2fe185b4bb854f42c1e7fd29
|
||||
SHA512 (freeipa-4.12.0.tar.gz.asc) = 896170fee005acc3cf46b22053d9f0f0e75f0af31af5c9fbd993674dc26549e479ea3468412ff35f947f7cf42bb7b9bf96f1ead21d754eec92a27b30d731dbe1
|
||||
|
Loading…
Reference in New Issue
Block a user