mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
client referral support for trusted domain principals
https://fedorahosted.org/freeipa/ticket/3559 Reviewed-By: Sumit Bose <sbose@redhat.com>
This commit is contained in:
committed by
Martin Basti
parent
4b381b1503
commit
766438aba0
@@ -274,6 +274,14 @@ 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);
|
||||
/* Checks whether a principal's realm is one of trusted domains' realm or NetBIOS name
|
||||
* and returns the realm of the matched trusted domain in 'trusted_domain'
|
||||
* Returns 0 in case of success and KRB5_KDB_NOENTRY otherwise
|
||||
* If DAL driver is not initialized, returns KRB5_KDB_DBNOTINITED */
|
||||
krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||||
const char *test_realm, size_t size,
|
||||
char **trusted_realm);
|
||||
|
||||
/* DELEGATION CHECKS */
|
||||
|
||||
krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
|
||||
|
||||
@@ -2790,3 +2790,63 @@ krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Checks whether a principal's realm is one of trusted domains' realm or NetBIOS name
|
||||
* and returns the realm of the matched trusted domain in 'trusted_domain'
|
||||
* Returns 0 in case of success and KRB5_KDB_NOENTRY otherwise
|
||||
* If DAL driver is not initialized, returns KRB5_KDB_DBNOTINITED */
|
||||
krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||||
const char *test_realm, size_t size,
|
||||
char **trusted_realm)
|
||||
{
|
||||
struct ipadb_context *ipactx;
|
||||
int i, j, length;
|
||||
const char *name;
|
||||
|
||||
if (test_realm == NULL || test_realm[0] == '\0') {
|
||||
return KRB5_KDB_NOENTRY;
|
||||
}
|
||||
|
||||
ipactx = ipadb_get_context(kcontext);
|
||||
if (!ipactx || !ipactx->mspac) {
|
||||
return KRB5_KDB_DBNOTINITED;
|
||||
}
|
||||
|
||||
/* First, compare realm with ours, it would not be from a trusted realm then */
|
||||
if (strncasecmp(test_realm, ipactx->realm, size) == 0) {
|
||||
return KRB5_KDB_NOENTRY;
|
||||
}
|
||||
|
||||
if (!ipactx->mspac || !ipactx->mspac->trusts) {
|
||||
return KRB5_KDB_NOENTRY;
|
||||
}
|
||||
|
||||
/* Iterate through list of trusts and check if input realm belongs to any of the trust */
|
||||
for(i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
|
||||
if ((strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].domain_name,
|
||||
size) == 0) ||
|
||||
(strncasecmp(test_realm,
|
||||
ipactx->mspac->trusts[i].flat_name,
|
||||
size) == 0)) {
|
||||
/* return the realm if caller supplied a place for it */
|
||||
if (trusted_realm != NULL) {
|
||||
name = (ipactx->mspac->trusts[i].parent_name != NULL) ?
|
||||
ipactx->mspac->trusts[i].parent_name :
|
||||
ipactx->mspac->trusts[i].domain_name;
|
||||
length = strlen(name) + 1;
|
||||
*trusted_realm = calloc(1, length);
|
||||
if (*trusted_realm != NULL) {
|
||||
for (j = 0; j < length; j++) {
|
||||
(*trusted_realm)[j] = toupper(name[j]);
|
||||
}
|
||||
} else {
|
||||
return KRB5_KDB_NOENTRY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return KRB5_KDB_NOENTRY;
|
||||
}
|
||||
|
||||
@@ -1023,8 +1023,10 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
struct ipadb_context *ipactx;
|
||||
krb5_error_code kerr;
|
||||
char *principal = NULL;
|
||||
char *trusted_realm = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
LDAPMessage *lentry;
|
||||
krb5_db_entry *kentry = NULL;
|
||||
uint32_t pol;
|
||||
|
||||
ipactx = ipadb_get_context(kcontext);
|
||||
@@ -1044,6 +1046,55 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
|
||||
kerr = ipadb_find_principal(kcontext, flags, res, &principal, &lentry);
|
||||
if (kerr != 0) {
|
||||
if ((kerr == KRB5_KDB_NOENTRY) &&
|
||||
((flags & (KRB5_KDB_FLAG_CANONICALIZE |
|
||||
KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY)) != 0)) {
|
||||
|
||||
/* First check if we got enterprise principal which looks like
|
||||
* username\@enterprise_realm@REALM */
|
||||
char *realm;
|
||||
krb5_data *upn;
|
||||
|
||||
upn = krb5_princ_component(kcontext, search_for,
|
||||
krb5_princ_size(kcontext, search_for) - 1);
|
||||
|
||||
if (upn == NULL) {
|
||||
kerr = KRB5_KDB_NOENTRY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
realm = memrchr(upn->data, '@', upn->length);
|
||||
if (realm == NULL) {
|
||||
kerr = KRB5_KDB_NOENTRY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* skip '@' and use part after '@' as an enterprise realm for comparison */
|
||||
realm++;
|
||||
|
||||
kerr = ipadb_is_princ_from_trusted_realm(kcontext,
|
||||
realm,
|
||||
upn->length - (realm - upn->data),
|
||||
&trusted_realm);
|
||||
if (kerr == 0) {
|
||||
kentry = calloc(1, sizeof(krb5_db_entry));
|
||||
if (!kentry) {
|
||||
kerr = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
kerr = krb5_parse_name(kcontext, principal,
|
||||
&kentry->princ);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
kerr = krb5_set_principal_realm(kcontext, kentry->princ, trusted_realm);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
*entry = kentry;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1060,6 +1111,10 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
}
|
||||
|
||||
done:
|
||||
free(trusted_realm);
|
||||
if ((kerr != 0) && (kentry != NULL)) {
|
||||
ipadb_free_principal(kcontext, kentry);
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
krb5_free_unparsed_name(kcontext, principal);
|
||||
return kerr;
|
||||
|
||||
Reference in New Issue
Block a user