} else {
union_ctx_id = (gss_union_ctx_id_t)*context_handle;
selected_mech = union_ctx_id->mech_type;
+ if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
}
/* Now create a new context if we didn't get one. */
free(union_ctx_id);
return (status);
}
-
- /* set the new context handle to caller's data */
- *context_handle = (gss_ctx_id_t)union_ctx_id;
}
/*
d_cred ? &tmp_d_cred : NULL);
/* If there's more work to do, keep going... */
- if (status == GSS_S_CONTINUE_NEEDED)
+ if (status == GSS_S_CONTINUE_NEEDED) {
+ *context_handle = (gss_ctx_id_t)union_ctx_id;
return GSS_S_CONTINUE_NEEDED;
+ }
/* if the call failed, return with failure */
if (status != GSS_S_COMPLETE) {
*mech_type = gssint_get_public_oid(actual_mech);
if (ret_flags != NULL)
*ret_flags = temp_ret_flags;
- return (status);
+ *context_handle = (gss_ctx_id_t)union_ctx_id;
+ return GSS_S_COMPLETE;
} else {
status = GSS_S_BAD_MECH;
}
error_out:
- if (union_ctx_id) {
+ /*
+ * RFC 2744 5.1 requires that we not create a context on a failed first
+ * call to accept, and recommends that on a failed subsequent call we
+ * make the caller responsible for calling gss_delete_sec_context.
+ * Even if the mech deleted its context, keep the union context around
+ * for the caller to delete.
+ */
+ if (union_ctx_id && *context_handle == GSS_C_NO_CONTEXT) {
if (union_ctx_id->mech_type) {
if (union_ctx_id->mech_type->elements)
free(union_ctx_id->mech_type->elements);
GSS_C_NO_BUFFER);
}
free(union_ctx_id);
- *context_handle = GSS_C_NO_CONTEXT;
}
if (src_name)
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
mech = gssint_get_mechanism (ctx->mech_type);
if (mech != NULL) {
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
if (GSSINT_CHK_LOOP(ctx))
return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
- status = gssint_delete_internal_sec_context(minor_status,
- ctx->mech_type,
- &ctx->internal_ctx_id,
- output_token);
- if (status)
- return status;
+ if (ctx->internal_ctx_id != GSS_C_NO_CONTEXT) {
+ status = gssint_delete_internal_sec_context(minor_status,
+ ctx->mech_type,
+ &ctx->internal_ctx_id,
+ output_token);
+ if (status)
+ return status;
+ }
/* now free up the space for the union context structure */
free(ctx->mech_type->elements);
*/
ctx = (gss_union_ctx_id_t) *context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (!mech)
return GSS_S_BAD_MECH;
/* copy the supplied context handle */
union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
- } else
+ } else {
union_ctx_id = (gss_union_ctx_id_t)*context_handle;
+ if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) {
+ status = GSS_S_NO_CONTEXT;
+ goto end;
+ }
+ }
/*
* get the appropriate cred handle from the union cred struct.
if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) {
/*
- * The spec says the preferred method is to delete all context info on
- * the first call to init, and on all subsequent calls make the caller
- * responsible for calling gss_delete_sec_context. However, if the
- * mechanism decided to delete the internal context, we should also
- * delete the union context.
+ * RFC 2744 5.19 requires that we not create a context on a failed
+ * first call to init, and recommends that on a failed subsequent call
+ * we make the caller responsible for calling gss_delete_sec_context.
+ * Even if the mech deleted its context, keep the union context around
+ * for the caller to delete.
*/
map_error(minor_status, mech);
- if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT)
- *context_handle = GSS_C_NO_CONTEXT;
if (*context_handle == GSS_C_NO_CONTEXT) {
free(union_ctx_id->mech_type->elements);
free(union_ctx_id->mech_type);
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (!mech || !mech->gss_inquire_context || !mech->gss_display_name ||
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
mech = gssint_get_mechanism (ctx->mech_type);
if (mech != NULL) {
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (!mech)
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
* call it.
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
* call it.
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (!mech)
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
/* Select the approprate underlying mechanism routine and call it. */
ctx = (gss_union_ctx_id_t)context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
mech = gssint_get_mechanism(ctx->mech_type);
if (mech == NULL)
return GSS_S_BAD_MECH;
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
* call it.
*/
ctx = (gss_union_ctx_id_t)context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (!mech)
return (GSS_S_BAD_MECH);
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
*/
ctx = (gss_union_ctx_id_t) context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return (GSS_S_NO_CONTEXT);
mech = gssint_get_mechanism (ctx->mech_type);
if (mech) {
/* Select the approprate underlying mechanism routine and call it. */
ctx = (gss_union_ctx_id_t)context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
mech = gssint_get_mechanism(ctx->mech_type);
if (mech == NULL)
return GSS_S_BAD_MECH;
/* Select the approprate underlying mechanism routine and call it. */
ctx = (gss_union_ctx_id_t)context_handle;
+ if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
mech = gssint_get_mechanism(ctx->mech_type);
if (mech == NULL)
return GSS_S_BAD_MECH;