1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-27 03:21:53 +03:00

r11216: Upgrade to gd's PAC extraction code from Samba3. While I still want

to make some this the kerberos library's problem, we may as well use
the best code that is around.

Andrew Bartlett
(This used to be commit a7fe3078a6)
This commit is contained in:
Andrew Bartlett 2005-10-20 10:15:31 +00:00 committed by Gerald (Jerry) Carter
parent 10989431e5
commit 532b16f3d5
4 changed files with 140 additions and 47 deletions

View File

@ -822,6 +822,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
time_t authtime;
krb5_principal principal;
char *principal_string;
DATA_BLOB pac_blob;
DATA_BLOB unwrapped_pac;
if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
|| (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements,
@ -866,12 +868,19 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
KRB5_AUTHDATA_IF_RELEVANT,
&pac);
}
if (maj_stat == 0) {
pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length);
gss_release_buffer(&min_stat, &pac);
if (!unwrap_pac(mem_ctx, &pac_blob, &unwrapped_pac)) {
/* No pac actually present */
maj_stat = 1;
}
}
if (maj_stat == 0) {
krb5_error_code ret;
DATA_BLOB pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length);
pac_blob = unwrap_pac(mem_ctx, &pac_blob);
gss_release_buffer(&min_stat, &pac);
ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context,
principal_string, &principal);
@ -881,7 +890,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
}
/* decode and verify the pac */
nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob,
nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, unwrapped_pac,
gensec_gssapi_state->smb_krb5_context->krb5_context,
NULL, keyblock, principal, authtime);
krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal);

View File

