+/*
+ * The remainder of this file consists of wrappers so we can call into the
+ * mechanism glue without calling ourselves.
+ */
+static OM_uint32
+(*gssInitSecContextNext)(OM_uint32 *,
+ gss_cred_id_t,
+ gss_ctx_id_t *,
+ gss_name_t,
+ gss_OID,
+ OM_uint32,
+ OM_uint32,
+ gss_channel_bindings_t,
+ gss_buffer_t,
+ gss_OID *,
+ gss_buffer_t,
+ OM_uint32 *,
+ OM_uint32 *);
+
+static OM_uint32
+(*gssAcceptSecContextNext)(OM_uint32 *,
+ gss_ctx_id_t *,
+ gss_cred_id_t,
+ gss_buffer_t,
+ gss_channel_bindings_t,
+ gss_name_t *,
+ gss_OID *,
+ gss_buffer_t,
+ OM_uint32 *,
+ OM_uint32 *,
+ gss_cred_id_t *);
+
+static OM_uint32
+(*gssReleaseCredNext)(OM_uint32 *, gss_cred_id_t *);
+
+static OM_uint32
+(*gssReleaseNameNext)(OM_uint32 *, gss_name_t *);
+
+static OM_uint32
+(*gssInquireSecContextByOidNext)(OM_uint32 *,
+ const gss_ctx_id_t,
+ const gss_OID,
+ gss_buffer_set_t *);
+
+static OM_uint32
+(*gssDeleteSecContextNext)(OM_uint32 *,
+ gss_ctx_id_t *,
+ gss_buffer_t);
+
+static OM_uint32
+(*gssDisplayNameNext)(OM_uint32 *,
+ gss_name_t,
+ gss_buffer_t,
+ gss_OID *);
+
+static OM_uint32
+(*gssImportNameNext)(OM_uint32 *,
+ gss_buffer_t,
+ gss_OID,
+ gss_name_t *);
+
+static OM_uint32
+(*gssStoreCredNext)(OM_uint32 *,
+ const gss_cred_id_t,
+ gss_cred_usage_t,
+ const gss_OID,
+ OM_uint32,
+ OM_uint32,
+ gss_OID_set *,
+ gss_cred_usage_t *);
+
+static OM_uint32
+(*gssGetNameAttributeNext)(OM_uint32 *,
+ gss_name_t,
+ gss_buffer_t,
+ int *,
+ int *,
+ gss_buffer_t,
+ gss_buffer_t,
+ int *);
+
+#define NEXT_SYMBOL(local, global) do { \
+ ((local) = dlsym(RTLD_NEXT, (global))); \
+ if ((local) == NULL) { \
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL; \
+ major = GSS_S_UNAVAILABLE; \
+ /* but continue */ \
+ } \
+ } while (0)
+
+OM_uint32
+gssEapReauthInitialize(OM_uint32 *minor)
+{
+ OM_uint32 major = GSS_S_COMPLETE;
+
+ NEXT_SYMBOL(gssInitSecContextNext, "gss_init_sec_context");
+ NEXT_SYMBOL(gssAcceptSecContextNext, "gss_accept_sec_context");
+ NEXT_SYMBOL(gssReleaseCredNext, "gss_release_cred");
+ NEXT_SYMBOL(gssReleaseNameNext, "gss_release_name");
+ NEXT_SYMBOL(gssInquireSecContextByOidNext, "gss_inquire_sec_context_by_oid");
+ NEXT_SYMBOL(gssDeleteSecContextNext, "gss_delete_sec_context");
+ NEXT_SYMBOL(gssDisplayNameNext, "gss_display_name");
+ NEXT_SYMBOL(gssImportNameNext, "gss_import_name");
+ NEXT_SYMBOL(gssStoreCredNext, "gss_store_cred");
+ NEXT_SYMBOL(gssGetNameAttributeNext, "gss_get_name_attribute");
+
+ return major;
+}
+
+OM_uint32
+gssInitSecContext(OM_uint32 *minor,
+ 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)
+{
+ if (gssInitSecContextNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssInitSecContextNext(minor, 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);
+}
+
+OM_uint32
+gssAcceptSecContext(OM_uint32 *minor,
+ gss_ctx_id_t *context_handle,
+ gss_cred_id_t cred,
+ gss_buffer_t input_token,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_name_t *src_name,
+ gss_OID *mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ gss_cred_id_t *delegated_cred_handle)
+{
+ if (gssAcceptSecContextNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssAcceptSecContextNext(minor, context_handle, cred,
+ input_token, input_chan_bindings,
+ src_name, mech_type, output_token,
+ ret_flags, time_rec, delegated_cred_handle);
+}
+
+OM_uint32
+gssReleaseCred(OM_uint32 *minor,
+ gss_cred_id_t *cred_handle)
+{
+ if (gssReleaseCredNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssReleaseCredNext(minor, cred_handle);
+}
+
+OM_uint32
+gssReleaseName(OM_uint32 *minor,
+ gss_name_t *name)
+{
+ if (gssReleaseName == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssReleaseNameNext(minor, name);
+}
+
+OM_uint32
+gssDeleteSecContext(OM_uint32 *minor,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token)
+{
+ if (gssDeleteSecContextNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssDeleteSecContextNext(minor, context_handle, output_token);
+}
+
+static OM_uint32
+gssDisplayName(OM_uint32 *minor,
+ gss_name_t name,
+ gss_buffer_t buffer,
+ gss_OID *name_type)
+{
+ if (gssDisplayNameNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssDisplayNameNext(minor, name, buffer, name_type);
+}
+
+static OM_uint32
+gssImportName(OM_uint32 *minor,
+ gss_buffer_t buffer,
+ gss_OID name_type,
+ gss_name_t *name)
+{
+ if (gssImportNameNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssImportNameNext(minor, buffer, name_type, name);
+}
+
+OM_uint32
+gssInquireSecContextByOid(OM_uint32 *minor,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ if (gssInquireSecContextByOidNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssInquireSecContextByOidNext(minor, context_handle,
+ desired_object, data_set);
+}
+
+OM_uint32
+gssStoreCred(OM_uint32 *minor,
+ const gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t input_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ if (gssStoreCredNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssStoreCredNext(minor, input_cred_handle, input_usage,
+ desired_mech, overwrite_cred, default_cred,
+ elements_stored, cred_usage_stored);
+}
+
+OM_uint32
+gssGetNameAttribute(OM_uint32 *minor,
+ gss_name_t name,
+ gss_buffer_t attr,
+ int *authenticated,
+ int *complete,
+ gss_buffer_t value,
+ gss_buffer_t display_value,
+ int *more)
+{
+ if (gssGetNameAttributeNext == NULL) {
+ *minor = GSSEAP_NO_MECHGLUE_SYMBOL;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ return gssGetNameAttributeNext(minor, name, attr, authenticated, complete,
+ value, display_value, more);
+}