summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>2003-07-17 20:50:36 +0000
committerTom Yu <tlyu@mit.edu>2003-07-17 20:50:36 +0000
commit24232fb5e0497300f36d85285d9b156bc936eb2d (patch)
treeabd9059fe1daf3707e4ade8a075c6d7464968bc3 /src
parent3a507eb5f473854153d48197b3cd6c3d81534d48 (diff)
downloadkrb5-24232fb5e0497300f36d85285d9b156bc936eb2d.tar.gz
krb5-24232fb5e0497300f36d85285d9b156bc936eb2d.tar.xz
krb5-24232fb5e0497300f36d85285d9b156bc936eb2d.zip
Remove kg_release_defcred and caching of default credential. Rewrite
krb5_gss_init_sec_context() while we're at it to make defcred-related changes easier, and as a side effect, fix some error condition memory leaks. ticket: 1365 target_version: 1.3.1 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15694 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/lib/gssapi/ChangeLog5
-rw-r--r--src/lib/gssapi/gss_libinit.c3
-rw-r--r--src/lib/gssapi/krb5/ChangeLog37
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h2
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c36
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c988
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c25
-rw-r--r--src/lib/gssapi/krb5/rel_cred.c6
-rw-r--r--src/lib/gssapi/krb5/set_ccache.c2
9 files changed, 625 insertions, 479 deletions
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 26747104bc..27fc2d9a9e 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,8 @@
+2003-07-17 Tom Yu <tlyu@mit.edu>
+
+ * gss_libinit.c (gssint_initialize_library): Don't call
+ kg_release_defcred(); it doesn't exist any more.
+
2003-03-08 Ken Raeburn <raeburn@mit.edu>
* Makefile.in ($(BUILDTOP)/include/gssapi/gssapi.h,
diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c
index 7906786e95..0568f29640 100644
--- a/src/lib/gssapi/gss_libinit.c
+++ b/src/lib/gssapi/gss_libinit.c
@@ -33,12 +33,9 @@ OM_uint32 gssint_initialize_library (void)
void gssint_cleanup_library (void)
{
- OM_uint32 min_stat;
assert (initialized);
- (void) kg_release_defcred (&min_stat);
-
#if !USE_BUNDLE_ERROR_STRINGS
remove_error_table(&et_k5g_error_table);
remove_error_table(&et_ggss_error_table);
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index 88948c4404..44ba4200eb 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,3 +1,40 @@
+2003-07-17 Tom Yu <tlyu@mit.edu>
+
+ * gssapiP_krb5.h: Delete kg_release_defcred(); it's no longer
+ used.
+
+ * gssapi_krb5.c: Delete defcred; it's no longer cached.
+ (kg_get_defcred): Don't cache.
+ (kg_release_defcred): Delete; it's no longer used.
+
+ * init_sec_context.c (krb5_gss_init_sec_context): Break into more
+ manageable pieces. Clean up a few error condition memory leaks
+ previously obscured by the sheer size of this function.
+ (setup_enc): New function; used to be part of
+ krb5_gss_init_sec_context() responsible for setting up enctypes,
+ keyblocks, related nastiness.
+ (get_requested_enctypes): New function; used to be part of
+ krb5_gss_init_sec_context() responsible for pruning the krb5
+ library's default enctype list to the limited set of enctypes
+ usable with GSSAPI.
+ (new_connection): New function; used to be part of
+ krb5_gss_init_sec_context() responsible for initial gss_ctx setup
+ and creating the AP-REQ.
+ (mutual_auth): New function; used to be part of
+ krb5_gss_init_sec_context() responsible for reading the AP-REP if
+ mutual auth was requested.
+
+ * inq_cred.c (krb5_gss_inquire_cred): Rearrange due to removal of
+ kg_release_defcred(), particularly to explicitly release the
+ defcred once it's obtained.
+
+ * rel_cred.c (krb5_gss_release_cred): Remove call to
+ kg_release_defcred(), and always succeed in releasing the null
+ credential.
+
+ * set_ccache.c (gss_krb5_ccache_name): Remove call to
+ kg_release_defcred().
+
2003-07-17 Ken Raeburn <raeburn@mit.edu>
* Makefile.in (LIBNAME) [##WIN16##]: Don't define.
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index f50653dbfd..1215b1a9a6 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -202,8 +202,6 @@ OM_uint32 kg_get_defcred
(OM_uint32 *minor_status,
gss_cred_id_t *cred);
-OM_uint32 kg_release_defcred (OM_uint32 *minor_status);
-
krb5_error_code kg_checksum_channel_bindings
(krb5_context context, gss_channel_bindings_t cb,
krb5_checksum *cksum,
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index db6eabd5d4..2c7803bc55 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -128,10 +128,6 @@ void *kg_vdb = NULL;
/** default credential support */
-/* default credentials */
-
-static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
-
/*
* init_sec_context() will explicitly re-acquire default credentials,
* so handling the expiration/invalidation condition here isn't needed.
@@ -141,37 +137,19 @@ kg_get_defcred(minor_status, cred)
OM_uint32 *minor_status;
gss_cred_id_t *cred;
{
- if (defcred == GSS_C_NO_CREDENTIAL) {
- OM_uint32 major;
-
- if ((major = krb5_gss_acquire_cred(minor_status,
- (gss_name_t) NULL, GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET, GSS_C_INITIATE,
- &defcred, NULL, NULL)) &&
- GSS_ERROR(major)) {
- defcred = GSS_C_NO_CREDENTIAL;
- return(major);
- }
- }
+ OM_uint32 major;
- *cred = defcred;
+ if ((major = krb5_gss_acquire_cred(minor_status,
+ (gss_name_t) NULL, GSS_C_INDEFINITE,
+ GSS_C_NULL_OID_SET, GSS_C_INITIATE,
+ cred, NULL, NULL)) && GSS_ERROR(major)) {
+ return(major);
+ }
*minor_status = 0;
return(GSS_S_COMPLETE);
}
OM_uint32
-kg_release_defcred(minor_status)
- OM_uint32 *minor_status;
-{
- if (defcred == GSS_C_NO_CREDENTIAL) {
- *minor_status = 0;
- return(GSS_S_COMPLETE);
- }
-
- return(krb5_gss_release_cred(minor_status, &defcred));
-}
-
-OM_uint32
kg_get_context(minor_status, context)
OM_uint32 *minor_status;
krb5_context *context;
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 0d3ddc9689..98102ce870 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -324,29 +324,21 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
return (code);
}
-OM_uint32
-krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
- context_handle, target_name, mech_type,
- req_flags, time_req, input_chan_bindings,
- input_token, actual_mech_type, output_token,
- ret_flags, time_rec)
- OM_uint32 *minor_status;
- gss_cred_id_t claimant_cred_handle;
- gss_ctx_id_t *context_handle;
- gss_name_t target_name;
- gss_OID mech_type;
- OM_uint32 req_flags;
- OM_uint32 time_req;
- gss_channel_bindings_t input_chan_bindings;
- gss_buffer_t input_token;
- gss_OID *actual_mech_type;
- gss_buffer_t output_token;
- OM_uint32 *ret_flags;
- OM_uint32 *time_rec;
+/*
+ * get_requested_enctypes
+ *
+ * Filter the krb5 library's default enctype list with the set of
+ * enctypes we support for GSSAPI.
+ */
+static krb5_error_code
+get_requested_enctypes(
+ krb5_context context,
+ krb5_enctype **ret_enctypes)
{
- krb5_context context;
- krb5_gss_cred_id_t cred;
- krb5_creds *k_cred = 0;
+ krb5_error_code code;
+ int i, j, k;
+ int is_duplicate_enctype;
+ int is_wanted_enctype;
static const krb5_enctype wanted_enctypes[] = {
#if 1
ENCTYPE_DES3_CBC_SHA1,
@@ -356,488 +348,614 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
};
#define N_WANTED_ENCTYPES (sizeof(wanted_enctypes)/sizeof(wanted_enctypes[0]))
- krb5_enctype requested_enctypes[N_WANTED_ENCTYPES + 1];
krb5_enctype *default_enctypes = 0;
- krb5_error_code code;
- krb5_gss_ctx_id_rec *ctx, *ctx_free;
- krb5_timestamp now;
- gss_buffer_desc token;
- int i, j, k, err;
- int default_mech = 0;
- OM_uint32 major_status;
+ krb5_enctype *requested_enctypes;
- if (GSS_ERROR(kg_get_context(minor_status, &context)))
- return(GSS_S_FAILURE);
+ *ret_enctypes = malloc((N_WANTED_ENCTYPES + 1) * sizeof(krb5_enctype));
+ if (*ret_enctypes == NULL)
+ return ENOMEM;
- /* set up return values so they can be "freed" successfully */
+ code = krb5_get_tgs_ktypes (context, 0, &default_enctypes);
+ if (code) {
+ free(*ret_enctypes);
+ *ret_enctypes = NULL;
+ return code;
+ }
+ requested_enctypes = *ret_enctypes;
+
+ /* "i" denotes *next* slot to fill. Don't forget to save room
+ for a trailing zero. */
+ i = 0;
+ for (j = 0;
+ (default_enctypes[j] != 0
+ /* This part should be redundant, but let's be paranoid. */
+ && i < N_WANTED_ENCTYPES);
+ j++) {
+
+ krb5_enctype e = default_enctypes[j];
+
+ /* Is this enctype one of the ones we want for GSSAPI? */
+ is_wanted_enctype = 0;
+ for (k = 0; k < N_WANTED_ENCTYPES; k++) {
+ if (wanted_enctypes[k] == e) {
+ is_wanted_enctype = 1;
+ break;
+ }
+ }
+ /* If unwanted, go to the next one. */
+ if (!is_wanted_enctype)
+ continue;
+
+ /* Is this enctype already in the list of enctypes to
+ request? (Is it a duplicate?) */
+ is_duplicate_enctype = 0;
+ for (k = 0; k < i; k++) {
+ if (requested_enctypes[k] == e) {
+ is_duplicate_enctype = 1;
+ break;
+ }
+ }
+ /* If it is not a duplicate, add it. */
+ if (!is_duplicate_enctype)
+ requested_enctypes[i++] = e;
+ }
+ krb5_free_ktypes(context, default_enctypes);
+ requested_enctypes[i++] = 0;
+ return GSS_S_COMPLETE;
+}
- major_status = GSS_S_FAILURE; /* Default major code */
- output_token->length = 0;
- output_token->value = NULL;
- if (actual_mech_type)
- *actual_mech_type = NULL;
- token.value = 0;
- ctx_free = 0;
+/*
+ * setup_enc
+ *
+ * Fill in the encryption descriptors. Called after AP-REQ is made.
+ */
+static OM_uint32
+setup_enc(
+ OM_uint32 *minor_status,
+ krb5_gss_ctx_id_rec *ctx,
+ krb5_context context)
+{
+ krb5_error_code code;
+ int i;
+
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
- /* verify the credential, or use the default */
- /*SUPPRESS 29*/
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
- OM_uint32 major;
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
- /*
- * Release default cred prior to re-acquiring it, to notice when
- * the ccache has changed.
- */
- major = kg_release_defcred(minor_status);
- if (GSS_ERROR(major))
- return major;
- if ((major = kg_get_defcred(minor_status, &claimant_cred_handle)) &&
- GSS_ERROR(major)) {
- return(major);
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
+ goto fail;
+
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
}
- } else {
- OM_uint32 major;
-
- major = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
- if (GSS_ERROR(major))
- return(major);
+ break;
+ case ENCTYPE_ARCFOUR_HMAC:
+ ctx->signalg = SGN_ALG_HMAC_MD5 ;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
+ break;
+#if 0
+ case ENCTYPE_DES3_CBC_MD5:
+ enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = 3;
+ ctx->cksum_size = 16;
+ ctx->sealalg = 1;
+ break;
+#endif
+ default:
+ *minor_status = KRB5_BAD_ENCTYPE;
+ return GSS_S_FAILURE;
}
+fail:
+ *minor_status = code;
+ return GSS_S_FAILURE;
+}
- cred = (krb5_gss_cred_id_t) claimant_cred_handle;
+/*
+ * new_connection
+ *
+ * Do the grunt work of setting up a new context.
+ */
+static OM_uint32
+new_connection(
+ OM_uint32 *minor_status,
+ krb5_gss_cred_id_t cred,
+ gss_ctx_id_t *context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_OID *actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ krb5_context context,
+ int default_mech)
+{
+ OM_uint32 major_status;
+ krb5_error_code code;
+ krb5_enctype *requested_enctypes;
+ krb5_creds *k_cred;
+ krb5_gss_ctx_id_rec *ctx, *ctx_free;
+ krb5_timestamp now;
+ gss_buffer_desc token;
- /* verify the mech_type */
+ major_status = GSS_S_FAILURE;
+ token.length = 0;
+ token.value = NULL;
- err = 0;
- if (mech_type == GSS_C_NULL_OID) {
- default_mech = 1;
- if (cred->rfc_mech) {
- mech_type = (gss_OID) gss_mech_krb5;
- } else if (cred->prerfc_mech) {
- mech_type = (gss_OID) gss_mech_krb5_old;
- } else {
- err = 1;
- }
- } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
- if (!cred->rfc_mech)
- err = 1;
- } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
- if (!cred->prerfc_mech)
- err = 1;
- } else {
- err = 1;
+ /* make sure the cred is usable for init */
+
+ if ((cred->usage != GSS_C_INITIATE) &&
+ (cred->usage != GSS_C_BOTH)) {
+ *minor_status = 0;
+ return(GSS_S_NO_CRED);
}
-
- if (err) {
+
+ /* complain if the input token is non-null */
+
+ if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
*minor_status = 0;
- return(GSS_S_BAD_MECH);
+ return(GSS_S_DEFECTIVE_TOKEN);
}
- /* verify that the target_name is valid and usable */
+ /* create the ctx */
- if (! kg_validate_name(target_name)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+ == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
}
- /* is this a new connection or not? */
+ /* fill in the ctx */
+ memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
+ ctx_free = ctx;
+ if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
+ goto fail;
+ krb5_auth_con_setflags(context, ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+ ctx->initiate = 1;
+ ctx->gss_flags = KG_IMPLFLAGS(req_flags);
+ ctx->seed_init = 0;
+ ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
+ ctx->seqstate = 0;
+ ctx->nctypes = 0;
+ ctx->ctypes = 0;
+
+ if ((code = krb5_timeofday(context, &now)))
+ goto fail;
+
+ if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
+ ctx->endtime = 0;
+ } else {
+ ctx->endtime = now + time_req;
+ }
- /*SUPPRESS 29*/
- if (*context_handle == GSS_C_NO_CONTEXT) {
- /* make sure the cred is usable for init */
+ if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
+ goto fail;
+
+ if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
+ &ctx->there)))
+ goto fail;
+
+ code = get_requested_enctypes(context, &requested_enctypes);
+ if (code)
+ goto fail;
+
+ code = get_credentials(context, cred, ctx->there, now,
+ ctx->endtime, requested_enctypes, &k_cred);
+ free(requested_enctypes);
+ if (code)
+ goto fail;
+
+ if (default_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ }
- if ((cred->usage != GSS_C_INITIATE) &&
- (cred->usage != GSS_C_BOTH)) {
- *minor_status = 0;
- return(GSS_S_NO_CRED);
+ if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
+ != GSS_S_COMPLETE) {
+ code = *minor_status;
+ goto fail;
+ }
+ /*
+ * Now try to make it static if at all possible....
+ */
+ ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
+
+ {
+ /* gsskrb5 v1 */
+ if ((code = make_ap_req_v1(context, ctx,
+ cred, k_cred, input_chan_bindings,
+ mech_type, &token))) {
+ if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
+ (code == KG_EMPTY_CCACHE))
+ major_status = GSS_S_NO_CRED;
+ if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
+ major_status = GSS_S_CREDENTIALS_EXPIRED;
+ goto fail;
}
- /* complain if the input token is non-null */
+ krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
+ &ctx->seq_send);
+ krb5_auth_con_getsendsubkey(context, ctx->auth_context,
+ &ctx->subkey);
+ }
- if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ major_status = setup_enc(minor_status, ctx, context);
- /* create the ctx */
+ if (k_cred) {
+ krb5_free_creds(context, k_cred);
+ k_cred = 0;
+ }
+
+ /* at this point, the context is constructed and valid,
+ hence, releaseable */
- if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
- == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ /* intern the context handle */
- /* fill in the ctx */
- memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
- ctx_free = ctx;
- if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
- goto fail;
- krb5_auth_con_setflags(context, ctx->auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
- ctx->initiate = 1;
- ctx->gss_flags = KG_IMPLFLAGS(req_flags);
- ctx->seed_init = 0;
- ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
- ctx->seqstate = 0;
- ctx->nctypes = 0;
- ctx->ctypes = 0;
+ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+ code = G_VALIDATE_FAILED;
+ goto fail;
+ }
+ *context_handle = (gss_ctx_id_t) ctx;
+ ctx_free = 0;
+ /* compute time_rec */
+ if (time_rec) {
if ((code = krb5_timeofday(context, &now)))
- goto fail;
+ goto fail;
+ *time_rec = ctx->endtime - now;
+ }
- if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
- ctx->endtime = 0;
- } else {
- ctx->endtime = now + time_req;
- }
+ /* set the other returns */
+ *output_token = token;
- if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
- goto fail;
-
- if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
- &ctx->there)))
- goto fail;
+ if (ret_flags)
+ *ret_flags = ctx->gss_flags;
- code = krb5_get_tgs_ktypes (context, 0, &default_enctypes);
- if (code)
- goto fail;
- /* "i" denotes *next* slot to fill. Don't forget to save room
- for a trailing zero. */
- i = 0;
- for (j = 0;
- (default_enctypes[j] != 0
- /* This part should be redundant, but let's be paranoid. */
- && i < N_WANTED_ENCTYPES);
- j++) {
-
- int is_duplicate_enctype;
- int is_wanted_enctype;
-
- krb5_enctype e = default_enctypes[j];
-
- /* Is this enctype one of the ones we want for GSSAPI? */
- is_wanted_enctype = 0;
- for (k = 0; k < N_WANTED_ENCTYPES; k++) {
- if (wanted_enctypes[k] == e) {
- is_wanted_enctype = 1;
- break;
- }
- }
- /* If unwanted, go to the next one. */
- if (!is_wanted_enctype)
- continue;
-
- /* Is this enctype already in the list of enctypes to
- request? (Is it a duplicate?) */
- is_duplicate_enctype = 0;
- for (k = 0; k < i; k++) {
- if (requested_enctypes[k] == e) {
- is_duplicate_enctype = 1;
- break;
- }
- }
- /* If it is not a duplicate, add it. */
- if (!is_duplicate_enctype)
- requested_enctypes[i++] = e;
- }
- krb5_free_ktypes(context, default_enctypes);
- requested_enctypes[i++] = 0;
+ if (actual_mech_type)
+ *actual_mech_type = mech_type;
- if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, requested_enctypes, &k_cred)))
- goto fail;
+ /* return successfully */
- if (default_mech) {
- mech_type = (gss_OID) gss_mech_krb5;
- }
+ *minor_status = 0;
+ if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
+ ctx->established = 0;
+ return(GSS_S_CONTINUE_NEEDED);
+ } else {
+ ctx->seq_recv = ctx->seq_send;
+ g_order_init(&(ctx->seqstate), ctx->seq_recv,
+ (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+ (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0);
+ ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
+ ctx->established = 1;
+ return(GSS_S_COMPLETE);
+ }
- if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
- != GSS_S_COMPLETE) {
- code = *minor_status;
- goto fail;
- }
- /*
- * Now try to make it static if at all possible....
- */
- ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
-
- {
- /* gsskrb5 v1 */
- if ((code = make_ap_req_v1(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
- &ctx->seq_send);
- krb5_auth_con_getsendsubkey(context, ctx->auth_context,
- &ctx->subkey);
-
- /* fill in the encryption descriptors */
-
- switch(ctx->subkey->enctype) {
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_CRC:
- ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = SGN_ALG_DES_MAC_MD5;
- ctx->cksum_size = 8;
- ctx->sealalg = SEAL_ALG_DES;
-
- /* The encryption key is the session key XOR
- 0xf0f0f0f0f0f0f0f0. */
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
- goto fail;
-
- break;
-
- case ENCTYPE_DES3_CBC_SHA1:
- ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
- ctx->cksum_size = 20;
- ctx->sealalg = SEAL_ALG_DES3KD;
-
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
- if (code)
- goto fail;
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
- if (code) {
- krb5_free_keyblock (context, ctx->enc);
- goto fail;
- }
- break;
- case ENCTYPE_ARCFOUR_HMAC:
- ctx->signalg = SGN_ALG_HMAC_MD5 ;
- ctx->cksum_size = 8;
- ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
-
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
- if (code)
- goto fail;
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
- if (code) {
- krb5_free_keyblock (context, ctx->enc);
- goto fail;
- }
- break;
-#if 0
- case ENCTYPE_DES3_CBC_MD5:
- enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = 3;
- ctx->cksum_size = 16;
- ctx->sealalg = 1;
- break;
-#endif
- default:
- *minor_status = KRB5_BAD_ENCTYPE;
- return GSS_S_FAILURE;
- }
+fail:
+ if (ctx_free) {
+ if (ctx_free->auth_context)
+ krb5_auth_con_free(context, ctx_free->auth_context);
+ if (ctx_free->here)
+ krb5_free_principal(context, ctx_free->here);
+ if (ctx_free->there)
+ krb5_free_principal(context, ctx_free->there);
+ if (ctx_free->subkey)
+ krb5_free_keyblock(context, ctx_free->subkey);
+ if (ctx_free->ctypes)
+ krb5_free_cksumtypes(context, ctx_free->ctypes);
+ xfree(ctx_free);
+ } else
+ (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
- }
+ *minor_status = code;
+ return (major_status);
+}
- if (k_cred) {
- krb5_free_creds(context, k_cred);
- k_cred = 0;
- }
-
- /* at this point, the context is constructed and valid,
- hence, releaseable */
+/*
+ * mutual_auth
+ *
+ * Handle the reply from the acceptor, if we're doing mutual auth.
+ */
+static OM_uint32
+mutual_auth(
+ OM_uint32 *minor_status,
+ krb5_gss_cred_id_t cred,
+ gss_ctx_id_t *context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_OID *actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ krb5_context context)
+{
+ OM_uint32 major_status;
+ unsigned char *ptr;
+ char *sptr;
+ krb5_data ap_rep;
+ krb5_ap_rep_enc_part *ap_rep_data;
+ krb5_timestamp now;
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error *krb_error;
+ krb5_error_code code;
- /* intern the context handle */
+ major_status = GSS_S_FAILURE;
- if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
- code = G_VALIDATE_FAILED;
- goto fail;
- }
- *context_handle = (gss_ctx_id_t) ctx;
- ctx_free = 0;
-
- /* compute time_rec */
- if (time_rec) {
- if ((code = krb5_timeofday(context, &now)))
- goto fail;
- *time_rec = ctx->endtime - now;
- }
+ /* validate the context handle */
+ /*SUPPRESS 29*/
+ if (! kg_validate_ctx_id(*context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- /* set the other returns */
- *output_token = token;
+ ctx = (gss_ctx_id_t) *context_handle;
- if (ret_flags)
- *ret_flags = ctx->gss_flags;
+ /* make sure the context is non-established, and that certain
+ arguments are unchanged */
- if (actual_mech_type)
- *actual_mech_type = mech_type;
+ if ((ctx->established) ||
+ ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
+ code = KG_CONTEXT_ESTABLISHED;
+ goto fail;
+ }
- /* return successfully */
+ if (! krb5_principal_compare(context, ctx->there,
+ (krb5_principal) target_name)) {
+ (void)krb5_gss_delete_sec_context(minor_status,
+ context_handle, NULL);
+ code = 0;
+ major_status = GSS_S_BAD_NAME;
+ goto fail;
+ }
- *minor_status = 0;
- if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
- ctx->established = 0;
- return(GSS_S_CONTINUE_NEEDED);
- } else {
- ctx->seq_recv = ctx->seq_send;
- g_order_init(&(ctx->seqstate), ctx->seq_recv,
- (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
- (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0);
- ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
- ctx->established = 1;
- /* fall through to GSS_S_COMPLETE */
- }
- } else {
- unsigned char *ptr;
- char *sptr;
- krb5_data ap_rep;
- krb5_ap_rep_enc_part *ap_rep_data;
- krb5_error *krb_error;
-
- /* validate the context handle */
- /*SUPPRESS 29*/
- if (! kg_validate_ctx_id(*context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
+ /* verify the token and leave the AP_REP message in ap_rep */
- ctx = (gss_ctx_id_t) *context_handle;
+ if (input_token == GSS_C_NO_BUFFER) {
+ (void)krb5_gss_delete_sec_context(minor_status,
+ context_handle, NULL);
+ code = 0;
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto fail;
+ }
- /* make sure the context is non-established, and that certain
- arguments are unchanged */
+ ptr = (unsigned char *) input_token->value;
- if ((ctx->established) ||
- (((gss_cred_id_t) cred) != claimant_cred_handle) ||
- ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
- code = KG_CONTEXT_ESTABLISHED;
- goto fail;
- }
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length)) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length) == 0) {
+
+ /* Handle a KRB_ERROR message from the server */
- if (! krb5_principal_compare(context, ctx->there,
- (krb5_principal) target_name)) {
- (void)krb5_gss_delete_sec_context(minor_status,
- context_handle, NULL);
- code = 0;
- major_status = GSS_S_BAD_NAME;
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ code = krb5_rd_error(context, &ap_rep, &krb_error);
+ if (code)
+ goto fail;
+ if (krb_error->error)
+ code = krb_error->error + ERROR_TABLE_BASE_krb5;
+ else
+ code = 0;
+ krb5_free_error(context, krb_error);
goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
+ }
- /* verify the token and leave the AP_REP message in ap_rep */
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
- if (input_token == GSS_C_NO_BUFFER) {
- (void)krb5_gss_delete_sec_context(minor_status,
- context_handle, NULL);
- code = 0;
- major_status = GSS_S_DEFECTIVE_TOKEN;
+ /* decode the ap_rep */
+ if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+ &ap_rep_data))) {
+ /*
+ * XXX A hack for backwards compatiblity.
+ * To be removed in 1999 -- proven
+ */
+ krb5_auth_con_setuseruserkey(context, ctx->auth_context,
+ ctx->subkey);
+ if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+ &ap_rep_data)))
goto fail;
- }
+ }
- ptr = (unsigned char *) input_token->value;
+ /* store away the sequence number */
+ ctx->seq_recv = ap_rep_data->seq_number;
+ g_order_init(&(ctx->seqstate), ctx->seq_recv,
+ (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+ (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0);
- if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length))) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length) == 0) {
+ /* free the ap_rep_data */
+ krb5_free_ap_rep_enc_part(context, ap_rep_data);
- /* Handle a KRB_ERROR message from the server */
+ /* set established */
+ ctx->established = 1;
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- code = krb5_rd_error(context, &ap_rep, &krb_error);
- if (code)
- goto fail;
- if (krb_error->error)
- code = krb_error->error + ERROR_TABLE_BASE_krb5;
- else
- code = 0;
- krb5_free_error(context, krb_error);
- goto fail;
- } else {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
- }
+ /* set returns */
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- /* decode the ap_rep */
- if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
- &ap_rep_data))) {
- /*
- * XXX A hack for backwards compatiblity.
- * To be removed in 1999 -- proven
- */
- krb5_auth_con_setuseruserkey(context, ctx->auth_context,
- ctx->subkey);
- if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
- &ap_rep_data)))
- goto fail;
- }
+ if (time_rec) {
+ if ((code = krb5_timeofday(context, &now)))
+ goto fail;
+ *time_rec = ctx->endtime - now;
+ }
- /* store away the sequence number */
- ctx->seq_recv = ap_rep_data->seq_number;
- g_order_init(&(ctx->seqstate), ctx->seq_recv,
- (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
- (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0);
+ if (ret_flags)
+ *ret_flags = ctx->gss_flags;
- /* free the ap_rep_data */
- krb5_free_ap_rep_enc_part(context, ap_rep_data);
+ if (actual_mech_type)
+ *actual_mech_type = mech_type;
- /* set established */
- ctx->established = 1;
+ /* success */
- /* set returns */
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
- if (time_rec) {
- if ((code = krb5_timeofday(context, &now)))
- goto fail;
- *time_rec = ctx->endtime - now;
- }
+fail:
+ (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
- if (ret_flags)
- *ret_flags = ctx->gss_flags;
+ *minor_status = code;
+ return (major_status);
+}
- if (actual_mech_type)
- *actual_mech_type = mech_type;
+OM_uint32
+krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
+ context_handle, target_name, mech_type,
+ req_flags, time_req, input_chan_bindings,
+ input_token, actual_mech_type, output_token,
+ ret_flags, time_rec)
+ OM_uint32 *minor_status;
+ gss_cred_id_t claimant_cred_handle;
+ gss_ctx_id_t *context_handle;
+ gss_name_t target_name;
+ gss_OID mech_type;
+ OM_uint32 req_flags;
+ OM_uint32 time_req;
+ gss_channel_bindings_t input_chan_bindings;
+ gss_buffer_t input_token;
+ gss_OID *actual_mech_type;
+ gss_buffer_t output_token;
+ OM_uint32 *ret_flags;
+ OM_uint32 *time_rec;
+{
+ krb5_context context;
+ krb5_gss_cred_id_t cred;
+ int err;
+ int default_mech = 0;
+ OM_uint32 major_status;
+ OM_uint32 tmp_min_stat;
+
+ if (GSS_ERROR(kg_get_context(minor_status, &context)))
+ return(GSS_S_FAILURE);
+
+ /* set up return values so they can be "freed" successfully */
+
+ major_status = GSS_S_FAILURE; /* Default major code */
+ output_token->length = 0;
+ output_token->value = NULL;
+ if (actual_mech_type)
+ *actual_mech_type = NULL;
- /* success */
+ /* verify that the target_name is valid and usable */
+ if (! kg_validate_name(target_name)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+ }
+
+ /* verify the credential, or use the default */
+ /*SUPPRESS 29*/
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+ major_status = kg_get_defcred(minor_status, &cred);
+ if (major_status && GSS_ERROR(major_status)) {
+ return(major_status);
+ }
+ } else {
+ major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
+ if (GSS_ERROR(major_status))
+ return(major_status);
+ cred = (krb5_gss_cred_id_t) claimant_cred_handle;
+ }
+
+ /* verify the mech_type */
+
+ err = 0;
+ if (mech_type == GSS_C_NULL_OID) {
+ default_mech = 1;
+ if (cred->rfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ } else if (cred->prerfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5_old;
+ } else {
+ err = 1;
+ }
+ } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
+ if (!cred->rfc_mech)
+ err = 1;
+ } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
+ if (!cred->prerfc_mech)
+ err = 1;
+ } else {
+ err = 1;
+ }
+
+ if (err) {
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+ krb5_gss_release_cred(minor_status, (gss_cred_id_t)cred);
*minor_status = 0;
- /* fall through to GSS_S_COMPLETE */
+ return(GSS_S_BAD_MECH);
}
- return(GSS_S_COMPLETE);
+ /* is this a new connection or not? */
-fail:
- if (ctx_free) {
- if (ctx_free->auth_context)
- krb5_auth_con_free(context, ctx_free->auth_context);
- if (ctx_free->here)
- krb5_free_principal(context, ctx_free->here);
- if (ctx_free->there)
- krb5_free_principal(context, ctx_free->there);
- if (ctx_free->subkey)
- krb5_free_keyblock(context, ctx_free->subkey);
- if (ctx_free->ctypes)
- krb5_free_cksumtypes(context, ctx_free->ctypes);
- xfree(ctx_free);
- } else
- (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+ /*SUPPRESS 29*/
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ major_status = new_connection(minor_status, cred, context_handle,
+ target_name, mech_type, req_flags,
+ time_req, input_chan_bindings,
+ input_token, actual_mech_type,
+ output_token, ret_flags, time_rec,
+ context, default_mech);
+ } else {
+ major_status = mutual_auth(minor_status, cred, context_handle,
+ target_name, mech_type, req_flags,
+ time_req, input_chan_bindings,
+ input_token, actual_mech_type,
+ output_token, ret_flags, time_rec,
+ context);
+ }
- *minor_status = code;
- return (major_status);
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+ krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t)cred);
+
+ return(major_status);
}
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index a79034d9ec..83782162be 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -91,6 +91,8 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
gss_OID_set mechs;
OM_uint32 ret;
+ ret = GSS_S_FAILURE;
+
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -102,7 +104,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
if (cred_handle == GSS_C_NO_CREDENTIAL) {
OM_uint32 major;
- if ((major = kg_get_defcred(minor_status, &cred_handle)) &&
+ if ((major = kg_get_defcred(minor_status, (gss_cred_id_t)&cred)) &&
GSS_ERROR(major)) {
return(major);
}
@@ -112,13 +114,13 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
major = krb5_gss_validate_cred(minor_status, cred_handle);
if (GSS_ERROR(major))
return(major);
+ cred = (krb5_gss_cred_id_t) cred_handle;
}
- cred = (krb5_gss_cred_id_t) cred_handle;
-
if ((code = krb5_timeofday(context, &now))) {
*minor_status = code;
- return(GSS_S_FAILURE);
+ ret = GSS_S_FAILURE;
+ goto fail;
}
if (cred->tgt_expire > 0) {
@@ -132,7 +134,8 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
if (cred->princ &&
(code = krb5_copy_principal(context, cred->princ, &ret_name))) {
*minor_status = code;
- return(GSS_S_FAILURE);
+ ret = GSS_S_FAILURE;
+ goto fail;
}
}
@@ -149,7 +152,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
&mechs)))) {
krb5_free_principal(context, ret_name);
/* *minor_status set above */
- return(ret);
+ goto fail;
}
}
@@ -172,8 +175,18 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
if (mechanisms)
*mechanisms = mechs;
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ krb5_gss_release_cred(minor_status, (gss_cred_id_t)cred);
+
*minor_status = 0;
return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
+fail:
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ OM_uint32 tmp_min_stat;
+
+ krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t)cred);
+ }
+ return ret;
}
/* V2 interface */
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
index 0d81399af2..43d5ca1c2e 100644
--- a/src/lib/gssapi/krb5/rel_cred.c
+++ b/src/lib/gssapi/krb5/rel_cred.c
@@ -34,8 +34,10 @@ krb5_gss_release_cred(minor_status, cred_handle)
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
- if (*cred_handle == GSS_C_NO_CREDENTIAL)
- return(kg_release_defcred(minor_status));
+ if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return(GSS_S_COMPLETE);
+ }
if (! kg_delete_cred_id(*cred_handle)) {
*minor_status = (OM_uint32) G_VALIDATE_FAILED;
diff --git a/src/lib/gssapi/krb5/set_ccache.c b/src/lib/gssapi/krb5/set_ccache.c
index 9a612201b5..236a83afff 100644
--- a/src/lib/gssapi/krb5/set_ccache.c
+++ b/src/lib/gssapi/krb5/set_ccache.c
@@ -38,7 +38,6 @@ gss_krb5_ccache_name(minor_status, name, out_name)
{
krb5_context context;
krb5_error_code retval;
- OM_uint32 foo_stat;
static char *oldname = NULL;
const char *tmpname = NULL;
@@ -66,6 +65,5 @@ gss_krb5_ccache_name(minor_status, name, out_name)
*minor_status = retval;
return GSS_S_FAILURE;
}
- kg_release_defcred(&foo_stat);
return GSS_S_COMPLETE;
}