diff options
Diffstat (limited to 'source4/heimdal/lib/gssapi/krb5/init_sec_context.c')
-rw-r--r-- | source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 198 |
1 files changed, 104 insertions, 94 deletions
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 3d5e3b71c5..dfa0e935e6 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -1,34 +1,34 @@ /* - * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include "krb5/gsskrb5_locl.h" @@ -43,14 +43,14 @@ RCSID("$Id$"); static OM_uint32 set_addresses (krb5_context context, krb5_auth_context ac, - const gss_channel_bindings_t input_chan_bindings) + const gss_channel_bindings_t input_chan_bindings) { - /* Port numbers are expected to be in application_data.value, - * initator's port first */ + /* Port numbers are expected to be in application_data.value, + * initator's port first */ krb5_address initiator_addr, acceptor_addr; krb5_error_code kret; - + if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS || input_chan_bindings->application_data.length != 2 * sizeof(ac->local_port)) @@ -58,13 +58,13 @@ set_addresses (krb5_context context, memset(&initiator_addr, 0, sizeof(initiator_addr)); memset(&acceptor_addr, 0, sizeof(acceptor_addr)); - + ac->local_port = *(int16_t *) input_chan_bindings->application_data.value; - + ac->remote_port = *((int16_t *) input_chan_bindings->application_data.value + 1); - + kret = _gsskrb5i_address_to_krb5addr(context, input_chan_bindings->acceptor_addrtype, &input_chan_bindings->acceptor_address, @@ -72,7 +72,7 @@ set_addresses (krb5_context context, &acceptor_addr); if (kret) return kret; - + kret = _gsskrb5i_address_to_krb5addr(context, input_chan_bindings->initiator_addrtype, &input_chan_bindings->initiator_address, @@ -82,15 +82,15 @@ set_addresses (krb5_context context, krb5_free_address (context, &acceptor_addr); return kret; } - + kret = krb5_auth_con_setaddrs(context, ac, &initiator_addr, /* local address */ &acceptor_addr); /* remote address */ - + krb5_free_address (context, &initiator_addr); krb5_free_address (context, &acceptor_addr); - + #if 0 free(input_chan_bindings->application_data.value); input_chan_bindings->application_data.value = NULL; @@ -173,7 +173,8 @@ gsskrb5_get_creds( krb5_context context, krb5_ccache ccache, gsskrb5_ctx ctx, - krb5_const_principal target_name, + const gss_name_t target_name, + int use_dns, OM_uint32 time_req, OM_uint32 * time_rec, krb5_creds ** cred) @@ -185,6 +186,16 @@ gsskrb5_get_creds( *cred = NULL; + if (ctx->target) { + krb5_free_principal(context, ctx->target); + ctx->target = NULL; + } + + ret = _gsskrb5_canon_name(minor_status, context, use_dns, + target_name, &ctx->target); + if (ret) + return ret; + memset(&this_cred, 0, sizeof(this_cred)); this_cred.client = ctx->source; this_cred.server = ctx->target; @@ -236,7 +247,7 @@ gsskrb5_initiator_ready( int32_t seq_number; int is_cfx = 0; OM_uint32 flags = ctx->flags; - + krb5_free_creds(context, ctx->kcred); ctx->kcred = NULL; @@ -245,18 +256,18 @@ gsskrb5_initiator_ready( ctx->ccache = NULL; krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number); - + _gsskrb5i_is_cfx(ctx, &is_cfx); - + ret = _gssapi_msg_order_create(minor_status, &ctx->order, _gssapi_msg_order_f(flags), seq_number, 0, is_cfx); if (ret) return ret; - + ctx->state = INITIATOR_READY; ctx->more_flags |= OPEN; - + return GSS_S_COMPLETE; } @@ -277,14 +288,14 @@ do_delegation (krb5_context context, krb5_creds creds; KDCOptions fwd_flags; krb5_error_code kret; - + memset (&creds, 0, sizeof(creds)); krb5_data_zero (fwd_data); - + kret = krb5_cc_get_principal(context, ccache, &creds.client); - if (kret) + if (kret) goto out; - + kret = krb5_build_principal(context, &creds.server, strlen(creds.client->realm), @@ -293,18 +304,18 @@ do_delegation (krb5_context context, creds.client->realm, NULL); if (kret) - goto out; - + goto out; + creds.times.endtime = 0; - + memset(&fwd_flags, 0, sizeof(fwd_flags)); fwd_flags.forwarded = 1; fwd_flags.forwardable = 1; - + if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/ - name->name.name_string.len < 2) + name->name.name_string.len < 2) goto out; - + kret = krb5_get_forwarded_creds(context, ac, ccache, @@ -312,13 +323,13 @@ do_delegation (krb5_context context, name->name.name_string.val[1], &creds, fwd_data); - + out: if (kret) *flags &= ~flagmask; else *flags |= flagmask; - + if (creds.client) krb5_free_principal(context, creds.client); if (creds.server) @@ -351,7 +362,7 @@ init_auth krb5_data outbuf; krb5_data fwd_data; OM_uint32 lifetime_rec; - int use_dns = 1; + int allow_dns = 1; krb5_data_zero(&outbuf); krb5_data_zero(&fwd_data); @@ -379,21 +390,6 @@ init_auth goto failure; } - /* canon name if needed for client + target realm */ - kret = krb5_cc_get_config(context, ctx->ccache, NULL, - "realm-config", &outbuf); - if (kret == 0) { - /* XXX 2 is no server canon */ - if (outbuf.length < 1 || ((((unsigned char *)outbuf.data)[0]) & 2)) - use_dns = 0; - krb5_data_free(&outbuf); - } - - ret = _gsskrb5_canon_name(minor_status, context, use_dns, - name, &ctx->target); - if (ret) - goto failure; - ret = _gss_DES3_get_mic_compat(minor_status, ctx, context); if (ret) goto failure; @@ -413,14 +409,29 @@ init_auth krb5_set_default_in_tkt_etypes(context, enctypes); } - ret = gsskrb5_get_creds(minor_status, - context, - ctx->ccache, - ctx, - ctx->target, - time_req, - time_rec, - &ctx->kcred); + /* canon name if needed for client + target realm */ + kret = krb5_cc_get_config(context, ctx->ccache, NULL, + "realm-config", &outbuf); + if (kret == 0) { + /* XXX 2 is no server canon */ + if (outbuf.length < 1 || ((((unsigned char *)outbuf.data)[0]) & 2)) + allow_dns = 0; + krb5_data_free(&outbuf); + } + + /* + * First we try w/o dns, hope that the KDC have register alias + * (and referrals if cross realm) for this principal. If that + * fails and if we are allowed to using this realm try again with + * DNS canonicalizion. + */ + ret = gsskrb5_get_creds(minor_status, context, ctx->ccache, + ctx, name, 0, time_req, + time_rec, &ctx->kcred); + if (ret && allow_dns) + ret = gsskrb5_get_creds(minor_status, context, ctx->ccache, + ctx, name, 1, time_req, + time_rec, &ctx->kcred); if (ret) goto failure; @@ -430,9 +441,8 @@ init_auth context, ctx->lifetime, &lifetime_rec); - if (ret) { + if (ret) goto failure; - } if (lifetime_rec == 0) { *minor_status = 0; @@ -440,11 +450,11 @@ init_auth goto failure; } - krb5_auth_con_setkey(context, - ctx->auth_context, + krb5_auth_con_setkey(context, + ctx->auth_context, &ctx->kcred->session); - kret = krb5_auth_con_generatelocalsubkey(context, + kret = krb5_auth_con_generatelocalsubkey(context, ctx->auth_context, &ctx->kcred->session); if(kret) { @@ -496,7 +506,7 @@ init_auth_restart *minor_status = 0; - /* + /* * If the credential doesn't have ok-as-delegate, check if there * is a realm setting and use that. */ @@ -532,12 +542,12 @@ init_auth_restart ctx->ccache, ctx->kcred, ctx->target, &fwd_data, flagmask, &flags); } - + if (req_flags & GSS_C_MUTUAL_FLAG) { flags |= GSS_C_MUTUAL_FLAG; ap_options |= AP_OPTS_MUTUAL_REQUIRED; } - + if (req_flags & GSS_C_REPLAY_FLAG) flags |= GSS_C_REPLAY_FLAG; if (req_flags & GSS_C_SEQUENCE_FLAG) @@ -565,12 +575,12 @@ init_auth_restart flags |= GSS_C_INTEG_FLAG; } flags |= GSS_C_TRANS_FLAG; - + if (ret_flags) *ret_flags = flags; ctx->flags = flags; ctx->more_flags |= LOCAL; - + ret = _gsskrb5_create_8003_checksum (minor_status, input_chan_bindings, flags, @@ -748,13 +758,13 @@ repl_mutual } krb5_free_ap_rep_enc_part (context, repl); - + _gsskrb5i_is_cfx(ctx, &is_cfx); if (is_cfx) { krb5_keyblock *key = NULL; kret = krb5_auth_con_getremotesubkey(context, - ctx->auth_context, + ctx->auth_context, &key); if (kret == 0 && key != NULL) { ctx->more_flags |= ACCEPTOR_SUBKEY; @@ -853,7 +863,7 @@ OM_uint32 _gsskrb5_init_sec_context return GSS_S_BAD_NAME; } - if (mech_type != GSS_C_NO_OID && + if (mech_type != GSS_C_NO_OID && !gss_oid_equal(mech_type, GSS_KRB5_MECHANISM)) return GSS_S_BAD_MECH; @@ -864,7 +874,7 @@ OM_uint32 _gsskrb5_init_sec_context *minor_status = 0; return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE; } - + ret = _gsskrb5_create_ctx(minor_status, context_handle, context, @@ -900,7 +910,7 @@ OM_uint32 _gsskrb5_init_sec_context ret_flags, time_rec); if (ret != GSS_S_COMPLETE) - break; + break; /* FALL THOUGH */ case INITIATOR_RESTART: ret = init_auth_restart(minor_status, @@ -932,7 +942,7 @@ OM_uint32 _gsskrb5_init_sec_context goto again; break; case INITIATOR_READY: - /* + /* * If we get there, the caller have called * gss_init_sec_context() one time too many. */ |