ipa-kdb: add support for PAC_UPN_DNS_INFO_EX

CVE-2020-25721 mitigation: KDC must provide the new HAS_SAM_NAME_AND_SID
buffer with sAMAccountName and ObjectSID values associated with the
principal.

The mitigation only works if NDR library supports the
PAC_UPN_DNS_INFO_EX buffer type. In case we cannot detect it at compile
time, a warning will be displayed at configure stage.

Fixes: https://pagure.io/freeipa/issue/9031

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Alexander Bokovoy 2021-10-30 10:08:34 +03:00 committed by Rob Crittenden
parent 6828273b56
commit 23336160f2
2 changed files with 46 additions and 2 deletions

View File

@ -812,6 +812,25 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
return ret;
}
static krb5_error_code ipadb_get_sid_from_pac(TALLOC_CTX *ctx,
struct PAC_LOGON_INFO *info,
struct dom_sid *sid)
{
struct dom_sid *client_sid = NULL;
/* Construct SID from the PAC */
if (info->info3.base.rid == 0) {
client_sid = info->info3.sids[0].sid;
} else {
client_sid = dom_sid_dup(ctx, info->info3.base.domain_sid);
if (!client_sid) {
return ENOMEM;
}
sid_append_rid(client_sid, info->info3.base.rid);
}
*sid = *client_sid;
return 0;
}
static krb5_error_code ipadb_get_pac(krb5_context kcontext,
krb5_db_entry *client,
unsigned int flags,
@ -830,6 +849,7 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext,
enum ndr_err_code ndr_err;
union PAC_INFO pac_upn;
char *principal = NULL;
struct dom_sid client_sid;
/* When no client entry is there, we cannot generate MS-PAC */
if (!client) {
@ -930,6 +950,18 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext,
pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_CONSTRUCTED;
}
kerr = ipadb_get_sid_from_pac(tmpctx, pac_info.logon_info.info, &client_sid);
if (kerr) {
goto done;
}
#ifdef HAVE_PAC_UPN_DNS_INFO_EX
/* Add samAccountName and a SID */
pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID;
pac_upn.upn_dns_info.ex.sam_name_and_sid.samaccountname = pac_info.logon_info.info->info3.base.account_name.string;
pac_upn.upn_dns_info.ex.sam_name_and_sid.objectsid = &client_sid;
#endif
ndr_err = ndr_push_union_blob(&pac_data, tmpctx, &pac_upn,
PAC_TYPE_UPN_DNS_INFO,
(ndr_push_flags_fn_t)ndr_push_PAC_INFO);
@ -1415,6 +1447,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
krb5_db_entry *client_actual = NULL;
struct ipadb_e_data *ied = NULL;
int flags = 0;
struct dom_sid client_sid;
#ifdef KRB5_KDB_FLAG_ALIAS_OK
flags = KRB5_KDB_FLAG_ALIAS_OK;
#endif
@ -1460,11 +1493,15 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
goto done;
}
result = dom_sid_check(ied->sid, info->info->info3.sids[0].sid, true);
kerr = ipadb_get_sid_from_pac(memctx, info->info, &client_sid);
if (kerr) {
goto done;
}
result = dom_sid_check(ied->sid, &client_sid, true);
if (!result) {
/* memctx is freed by the caller */
char *local_sid = dom_sid_string(memctx, ied->sid);
char *pac_sid = dom_sid_string(memctx, info->info->info3.sids[0].sid);
char *pac_sid = dom_sid_string(memctx, &client_sid);
krb5_klog_syslog(LOG_ERR, "PAC issue: client principal has a SID "
"different from what PAC claims. "
"local [%s] vs PAC [%s]",

View File

@ -101,6 +101,13 @@ AC_CHECK_MEMBER(
[AC_MSG_NOTICE([struct PAC_DOMAIN_GROUP_MEMBERSHIP is not available])],
[[#include <ndr.h>
#include <gen_ndr/krb5pac.h>]])
AC_CHECK_MEMBER(
[struct PAC_UPN_DNS_INFO.ex],
[AC_DEFINE([HAVE_PAC_UPN_DNS_INFO_EX], [1],
[union PAC_UPN_DNS_INFO_EX is available.])],
[AC_MSG_NOTICE([union PAC_UPN_DNS_INFO_EX is not available, account protection is not active])],
[[#include <ndr.h>
#include <gen_ndr/krb5pac.h>]])
CFLAGS="$bck_cflags"