kdc: allow referrals for krbtgt in transitively trusted realm

Isaac Boukris iboukris at gmail.com
Mon Aug 6 14:07:00 UTC 2018


Hello,

> However, I think I found another bug in samba KDC with transitive
> trust, which would cause s4u2self to fail.
> This bug is not directly related to s4u2self, and can easily be
> reproduces with MIT's kvno tool against samba KDC (in transitive trust
> env).
>
> In short, the first step in cross-realm s4u2self, is to obtain a
> krbtgt to client realm, and while samba kdc gives proper referral to
> intermediate realm when asked for HOST/transitively-trusted-realm, it
> won't give a referral when asked for
> krbtgt/transitively-trusted-realm, so the service cannot get started
> (windows kdc does give referral in that case).
> I have a POC patch for this bug (which I'm not happy with), but since
> it's not directly related, I send it with more details in a separate
> thread.


Consider a samba KDC in domain S trusting ad domain A (forest trust),
who has a child domain C.
Once I acquire creds in domain S, I run 'kvno HOST/dc-in-domain-C'
and samba kdc returns tgt-referral to A, which the kvno tool follows
to ends up getting a service ticket from domain C.
However, if I run 'kvno krbtgt/C at S' samba kdc returns
KDC_ERR_S_PRINCIPAL_UNKNOWN (while windows kdc returns a referral in
such case).
As mentioned, this is necessary for cross-realm s4u2self.

The attached poc patch solves the bug, but I think not efficient (and
may leak?). I think what I need is, to find out efficiently in
samba_kdc_lookup_realm(krbtgt) whether the realm is directly trusted
in which case return 0, or only transitively trusted and then return
WRONG_REALM with referral to intermediate realm.
-------------- next part --------------
From 7a0ea19be4402043a618f2b2bd47e93b568ab98b Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris at gmail.com>
Date: Mon, 6 Aug 2018 16:19:00 +0300
Subject: [PATCH] WIP: sdb: allow referrals for krbtgt in transitively trusted
 realm

Signed-off-by: Isaac Boukris <iboukris at gmail.com>
---
 source4/kdc/db-glue.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index bb428e45cbc..2189fc8d154 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -2212,15 +2212,6 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
 	if (flags & SDB_F_GET_SERVER) {
 		char *service_realm = NULL;
 
-		ret = principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME);
-		if (ret == 0) {
-			/*
-			 * we need to search krbtgt/ locally
-			 */
-			TALLOC_FREE(frame);
-			return 0;
-		}
-
 		/*
 		 * We need to check the last component against the routing table.
 		 *
@@ -2253,6 +2244,25 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
 		return 0;
 	}
 
+	ret = principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME);
+	if (ret == 0) {
+		const char * const *attrs = trust_attrs;
+		struct ldb_message *msg = NULL;
+		status = dsdb_trust_search_tdo(kdc_db_ctx->samdb, realm, realm,
+						attrs, frame, &msg);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
+			TALLOC_FREE(frame);
+			return ENOMEM;
+		}
+		if (NT_STATUS_IS_OK(status)) {
+			/*
+			* we need to search krbtgt/ locally
+			*/
+			TALLOC_FREE(frame);
+			return 0;
+		}
+	}
+
 	status = dsdb_trust_routing_table_load(kdc_db_ctx->samdb,
 					       frame, &trt);
 	if (!NT_STATUS_IS_OK(status)) {
-- 
2.14.3



More information about the samba-technical mailing list