From 49f8113fabd2603b45439404c91d350b4d6eaeac Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 11 Jan 2012 18:06:55 +1100 Subject: s4-kdc Do the KDC PAC checksum validation in the Samba plugin Here we can fetch the right key, and check if the PAC is likely to be signed by a key that we know. We cannot check the KDC signature on incoming trusts. Andrew Bartlett --- source4/kdc/wdc-samba4.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'source4/kdc/wdc-samba4.c') diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c index 99ad96a6b5..70e849ccb7 100644 --- a/source4/kdc/wdc-samba4.c +++ b/source4/kdc/wdc-samba4.c @@ -68,6 +68,9 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, DATA_BLOB *deleg_blob = NULL; krb5_error_code ret; NTSTATUS nt_status; + struct PAC_SIGNATURE_DATA *pac_srv_sig; + struct PAC_SIGNATURE_DATA *pac_kdc_sig; + bool is_in_db, is_untrusted; if (!mem_ctx) { return ENOMEM; @@ -82,7 +85,13 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, /* If the krbtgt was generated by an RODC, and we are not that * RODC, then we need to regenerate the PAC - we can't trust * it */ - if (samba_krbtgt_was_untrusted_rodc(krbtgt)) { + ret = samba_krbtgt_is_in_db(krbtgt, &is_in_db, &is_untrusted); + if (ret != 0) { + talloc_free(mem_ctx); + return ret; + } + + if (is_untrusted) { if (client == NULL) { return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; } @@ -98,14 +107,37 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, return ENOMEM; } + pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_srv_sig) { + talloc_free(mem_ctx); + return ENOMEM; + } + + pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_kdc_sig) { + talloc_free(mem_ctx); + return ENOMEM; + } + nt_status = samba_kdc_update_pac_blob(mem_ctx, context, - *pac, pac_blob); + *pac, pac_blob, + pac_srv_sig, pac_kdc_sig); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Building PAC failed: %s\n", nt_errstr(nt_status))); talloc_free(mem_ctx); return EINVAL; } + + if (is_in_db) { + /* Now check the KDC signature, fetching the correct key based on the enc type */ + ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt); + if (ret != 0) { + DEBUG(1, ("PAC KDC signature failed to verify\n")); + talloc_free(mem_ctx); + return ret; + } + } } if (delegated_proxy_principal) { -- cgit