diff options
author | Joseph Sutton <josephsutton@catalyst.net.nz> | 2022-06-15 19:37:39 +1200 |
---|---|---|
committer | Jule Anger <janger@samba.org> | 2022-07-24 11:42:01 +0200 |
commit | c0395578c50fbc4f1946e2f5a065d94f67212eb0 (patch) | |
tree | 542face7137777a1f2e93ec675af6b967a5d7daa | |
parent | bff1978187d530164888f2a0c3daa3d6a4ae2245 (diff) | |
download | samba-c0395578c50fbc4f1946e2f5a065d94f67212eb0.tar.gz |
CVE-2022-2031 s4:kdc: Add MIT support for ATTRIBUTES_INFO and REQUESTER_SID PAC buffers
So that we do not confuse TGTs and kpasswd tickets, it is critical to
check that the REQUESTER_SID buffer exists in TGTs, and to ensure that
it is not propagated to service tickets.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
[jsutton@samba.org Brought in changes to add ATTRIBUTES_INFO and
REQUESTER_SID buffers to new PACs, and updated knownfails]
[jsutton@samba.org Adjusted MIT knownfails]
-rw-r--r-- | selftest/knownfail_mit_kdc | 17 | ||||
-rw-r--r-- | source4/kdc/mit-kdb/kdb_samba_policies.c | 5 | ||||
-rw-r--r-- | source4/kdc/mit_samba.c | 93 | ||||
-rw-r--r-- | source4/kdc/mit_samba.h | 1 |
4 files changed, 94 insertions, 22 deletions
diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index 4d685af7140..108c6055d0c 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -445,7 +445,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_req ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied @@ -482,7 +481,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rename ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_invalid -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link @@ -518,7 +516,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_req ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied @@ -536,21 +533,17 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ # ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_false ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_false -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_false ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_true -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_false -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_pac_attrs # @@ -571,21 +564,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ # # PAC requester SID tests # -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate -^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_validate ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c index 7bc9a7b3347..3b25fff410b 100644 --- a/source4/kdc/mit-kdb/kdb_samba_policies.c +++ b/source4/kdc/mit-kdb/kdb_samba_policies.c @@ -159,6 +159,7 @@ done: static krb5_error_code ks_get_pac(krb5_context context, krb5_db_entry *client, + krb5_db_entry *server, krb5_keyblock *client_key, krb5_pac *pac) { @@ -173,6 +174,7 @@ static krb5_error_code ks_get_pac(krb5_context context, code = mit_samba_get_pac(mit_ctx, context, client, + server, client_key, pac); if (code != 0) { @@ -439,7 +441,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, */ if (with_pac && generate_pac) { DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name); - code = ks_get_pac(context, client_entry, client_key, &pac); + code = ks_get_pac(context, client_entry, server, client_key, &pac); if (code != 0) { goto done; } @@ -490,6 +492,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, code = ks_get_pac(context, client_entry, + server, client_key, &pac); if (code != 0 && code != ENOENT) { diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c index c2a604045d9..df2ba0a906f 100644 --- a/source4/kdc/mit_samba.c +++ b/source4/kdc/mit_samba.c @@ -407,6 +407,7 @@ int mit_samba_get_nextkey(struct mit_samba_context *ctx, int mit_samba_get_pac(struct mit_samba_context *smb_ctx, krb5_context context, krb5_db_entry *client, + krb5_db_entry *server, krb5_keyblock *client_key, krb5_pac *pac) { @@ -417,9 +418,12 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, DATA_BLOB **cred_ndr_ptr = NULL; DATA_BLOB cred_blob = data_blob_null; DATA_BLOB *pcred_blob = NULL; + DATA_BLOB *pac_attrs_blob = NULL; + DATA_BLOB *requester_sid_blob = NULL; NTSTATUS nt_status; krb5_error_code code; struct samba_kdc_entry *skdc_entry; + bool is_krbtgt; skdc_entry = talloc_get_type_abort(client->e_data, struct samba_kdc_entry); @@ -438,12 +442,16 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, } #endif + is_krbtgt = ks_is_tgs_principal(smb_ctx, server->princ); + nt_status = samba_kdc_get_pac_blobs(tmp_ctx, skdc_entry, &logon_info_blob, cred_ndr_ptr, &upn_dns_info_blob, - NULL, NULL, NULL, + is_krbtgt ? &pac_attrs_blob : NULL, + NULL, + is_krbtgt ? &requester_sid_blob : NULL, NULL); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); @@ -471,8 +479,8 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, logon_info_blob, pcred_blob, upn_dns_info_blob, - NULL, - NULL, + pac_attrs_blob, + requester_sid_blob, NULL, pac); @@ -496,6 +504,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, DATA_BLOB *pac_blob = NULL; DATA_BLOB *upn_blob = NULL; DATA_BLOB *deleg_blob = NULL; + DATA_BLOB *requester_sid_blob = NULL; struct samba_kdc_entry *client_skdc_entry = NULL; struct samba_kdc_entry *krbtgt_skdc_entry = NULL; struct samba_kdc_entry *server_skdc_entry = NULL; @@ -511,8 +520,12 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, ssize_t upn_dns_info_idx = -1; ssize_t srv_checksum_idx = -1; ssize_t kdc_checksum_idx = -1; + ssize_t tkt_checksum_idx = -1; + ssize_t attrs_info_idx = -1; + ssize_t requester_sid_idx = -1; krb5_pac new_pac = NULL; bool ok; + bool is_krbtgt; /* Create a memory context early so code can use talloc_stackframe() */ tmp_ctx = talloc_named(ctx, 0, "mit_samba_reget_pac context"); @@ -520,6 +533,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, return ENOMEM; } + is_krbtgt = ks_is_tgs_principal(ctx, server->princ); + if (client != NULL) { client_skdc_entry = talloc_get_type_abort(client->e_data, @@ -578,7 +593,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, NULL, &upn_blob, NULL, NULL, - NULL, + &requester_sid_blob, NULL); if (!NT_STATUS_IS_OK(nt_status)) { code = EINVAL; @@ -737,6 +752,45 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, } kdc_checksum_idx = i; break; + case PAC_TYPE_TICKET_CHECKSUM: + if (tkt_checksum_idx != -1) { + DBG_WARNING("ticket checksum type[%u] twice " + "[%zd] and [%zu]: \n", + types[i], + tkt_checksum_idx, + i); + SAFE_FREE(types); + code = EINVAL; + goto done; + } + tkt_checksum_idx = i; + break; + case PAC_TYPE_ATTRIBUTES_INFO: + if (attrs_info_idx != -1) { + DBG_WARNING("attributes info type[%u] twice " + "[%zd] and [%zu]: \n", + types[i], + attrs_info_idx, + i); + SAFE_FREE(types); + code = EINVAL; + goto done; + } + attrs_info_idx = i; + break; + case PAC_TYPE_REQUESTER_SID: + if (requester_sid_idx != -1) { + DBG_WARNING("requester sid type[%u] twice" + "[%zd] and [%zu]: \n", + types[i], + requester_sid_idx, + i); + SAFE_FREE(types); + code = EINVAL; + goto done; + } + requester_sid_idx = i; + break; default: continue; } @@ -766,6 +820,13 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, code = EINVAL; goto done; } + if (!(flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) && + requester_sid_idx == -1) { + DEBUG(1, ("PAC_TYPE_REQUESTER_SID missing\n")); + SAFE_FREE(types); + code = KRB5KDC_ERR_TGT_REVOKED; + goto done; + } /* Build an updated PAC */ code = krb5_pac_init(context, &new_pac); @@ -831,6 +892,10 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, } break; case PAC_TYPE_SRV_CHECKSUM: + if (requester_sid_idx == -1 && requester_sid_blob != NULL) { + /* inject REQUESTER_SID */ + forced_next_type = PAC_TYPE_REQUESTER_SID; + } /* * This is generated in the main KDC code */ @@ -840,6 +905,26 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, * This is generated in the main KDC code */ continue; + case PAC_TYPE_ATTRIBUTES_INFO: + if (!is_untrusted && is_krbtgt) { + /* just copy... */ + break; + } + + continue; + case PAC_TYPE_REQUESTER_SID: + if (!is_krbtgt) { + continue; + } + + /* + * Replace in the RODC case, otherwise + * requester_sid_blob is NULL and we just copy. + */ + if (requester_sid_blob != NULL) { + type_blob = *requester_sid_blob; + } + break; default: /* just copy... */ break; diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h index 636c77ec97c..4431e82a1b2 100644 --- a/source4/kdc/mit_samba.h +++ b/source4/kdc/mit_samba.h @@ -50,6 +50,7 @@ int mit_samba_get_nextkey(struct mit_samba_context *ctx, int mit_samba_get_pac(struct mit_samba_context *smb_ctx, krb5_context context, krb5_db_entry *client, + krb5_db_entry *server, krb5_keyblock *client_key, krb5_pac *pac); |