mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-24 16:10:02 -06:00
kdb: add minimal server referrals support for enterprise principals
Implement minimal server referrals support for enterprise principals as defined in RFC 6806. Use krb5_pac_verify_ext() and krb5_pac_sign_ext() to support cross-realm S4U extensions. We have to verify/sign PAC and take the realm into account for S4U in these cases. The use of extended functions require krb5 1.17+. For PAC verification, we have to filter existing PAC CLIENT-INFO structure in cross-realm S4U case because otherwise old CLIENT-INFO would change the PAC principal due to adding or ommiting the realm in transition. Since a new PAC CLIENT-INFO will be provided by k5_insert_client_info() anyway, we can filter it in all cases. Generate PAC only for the first S4U2Self request to the client realm (client != NULL). Otherwise, use the PAC from the cross-realm ticket. The latter PAC belongs to the impersonated user. Foreign (inner) principal look up in non-AS request returns KRB5_KDB_NOENTRY. Finally, in PAC signing we have to take the realm into account as well for S4U2Self cross-realm operation. This does not work when compiling against krb5 1.17 at the moment because sign_authdata() callback does not know whether we are dealing with an issuing referral or not. In 1.18 a KDC will set a special client flag to signify this when asking KDB driver to sign a PAC record. Fixes: https://pagure.io/freeipa/issue/8319 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Signed-off-by: Isaac Boukris <iboukris@redhat.com> Reviewed-By: Isaac Boukris <iboukris@redhat.com> Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
parent
0f881ca0f2
commit
44a255d423
@ -1840,8 +1840,12 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
|
||||
priv_key = krbtgt_key;
|
||||
}
|
||||
|
||||
kerr = krb5_pac_verify(context, old_pac, authtime,
|
||||
client_princ, srv_key, priv_key);
|
||||
/* only pass with_realm TRUE when it is cross-realm ticket and S4U
|
||||
* extension (S4U2Self or S4U2Proxy (RBCD)) was requested */
|
||||
kerr = krb5_pac_verify_ext(context, old_pac, authtime,
|
||||
client_princ, srv_key, priv_key,
|
||||
(is_cross_realm &&
|
||||
(flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION)));
|
||||
if (kerr) {
|
||||
goto done;
|
||||
}
|
||||
@ -1875,7 +1879,8 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
|
||||
|
||||
for (i = 0; i < num_buffers; i++) {
|
||||
if (types[i] == KRB5_PAC_SERVER_CHECKSUM ||
|
||||
types[i] == KRB5_PAC_PRIVSVR_CHECKSUM) {
|
||||
types[i] == KRB5_PAC_PRIVSVR_CHECKSUM ||
|
||||
types[i] == KRB5_PAC_CLIENT_INFO) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1933,6 +1938,7 @@ done:
|
||||
}
|
||||
|
||||
static krb5_error_code ipadb_sign_pac(krb5_context context,
|
||||
unsigned int flags,
|
||||
krb5_const_principal client_princ,
|
||||
krb5_db_entry *server,
|
||||
krb5_db_entry *krbtgt,
|
||||
@ -1948,6 +1954,7 @@ static krb5_error_code ipadb_sign_pac(krb5_context context,
|
||||
krb5_principal krbtgt_princ = NULL;
|
||||
krb5_error_code kerr;
|
||||
char *princ = NULL;
|
||||
bool is_issuing_referral = false;
|
||||
int ret;
|
||||
|
||||
/* for cross realm trusts cases we need to sign with the right key.
|
||||
@ -2006,8 +2013,17 @@ static krb5_error_code ipadb_sign_pac(krb5_context context,
|
||||
right_krbtgt_signing_key = krbtgt_key;
|
||||
}
|
||||
|
||||
kerr = krb5_pac_sign(context, pac, authtime, client_princ,
|
||||
server_key, right_krbtgt_signing_key, pac_data);
|
||||
#ifdef KRB5_KDB_FLAG_ISSUING_REFERRAL
|
||||
is_issuing_referral = (flags & KRB5_KDB_FLAG_ISSUING_REFERRAL) != 0;
|
||||
#endif
|
||||
|
||||
/* only pass with_realm TRUE when it is cross-realm ticket and S4U2Self
|
||||
* was requested */
|
||||
kerr = krb5_pac_sign_ext(context, pac, authtime, client_princ, server_key,
|
||||
right_krbtgt_signing_key,
|
||||
(is_issuing_referral &&
|
||||
(flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION)),
|
||||
pac_data);
|
||||
|
||||
done:
|
||||
free(princ);
|
||||
@ -2224,9 +2240,10 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
|
||||
}
|
||||
|
||||
/* we need to create a PAC if we are requested one and this is an AS REQ,
|
||||
* or we are doing protocol transition (s4u2self) */
|
||||
* or we are doing protocol transition (S4USelf) but not over cross-realm
|
||||
*/
|
||||
if ((is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) ||
|
||||
(flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
|
||||
((flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION) && (client != NULL))) {
|
||||
make_ad = true;
|
||||
}
|
||||
|
||||
@ -2296,7 +2313,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
kerr = ipadb_sign_pac(context, ks_client_princ, server, krbtgt,
|
||||
kerr = ipadb_sign_pac(context, flags, ks_client_princ, server, krbtgt,
|
||||
server_key, krbtgt_key, authtime, pac, &pac_data);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
|
@ -1361,7 +1361,12 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
upn->length - (realm - upn->data),
|
||||
&trusted_realm);
|
||||
}
|
||||
if (kerr == 0) {
|
||||
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) {
|
||||
kentry = calloc(1, sizeof(krb5_db_entry));
|
||||
if (!kentry) {
|
||||
kerr = ENOMEM;
|
||||
@ -1378,8 +1383,47 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
||||
goto done;
|
||||
}
|
||||
*entry = kentry;
|
||||
|
||||
goto done;
|
||||
} else if (flags & KRB5_KDB_FLAG_INCLUDE_PAC) {
|
||||
kerr = KRB5_KDB_NOENTRY;
|
||||
goto done;
|
||||
} else {
|
||||
/* server referrals: lookup krbtgt/next_realm@our_realm */
|
||||
krb5_principal tgtp;
|
||||
|
||||
kerr = krb5_build_principal_ext(kcontext, &tgtp,
|
||||
strlen(ipactx->realm),
|
||||
ipactx->realm,
|
||||
KRB5_TGS_NAME_SIZE,
|
||||
KRB5_TGS_NAME,
|
||||
strlen(trusted_realm),
|
||||
trusted_realm, 0);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
krb5_free_unparsed_name(kcontext, principal);
|
||||
principal = NULL;
|
||||
kerr = krb5_unparse_name(kcontext, tgtp, &principal);
|
||||
krb5_free_principal(kcontext, tgtp);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ldap_msgfree(res);
|
||||
res = NULL;
|
||||
kerr = ipadb_fetch_principals(ipactx, flags, principal, &res);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
kerr = ipadb_find_principal(kcontext, flags, res, &principal,
|
||||
&lentry);
|
||||
if (kerr != 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
goto done;
|
||||
|
Loading…
Reference in New Issue
Block a user