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 *tr_contents,
|
||||||
const krb5_data *client_realm,
|
const krb5_data *client_realm,
|
||||||
const krb5_data *server_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 */
|
/* DELEGATION CHECKS */
|
||||||
|
|
||||||
krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
|
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;
|
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;
|
struct ipadb_context *ipactx;
|
||||||
krb5_error_code kerr;
|
krb5_error_code kerr;
|
||||||
char *principal = NULL;
|
char *principal = NULL;
|
||||||
|
char *trusted_realm = NULL;
|
||||||
LDAPMessage *res = NULL;
|
LDAPMessage *res = NULL;
|
||||||
LDAPMessage *lentry;
|
LDAPMessage *lentry;
|
||||||
|
krb5_db_entry *kentry = NULL;
|
||||||
uint32_t pol;
|
uint32_t pol;
|
||||||
|
|
||||||
ipactx = ipadb_get_context(kcontext);
|
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);
|
kerr = ipadb_find_principal(kcontext, flags, res, &principal, &lentry);
|
||||||
if (kerr != 0) {
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,6 +1111,10 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
free(trusted_realm);
|
||||||
|
if ((kerr != 0) && (kentry != NULL)) {
|
||||||
|
ipadb_free_principal(kcontext, kentry);
|
||||||
|
}
|
||||||
ldap_msgfree(res);
|
ldap_msgfree(res);
|
||||||
krb5_free_unparsed_name(kcontext, principal);
|
krb5_free_unparsed_name(kcontext, principal);
|
||||||
return kerr;
|
return kerr;
|
||||||
|
|||||||
Reference in New Issue
Block a user