diff options
Diffstat (limited to 'source4/kdc/mit_samba.c')
-rw-r--r-- | source4/kdc/mit_samba.c | 93 |
1 files changed, 89 insertions, 4 deletions
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; |