import OL ipa-4.10.1-7.0.1.el9_2
This commit is contained in:
parent
8d6169b43d
commit
290fb9e114
@ -0,0 +1,574 @@
|
||||
From 51c378f66fcf59322a0774a6d9b37e7e9ac55a17 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 7 Apr 2023 17:04:06 +0200
|
||||
Subject: [PATCH] Tolerate absence of PAC ticket signature depending of server
|
||||
capabilities
|
||||
|
||||
Since November 2020, Active Directory KDC generates a new type of
|
||||
signature as part of the PAC. It is called "ticket signature", and is
|
||||
generated based on the encrypted part of the ticket. The presence of
|
||||
this signature is not mandatory in order for the PAC to be accepted for
|
||||
S4U requests.
|
||||
|
||||
However, the behavior is different for MIT krb5. Support was added as
|
||||
part of the 1.20 release, and this signature is required in order to
|
||||
process S4U requests. Contrary to the PAC extended KDC signature, the
|
||||
code generating this signature cannot be isolated and backported to
|
||||
older krb5 versions because this version of the KDB API does not allow
|
||||
passing the content of the ticket's encrypted part to IPA.
|
||||
|
||||
This is an issue in gradual upgrade scenarios where some IPA servers
|
||||
rely on 1.19 and older versions of MIT krb5, while others use version
|
||||
1.20 or newer. A service ticket that was provided by 1.19- IPA KDC will
|
||||
be rejected when used by a service against a 1.20+ IPA KDC for S4U
|
||||
requests.
|
||||
|
||||
On Fedora, CentOS 9 Stream, and RHEL 9, when the krb5 version is 1.20 or
|
||||
newer, it will include a downstream-only update adding the
|
||||
"optional_pac_tkt_chksum" KDB string attribute allowing to tolerate the
|
||||
absence of PAC ticket signatures, if necessary.
|
||||
|
||||
This commit adds an extra step during the installation and update
|
||||
processes where it adds a "pacTktSignSupported" ipaConfigString
|
||||
attribute in "cn=KDC,cn=[server],cn=masters,cn=ipa,cn=etc,[basedn]" if
|
||||
the MIT krb5 version IPA what built with was 1.20 or newer.
|
||||
|
||||
This commit also set "optional_pac_tkt_chksum" as a virtual KDB entry
|
||||
attribute. This means the value of the attribute is not actually stored
|
||||
in the database (to avoid race conditions), but its value is determined
|
||||
at the KDC starting time by search the "pacTktSignSupported"
|
||||
ipaConfigString in the server list. If this value is missing for at
|
||||
least of them is missing, enforcement of the PAC ticket signature is
|
||||
disabled by setting "optional_pac_tkt_chksum" to true for the local
|
||||
realm TGS KDB entry.
|
||||
|
||||
For foreign realm TGS KDB entries, the "optional_pac_tkt_chksum" virtual
|
||||
string attribute is set to true systematically, because, at least for
|
||||
now, trusted AD domains can still have PAC ticket signature support
|
||||
disabled.
|
||||
|
||||
Given the fact the "pacTktSignSupported" ipaConfigString for a single
|
||||
server is added when this server is updated, and that the value of
|
||||
"optional_pac_tkt_chksum" is determined at KDC starting time based on
|
||||
the ipaConfigString attributes of all the KDCs in the domain, this
|
||||
requires to restart all the KDCs in the domain after all IPA servers
|
||||
were updated in order for PAC ticket signature enforcement to actually
|
||||
take effect.
|
||||
|
||||
Fixes: https://pagure.io/freeipa/issue/9371
|
||||
Signed-off-by: Julien Rische <jrische@redhat.com>
|
||||
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||||
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
(cherry picked from commit bbe545ff9feb972e549c743025e4a26b14ef8f89)
|
||||
---
|
||||
VERSION.m4 | 6 ++
|
||||
configure.ac | 1 +
|
||||
daemons/ipa-kdb/ipa_kdb.c | 55 +++++++++++
|
||||
daemons/ipa-kdb/ipa_kdb.h | 1 +
|
||||
daemons/ipa-kdb/ipa_kdb_principals.c | 139 +++++++++++++++++++++++----
|
||||
ipapython/Makefile.am | 15 +--
|
||||
ipapython/version.py.in | 4 +
|
||||
ipaserver/install/krbinstance.py | 25 ++++-
|
||||
ipaserver/install/server/upgrade.py | 5 +
|
||||
ipaserver/masters.py | 2 +
|
||||
10 files changed, 225 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/VERSION.m4 b/VERSION.m4
|
||||
index e5d60c4c3..9b727feca 100644
|
||||
--- a/VERSION.m4
|
||||
+++ b/VERSION.m4
|
||||
@@ -137,6 +137,11 @@ ifelse(IPA_VERSION_IS_GIT_SNAPSHOT, yes,
|
||||
IPA_GIT_VERSION),
|
||||
NEWLINE)) dnl IPA_VERSION end
|
||||
|
||||
+########################################################
|
||||
+# Version of MIT krb5 used to build IPA
|
||||
+########################################################
|
||||
+define(IPA_KRB5_BUILD_VERSION, translit(esyscmd(krb5-config --version | awk '{ print $NF }'), NEWLINE))
|
||||
+
|
||||
dnl DEBUG: uncomment following lines and run command m4 VERSION.m4
|
||||
dnl `IPA_VERSION: ''IPA_VERSION'
|
||||
dnl `IPA_GIT_VERSION: ''IPA_GIT_VERSION'
|
||||
@@ -144,3 +149,4 @@ dnl `IPA_GIT_BRANCH: ''IPA_GIT_BRANCH'
|
||||
dnl `IPA_API_VERSION: ''IPA_API_VERSION'
|
||||
dnl `IPA_DATA_VERSION: ''IPA_DATA_VERSION'
|
||||
dnl `IPA_NUM_VERSION: ''IPA_NUM_VERSION'
|
||||
+dnl `IPA_KRB5_BUILD_VERSION: ''IPA_KRB5_BUILD_VERSION'
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 140045821..973cba33c 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -460,6 +460,7 @@ AC_SUBST(VENDOR_SUFFIX)
|
||||
AC_SUBST([VERSION], [IPA_VERSION])
|
||||
AC_SUBST([GIT_VERSION], [IPA_GIT_VERSION])
|
||||
AC_SUBST([GIT_BRANCH], [IPA_GIT_BRANCH])
|
||||
+AC_SUBST([KRB5_BUILD_VERSION], [IPA_KRB5_BUILD_VERSION])
|
||||
# used by Makefile.am for files depending on templates
|
||||
AC_SUBST([CONFIG_STATUS])
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
|
||||
index 93563536c..9a56640ff 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb.c
|
||||
@@ -524,6 +524,52 @@ static krb5_principal ipadb_create_local_tgs(krb5_context kcontext,
|
||||
return tgtp;
|
||||
}
|
||||
|
||||
+static char *no_attrs[] = {
|
||||
+ LDAP_NO_ATTRS,
|
||||
+
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static krb5_error_code
|
||||
+should_support_pac_tkt_sign(krb5_context kcontext, bool *result)
|
||||
+{
|
||||
+ struct ipadb_context *ipactx;
|
||||
+ krb5_error_code kerr;
|
||||
+ LDAPMessage *res = NULL;
|
||||
+ char *masters_dn = NULL;
|
||||
+ int count;
|
||||
+
|
||||
+ char *kdc_filter = "(&(cn=KDC)(objectClass=ipaConfigObject)"
|
||||
+ "(!(ipaConfigString=pacTktSignSupported)))";
|
||||
+
|
||||
+ ipactx = ipadb_get_context(kcontext);
|
||||
+ if (!ipactx) {
|
||||
+ kerr = KRB5_KDB_DBNOTINITED;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ count = asprintf(&masters_dn, "cn=masters,cn=ipa,cn=etc,%s", ipactx->base);
|
||||
+ if (count < 0) {
|
||||
+ kerr = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = ipadb_simple_search(ipactx, masters_dn, LDAP_SCOPE_SUBTREE,
|
||||
+ kdc_filter, no_attrs, &res);
|
||||
+ if (kerr)
|
||||
+ goto done;
|
||||
+
|
||||
+ count = ldap_count_entries(ipactx->lcontext, res);
|
||||
+
|
||||
+ if (result)
|
||||
+ *result = (count == 0);
|
||||
+
|
||||
+done:
|
||||
+ free(masters_dn);
|
||||
+ ldap_msgfree(res);
|
||||
+ return kerr;
|
||||
+}
|
||||
+
|
||||
/* INTERFACE */
|
||||
|
||||
static krb5_error_code ipadb_init_library(void)
|
||||
@@ -544,6 +590,7 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
|
||||
krb5_error_code kerr;
|
||||
int ret;
|
||||
int i;
|
||||
+ bool pac_tkt_sign_supported;
|
||||
|
||||
/* make sure the context is freed to avoid leaking it */
|
||||
ipactx = ipadb_get_context(kcontext);
|
||||
@@ -628,6 +675,14 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ /* Enforce PAC ticket signature verification if supported by all KDCs */
|
||||
+ kerr = should_support_pac_tkt_sign(kcontext, &pac_tkt_sign_supported);
|
||||
+ if (kerr) {
|
||||
+ ret = kerr;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ ipactx->optional_pac_tkt_chksum = !pac_tkt_sign_supported;
|
||||
+
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
|
||||
index 7aa5be494..0f4d3e431 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb.h
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb.h
|
||||
@@ -143,6 +143,7 @@ struct ipadb_context {
|
||||
krb5_key_salt_tuple *def_encs;
|
||||
int n_def_encs;
|
||||
struct ipadb_mspac *mspac;
|
||||
+ bool optional_pac_tkt_chksum;
|
||||
#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
|
||||
krb5_certauth_moddata certauth_moddata;
|
||||
#endif
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
index e95cb453c..e6c3fba21 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
@@ -113,6 +113,8 @@ static char *std_principal_obj_classes[] = {
|
||||
|
||||
#define DEFAULT_TL_DATA_CONTENT "\x00\x00\x00\x00principal@UNINITIALIZED"
|
||||
|
||||
+#define OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME "optional_pac_tkt_chksum"
|
||||
+
|
||||
static int ipadb_ldap_attr_to_tl_data(LDAP *lcontext, LDAPMessage *le,
|
||||
char *attrname,
|
||||
krb5_tl_data **result, int *num)
|
||||
@@ -178,10 +180,56 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static krb5_error_code ipadb_set_tl_data(krb5_db_entry *entry,
|
||||
- krb5_int16 type,
|
||||
- krb5_ui_2 length,
|
||||
- const krb5_octet *data)
|
||||
+static bool
|
||||
+is_tgs_princ(krb5_context kcontext, krb5_const_principal princ)
|
||||
+{
|
||||
+ krb5_data *primary;
|
||||
+ size_t l_tgs_name;
|
||||
+
|
||||
+ if (2 != krb5_princ_size(kcontext, princ))
|
||||
+ return false;
|
||||
+
|
||||
+ primary = krb5_princ_component(kcontext, princ, 0);
|
||||
+
|
||||
+ l_tgs_name = strlen(KRB5_TGS_NAME);
|
||||
+
|
||||
+ if (l_tgs_name != primary->length)
|
||||
+ return false;
|
||||
+
|
||||
+ return 0 == memcmp(primary->data, KRB5_TGS_NAME, l_tgs_name);
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+cmp_local_tgs_princ(krb5_context kcontext, const char *local_realm,
|
||||
+ krb5_const_principal princ, bool *result)
|
||||
+{
|
||||
+ krb5_principal local_tgs_princ;
|
||||
+ size_t l_local_realm;
|
||||
+ krb5_error_code kerr;
|
||||
+ bool res;
|
||||
+
|
||||
+ l_local_realm = strlen(local_realm);
|
||||
+
|
||||
+ kerr = krb5_build_principal(kcontext, &local_tgs_princ,
|
||||
+ l_local_realm, local_realm,
|
||||
+ KRB5_TGS_NAME, local_realm, NULL);
|
||||
+ if (kerr)
|
||||
+ goto end;
|
||||
+
|
||||
+ res = (bool) krb5_principal_compare(kcontext, local_tgs_princ, princ);
|
||||
+
|
||||
+ if (result)
|
||||
+ *result = res;
|
||||
+
|
||||
+end:
|
||||
+ krb5_free_principal(kcontext, local_tgs_princ);
|
||||
+ return kerr;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code ipadb_set_tl_data(krb5_db_entry *entry,
|
||||
+ krb5_int16 type,
|
||||
+ krb5_ui_2 length,
|
||||
+ const krb5_octet *data)
|
||||
{
|
||||
krb5_error_code kerr;
|
||||
krb5_tl_data *new_td = NULL;
|
||||
@@ -1632,6 +1680,8 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
krb5_db_entry **entry)
|
||||
{
|
||||
struct ipadb_context *ipactx;
|
||||
+ bool is_local_tgs_princ;
|
||||
+ const char *opt_pac_tkt_chksum_val;
|
||||
krb5_error_code kerr;
|
||||
|
||||
*entry = NULL;
|
||||
@@ -1647,11 +1697,33 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
|
||||
/* Lookup local names and aliases first. */
|
||||
kerr = dbget_princ(kcontext, ipactx, search_for, flags, entry);
|
||||
- if (kerr != KRB5_KDB_NOENTRY) {
|
||||
+ if (kerr == KRB5_KDB_NOENTRY) {
|
||||
+ kerr = dbget_alias(kcontext, ipactx, search_for, flags, entry);
|
||||
+ }
|
||||
+ if (kerr)
|
||||
return kerr;
|
||||
+
|
||||
+ /* If TGS principal, some virtual attributes may be added */
|
||||
+ if (is_tgs_princ(kcontext, (*entry)->princ)) {
|
||||
+ kerr = cmp_local_tgs_princ(kcontext, ipactx->realm, (*entry)->princ,
|
||||
+ &is_local_tgs_princ);
|
||||
+ if (kerr)
|
||||
+ return kerr;
|
||||
+
|
||||
+ /* PAC ticket signature should be optional for foreign realms, and local
|
||||
+ * realm if not supported by all servers
|
||||
+ */
|
||||
+ if (!is_local_tgs_princ || ipactx->optional_pac_tkt_chksum)
|
||||
+ opt_pac_tkt_chksum_val = "true";
|
||||
+ else
|
||||
+ opt_pac_tkt_chksum_val = "false";
|
||||
+
|
||||
+ kerr = krb5_dbe_set_string(kcontext, *entry,
|
||||
+ OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ opt_pac_tkt_chksum_val);
|
||||
}
|
||||
|
||||
- return dbget_alias(kcontext, ipactx, search_for, flags, entry);
|
||||
+ return kerr;
|
||||
}
|
||||
|
||||
void ipadb_free_principal_e_data(krb5_context kcontext, krb5_octet *e_data)
|
||||
@@ -1954,6 +2026,20 @@ done:
|
||||
return kerr;
|
||||
}
|
||||
|
||||
+static bool should_filter_out_attr(krb5_tl_data *data)
|
||||
+{
|
||||
+ switch (data->tl_data_type) {
|
||||
+ case KRB5_TL_DB_ARGS:
|
||||
+ case KRB5_TL_KADM_DATA:
|
||||
+ case KRB5_TL_LAST_ADMIN_UNLOCK:
|
||||
+ case KRB5_TL_LAST_PWD_CHANGE:
|
||||
+ case KRB5_TL_MKVNO:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static krb5_error_code ipadb_get_ldap_mod_extra_data(struct ipadb_mods *imods,
|
||||
krb5_tl_data *tl_data,
|
||||
int mod_op)
|
||||
@@ -1965,13 +2051,8 @@ static krb5_error_code ipadb_get_ldap_mod_extra_data(struct ipadb_mods *imods,
|
||||
int n, i;
|
||||
|
||||
for (n = 0, data = tl_data; data; data = data->tl_data_next) {
|
||||
- if (data->tl_data_type == KRB5_TL_LAST_PWD_CHANGE ||
|
||||
- data->tl_data_type == KRB5_TL_KADM_DATA ||
|
||||
- data->tl_data_type == KRB5_TL_DB_ARGS ||
|
||||
- data->tl_data_type == KRB5_TL_MKVNO ||
|
||||
- data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) {
|
||||
+ if (should_filter_out_attr(data))
|
||||
continue;
|
||||
- }
|
||||
n++;
|
||||
}
|
||||
|
||||
@@ -1987,13 +2068,8 @@ static krb5_error_code ipadb_get_ldap_mod_extra_data(struct ipadb_mods *imods,
|
||||
|
||||
for (i = 0, data = tl_data; data; data = data->tl_data_next) {
|
||||
|
||||
- if (data->tl_data_type == KRB5_TL_LAST_PWD_CHANGE ||
|
||||
- data->tl_data_type == KRB5_TL_KADM_DATA ||
|
||||
- data->tl_data_type == KRB5_TL_DB_ARGS ||
|
||||
- data->tl_data_type == KRB5_TL_MKVNO ||
|
||||
- data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) {
|
||||
+ if (should_filter_out_attr(data))
|
||||
continue;
|
||||
- }
|
||||
|
||||
be_type = htons(data->tl_data_type);
|
||||
|
||||
@@ -2745,10 +2821,37 @@ done:
|
||||
return kerr;
|
||||
}
|
||||
|
||||
+static krb5_error_code
|
||||
+remove_virtual_str_attrs(krb5_context kcontext, krb5_db_entry *entry)
|
||||
+{
|
||||
+ char *str_attr_val;
|
||||
+ krb5_error_code kerr;
|
||||
+
|
||||
+ kerr = krb5_dbe_get_string(kcontext, entry,
|
||||
+ OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ &str_attr_val);
|
||||
+ if (kerr)
|
||||
+ return kerr;
|
||||
+
|
||||
+ if (str_attr_val)
|
||||
+ kerr = krb5_dbe_set_string(kcontext, entry,
|
||||
+ OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ NULL);
|
||||
+
|
||||
+ krb5_dbe_free_string(kcontext, str_attr_val);
|
||||
+ return kerr;
|
||||
+}
|
||||
+
|
||||
krb5_error_code ipadb_put_principal(krb5_context kcontext,
|
||||
krb5_db_entry *entry,
|
||||
char **db_args)
|
||||
{
|
||||
+ krb5_error_code kerr;
|
||||
+
|
||||
+ kerr = remove_virtual_str_attrs(kcontext, entry);
|
||||
+ if (kerr)
|
||||
+ return kerr;
|
||||
+
|
||||
if (entry->mask & KMASK_PRINCIPAL) {
|
||||
return ipadb_add_principal(kcontext, entry);
|
||||
} else {
|
||||
diff --git a/ipapython/Makefile.am b/ipapython/Makefile.am
|
||||
index 7038e8b57..6b336d8fe 100644
|
||||
--- a/ipapython/Makefile.am
|
||||
+++ b/ipapython/Makefile.am
|
||||
@@ -13,11 +13,12 @@ bdist_wheel: version.py
|
||||
$(AM_V_GEN)awk '$$1 == "default:" { print $$2 }' $< >$@
|
||||
|
||||
version.py: version.py.in .DEFAULT_PLUGINS $(top_builddir)/$(CONFIG_STATUS)
|
||||
- $(AM_V_GEN)sed \
|
||||
- -e 's|@API_VERSION[@]|$(API_VERSION)|g' \
|
||||
- -e 's|@NUM_VERSION[@]|$(NUM_VERSION)|g' \
|
||||
- -e 's|@VERSION[@]|$(VERSION)|g' \
|
||||
- -e 's|@VENDOR_SUFFIX[@]|$(VENDOR_SUFFIX)|g' \
|
||||
- -e '/@DEFAULT_PLUGINS[@]/r .DEFAULT_PLUGINS' \
|
||||
- -e '/@DEFAULT_PLUGINS[@]/d' \
|
||||
+ $(AM_V_GEN)sed \
|
||||
+ -e 's|@API_VERSION[@]|$(API_VERSION)|g' \
|
||||
+ -e 's|@NUM_VERSION[@]|$(NUM_VERSION)|g' \
|
||||
+ -e 's|@VERSION[@]|$(VERSION)|g' \
|
||||
+ -e 's|@VENDOR_SUFFIX[@]|$(VENDOR_SUFFIX)|g' \
|
||||
+ -e 's|@KRB5_BUILD_VERSION[@]|$(KRB5_BUILD_VERSION)|g' \
|
||||
+ -e '/@DEFAULT_PLUGINS[@]/r .DEFAULT_PLUGINS' \
|
||||
+ -e '/@DEFAULT_PLUGINS[@]/d' \
|
||||
$< > $@
|
||||
diff --git a/ipapython/version.py.in b/ipapython/version.py.in
|
||||
index 5a71fb8cf..a8f4218a7 100644
|
||||
--- a/ipapython/version.py.in
|
||||
+++ b/ipapython/version.py.in
|
||||
@@ -17,6 +17,8 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
+from pkg_resources import parse_version
|
||||
+
|
||||
# The full version including strings
|
||||
VERSION = "@VERSION@"
|
||||
|
||||
@@ -51,3 +53,5 @@ API_VERSION = "@API_VERSION@"
|
||||
DEFAULT_PLUGINS = frozenset(l.strip() for l in """
|
||||
@DEFAULT_PLUGINS@
|
||||
""".strip().splitlines())
|
||||
+
|
||||
+KRB5_BUILD_VERSION = parse_version("@KRB5_BUILD_VERSION@")
|
||||
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
|
||||
index a5eaa7b17..acb7419d6 100644
|
||||
--- a/ipaserver/install/krbinstance.py
|
||||
+++ b/ipaserver/install/krbinstance.py
|
||||
@@ -26,6 +26,7 @@ import socket
|
||||
import dbus
|
||||
|
||||
import dns.name
|
||||
+from pkg_resources import parse_version
|
||||
|
||||
from ipalib import x509
|
||||
from ipalib.install import certstore
|
||||
@@ -34,6 +35,7 @@ from ipaserver.install import installutils
|
||||
from ipapython import ipaldap
|
||||
from ipapython import ipautil
|
||||
from ipapython import kernel_keyring
|
||||
+from ipapython.version import KRB5_BUILD_VERSION
|
||||
from ipalib import api, errors
|
||||
from ipalib.constants import ANON_USER
|
||||
from ipalib.install import certmonger
|
||||
@@ -42,15 +44,17 @@ from ipapython.dogtag import KDC_PROFILE
|
||||
|
||||
from ipaserver.install import replication
|
||||
from ipaserver.install import certs
|
||||
-from ipaserver.masters import find_providing_servers
|
||||
+from ipaserver.masters import (
|
||||
+ find_providing_servers,
|
||||
+ PAC_TKT_SIGN_SUPPORTED,
|
||||
+ PKINIT_ENABLED,
|
||||
+)
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.tasks import tasks
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
-PKINIT_ENABLED = 'pkinitEnabled'
|
||||
-
|
||||
MASTER_KEY_TYPE = 'aes256-sha2'
|
||||
SUPPORTED_ENCTYPES = ('aes256-sha2:special', 'aes128-sha2:special',
|
||||
'aes256-sha2:normal', 'aes128-sha2:normal',
|
||||
@@ -169,6 +173,13 @@ class KrbInstance(service.Service):
|
||||
# Add the host to the ipaserver host group
|
||||
self._ldap_update(['20-ipaservers_hostgroup.update'])
|
||||
|
||||
+ def pac_tkt_sign_support_enable(self):
|
||||
+ """
|
||||
+ Advertise PAC ticket signature support in master's KDC entry in LDAP
|
||||
+ """
|
||||
+ service.set_service_entry_config(
|
||||
+ 'KDC', self.fqdn, [PAC_TKT_SIGN_SUPPORTED], self.suffix)
|
||||
+
|
||||
def __common_setup(self, realm_name, host_name, domain_name, admin_password):
|
||||
self.fqdn = host_name
|
||||
self.realm = realm_name.upper()
|
||||
@@ -212,6 +223,10 @@ class KrbInstance(service.Service):
|
||||
|
||||
self.__common_post_setup()
|
||||
|
||||
+ if KRB5_BUILD_VERSION >= parse_version('1.20'):
|
||||
+ self.step("enable PAC ticket signature support",
|
||||
+ self.pac_tkt_sign_support_enable)
|
||||
+
|
||||
self.start_creation()
|
||||
|
||||
self.kpasswd = KpasswdInstance()
|
||||
@@ -235,6 +250,10 @@ class KrbInstance(service.Service):
|
||||
|
||||
self.__common_post_setup()
|
||||
|
||||
+ if KRB5_BUILD_VERSION >= parse_version('1.20'):
|
||||
+ self.step("enable PAC ticket signature support",
|
||||
+ self.pac_tkt_sign_support_enable)
|
||||
+
|
||||
self.start_creation()
|
||||
|
||||
self.kpasswd = KpasswdInstance()
|
||||
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
|
||||
index 5f5a60d10..f8701c8a0 100644
|
||||
--- a/ipaserver/install/server/upgrade.py
|
||||
+++ b/ipaserver/install/server/upgrade.py
|
||||
@@ -18,6 +18,7 @@ import sys
|
||||
import tempfile
|
||||
from contextlib import contextmanager
|
||||
from augeas import Augeas
|
||||
+from pkg_resources import parse_version
|
||||
|
||||
from ipalib import api, x509
|
||||
from ipalib.constants import RENEWAL_CA_NAME, RA_AGENT_PROFILE, IPA_CA_RECORD
|
||||
@@ -36,6 +37,7 @@ from ipapython import ipautil, version
|
||||
from ipapython import ipaldap
|
||||
from ipapython import directivesetter
|
||||
from ipapython.dn import DN
|
||||
+from ipapython.version import KRB5_BUILD_VERSION
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.paths import paths
|
||||
from ipaserver import servroles
|
||||
@@ -1961,6 +1963,9 @@ def upgrade_configuration():
|
||||
enable_server_snippet()
|
||||
setup_kpasswd_server(krb)
|
||||
|
||||
+ if KRB5_BUILD_VERSION >= parse_version('1.20'):
|
||||
+ krb.pac_tkt_sign_support_enable()
|
||||
+
|
||||
# Must be executed after certificate_renewal_update
|
||||
# (see function docstring for details)
|
||||
http_certificate_ensure_ipa_ca_dnsname(http)
|
||||
diff --git a/ipaserver/masters.py b/ipaserver/masters.py
|
||||
index b532f2b72..c9b57b2a5 100644
|
||||
--- a/ipaserver/masters.py
|
||||
+++ b/ipaserver/masters.py
|
||||
@@ -20,6 +20,8 @@ logger = logging.getLogger(__name__)
|
||||
CONFIGURED_SERVICE = u'configuredService'
|
||||
ENABLED_SERVICE = u'enabledService'
|
||||
HIDDEN_SERVICE = u'hiddenService'
|
||||
+PAC_TKT_SIGN_SUPPORTED = u'pacTktSignSupported'
|
||||
+PKINIT_ENABLED = u'pkinitEnabled'
|
||||
|
||||
# The service name as stored in cn=masters,cn=ipa,cn=etc. The values are:
|
||||
# 0: systemd service name
|
||||
--
|
||||
2.39.2
|
||||
|
@ -0,0 +1,269 @@
|
||||
From 33242a967011b9cbce74b6b3c39a7247d66eda19 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Thu, 25 May 2023 09:19:57 +0300
|
||||
Subject: [PATCH] ipa-kdb: postpone ticket checksum configuration
|
||||
|
||||
Postpone ticket checksum configuration after KDB module was initialized.
|
||||
This, in practice, should now happen when a master key is retrieved.
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Reviewed-By: Julien Rische <jrische@redhat.com>
|
||||
(cherry picked from commit fefa0248296413b6ee5ad2543d8feb1b31840aee)
|
||||
---
|
||||
daemons/ipa-kdb/ipa_kdb.c | 56 +----------------------
|
||||
daemons/ipa-kdb/ipa_kdb.h | 8 +++-
|
||||
daemons/ipa-kdb/ipa_kdb_common.c | 67 +++++++++++++++++++++++++++-
|
||||
daemons/ipa-kdb/ipa_kdb_principals.c | 14 ++++--
|
||||
4 files changed, 84 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
|
||||
index 9a56640ff..a3c3746c2 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb.c
|
||||
@@ -524,52 +524,6 @@ static krb5_principal ipadb_create_local_tgs(krb5_context kcontext,
|
||||
return tgtp;
|
||||
}
|
||||
|
||||
-static char *no_attrs[] = {
|
||||
- LDAP_NO_ATTRS,
|
||||
-
|
||||
- NULL
|
||||
-};
|
||||
-
|
||||
-static krb5_error_code
|
||||
-should_support_pac_tkt_sign(krb5_context kcontext, bool *result)
|
||||
-{
|
||||
- struct ipadb_context *ipactx;
|
||||
- krb5_error_code kerr;
|
||||
- LDAPMessage *res = NULL;
|
||||
- char *masters_dn = NULL;
|
||||
- int count;
|
||||
-
|
||||
- char *kdc_filter = "(&(cn=KDC)(objectClass=ipaConfigObject)"
|
||||
- "(!(ipaConfigString=pacTktSignSupported)))";
|
||||
-
|
||||
- ipactx = ipadb_get_context(kcontext);
|
||||
- if (!ipactx) {
|
||||
- kerr = KRB5_KDB_DBNOTINITED;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- count = asprintf(&masters_dn, "cn=masters,cn=ipa,cn=etc,%s", ipactx->base);
|
||||
- if (count < 0) {
|
||||
- kerr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = ipadb_simple_search(ipactx, masters_dn, LDAP_SCOPE_SUBTREE,
|
||||
- kdc_filter, no_attrs, &res);
|
||||
- if (kerr)
|
||||
- goto done;
|
||||
-
|
||||
- count = ldap_count_entries(ipactx->lcontext, res);
|
||||
-
|
||||
- if (result)
|
||||
- *result = (count == 0);
|
||||
-
|
||||
-done:
|
||||
- free(masters_dn);
|
||||
- ldap_msgfree(res);
|
||||
- return kerr;
|
||||
-}
|
||||
-
|
||||
/* INTERFACE */
|
||||
|
||||
static krb5_error_code ipadb_init_library(void)
|
||||
@@ -590,7 +544,6 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
|
||||
krb5_error_code kerr;
|
||||
int ret;
|
||||
int i;
|
||||
- bool pac_tkt_sign_supported;
|
||||
|
||||
/* make sure the context is freed to avoid leaking it */
|
||||
ipactx = ipadb_get_context(kcontext);
|
||||
@@ -662,6 +615,8 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ ipactx->optional_pac_tkt_chksum = IPADB_TRISTATE_UNDEFINED;
|
||||
+
|
||||
ret = ipadb_get_connection(ipactx);
|
||||
if (ret != 0) {
|
||||
/* Not a fatal failure, as the LDAP server may be temporarily down. */
|
||||
@@ -675,13 +630,6 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- /* Enforce PAC ticket signature verification if supported by all KDCs */
|
||||
- kerr = should_support_pac_tkt_sign(kcontext, &pac_tkt_sign_supported);
|
||||
- if (kerr) {
|
||||
- ret = kerr;
|
||||
- goto fail;
|
||||
- }
|
||||
- ipactx->optional_pac_tkt_chksum = !pac_tkt_sign_supported;
|
||||
|
||||
return 0;
|
||||
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
|
||||
index 0f4d3e431..edf3b0dfc 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb.h
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb.h
|
||||
@@ -126,6 +126,12 @@ struct ipadb_global_config {
|
||||
bool disable_preauth_for_spns;
|
||||
};
|
||||
|
||||
+enum ipadb_tristate_option {
|
||||
+ IPADB_TRISTATE_FALSE = FALSE,
|
||||
+ IPADB_TRISTATE_TRUE = TRUE,
|
||||
+ IPADB_TRISTATE_UNDEFINED,
|
||||
+};
|
||||
+
|
||||
#define IPA_CONTEXT_MAGIC 0x0c027ea7
|
||||
struct ipadb_context {
|
||||
int magic;
|
||||
@@ -143,7 +149,7 @@ struct ipadb_context {
|
||||
krb5_key_salt_tuple *def_encs;
|
||||
int n_def_encs;
|
||||
struct ipadb_mspac *mspac;
|
||||
- bool optional_pac_tkt_chksum;
|
||||
+ enum ipadb_tristate_option optional_pac_tkt_chksum;
|
||||
#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
|
||||
krb5_certauth_moddata certauth_moddata;
|
||||
#endif
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_common.c b/daemons/ipa-kdb/ipa_kdb_common.c
|
||||
index 42e0856d0..ae7742a32 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_common.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_common.c
|
||||
@@ -158,12 +158,75 @@ static bool ipadb_need_retry(struct ipadb_context *ipactx, int error)
|
||||
return false;
|
||||
}
|
||||
|
||||
+static char *no_attrs[] = {
|
||||
+ LDAP_NO_ATTRS,
|
||||
+
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+should_support_pac_tkt_sign(struct ipadb_context *ipactx, bool *result)
|
||||
+{
|
||||
+ int ret;
|
||||
+ LDAPMessage *res = NULL;
|
||||
+ char *masters_dn = NULL;
|
||||
+ int count;
|
||||
+
|
||||
+ char *kdc_filter = "(&(cn=KDC)(objectClass=ipaConfigObject)"
|
||||
+ "(!(ipaConfigString=pacTktSignSupported)))";
|
||||
+
|
||||
+ if (!ipactx) {
|
||||
+ ret = KRB5_KDB_DBNOTINITED;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ count = asprintf(&masters_dn, "cn=masters,cn=ipa,cn=etc,%s", ipactx->base);
|
||||
+ if (count < 0) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ipadb_simple_search(ipactx, masters_dn, LDAP_SCOPE_SUBTREE,
|
||||
+ kdc_filter, no_attrs, &res);
|
||||
+ if (ret)
|
||||
+ goto done;
|
||||
+
|
||||
+ count = ldap_count_entries(ipactx->lcontext, res);
|
||||
+
|
||||
+ if (result)
|
||||
+ *result = (count == 0);
|
||||
+
|
||||
+done:
|
||||
+ free(masters_dn);
|
||||
+ ldap_msgfree(res);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int ipadb_check_connection(struct ipadb_context *ipactx)
|
||||
{
|
||||
+ int ret = 0;
|
||||
+
|
||||
if (ipactx->lcontext == NULL) {
|
||||
- return ipadb_get_connection(ipactx);
|
||||
+ ret = ipadb_get_connection(ipactx);
|
||||
+ }
|
||||
+ if ((ret == 0) && (ipactx->optional_pac_tkt_chksum == IPADB_TRISTATE_UNDEFINED)) {
|
||||
+ bool pac_tkt_sign_supported;
|
||||
+
|
||||
+ /* Enforce PAC ticket signature verification if supported by all KDCs
|
||||
+ * To avoid loops as all search functions call into
|
||||
+ * ipadb_check_connection(), mark that the init is complete at this
|
||||
+ * point. Default to not issuing PAC to be safe.
|
||||
+ */
|
||||
+ ipactx->optional_pac_tkt_chksum = IPADB_TRISTATE_FALSE;
|
||||
+ ret = should_support_pac_tkt_sign(ipactx,
|
||||
+ &pac_tkt_sign_supported);
|
||||
+ if (ret == 0) {
|
||||
+ ipactx->optional_pac_tkt_chksum = !pac_tkt_sign_supported;
|
||||
+ } else {
|
||||
+ ipactx->optional_pac_tkt_chksum = IPADB_TRISTATE_UNDEFINED;
|
||||
+ }
|
||||
}
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
krb5_error_code ipadb_simple_search(struct ipadb_context *ipactx,
|
||||
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
index e6c3fba21..d35cec2e0 100644
|
||||
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
|
||||
@@ -113,7 +113,9 @@ static char *std_principal_obj_classes[] = {
|
||||
|
||||
#define DEFAULT_TL_DATA_CONTENT "\x00\x00\x00\x00principal@UNINITIALIZED"
|
||||
|
||||
-#define OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME "optional_pac_tkt_chksum"
|
||||
+#ifndef KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM
|
||||
+#define KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM "optional_pac_tkt_chksum"
|
||||
+#endif
|
||||
|
||||
static int ipadb_ldap_attr_to_tl_data(LDAP *lcontext, LDAPMessage *le,
|
||||
char *attrname,
|
||||
@@ -1710,6 +1712,10 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
if (kerr)
|
||||
return kerr;
|
||||
|
||||
+ /* We should have been initialized at this point already */
|
||||
+ if (ipactx->optional_pac_tkt_chksum == IPADB_TRISTATE_UNDEFINED) {
|
||||
+ return KRB5_KDB_SERVER_INTERNAL_ERR;
|
||||
+ }
|
||||
/* PAC ticket signature should be optional for foreign realms, and local
|
||||
* realm if not supported by all servers
|
||||
*/
|
||||
@@ -1719,7 +1725,7 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
opt_pac_tkt_chksum_val = "false";
|
||||
|
||||
kerr = krb5_dbe_set_string(kcontext, *entry,
|
||||
- OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM,
|
||||
opt_pac_tkt_chksum_val);
|
||||
}
|
||||
|
||||
@@ -2828,14 +2834,14 @@ remove_virtual_str_attrs(krb5_context kcontext, krb5_db_entry *entry)
|
||||
krb5_error_code kerr;
|
||||
|
||||
kerr = krb5_dbe_get_string(kcontext, entry,
|
||||
- OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM,
|
||||
&str_attr_val);
|
||||
if (kerr)
|
||||
return kerr;
|
||||
|
||||
if (str_attr_val)
|
||||
kerr = krb5_dbe_set_string(kcontext, entry,
|
||||
- OPT_PAC_TKT_CHKSUM_STR_ATTR_NAME,
|
||||
+ KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM,
|
||||
NULL);
|
||||
|
||||
krb5_dbe_free_string(kcontext, str_attr_val);
|
||||
--
|
||||
2.39.2
|
||||
|
@ -66,7 +66,7 @@
|
||||
%if 0%{?rhel}
|
||||
%global package_name ipa
|
||||
%global alt_name freeipa
|
||||
%global krb5_version 1.20.1-1
|
||||
%global krb5_version 1.20.1-9
|
||||
%global krb5_kdb_version 9.0
|
||||
# 0.7.16: https://github.com/drkjam/netaddr/issues/71
|
||||
%global python_netaddr_version 0.7.19
|
||||
@ -223,7 +223,7 @@
|
||||
|
||||
Name: %{package_name}
|
||||
Version: %{IPA_VERSION}
|
||||
Release: 6%{?rc_version:.%rc_version}%{?dist}
|
||||
Release: 7%{?rc_version:.%rc_version}.0.1%{?dist}
|
||||
Summary: The Identity, Policy and Audit system
|
||||
|
||||
License: GPLv3+
|
||||
@ -269,6 +269,8 @@ Patch0019: 0019-tests-Add-new-ipa-ca-error-messages-to-IPADNSSystemR.patch
|
||||
Patch0020: 0020-ipatests-tests-for-certificate-pruning.patch
|
||||
Patch0021: 0021-ipatests-ensure-that-ipa-automember-rebuild-prints-a.patch
|
||||
Patch0022: 0022-ipatests-fix-tests-in-TestACMEPrune.patch
|
||||
Patch0023: 0023-Tolerate-absence-of-PAC-ticket-signature-depending-o.patch
|
||||
Patch0024: 0024-ipa-kdb-postpone-ticket-checksum-configuration.patch
|
||||
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
|
||||
%endif
|
||||
%endif
|
||||
@ -1018,7 +1020,8 @@ autoreconf -ivf
|
||||
%{enable_server_option} \
|
||||
%{with_ipatests_option} \
|
||||
%{with_ipa_join_xml_option} \
|
||||
%{linter_options}
|
||||
%{linter_options} \
|
||||
--with-ipaplatform=rhel
|
||||
|
||||
# run build in default dir
|
||||
# -Onone is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1398405
|
||||
@ -1756,6 +1759,12 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jun 21 2023 EL Errata <el-errata_ww@oracle.com> - 4.10.1-7.0.1
|
||||
- Set IPAPLATFORM=rhel when build on Oracle Linux [Orabug: 29516674]
|
||||
|
||||
* Thu Jun 01 2023 Julien Rische <jrische@redhat.com> - 4.10.1-7
|
||||
- Resolves: rhbz#2211389 Handle PAC signatures based on domain and server capabilities
|
||||
|
||||
* Wed Feb 22 2023 Florence Blanc-Renaud <flo@redhat.com> - 4.10.1-6
|
||||
- Resolves: rhbz#2169632 Backport latest test fixes in python3-ipatests
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user