@ -471,7 +471,7 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security,
static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security,
struct auth_session_info **_session_info)
{
NTSTATUS nt_status;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data;
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info = NULL;
@ -479,45 +479,44 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
krb5_const_principal client_principal;
DATA_BLOB pac_wrapped;
DATA_BLOB pac;
BOOL got_auth_data;
TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
if (!mem_ctx) {
return NT_STATUS_NO_MEMORY;
}
pac_wrapped = get_auth_data_from_tkt(mem_ctx, gensec_krb5_state->ticket);
pac = unwrap_pac(mem_ctx, &pac_wrapped);
client_principal = get_principal_from_tkt(gensec_krb5_state->ticket);
/* decode and verify the pac */
nt_status = kerberos_pac_logon_info(gensec_krb5_state, &logon_info, pac,
gensec_krb5_state->smb_krb5_context->krb5_context,
NULL, gensec_krb5_state->keyblock,
client_principal,
gensec_krb5_state->ticket->ticket.authtime);
got_auth_data = get_auth_data_from_tkt(mem_ctx, &pac, gensec_krb5_state->ticket);
/* IF we have the PAC - otherwise we need to get this
* data from elsewere - local ldb, or (TODO) lookup of some
* kind...
*
* when heimdal can generate the PAC, we should fail if there's
* no PAC present
*/
if (got_auth_data) {
if (NT_STATUS_IS_OK(nt_status)) {
union netr_Validation validation;
validation.sam3 = &logon_info->info3;
nt_status = make_server_info_netlogon_validation(gensec_krb5_state,
NULL,
3, &validation,
&server_info);
client_principal = get_principal_from_tkt(gensec_krb5_state->ticket);
/* decode and verify the pac */
nt_status = kerberos_pac_logon_info(gensec_krb5_state, &logon_info, pac,
gensec_krb5_state->smb_krb5_context->krb5_context,
NULL, gensec_krb5_state->keyblock,
client_principal,
gensec_krb5_state->ticket->ticket.authtime);
if (NT_STATUS_IS_OK(nt_status)) {
union netr_Validation validation;
validation.sam3 = &logon_info->info3;
nt_status = make_server_info_netlogon_validation(gensec_krb5_state,
NULL,
3, &validation,
&server_info);
}
talloc_free(mem_ctx);
NT_STATUS_NOT_OK_RETURN(nt_status);
} else {
}
if (!NT_STATUS_IS_OK(nt_status)) {
/* NO pac, or can't parse or verify it */
krb5_error_code ret;
DATA_BLOB user_sess_key = data_blob(NULL, 0);
DATA_BLOB lm_sess_key = data_blob(NULL, 0);

View File

@ -4,7 +4,8 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Luke Howard 2002-2003
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
Copyright (C) Guenther Deschner 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@ -25,6 +26,7 @@
#include "system/kerberos.h"
#include "system/time.h"
#include "auth/kerberos/kerberos.h"
#include "asn_1.h"
#ifdef HAVE_KRB5
@ -157,23 +159,107 @@
}
#endif
DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx,
krb5_ticket *tkt)
BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data)
{
DATA_BLOB auth_data = data_blob(NULL, 0);
DATA_BLOB pac_contents;
struct asn1_data data;
int data_type;
if (!auth_data->length) {
return False;
}
asn1_load(&data, *auth_data);
asn1_start_tag(&data, ASN1_SEQUENCE(0));
asn1_start_tag(&data, ASN1_SEQUENCE(0));
asn1_start_tag(&data, ASN1_CONTEXT(0));
asn1_read_Integer(&data, &data_type);
if (data_type != KRB5_AUTHDATA_WIN2K_PAC ) {
DEBUG(10,("authorization data is not a Windows PAC (type: %d)\n", data_type));
asn1_free(&data);
return False;
}
asn1_end_tag(&data);
asn1_start_tag(&data, ASN1_CONTEXT(1));
asn1_read_OctetString(&data, &pac_contents);
asn1_end_tag(&data);
asn1_end_tag(&data);
asn1_end_tag(&data);
asn1_free(&data);
*unwrapped_pac_data = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length);
data_blob_free(&pac_contents);
return True;
}
BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt)
{
DATA_BLOB auth_data_wrapped;
BOOL got_auth_data_pac = False;
int i;
#if defined(HAVE_KRB5_TKT_ENC_PART2)
if (tkt && tkt->enc_part2
&& tkt->enc_part2->authorization_data
&& tkt->enc_part2->authorization_data[0]
&& tkt->enc_part2->authorization_data[0]->length)
auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
tkt->enc_part2->authorization_data[0]->length);
if (tkt->enc_part2 && tkt->enc_part2->authorization_data &&
tkt->enc_part2->authorization_data[0] &&
tkt->enc_part2->authorization_data[0]->length)
{
for (i = 0; tkt->enc_part2->authorization_data[i] != NULL; i++) {
if (tkt->enc_part2->authorization_data[i]->ad_type !=
KRB5_AUTHDATA_IF_RELEVANT) {
DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
tkt->enc_part2->authorization_data[i]->ad_type));
continue;
}
auth_data_wrapped = data_blob(tkt->enc_part2->authorization_data[i]->contents,
tkt->enc_part2->authorization_data[i]->length);
/* check if it is a PAC */
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
data_blob_free(&auth_data_wrapped);
if (!got_auth_data_pac) {
continue;
}
}
return got_auth_data_pac;
}
#else
if (tkt && tkt->ticket.authorization_data && tkt->ticket.authorization_data->len)
auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data,
tkt->ticket.authorization_data->val->ad_data.length);
if (tkt->ticket.authorization_data &&
tkt->ticket.authorization_data->len)
{
for (i = 0; i < tkt->ticket.authorization_data->len; i++) {
if (tkt->ticket.authorization_data->val[i].ad_type !=
KRB5_AUTHDATA_IF_RELEVANT) {
DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
tkt->ticket.authorization_data->val[i].ad_type));
continue;
}
auth_data_wrapped = data_blob(tkt->ticket.authorization_data->val[i].ad_data.data,
tkt->ticket.authorization_data->val[i].ad_data.length);
/* check if it is a PAC */
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
data_blob_free(&auth_data_wrapped);
if (!got_auth_data_pac) {
continue;
}
}
return got_auth_data_pac;
}
#endif
return auth_data;
return False;
}
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt)

View File

@ -85,8 +85,7 @@ krb5_error_code ads_krb5_mk_req(krb5_context context,
const char *principal,
krb5_ccache ccache,
krb5_data *outbuf);
DATA_BLOB get_auth_data_from_tkt(TALLOC_CTX *mem_ctx,
krb5_ticket *tkt);
BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
struct smb_krb5_context *smb_krb5_context,
krb5_auth_context *auth_context,