Rebuild against Samba 4.20rc1

Add upstream fixes
- Fix memory leak in Kerberos KDC driver
- Fix possible crash in IPA command line tool when accessing Kerberos credentials
- Compatibility fix for Python Cryptography 42.0.0
- Fix CA affinity when installing replica

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Alexander Bokovoy 2024-01-30 17:40:16 +02:00
parent dc24d637fb
commit f19c883a04
5 changed files with 845 additions and 4 deletions

View File

@ -0,0 +1,91 @@
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

View File

@ -0,0 +1,247 @@
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

View File

@ -0,0 +1,424 @@
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

View File

@ -0,0 +1,69 @@
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

View File

@ -96,9 +96,8 @@
%global alt_name ipa
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
%global python_netaddr_version 0.7.16
# Require 4.7.0 which brings Python 3 bindings
# Require 4.12 which has DsRGetForestTrustInformation access rights fixes
%global samba_version 2:4.12.10
# Require 4.20.0 for libndr4
%global samba_version 2:4.20.0
# 38.28 or later includes passkey-related fixes
%global selinux_policy_version 38.28-1
@ -201,7 +200,7 @@
Name: %{package_name}
Version: %{IPA_VERSION}
Release: 1%{?rc_version:.%rc_version}%{?dist}.2
Release: 2%{?rc_version:.%rc_version}%{?dist}
Summary: The Identity, Policy and Audit system
License: GPL-3.0-or-later
@ -224,6 +223,10 @@ 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: 0003-kdb-memory-leak.patch
Patch0006: 0004-ipa-cli-krb5-crash.patch
Patch0007: 0005-pyca-42.0.0-support.patch
Patch0008: 0006-ca-affinity-fix.patch
# RHEL spec file only: START: Change branding to IPA and Identity Management
# Moved branding logos and background to redhat-logos-ipa-80.4:
@ -1744,6 +1747,13 @@ fi
%endif
%changelog
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.11.1-2
- Rebuild against Samba 4.20rc1
- Fix memory leak in Kerberos KDC driver
- Fix possible crash in IPA command line tool when accessing Kerberos credentials
- Compatibility fix for Python Cryptography 42.0.0
- Fix CA affinity when installing replica
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.11.1-1.2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild