From 9e6b0c28712ee77ce878809c8576826a3ba08d95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Mar 2008 10:17:42 +1100 Subject: Merge lorikeet-heimdal -r 787 into Samba4 tree. Andrew Bartlett (This used to be commit d88b530522d3cef67c24422bd5182fb875d87ee2) --- source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h | 3 +- source4/heimdal/lib/gssapi/gssapi_mech.h | 2 + source4/heimdal/lib/gssapi/krb5/acquire_cred.c | 74 +++++++++++++--------- source4/heimdal/lib/gssapi/krb5/external.c | 4 +- source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h | 2 +- source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h | 3 +- source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 54 ++++++++-------- source4/heimdal/lib/gssapi/krb5/set_cred_option.c | 39 +++++++++++- source4/heimdal/lib/gssapi/mech/context.c | 18 +++++- .../lib/gssapi/mech/gss_accept_sec_context.c | 6 +- source4/heimdal/lib/gssapi/mech/gss_krb5.c | 43 ++++++++++++- source4/heimdal/lib/gssapi/mech/gss_mech_switch.c | 2 +- .../heimdal/lib/gssapi/mech/gss_release_oid_set.c | 4 +- .../heimdal/lib/gssapi/spnego/accept_sec_context.c | 27 ++++---- source4/heimdal/lib/gssapi/spnego/compat.c | 3 +- source4/heimdal/lib/gssapi/spnego/context_stubs.c | 70 ++++++++++++-------- source4/heimdal/lib/gssapi/spnego/external.c | 4 +- .../heimdal/lib/gssapi/spnego/init_sec_context.c | 11 +++- source4/heimdal/lib/gssapi/spnego/spnego-private.h | 9 --- 19 files changed, 254 insertions(+), 124 deletions(-) (limited to 'source4/heimdal/lib/gssapi') diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h index cca529fe26..2223f4f22f 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_krb5.h 20385 2007-04-18 08:51:32Z lha $ */ +/* $Id: gssapi_krb5.h 22655 2008-02-26 12:40:35Z lha $ */ #ifndef GSSAPI_KRB5_H_ #define GSSAPI_KRB5_H_ @@ -80,6 +80,7 @@ extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X; /* Extensions creds */ extern gss_OID GSS_KRB5_IMPORT_CRED_X; extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X; +extern gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X; /* * kerberos mechanism specific functions diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h index 403990ad47..b360de13fc 100644 --- a/source4/heimdal/lib/gssapi/gssapi_mech.h +++ b/source4/heimdal/lib/gssapi/gssapi_mech.h @@ -356,4 +356,6 @@ gssapi_mech_interface __gss_spnego_initialize(void); gssapi_mech_interface __gss_krb5_initialize(void); gssapi_mech_interface __gss_ntlm_initialize(void); +void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32); + #endif /* GSSAPI_MECH_H */ diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index d5c70636bc..051446c19b 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: acquire_cred.c 21221 2007-06-20 08:42:10Z lha $"); +RCSID("$Id: acquire_cred.c 22596 2008-02-18 18:05:55Z lha $"); OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, @@ -128,9 +128,12 @@ static OM_uint32 acquire_initiator_cred ret = GSS_S_FAILURE; memset(&cred, 0, sizeof(cred)); - /* If we have a preferred principal, lets try to find it in all - * caches, otherwise, fall back to default cache. Ignore - * errors. */ + /* + * If we have a preferred principal, lets try to find it in all + * caches, otherwise, fall back to default cache, ignore all + * errors while searching. + */ + if (handle->principal) kret = krb5_cc_cache_match (context, handle->principal, @@ -142,32 +145,30 @@ static OM_uint32 acquire_initiator_cred if (kret) goto end; } - kret = krb5_cc_get_principal(context, ccache, - &def_princ); + kret = krb5_cc_get_principal(context, ccache, &def_princ); if (kret != 0) { /* we'll try to use a keytab below */ - krb5_cc_destroy(context, ccache); - ccache = NULL; + krb5_cc_close(context, ccache); + def_princ = NULL; kret = 0; } else if (handle->principal == NULL) { - kret = krb5_copy_principal(context, def_princ, - &handle->principal); + kret = krb5_copy_principal(context, def_princ, &handle->principal); if (kret) goto end; } else if (handle->principal != NULL && - krb5_principal_compare(context, handle->principal, - def_princ) == FALSE) { - /* Before failing, lets check the keytab */ + krb5_principal_compare(context, handle->principal, + def_princ) == FALSE) { krb5_free_principal(context, def_princ); def_princ = NULL; + krb5_cc_close(context, ccache); + ccache = NULL; } if (def_princ == NULL) { /* We have no existing credentials cache, * so attempt to get a TGT using a keytab. */ if (handle->principal == NULL) { - kret = krb5_get_default_principal(context, - &handle->principal); + kret = krb5_get_default_principal(context, &handle->principal); if (kret) goto end; } @@ -182,16 +183,19 @@ static OM_uint32 acquire_initiator_cred krb5_get_init_creds_opt_free(context, opt); if (kret) goto end; - kret = krb5_cc_gen_new(context, &krb5_mcc_ops, - &ccache); + kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache); if (kret) goto end; kret = krb5_cc_initialize(context, ccache, cred.client); - if (kret) + if (kret) { + krb5_cc_destroy(context, ccache); goto end; + } kret = krb5_cc_store_cred(context, ccache, &cred); - if (kret) + if (kret) { + krb5_cc_destroy(context, ccache); goto end; + } handle->lifetime = cred.times.endtime; handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; } else { @@ -201,8 +205,10 @@ static OM_uint32 acquire_initiator_cred ccache, handle->principal, &handle->lifetime); - if (ret != GSS_S_COMPLETE) + if (ret != GSS_S_COMPLETE) { + krb5_cc_close(context, ccache); goto end; + } kret = 0; } @@ -216,13 +222,8 @@ end: krb5_free_principal(context, def_princ); if (keytab != NULL) krb5_kt_close(context, keytab); - if (ret != GSS_S_COMPLETE) { - if (ccache != NULL) - krb5_cc_close(context, ccache); - if (kret != 0) { - *minor_status = kret; - } - } + if (ret != GSS_S_COMPLETE && kret != 0) + *minor_status = kret; return (ret); } @@ -257,8 +258,23 @@ static OM_uint32 acquire_acceptor_cred goto end; krb5_kt_free_entry(context, &entry); ret = GSS_S_COMPLETE; - } - + } else { + /* + * Check if there is at least one entry in the keytab before + * declaring it as an useful keytab. + */ + krb5_keytab_entry tmp; + krb5_kt_cursor c; + + kret = krb5_kt_start_seq_get (context, handle->keytab, &c); + if (kret) + goto end; + if (krb5_kt_next_entry(context, handle->keytab, &tmp, &c) == 0) { + krb5_kt_free_entry(context, &tmp); + ret = GSS_S_COMPLETE; /* ok found one entry */ + } + krb5_kt_end_seq_get (context, handle->keytab, &c); + } end: if (ret != GSS_S_COMPLETE) { if (handle->keytab != NULL) diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index d4c1bc4db2..03fe61dc57 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,7 +34,7 @@ #include "krb5/gsskrb5_locl.h" #include -RCSID("$Id: external.c 20386 2007-04-18 08:52:08Z lha $"); +RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $"); /* * The implementation must reserve static storage for a @@ -374,8 +374,6 @@ gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc; * Context for krb5 calls. */ -krb5_context context; - /* * */ diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h index c2239f1346..64a0dd36b1 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h @@ -413,7 +413,7 @@ _gsskrb5_init (krb5_context */*context*/); OM_uint32 _gsskrb5_init_sec_context ( OM_uint32 * /*minor_status*/, - const gss_cred_id_t /*initiator_cred_handle*/, + const gss_cred_id_t /*cred_handle*/, gss_ctx_id_t * /*context_handle*/, const gss_name_t /*target_name*/, const gss_OID /*mech_type*/, diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 6ffb607035..3e8c1b8fa6 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gsskrb5_locl.h 20324 2007-04-12 16:46:01Z lha $ */ +/* $Id: gsskrb5_locl.h 22655 2008-02-26 12:40:35Z lha $ */ #ifndef GSSKRB5_LOCL_H #define GSSKRB5_LOCL_H @@ -86,6 +86,7 @@ typedef struct { krb5_principal principal; int cred_flags; #define GSS_CF_DESTROY_CRED_ON_RELEASE 1 +#define GSS_CF_NO_CI_FLAGS 2 struct krb5_keytab_data *keytab; OM_uint32 lifetime; gss_cred_usage_t usage; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 4d1ae0daa9..d4482a54b2 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init_sec_context.c 20326 2007-04-12 16:49:57Z lha $"); +RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $"); /* * copy the addresses from `input_chan_bindings' (if any) to @@ -326,7 +326,7 @@ do_delegation (krb5_context context, static OM_uint32 init_auth (OM_uint32 * minor_status, - gsskrb5_cred initiator_cred_handle, + gsskrb5_cred cred, gsskrb5_ctx ctx, krb5_context context, krb5_const_principal name, @@ -344,7 +344,7 @@ init_auth OM_uint32 ret = GSS_S_FAILURE; krb5_error_code kret; krb5_flags ap_options; - krb5_creds *cred = NULL; + krb5_creds *kcred = NULL; krb5_data outbuf; krb5_ccache ccache = NULL; uint32_t flags; @@ -362,7 +362,7 @@ init_auth if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; - if (initiator_cred_handle == NULL) { + if (cred == NULL) { kret = krb5_cc_default (context, &ccache); if (kret) { *minor_status = kret; @@ -370,7 +370,7 @@ init_auth goto failure; } } else - ccache = initiator_cred_handle->ccache; + ccache = cred->ccache; kret = krb5_cc_get_principal (context, ccache, &ctx->source); if (kret) { @@ -400,8 +400,8 @@ init_auth { krb5_enctype *enctypes = NULL; - if (initiator_cred_handle && initiator_cred_handle->enctypes) - enctypes = initiator_cred_handle->enctypes; + if (cred && cred->enctypes) + enctypes = cred->enctypes; krb5_set_default_in_tkt_etypes(context, enctypes); } @@ -412,11 +412,11 @@ init_auth ctx->target, time_req, time_rec, - &cred); + &kcred); if (ret) goto failure; - ctx->lifetime = cred->times.endtime; + ctx->lifetime = kcred->times.endtime; ret = _gsskrb5_lifetime_left(minor_status, context, @@ -434,11 +434,11 @@ init_auth krb5_auth_con_setkey(context, ctx->auth_context, - &cred->session); + &kcred->session); kret = krb5_auth_con_generatelocalsubkey(context, ctx->auth_context, - &cred->session); + &kcred->session); if(kret) { *minor_status = kret; ret = GSS_S_FAILURE; @@ -449,10 +449,10 @@ init_auth * If the credential doesn't have ok-as-delegate, check what local * policy say about ok-as-delegate, default is FALSE that makes * code ignore the KDC setting and follow what the application - * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the + * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the * KDC doesn't set ok-as-delegate. */ - if (!cred->flags.b.ok_as_delegate) { + if (!kcred->flags.b.ok_as_delegate) { krb5_boolean delegate; krb5_appdefault_boolean(context, @@ -467,7 +467,7 @@ init_auth if (req_flags & GSS_C_DELEG_FLAG) do_delegation (context, ctx->auth_context, - ccache, cred, name, &fwd_data, &flags); + ccache, kcred, name, &fwd_data, &flags); if (req_flags & GSS_C_MUTUAL_FLAG) { flags |= GSS_C_MUTUAL_FLAG; @@ -490,8 +490,10 @@ init_auth if (req_flags & GSS_C_EXTENDED_ERROR_FLAG) flags |= GSS_C_EXTENDED_ERROR_FLAG; - flags |= GSS_C_CONF_FLAG; - flags |= GSS_C_INTEG_FLAG; + if (cred == NULL || !(cred->cred_flags & GSS_CF_NO_CI_FLAGS)) { + flags |= GSS_C_CONF_FLAG; + flags |= GSS_C_INTEG_FLAG; + } flags |= GSS_C_TRANS_FLAG; if (ret_flags) @@ -513,7 +515,7 @@ init_auth kret = krb5_build_authenticator (context, ctx->auth_context, enctype, - cred, + kcred, &cksum, NULL, &authenticator, @@ -527,7 +529,7 @@ init_auth kret = krb5_build_ap_req (context, enctype, - cred, + kcred, ap_options, authenticator, &outbuf); @@ -544,9 +546,9 @@ init_auth goto failure; krb5_data_free (&outbuf); - krb5_free_creds(context, cred); + krb5_free_creds(context, kcred); free_Checksum(&cksum); - if (initiator_cred_handle == NULL) + if (cred == NULL) krb5_cc_close(context, ccache); if (flags & GSS_C_MUTUAL_FLAG) { @@ -556,9 +558,9 @@ init_auth return gsskrb5_initiator_ready(minor_status, ctx, context); failure: - if(cred) - krb5_free_creds(context, cred); - if (ccache && initiator_cred_handle == NULL) + if(kcred) + krb5_free_creds(context, kcred); + if (ccache && cred == NULL) krb5_cc_close(context, ccache); return ret; @@ -682,7 +684,7 @@ repl_mutual OM_uint32 _gsskrb5_init_sec_context (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, + const gss_cred_id_t cred_handle, gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, @@ -697,7 +699,7 @@ OM_uint32 _gsskrb5_init_sec_context ) { krb5_context context; - gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle; + gsskrb5_cred cred = (gsskrb5_cred)cred_handle; krb5_const_principal name = (krb5_const_principal)target_name; gsskrb5_ctx ctx; OM_uint32 ret; diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index d0ca1c4d95..242dfa87b4 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,13 +32,22 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_cred_option.c 20325 2007-04-12 16:49:17Z lha $"); +RCSID("$Id: set_cred_option.c 22655 2008-02-26 12:40:35Z lha $"); +/* 1.2.752.43.13.17 */ +static gss_OID_desc gss_krb5_ccache_name_x_oid_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")}; + +gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_ccache_name_x_oid_desc; + +/* 1.2.752.43.13.18 */ static gss_OID_desc gss_krb5_import_cred_x_oid_desc = -{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */ +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")}; gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc; + + static OM_uint32 import_cred(OM_uint32 *minor_status, krb5_context context, @@ -201,6 +210,27 @@ out: return major_stat; } +static OM_uint32 +no_ci_flags(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + cred->cred_flags |= GSS_CF_NO_CI_FLAGS; + + *minor_status = 0; + return GSS_S_COMPLETE; + +} + OM_uint32 _gsskrb5_set_cred_option @@ -224,6 +254,11 @@ _gsskrb5_set_cred_option if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X)) return allowed_enctypes(minor_status, context, cred_handle, value); + if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) { + return no_ci_flags(minor_status, context, cred_handle, value); + } + + *minor_status = EINVAL; return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/mech/context.c b/source4/heimdal/lib/gssapi/mech/context.c index e4517bee44..926630c42d 100644 --- a/source4/heimdal/lib/gssapi/mech/context.c +++ b/source4/heimdal/lib/gssapi/mech/context.c @@ -1,7 +1,7 @@ #include "mech/mech_locl.h" #include "heim_threads.h" -RCSID("$Id: context.c 21248 2007-06-21 00:45:13Z lha $"); +RCSID("$Id: context.c 22600 2008-02-21 12:46:24Z lha $"); struct mg_thread_ctx { gss_OID mech; @@ -107,6 +107,13 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min) OM_uint32 message_content; struct mg_thread_ctx *mg; + /* + * Mechs without gss_display_status() does + * gss_mg_collect_error() by themself. + */ + if (m->gm_display_status == NULL) + return ; + mg = _gss_mechglue_thread(); if (mg == NULL) return; @@ -139,3 +146,12 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min) mg->min_error.length = 0; } } + +void +gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min) +{ + gssapi_mech_interface m = __gss_get_mechanism(mech); + if (m == NULL) + return; + _gss_mg_error(m, maj, min); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index d1e243d8b8..a6b1ded5ca 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_accept_sec_context.c 21237 2007-06-20 11:21:09Z lha $"); +RCSID("$Id: gss_accept_sec_context.c 22071 2007-11-14 20:04:50Z lha $"); static OM_uint32 parse_header(const gss_buffer_t input_token, gss_OID mech_oid) @@ -38,7 +38,7 @@ parse_header(const gss_buffer_t input_token, gss_OID mech_oid) /* * Token must start with [APPLICATION 0] SEQUENCE. - * But if it doesn't assume its DCE-STYLE Kerberos! + * But if it doesn't assume it is DCE-STYLE Kerberos! */ if (len == 0) return (GSS_S_DEFECTIVE_TOKEN); @@ -102,7 +102,7 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid) OM_uint32 status; /* - * First try to parse the gssapi token header and see if its a + * First try to parse the gssapi token header and see if it's a * correct header, use that in the first hand. */ diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c index 9e77f42982..03081cb70f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_krb5.c 21123 2007-06-18 20:05:26Z lha $"); +RCSID("$Id: gss_krb5.c 21889 2007-08-09 07:43:24Z lha $"); #include #include @@ -253,7 +253,6 @@ free_key(gss_krb5_lucid_key_t *key) memset(key, 0, sizeof(*key)); } - OM_uint32 gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, @@ -824,3 +823,43 @@ gsskrb5_set_default_realm(const char *realm) return (GSS_S_COMPLETE); } + +OM_uint32 +gss_krb5_get_tkt_flags(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + OM_uint32 *tkt_flags) +{ + + OM_uint32 major_status; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + GSS_KRB5_GET_TKT_FLAGS_X, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1 || + data_set->elements[0].length < 4) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + { + const u_char *p = data_set->elements[0].value; + *tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + } + + gss_release_buffer_set(minor_status, &data_set); + return GSS_S_COMPLETE; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c index f1a18afb13..fe65ad1ae1 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -28,7 +28,7 @@ #include "mech_locl.h" #include -RCSID("$Id: gss_mech_switch.c 21700 2007-07-26 19:08:34Z lha $"); +RCSID("$Id: gss_mech_switch.c 21698 2007-07-26 19:07:11Z lha $"); #ifndef _PATH_GSS_MECH #define _PATH_GSS_MECH "/etc/gss/mech" diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c index 4372e62294..388cfdbf4c 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_oid_set.c 19963 2007-01-17 16:01:22Z lha $"); +RCSID("$Id: gss_release_oid_set.c 22144 2007-12-04 17:31:55Z lha $"); OM_uint32 gss_release_oid_set(OM_uint32 *minor_status, @@ -35,7 +35,7 @@ gss_release_oid_set(OM_uint32 *minor_status, { *minor_status = 0; - if (*set) { + if (set && *set) { if ((*set)->elements) free((*set)->elements); free(*set); diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index 1afe26f1e3..df25b0f4bf 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: accept_sec_context.c 21461 2007-07-10 14:01:13Z lha $"); +RCSID("$Id: accept_sec_context.c 22600 2008-02-21 12:46:24Z lha $"); static OM_uint32 send_reject (OM_uint32 *minor_status, @@ -540,7 +540,7 @@ acceptor_start gss_cred_id_t *delegated_cred_handle ) { - OM_uint32 ret, junk, minor; + OM_uint32 ret, junk; NegotiationToken nt; size_t nt_len; NegTokenInit *ni; @@ -609,7 +609,7 @@ acceptor_start /* * First we try the opportunistic token if we have support for it, * don't try to verify we have credential for the token, - * gss_accept_sec_context will (hopefully) tell us that. + * gss_accept_sec_context() will (hopefully) tell us that. * If that failes, */ @@ -633,12 +633,12 @@ acceptor_start mech_cred = GSS_C_NO_CREDENTIAL; if (ctx->mech_src_name != GSS_C_NO_NAME) - gss_release_name(&minor, &ctx->mech_src_name); + gss_release_name(&junk, &ctx->mech_src_name); if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL) - _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); + _gss_spnego_release_cred(&junk, &ctx->delegated_cred_id); - ret = gss_accept_sec_context(&minor, + ret = gss_accept_sec_context(minor_status, &ctx->negotiated_ctx_id, mech_cred, mech_input_token, @@ -656,7 +656,7 @@ acceptor_start ctx->open = 1; if (mech_delegated_cred && delegated_cred_handle) - ret = _gss_spnego_alloc_cred(minor_status, + ret = _gss_spnego_alloc_cred(&junk, mech_delegated_cred, delegated_cred_handle); else @@ -674,6 +674,8 @@ acceptor_start goto out; first_ok = 1; + } else { + gss_mg_collect_error(preferred_mech_type, ret, *minor_status); } } @@ -681,7 +683,9 @@ acceptor_start * If opportunistic token failed, lets try the other mechs. */ - if (!first_ok) { + if (!first_ok && ni->mechToken != NULL) { + + preferred_mech_type = GSS_C_NO_OID; /* Call glue layer to find first mech we support */ for (i = 1; i < ni->mechTypes.len; ++i) { @@ -695,7 +699,7 @@ acceptor_start if (preferred_mech_type == GSS_C_NO_OID) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_NegotiationToken(&nt); - return GSS_S_BAD_MECH; + return ret; } ctx->preferred_mech_type = preferred_mech_type; @@ -717,7 +721,7 @@ acceptor_start out: if (mech_output_token.value != NULL) - gss_release_buffer(&minor, &mech_output_token); + gss_release_buffer(&junk, &mech_output_token); if (mech_buf.value != NULL) { free(mech_buf.value); mech_buf.value = NULL; @@ -754,7 +758,7 @@ out: return ret; } - _gss_spnego_internal_delete_sec_context(&minor, context_handle, + _gss_spnego_internal_delete_sec_context(&junk, context_handle, GSS_C_NO_BUFFER); return ret; @@ -877,6 +881,7 @@ acceptor_continue } if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { free_NegotiationToken(&nt); + gss_mg_collect_error(ctx->negotiated_mech_type, ret, minor); send_reject (minor_status, output_token); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c index bc7da9410e..287f4f760e 100644 --- a/source4/heimdal/lib/gssapi/spnego/compat.c +++ b/source4/heimdal/lib/gssapi/spnego/compat.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: compat.c 19415 2006-12-18 17:52:26Z lha $"); +RCSID("$Id: compat.c 21866 2007-08-08 11:31:29Z lha $"); /* * Apparently Microsoft got the OID wrong, and used @@ -129,6 +129,7 @@ OM_uint32 _gss_spnego_internal_delete_sec_context gss_release_oid(&minor, &ctx->preferred_mech_type); ctx->negotiated_mech_type = GSS_C_NO_OID; + gss_release_name(&minor, &ctx->target_name); gss_release_name(&minor, &ctx->mech_src_name); if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) { diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c index 3535c7bb35..0169017ee5 100644 --- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: context_stubs.c 21035 2007-06-09 15:32:47Z lha $"); +RCSID("$Id: context_stubs.c 22604 2008-02-21 21:12:48Z lha $"); static OM_uint32 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) @@ -263,18 +263,6 @@ OM_uint32 _gss_spnego_unwrap qop_state); } -OM_uint32 _gss_spnego_display_status - (OM_uint32 * minor_status, - OM_uint32 status_value, - int status_type, - const gss_OID mech_type, - OM_uint32 * message_context, - gss_buffer_t status_string - ) -{ - return GSS_S_FAILURE; -} - OM_uint32 _gss_spnego_compare_name (OM_uint32 *minor_status, const gss_name_t name1, @@ -406,28 +394,58 @@ OM_uint32 _gss_spnego_inquire_context ( ) { gssspnego_ctx ctx; + OM_uint32 maj_stat, junk; + gss_name_t src_mn, targ_mn; *minor_status = 0; - if (context_handle == GSS_C_NO_CONTEXT) { + if (context_handle == GSS_C_NO_CONTEXT) return GSS_S_NO_CONTEXT; - } ctx = (gssspnego_ctx)context_handle; - if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) return GSS_S_NO_CONTEXT; - } - return gss_inquire_context(minor_status, - ctx->negotiated_ctx_id, - src_name, - targ_name, - lifetime_rec, - mech_type, - ctx_flags, - locally_initiated, - open_context); + maj_stat = gss_inquire_context(minor_status, + ctx->negotiated_ctx_id, + &src_mn, + &targ_mn, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open_context); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + + if (src_name) { + spnego_name name = calloc(1, sizeof(*name)); + if (name == NULL) + goto enomem; + name->mech = src_mn; + *src_name = (gss_name_t)name; + } else + gss_release_name(&junk, &src_mn); + + if (targ_name) { + spnego_name name = calloc(1, sizeof(*name)); + if (name == NULL) { + gss_release_name(minor_status, src_name); + goto enomem; + } + name->mech = targ_mn; + *targ_name = (gss_name_t)name; + } else + gss_release_name(&junk, &targ_mn); + + return GSS_S_COMPLETE; + +enomem: + gss_release_name(&junk, &targ_mn); + gss_release_name(&junk, &src_mn); + *minor_status = ENOMEM; + return GSS_S_FAILURE; } OM_uint32 _gss_spnego_wrap_size_limit ( diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c index fbc231f3ae..6c9a03a3b0 100644 --- a/source4/heimdal/lib/gssapi/spnego/external.c +++ b/source4/heimdal/lib/gssapi/spnego/external.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" #include -RCSID("$Id: external.c 18336 2006-10-07 22:27:13Z lha $"); +RCSID("$Id: external.c 22600 2008-02-21 12:46:24Z lha $"); /* * RFC2478, SPNEGO: @@ -57,7 +57,7 @@ static gssapi_mech_interface_desc spnego_mech = { _gss_spnego_verify_mic, _gss_spnego_wrap, _gss_spnego_unwrap, - _gss_spnego_display_status, + NULL, NULL, _gss_spnego_compare_name, _gss_spnego_display_name, diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c index 7c74981e66..bee4895898 100644 --- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: init_sec_context.c 19411 2006-12-18 15:42:03Z lha $"); +RCSID("$Id: init_sec_context.c 22600 2008-02-21 12:46:24Z lha $"); /* * Is target_name an sane target for `mech´. @@ -59,8 +59,10 @@ initiator_approved(gss_name_t target_name, gss_OID mech) &out, NULL, NULL); - if (GSS_ERROR(maj_stat)) + if (GSS_ERROR(maj_stat)) { + gss_mg_collect_error(mech, maj_stat, min_stat); return GSS_S_BAD_MECH; + } gss_release_buffer(&min_stat, &out); gss_delete_sec_context(&min_stat, &ctx, NULL); @@ -268,6 +270,7 @@ spnego_initial if (GSS_ERROR(sub)) { free_NegTokenInit(&ni); *minor_status = minor; + gss_mg_collect_error(ctx->preferred_mech_type, sub, minor); _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); return sub; } @@ -480,7 +483,8 @@ spnego_reply return GSS_S_BAD_MECH; } - if (resp.responseToken != NULL || + /* if a token (of non zero length), or no context, pass to underlaying mech */ + if ((resp.responseToken != NULL && resp.responseToken->length) || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { gss_buffer_desc mech_input_token; @@ -515,6 +519,7 @@ spnego_reply if (GSS_ERROR(ret)) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_NegTokenResp(&resp); + gss_mg_collect_error(&mech, ret, minor); *minor_status = minor; return ret; } diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h index d80db0018a..69f4d8423d 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego-private.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h @@ -90,15 +90,6 @@ _gss_spnego_display_name ( gss_buffer_t /*output_name_buffer*/, gss_OID * output_name_type ); -OM_uint32 -_gss_spnego_display_status ( - OM_uint32 * /*minor_status*/, - OM_uint32 /*status_value*/, - int /*status_type*/, - const gss_OID /*mech_type*/, - OM_uint32 * /*message_context*/, - gss_buffer_t status_string ); - OM_uint32 _gss_spnego_duplicate_name ( OM_uint32 * /*minor_status*/, -- cgit