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/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 +++++++++++- 6 files changed, 114 insertions(+), 62 deletions(-) (limited to 'source4/heimdal/lib/gssapi/krb5') 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; } -- cgit