#include "mglueP.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <string.h>
#include <errno.h>
OM_uint32 KRB5_CALLCONV
gss_set_sec_context_option (OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_OID desired_object,
const gss_buffer_t value)
{
OM_uint32 status, minor;
gss_union_ctx_id_t ctx;
gss_mechanism mech;
gss_ctx_id_t internal_ctx = GSS_C_NO_CONTEXT;
if (minor_status == NULL)
return GSS_S_CALL_INACCESSIBLE_WRITE;
*minor_status = 0;
if (context_handle == NULL)
return GSS_S_CALL_INACCESSIBLE_WRITE;
ctx = (gss_union_ctx_id_t) *context_handle;
if (ctx == NULL) {
mech = gssint_get_mechanism (GSS_C_NO_OID);
} else {
mech = gssint_get_mechanism (ctx->mech_type);
}
if (mech == NULL)
return GSS_S_BAD_MECH;
if (mech->gss_set_sec_context_option == NULL)
return GSS_S_UNAVAILABLE;
status = mech->gss_set_sec_context_option(minor_status,
ctx ? &ctx->internal_ctx_id :
&internal_ctx,
desired_object,
value);
if (status != GSS_S_COMPLETE) {
map_error(minor_status, mech);
return status;
}
if (ctx == NULL && internal_ctx != GSS_C_NO_CONTEXT) {
status = gssint_create_union_context(minor_status, &mech->mech_type,
&ctx);
if (status != GSS_S_COMPLETE) {
gssint_delete_internal_sec_context(&minor, ctx->mech_type,
&internal_ctx, GSS_C_NO_BUFFER);
return status;
}
ctx->internal_ctx_id = internal_ctx;
*context_handle = (gss_ctx_id_t)ctx;
}
return GSS_S_COMPLETE;
}