From 14a3abd5591a7c310bdd2638e5c06833dc2c8f92 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Oct 2005 23:41:01 +0000 Subject: r11314: Use a patch from lha to have the kerberos libs extract the PAC, rather than doing ASN.1 parsing in Samba. Also use the API function for getting a client from a ticket, rather than just digging in the structure. Andrew Bartlett (This used to be commit 25d5ea6d724bd2b64a6086ae6e2e1c5148b8ca4a) --- source4/auth/gensec/gensec_gssapi.c | 9 +-- source4/auth/gensec/gensec_krb5.c | 54 +++++++++++---- source4/auth/kerberos/clikrb5.c | 112 ------------------------------- source4/auth/kerberos/kerberos-notes.txt | 14 ++-- 4 files changed, 50 insertions(+), 139 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 86ecb604ae..37c8333da3 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -873,18 +873,13 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi if (maj_stat == 0) { maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_IF_RELEVANT, + KRB5_AUTHDATA_WIN2K_PAC, &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 we have the PAC - otherwise we need to get this @@ -902,7 +897,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, unwrapped_pac, + nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, NULL, keyblock, principal, authtime); krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal); diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 3ed38a435c..36cfc49196 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -473,30 +473,44 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data; + krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; - krb5_const_principal client_principal; + krb5_principal client_principal; DATA_BLOB pac; + krb5_data pac_data; - BOOL got_auth_data; + krb5_error_code ret; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } - 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... - */ - if (got_auth_data) { + ret = krb5_ticket_get_authorization_data_type(context, gensec_krb5_state->ticket, + KRB5_AUTHDATA_WIN2K_PAC, + &pac_data); + + if (ret) { + DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", + smb_get_krb5_error_message(context, + ret, mem_ctx))); + } else { + pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length); + if (!pac.data) { + return NT_STATUS_NO_MEMORY; + } - client_principal = get_principal_from_tkt(gensec_krb5_state->ticket); + ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal); + if (ret) { + DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", + smb_get_krb5_error_message(context, + ret, mem_ctx))); + return NT_STATUS_NO_MEMORY; + } /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(gensec_krb5_state, &logon_info, pac, @@ -504,6 +518,8 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security NULL, gensec_krb5_state->keyblock, client_principal, gensec_krb5_state->ticket->ticket.authtime); + krb5_free_principal(context, client_principal); + if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; validation.sam3 = &logon_info->info3; @@ -515,12 +531,26 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security talloc_free(mem_ctx); } + + + /* IF we have the PAC - otherwise we need to get this + * data from elsewere - local ldb, or (TODO) lookup of some + * kind... + */ if (!NT_STATUS_IS_OK(nt_status)) { /* NO pac, or can't parse or verify it */ - krb5_error_code ret; char *principal_string; + ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal); + if (ret) { + DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", + smb_get_krb5_error_message(context, + ret, mem_ctx))); + return NT_STATUS_NO_MEMORY; + } + ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context, - get_principal_from_tkt(gensec_krb5_state->ticket), &principal_string); + client_principal, &principal_string); + krb5_free_principal(context, client_principal); if (ret) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/auth/kerberos/clikrb5.c b/source4/auth/kerberos/clikrb5.c index 17a1e5f3d4..3cac97cdc6 100644 --- a/source4/auth/kerberos/clikrb5.c +++ b/source4/auth/kerberos/clikrb5.c @@ -159,118 +159,6 @@ } #endif -BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) -{ - 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->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->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 False; -} - - krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - return tkt->enc_part2->client; -#else - return tkt->client; -#endif -} - #if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) void krb5_free_unparsed_name(krb5_context context, char *val) { diff --git a/source4/auth/kerberos/kerberos-notes.txt b/source4/auth/kerberos/kerberos-notes.txt index a36bf556aa..83fb886c45 100644 --- a/source4/auth/kerberos/kerberos-notes.txt +++ b/source4/auth/kerberos/kerberos-notes.txt @@ -309,6 +309,12 @@ Samba makes extensive use of the principal manipulation functions in Heimdal, including the known structure behind krb_principal and krb5_realm (a char *). +Authz data extraction +--------------------- + +We use krb5_ticket_get_authorization_data_type(), and expect it to +return the correct authz data, even if wrapped in an AD-IFRELEVENT container. + KDC Extensions -------------- @@ -392,14 +398,6 @@ PAC Correctness We need to put the PAC into the TGT, not just the service ticket. -Authz data extraction ---------------------- - -We need to parse the authz data field correctly, and have a generic -rouitine to get at particular types of data, no matter their inclusion -in 'if relevent' or other stuctures. This should be a utlity function -we can use in both the client libs and KDC. - Forwarded tickets ----------------- -- cgit