Blob Blame History Raw
From 1f0702bf9231a4898a2d58325fc51c71fea25047 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Fri, 23 Oct 2020 18:45:09 +0300
Subject: [PATCH] ipa-kdb: support subordinate/superior UPN suffixes

[MS-ADTS] 6.1.6.9.3.2 requires msDS-TrustForestTrustInfo attribute of
trusted domain information in Active Directory to conform certain rules.
One side-effect of those rules is that list of UPN suffixes reported
through the netr_DsRGetForestTrustInformation function is dynamically
filtered to deduplicate subordinate suffixes.

It means that if list of UPN suffixes contains the following top level
names (TLNs):

  fabrikam.com
  sub.fabrikam.com

then netr_DsRGetForestTrustInformation would only return 'fabrikam.com'
as the TLN, fully filtering 'sub.fabrikam.com'.

IPA KDB driver used exact comparison of the UPN suffixes so any
subordinate had to be specified exactly.

Modify logic so that if exact check does not succeed, we validate a
realm to test being a subordinate of the known UPN suffixes. The
subordinate check is done by making sure UPN suffix is at the end of the
test realm and is immediately preceded with a dot.

Because the function to check suffixes potentially called for every
Kerberos principal, precalculate and cache length for each UPN suffix at
the time we retrieve the list of them.

Fixes: https://pagure.io/freeipa/issue/8554

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
---
 daemons/ipa-kdb/ipa_kdb_mspac.c         | 30 +++++++++++++++++++++++++
 daemons/ipa-kdb/ipa_kdb_mspac_private.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 29dadc183..692f542c9 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -2393,6 +2393,7 @@ void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
                     free((*mspac)->trusts[i].upn_suffixes[j]);
                 }
                 free((*mspac)->trusts[i].upn_suffixes);
+                free((*mspac)->trusts[i].upn_suffixes_len);
             }
         }
         free((*mspac)->trusts);
@@ -2603,6 +2604,24 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
             }
         }
 
+        t[n].upn_suffixes_len = NULL;
+        if (t[n].upn_suffixes != NULL) {
+            size_t len = 0;
+
+            for (; t[n].upn_suffixes[len] != NULL; len++);
+
+            if (len != 0) {
+                t[n].upn_suffixes_len = calloc(n, sizeof(size_t));
+                if (t[n].upn_suffixes_len == NULL) {
+                    ret = ENOMEM;
+                    goto done;
+                }
+                for (i = 0; i < len; i++) {
+                    t[n].upn_suffixes_len[i] = strlen(t[n].upn_suffixes[i]);
+                }
+            }
+        }
+
         ret = ipadb_ldap_attr_to_strlist(lc, le, "ipaNTSIDBlacklistIncoming",
                                          &sid_blacklist_incoming);
 
@@ -2972,6 +2991,17 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
 				result = strncasecmp(test_realm,
 						     ipactx->mspac->trusts[i].upn_suffixes[j],
 						     size) == 0;
+				if (!result) {
+					/* if UPN suffix did not match exactly, find if it is
+					 * superior to the test_realm, e.g. if test_realm ends
+					 * with the UPN suffix prefixed with dot*/
+					size_t len = ipactx->mspac->trusts[i].upn_suffixes_len[j];
+					if ((size > len) && (test_realm[size - len - 1] == '.')) {
+						result = strncasecmp(test_realm + (size - len),
+								     ipactx->mspac->trusts[i].upn_suffixes[j],
+								     len) == 0;
+					}
+				}
 				if (result)
 					break;
 			}
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_private.h b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
index 30382d2ee..b21aa163f 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac_private.h
+++ b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
@@ -48,6 +48,7 @@ struct ipadb_adtrusts {
     struct ipadb_adtrusts *parent;
     char *parent_name;
     char **upn_suffixes;
+    size_t *upn_suffixes_len;
 };
 
 int string_to_sid(const char *str, struct dom_sid *sid);
-- 
2.29.2