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>
This commit is contained in:
Alexander Bokovoy 2020-10-23 18:45:09 +03:00 committed by Rob Crittenden
parent 3f59118ffc
commit 8b6d1ab854
2 changed files with 31 additions and 0 deletions

View File

@ -2392,6 +2392,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);
@ -2602,6 +2603,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_blocklist_incoming);
@ -2971,6 +2990,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;
}

View File

@ -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);