summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2013-09-28 21:49:57 +0200
committerMartin Kosek <mkosek@redhat.com>2013-10-04 10:26:35 +0200
commit6224ce0c70ee5b33cef436c36f5b21e46311d2f1 (patch)
tree71688a9c750cc56298de5e4f88df152f34b85ec7
parent0cd79231fb6ab93c08414255644f088c6bc837d7 (diff)
downloadfreeipa.git-6224ce0c70ee5b33cef436c36f5b21e46311d2f1.tar.gz
freeipa.git-6224ce0c70ee5b33cef436c36f5b21e46311d2f1.tar.xz
freeipa.git-6224ce0c70ee5b33cef436c36f5b21e46311d2f1.zip
KDC: implement transition check for trusted domains
When client principal requests for a ticket for a server principal and we have to perform transition, check that all three belong to either our domain or the domains we trust through forest trusts. In case all three realms (client, transition, and server) match trusted domains and our domain, issue permission to transition from client realm to server realm. Part of https://fedorahosted.org/freeipa/ticket/3909
-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 5e4d0474..c807bbcf 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 f4d35554..1c2aefc4 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 08b55af5..e20de366 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;
+}