import OL ipa-4.10.1-7.0.1.el9_2

This commit is contained in:
Andrew Lukoshko 2023-06-22 15:16:50 +00:00
parent 8d6169b43d
commit 290fb9e114
3 changed files with 855 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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