ipa/SOURCES/0024-ipa-kdb-postpone-ticke...

270 lines
8.5 KiB
Diff

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