Blame SOURCES/0026-ipa-kdb-support-subordinate-superior-UPN-suffixes_rhbz#1914823.patch

cce5df
From 1f0702bf9231a4898a2d58325fc51c71fea25047 Mon Sep 17 00:00:00 2001
cce5df
From: Alexander Bokovoy <abokovoy@redhat.com>
cce5df
Date: Fri, 23 Oct 2020 18:45:09 +0300
cce5df
Subject: [PATCH] ipa-kdb: support subordinate/superior UPN suffixes
cce5df
cce5df
[MS-ADTS] 6.1.6.9.3.2 requires msDS-TrustForestTrustInfo attribute of
cce5df
trusted domain information in Active Directory to conform certain rules.
cce5df
One side-effect of those rules is that list of UPN suffixes reported
cce5df
through the netr_DsRGetForestTrustInformation function is dynamically
cce5df
filtered to deduplicate subordinate suffixes.
cce5df
cce5df
It means that if list of UPN suffixes contains the following top level
cce5df
names (TLNs):
cce5df
cce5df
  fabrikam.com
cce5df
  sub.fabrikam.com
cce5df
cce5df
then netr_DsRGetForestTrustInformation would only return 'fabrikam.com'
cce5df
as the TLN, fully filtering 'sub.fabrikam.com'.
cce5df
cce5df
IPA KDB driver used exact comparison of the UPN suffixes so any
cce5df
subordinate had to be specified exactly.
cce5df
cce5df
Modify logic so that if exact check does not succeed, we validate a
cce5df
realm to test being a subordinate of the known UPN suffixes. The
cce5df
subordinate check is done by making sure UPN suffix is at the end of the
cce5df
test realm and is immediately preceded with a dot.
cce5df
cce5df
Because the function to check suffixes potentially called for every
cce5df
Kerberos principal, precalculate and cache length for each UPN suffix at
cce5df
the time we retrieve the list of them.
cce5df
cce5df
Fixes: https://pagure.io/freeipa/issue/8554
cce5df
cce5df
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
cce5df
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
cce5df
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
cce5df
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
cce5df
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
cce5df
---
cce5df
 daemons/ipa-kdb/ipa_kdb_mspac.c         | 30 +++++++++++++++++++++++++
cce5df
 daemons/ipa-kdb/ipa_kdb_mspac_private.h |  1 +
cce5df
 2 files changed, 31 insertions(+)
cce5df
cce5df
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
cce5df
index 29dadc183..692f542c9 100644
cce5df
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
cce5df
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
cce5df
@@ -2393,6 +2393,7 @@ void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
cce5df
                     free((*mspac)->trusts[i].upn_suffixes[j]);
cce5df
                 }
cce5df
                 free((*mspac)->trusts[i].upn_suffixes);
cce5df
+                free((*mspac)->trusts[i].upn_suffixes_len);
cce5df
             }
cce5df
         }
cce5df
         free((*mspac)->trusts);
cce5df
@@ -2603,6 +2604,24 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
cce5df
             }
cce5df
         }
cce5df
 
cce5df
+        t[n].upn_suffixes_len = NULL;
cce5df
+        if (t[n].upn_suffixes != NULL) {
cce5df
+            size_t len = 0;
cce5df
+
cce5df
+            for (; t[n].upn_suffixes[len] != NULL; len++);
cce5df
+
cce5df
+            if (len != 0) {
cce5df
+                t[n].upn_suffixes_len = calloc(n, sizeof(size_t));
cce5df
+                if (t[n].upn_suffixes_len == NULL) {
cce5df
+                    ret = ENOMEM;
cce5df
+                    goto done;
cce5df
+                }
cce5df
+                for (i = 0; i < len; i++) {
cce5df
+                    t[n].upn_suffixes_len[i] = strlen(t[n].upn_suffixes[i]);
cce5df
+                }
cce5df
+            }
cce5df
+        }
cce5df
+
cce5df
         ret = ipadb_ldap_attr_to_strlist(lc, le, "ipaNTSIDBlacklistIncoming",
cce5df
                                          &sid_blacklist_incoming);
cce5df
 
cce5df
@@ -2972,6 +2991,17 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
cce5df
 				result = strncasecmp(test_realm,
cce5df
 						     ipactx->mspac->trusts[i].upn_suffixes[j],
cce5df
 						     size) == 0;
cce5df
+				if (!result) {
cce5df
+					/* if UPN suffix did not match exactly, find if it is
cce5df
+					 * superior to the test_realm, e.g. if test_realm ends
cce5df
+					 * with the UPN suffix prefixed with dot*/
cce5df
+					size_t len = ipactx->mspac->trusts[i].upn_suffixes_len[j];
cce5df
+					if ((size > len) && (test_realm[size - len - 1] == '.')) {
cce5df
+						result = strncasecmp(test_realm + (size - len),
cce5df
+								     ipactx->mspac->trusts[i].upn_suffixes[j],
cce5df
+								     len) == 0;
cce5df
+					}
cce5df
+				}
cce5df
 				if (result)
cce5df
 					break;
cce5df
 			}
cce5df
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_private.h b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
cce5df
index 30382d2ee..b21aa163f 100644
cce5df
--- a/daemons/ipa-kdb/ipa_kdb_mspac_private.h
cce5df
+++ b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
cce5df
@@ -48,6 +48,7 @@ struct ipadb_adtrusts {
cce5df
     struct ipadb_adtrusts *parent;
cce5df
     char *parent_name;
cce5df
     char **upn_suffixes;
cce5df
+    size_t *upn_suffixes_len;
cce5df
 };
cce5df
 
cce5df
 int string_to_sid(const char *str, struct dom_sid *sid);
cce5df
-- 
cce5df
2.29.2
cce5df