summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemons/ipa-kdb/ipa_kdb.c2
-rw-r--r--daemons/ipa-kdb/ipa_kdb.h5
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c63
3 files changed, 68 insertions, 2 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
index 5e4d0474c..c807bbcfa 100644
--- a/daemons/ipa-kdb/ipa_kdb.c
+++ b/daemons/ipa-kdb/ipa_kdb.c
@@ -602,7 +602,7 @@ kdb_vftabl kdb_function_table = {
NULL, /* decrypt_key_data */
NULL, /* encrypt_key_data */
ipadb_sign_authdata, /* sign_authdata */
- NULL, /* check_transited_realms */
+ ipadb_check_transited_realms, /* check_transited_realms */
ipadb_check_policy_as, /* check_policy_as */
NULL, /* check_policy_tgs */
ipadb_audit_as_req, /* audit_as_req */
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index f4d35554c..1c2aefc4a 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -253,7 +253,10 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit);
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac);
-
+krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
+ const krb5_data *tr_contents,
+ const krb5_data *client_realm,
+ const krb5_data *server_realm);
/* DELEGATION CHECKS */
krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 08b55af54..e20de3662 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -2490,3 +2490,66 @@ done:
ldap_msgfree(result);
return kerr;
}
+
+krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
+ const krb5_data *tr_contents,
+ const krb5_data *client_realm,
+ const krb5_data *server_realm)
+{
+ struct ipadb_context *ipactx;
+ bool has_transited_contents, has_client_realm, has_server_realm;
+ int i;
+ krb5_error_code ret;
+
+ ipactx = ipadb_get_context(kcontext);
+ if (!ipactx || !ipactx->mspac) {
+ return KRB5_KDB_DBNOTINITED;
+ }
+
+ has_transited_contents = false;
+ has_client_realm = false;
+ has_server_realm = false;
+
+ /* First, compare client or server realm with ours */
+ if (strncasecmp(client_realm->data, ipactx->realm, client_realm->length) == 0) {
+ has_client_realm = true;
+ }
+ if (strncasecmp(server_realm->data, ipactx->realm, server_realm->length) == 0) {
+ has_server_realm = true;
+ }
+
+ if ((tr_contents->length == 0) || (tr_contents->data[0] == '\0')) {
+ /* For in-realm case allow transition */
+ if (has_client_realm && has_server_realm) {
+ return 0;
+ }
+ /* Since transited realm is empty, we don't need to check for it, it is a direct trust case */
+ has_transited_contents = true;
+ }
+
+ if (!ipactx->mspac || !ipactx->mspac->trusts) {
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ /* Iterate through list of trusts and check if any of input belongs to any of the trust */
+ for(i=0; i < ipactx->mspac->num_trusts ; i++) {
+ if (!has_transited_contents &&
+ (strncasecmp(tr_contents->data, ipactx->mspac->trusts[i].domain_name, tr_contents->length) == 0)) {
+ has_transited_contents = true;
+ }
+ if (!has_client_realm &&
+ (strncasecmp(client_realm->data, ipactx->mspac->trusts[i].domain_name, client_realm->length) == 0)) {
+ has_client_realm = true;
+ }
+ if (!has_server_realm &&
+ (strncasecmp(server_realm->data, ipactx->mspac->trusts[i].domain_name, server_realm->length) == 0)) {
+ has_server_realm = true;
+ }
+ }
+
+ ret = KRB5KRB_AP_ERR_ILL_CR_TKT;
+ if (has_client_realm && has_transited_contents && has_server_realm) {
+ ret = 0;
+ }
+ return ret;
+}