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:
parent
dc24d637fb
commit
f19c883a04
91
0003-kdb-memory-leak.patch
Normal file
91
0003-kdb-memory-leak.patch
Normal 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
|
||||
|
247
0004-ipa-cli-krb5-crash.patch
Normal file
247
0004-ipa-cli-krb5-crash.patch
Normal 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
|
||||
|
424
0005-pyca-42.0.0-support.patch
Normal file
424
0005-pyca-42.0.0-support.patch
Normal 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
|
||||
|
69
0006-ca-affinity-fix.patch
Normal file
69
0006-ca-affinity-fix.patch
Normal 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
|
||||
|
18
freeipa.spec
18
freeipa.spec
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user