#include "mysccs.h"
SCCSID("@(#)load_dll.c   %E%   SAP   %I%")

static char * this_File GNU_UNUSED = __FILE__;

/************************************************************************/
/* $Id: //tools/src/freeware/gsstest/load_dll.c#2 $
 ************************************************************************
 *
 * Copyright (c) 1998-2000  SAP AG.  All rights reserved.
 *
 * 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. 
 *
 * 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. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * 4. The name "SAP AG" must not be used to endorse or promote products
 *    derived from this software without prior written permission.
 *    For written permission, please contact www.press@sap.com
 *
 * 5. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * THIS SOFTWARE IS PROVIDED BY SAP AG ``AS IS'' AND ANY EXPRESSED
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. SAP AG SHALL BE LIABLE FOR ANY DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE ONLY IF CAUSED BY SAP AG'S
 * INTENT OR GROSS NEGLIGENCE. IN CASE SAP AG IS LIABLE UNDER THIS
 * AGREEMENT FOR DAMAGES CAUSED BY SAP AG'S GROSS NEGLIGENCE SAP AG
 * FURTHER SHALL NOT BE LIABLE FOR ANY 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, AND SHALL NOT BE LIABLE IN EXCESS OF THE AMOUNT OF
 * DAMAGES TYPICALLY FORESEEABLE FOR SAP AG, WHICH SHALL IN NO EVENT
 * EXCEED US$ 500.000.- 
 *
 ************************************************************************/


#include "gsstest.h"
#include "rtlink.h"
#include "sncgss.h"


int dll_dynamic_linking = TRUE;
int num_dlls		= 0;

static int dll_load_callset( int		       p_trclevel,
			     char                    * p_callset_name,
			     char		     * p_call_prefix,
			     DLL_GSSFP_T	     * p_gssfp,
			     struct dll_call_entry_s * p_dll_calls,
			     int		     * pp_flags );


#undef  OF
#define OF(x)   ( (offsetof(struct dll_gssfp_s, x ) \
		     - offsetof(struct dll_gssfp_s,GSS_FIRST_FUNC)) \
                  / sizeof(GSS_VOID_FUNC_T *) )

#define X_CALL_ENTRY(x)	   # x, OF(x)
#define CALL_ENTRY(x)	   X_CALL_ENTRY( gss_ ## x )


static struct dll_call_entry_s sap_extra_calls[] = {
  { "snc_init_adapter",		 OF(sapsnc_init_adapter),      GSS_DL_SAP,
			RTL_ATTR(OM_uint32, 3, ARG3_INIT_ADAPTER)	    },
  { "snc_export_cname_blob",	 OF(sapsnc_export_cname_blob), GSS_DL_SAP,
			RTL_ATTR(OM_uint32, 4, ARG4_EXPORT_CNAME_BLOB)	    },
  { "snc_import_cname_blob",	 OF(sapsnc_import_cname_blob), GSS_DL_SAP,
			RTL_ATTR(OM_uint32, 4, ARG4_IMPORT_CNAME_BLOB)	    },
  { NULL, 0, 0, 0 }

}; /* sap_extra_calls[] */

static struct dll_call_entry_s gss_generic_calls[]= {

  { CALL_ENTRY(indicate_mechs),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  2, ARG2_INDICATE_MECHS)        },
  { CALL_ENTRY(display_status),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  6, ARG6_DISPLAY_STATUS)        },
  { CALL_ENTRY(release_buffer),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  2, ARG2_RELEASE_BUFFER)        },
  { CALL_ENTRY(release_oid_set),	GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  2, ARG2_RELEASE_OID_SET)       },
  { CALL_ENTRY(inquire_names_for_mech),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  3, ARG3_INQUIRE_NAMES_FOR_MECH) },
  { CALL_ENTRY(create_empty_oid_set),	GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  2, ARG2_CREATE_EMPTY_OID_SET)  },
  { CALL_ENTRY(add_oid_set_member),	GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  3, ARG3_ADD_OID_SET_MEMBER)    },
  { CALL_ENTRY(test_oid_set_member),	GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  4, ARG4_TEST_OID_SET_MEMBER)   },
  { NULL, 0, 0, 0 }

}; /* gss_generic_calls[] */


static struct dll_call_entry_s gss_name_calls[]= {

  { CALL_ENTRY(compare_name),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  4, ARG4_COMPARE_NAME)          },
  { CALL_ENTRY(display_name),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  4, ARG4_DISPLAY_NAME)          },
  { CALL_ENTRY(import_name),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  4, ARG4_IMPORT_NAME)           },
  { CALL_ENTRY(release_name),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  2, ARG2_RELEASE_NAME)          },
  { CALL_ENTRY(canonicalize_name),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  4, ARG4_CANONICALIZE_NAME)     },
  { CALL_ENTRY(export_name),		GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  3, ARG3_EXPORT_NAME)	    },
  { CALL_ENTRY(duplicate_name),		GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  3, ARG3_DUPLICATE_NAME)        },
  { CALL_ENTRY(inquire_mechs_for_name),	GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  3, ARG3_INQUIRE_MECHS_FOR_NAME) },
  { NULL, 0, 0, 0 }

}; /* gss_name_calls[] */



static struct dll_call_entry_s gss_cred_calls[]= {

  { CALL_ENTRY(acquire_cred),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  8, ARG8_ACQUIRE_CRED)	     },
  { CALL_ENTRY(release_cred),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  2, ARG2_RELEASE_CRED)	     },
  { CALL_ENTRY(inquire_cred),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  6, ARG6_INQUIRE_CRED)          },
  { CALL_ENTRY(inquire_cred_by_mech),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  7, ARG7_INQUIRE_CRED_BY_MECH)  },
  { CALL_ENTRY(add_cred),		GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32, 11, ARG11_ADD_CRED)             },
  { NULL, 0, 0, 0 }

}; /* gss_cred_calls[] */


static struct dll_call_entry_s gss_context_calls[]= {

  { CALL_ENTRY(init_sec_context),	GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32, 13, ARG13_INIT_SEC_CONTEXT)     },
  { CALL_ENTRY(accept_sec_context),	GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32, 11, ARG11_ACCEPT_SEC_CONTEXT)   },
  { CALL_ENTRY(delete_sec_context),	GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  3, ARG3_DELETE_SEC_CONTEXT)    },
  { CALL_ENTRY(context_time),		GSS_DL_V1 | GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  3, ARG3_CONTEXT_TIME)	     },
  { CALL_ENTRY(inquire_context),	GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  9, ARG9_INQUIRE_CONTEXT)       },
  { CALL_ENTRY(export_sec_context),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  3, ARG3_EXPORT_SEC_CONTEXT)    },
  { CALL_ENTRY(import_sec_context),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  3, ARG3_IMPORT_SEC_CONTEXT)    },
  { CALL_ENTRY(wrap_size_limit),	GSS_DL_V2 | GSS_DL_NEED,
			RTL_ATTR(OM_uint32,  6, ARG6_WRAP_SIZE_LIMIT)       },
  { CALL_ENTRY(process_context_token),	GSS_DL_V1 | GSS_DL_V2 | GSS_DL_OPT,
			RTL_ATTR(OM_uint32,  3, ARG3_PROCESS_CONTEXT_TOKEN) },
  { NULL, 0, 0, 0 }

}; /* gss_context_calls[] */


static struct dll_call_entry_s gss_msgprotv2_calls[] = {

  { CALL_ENTRY(get_mic),		GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  5, ARG5_GET_MIC)		    },
  { CALL_ENTRY(verify_mic),		GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  5, ARG5_VERIFY_MIC)	    },
  { CALL_ENTRY(wrap),			GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  7, ARG7_WRAP)		    },
  { CALL_ENTRY(unwrap),			GSS_DL_V2 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  6, ARG6_UNWRAP)		    },
  { NULL, 0, 0, 0 }

}; /* gss_msgprotv2_calls[] */



static struct dll_call_entry_s gss_msgprotv1_calls[] = {

  { "gss_sign",	  OF(gss_get_mic),	GSS_DL_V1 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  5, ARG5_GET_MIC)		    },
  { "gss_verify", OF(gss_verify_mic),	GSS_DL_V1 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  5, ARG5_VERIFY_MIC)	    },
  { "gss_seal",	  OF(gss_wrap),		GSS_DL_V1 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  7, ARG7_WRAP)		    },
  { "gss_unseal", OF(gss_unwrap),	GSS_DL_V1 | GSS_DL_REQ,
			RTL_ATTR(OM_uint32,  6, ARG6_UNWRAP)		    },
  { NULL, 0, 0, 0 }

}; /* gss_msgprotv1_calls[] */




/*
 * dll_load_gssapi()
 *
 * Return Value:
 *    0    Loading of DLL succeeded
 *   -1    Failure
 *
 */
int
dll_load_gssapi( int	        p_trclevel,
		 char         * p_libname,
		 DLL_GSSFP_T  * p_gssfp )
{
   char      * libname    = NULL;
   char	     * prefix     = "sap";
   size_t      len;
   OM_uint32   result;
   int         rc         = 0;
   int	       sap_flags  = 0;
   int	       gen_flags  = 0;
   int	       name_flags = 0;
   int	       cred_flags = 0;
   int	       ctx_flags  = 0;
   int	       mp1_flags  = 0;
   int	       mp2_flags  = 0;
   DEBUG_BEGIN(dll_load_gssapi)


   if ( p_gssfp==NULL )
      return(RTLERR_INVALID_HANDLE);

   num_dlls++;

   XVEB((V_OK, p_trclevel, "Loading GSS-API %s #%d \"%s\" ...\n\n",
	       SHLIB_TERM, (int)num_dlls, p_libname));

   memset( p_gssfp, 0, sizeof(*p_gssfp) );

   rc = rtl_load_library( p_libname, (RTL_HANDLE *)&(p_gssfp->dll_handle) );
   if ( rc!=0 ) {
      XVEB((V_ERR, "loading of GSS-API %s \"%s\" FAILED! (%s)\n",
	    SHLIB_TERM, p_libname, rtl_error_name(rc) ));  
      DEBUG_ERR((dfp, "rtl_load_library(\"%.250s\") failed: %s\n",
	              p_libname!=NULL ? p_libname : "", rtl_error_name(rc) ))
      ERROR_RETURN_RC(rc);
   }

   rc = dll_load_callset( p_trclevel, "SAP SNC-Adapter", prefix, p_gssfp,
			  sap_extra_calls, &sap_flags );
   if ( rc!=0 )
      ERROR_RETURN_RC(-1);

   if ( sap_flags==GSS_DL_SAP ) {
      prefix = "";
   } else {
      p_gssfp->snc_adapter_flag = TRUE;
      /* The "info" structure is contained in p_gssfp, so it has been zero'ed at the beginning */
      result = (p_gssfp->sapsnc_init_adapter)( &(p_gssfp->info), sizeof(p_gssfp->info), 0 );
      if ( result!=0 ) {
	 XVEB((V_ERR, "Initialization of SNC-Adapter failed !!\n"));
	 ERROR_RETURN_RC(-1);
      }
   }

   rc = dll_load_callset( p_trclevel, "Misc Support", prefix, p_gssfp,
			  gss_generic_calls, &gen_flags );
   if ( rc!=0 )
      ERROR_RETURN_RC(-1);

   rc = dll_load_callset( p_trclevel, "Names management", prefix, p_gssfp,
			  gss_name_calls, &name_flags );
   if ( rc!=0 )
      ERROR_RETURN_RC(-1);

   rc = dll_load_callset( p_trclevel, "Credentials management", prefix, p_gssfp,
			  gss_cred_calls, &cred_flags );
   if ( rc!=0 )
      ERROR_RETURN_RC(-1);

   rc = dll_load_callset( p_trclevel, "Context-level", prefix, p_gssfp,
			  gss_context_calls, &ctx_flags );
   if ( rc!=0 )
      ERROR_RETURN_RC(-1);

   rc = dll_load_callset( p_trclevel, "V2 message protection", prefix, p_gssfp,
			  gss_msgprotv2_calls, &mp2_flags );
   if ( rc!=0 ) {
      rc = dll_load_callset( p_trclevel, "V1 message protection", prefix, p_gssfp,
			     gss_msgprotv1_calls, &mp1_flags );
      if ( rc!=0 )
	 ERROR_RETURN_RC(-1);
   }

   if ( rc==0 ) {

      int all_flags  = gen_flags|name_flags|cred_flags|ctx_flags|mp2_flags|mp1_flags ;

      p_gssfp->flags = (GSS_DL_V2|GSS_DL_V1|GSS_DL_REQ|GSS_DL_NEED|GSS_DL_OPT) & (~all_flags);

      XVEB((V_OK, p_trclevel-1, "\n"));

      if ( (all_flags&GSS_DL_V2)==0 ) {

	 XVEB((V_OK, p_trclevel-1, "GOOD! Complete GSS-API v2 set of functions available.\n"));

	 p_gssfp->context_transfer_calls = TRUE;
	 p_gssfp->canonical_names_calls  = TRUE;

      } else {

	 XVEB((V_OK, p_trclevel-1, "INcomplete GSS-API v2 implementation.\n"));

	 if ( (all_flags&GSS_DL_V1)!=0 ) {
	    XVEB((V_ERR, "This library does not even implement full GSS-API v1.\n"));
	 }

         if ( (all_flags&GSS_DL_NEED)!=0 ) {
	    XVEB((V_OK, p_trclevel-1, "At least one of the \"requested\" calls is missing.\n"));
	 }
	 if ( p_gssfp->gss_export_name!=0
	      && p_gssfp->gss_canonicalize_name!=0 ) {

	    p_gssfp->canonical_names_calls = TRUE;

	 } else {
	    XVEB((V_OK, p_trclevel-1, "Support for binary canonical names is missing.\n"));
	 }

	 if ( p_gssfp->gss_export_sec_context!=0
	    && p_gssfp->gss_import_sec_context!=0 ) {

	    p_gssfp->context_transfer_calls = TRUE;

	 } else {
	    XVEB((V_OK, p_trclevel-1, "Support for export/import of security contexts is missing.\n"));
	 }

	 if ( (all_flags&GSS_DL_OPT)!=0 ) {
	    XVEB((V_OK, p_trclevel-1, "At least one of the \"optional\" calls is missing\n"));
	 }

      }

      XVEB((V_OK, p_trclevel-1, "\nLoading of %s %s completed.\n",
	 ((p_gssfp->snc_adapter_flag)==FALSE) ? "GSS-API" : "SNC Adapter",
	 SHLIB_TERM));

      if ( rtl_library_name( p_gssfp->dll_handle, &libname )!=RTL_OK ) {
	 libname = p_libname;
      }

      len = strlen(libname);
      p_gssfp->dll_name = (char *)malloc( len+1 );
      if ( (p_gssfp->dll_name)!=0 ) {
	 memcpy( p_gssfp->dll_name, libname, len+1 );
      }

   } else { /* rc!=0 */

error:
      num_dlls = (num_dlls>0) ? num_dlls-1 : num_dlls;

      if ( (p_gssfp->dll_handle)!=RTL_INVALID_HANDLE ) {
	 int rc2;
	 rc2 = rtl_unload_library( (RTL_HANDLE *)&(p_gssfp->dll_handle) );
	 if ( rc2!=0 ) {
	    DEBUG_STRANGE((dfp, "rtl_unload_library() failed: %s\n",
			        rtl_error_name(rc2) ))
	 }
	 (p_gssfp->dll_handle) = RTL_INVALID_HANDLE;

      } /* endif dll_handle!=RTL_INVALID_HANDLE */

      memset( p_gssfp, 0, sizeof(*p_gssfp) );
      p_gssfp->dll_handle = RTL_INVALID_HANDLE;

   } /* endif  rc!=0  */

   XVEB((V_OK, p_trclevel-1, "\n"));

   return(rc);

} /* dll_load_gssapi() */




/*
 * dll_unload_gssapi()
 *
 *
 */
int
dll_unload_gssapi( int    p_trclevel,  DLL_GSSFP_T  * p_gssfp )
{
   int  rc = 0;
   DEBUG_BEGIN(dll_unload_gssapi)

   if ( p_gssfp!=NULL ) {

      release_name( p_gssfp, &(p_gssfp->ini_name) );
      release_name( p_gssfp, &(p_gssfp->acc_name) );

      if ( (p_gssfp->dll_handle)!=RTL_INVALID_HANDLE ) {

	 rc = rtl_unload_library( (RTL_HANDLE *) &(p_gssfp->dll_handle) );
	 if ( rc!=0 ) {
	    DEBUG_ERR((dfp, "rtl_unload_library() failed: %s\n",
			    rtl_error_name(rc) ))
	    ERROR_RETURN_RC(-1);
	 } else {

	    XVEB((V_OK, p_trclevel-1, "\nUnloading of GSS-API %s successful.\n", SHLIB_TERM));

	 }

      }

      verbose_freemem( (void **) &(p_gssfp->initiator), &(p_gssfp->initiator_len) );
      verbose_freemem( (void **) &(p_gssfp->acceptor),  &(p_gssfp->acceptor_len)  );
      verbose_freemem( (void **) &(p_gssfp->def_acc),   &(p_gssfp->def_acc_len)   );
      verbose_freemem( (void **) &(p_gssfp->can_acc),   &(p_gssfp->can_acc_len)   );

      if ( p_gssfp->dll_name!=0 ) {
	 free( p_gssfp->dll_name );
	 (p_gssfp->dll_name) = 0;
      }

      memset( p_gssfp, 0, sizeof(*p_gssfp) );

      num_dlls = (num_dlls>0) ? num_dlls-1 : num_dlls;
   }

error:
   return(rc);

} /* dll_unload_gssapi() */



static char * status[] = {
      "REQUIRED ",
      "requested",
      "  opt.   "
};

static char * severance[] = {
      " MISSING !!",
      " MISSING",
      "(missing)"
};

#define FLAGS_TO_STATUS_IDX(flags)	    \
   ( ((flags)&GSS_DL_REQ)!=0 ? 0 : ( ((flags)&GSS_DL_NEED)!=0 ? 1 : 2 ) )

/*
 * dll_load_callset()
 *
 *
 */
static int
dll_load_callset( int			      p_trclevel,
		  char                      * p_callset_name,
		  char			    * p_call_prefix,
		  DLL_GSSFP_T	            * p_gssfp,
	          struct dll_call_entry_s   * p_dll_calls,
		  int			    * pp_flags )
{
   RTL_FUNC_ADR  * afptr;
   char          * func_name;
   char		 * space = "                                   ";
   int             fill;
   ptrdiff_t	   offset;
   int	           flags       = 0;
   int		   rc          = 0;
   int		   final_rc    = 0;
   int		   version     = 0;
   int		   idx	       = 0;
   int		   i;

   (*pp_flags) = 0;

   XVEB((V_INFO, p_trclevel-1, "Resolving %s functions ...\n", p_callset_name));
   afptr = (RTL_FUNC_ADR *) &(p_gssfp->GSS_FIRST_FUNC);

   for ( i=0 ; p_dll_calls[i].name!=NULL ; i++ ) {
      offset        = p_dll_calls[i].offset;
      flags         = p_dll_calls[i].flags;
      func_name     = p_dll_calls[i].name;
      afptr[offset] = 0;

      rc = rtl_load_function( p_gssfp->dll_handle, p_call_prefix, func_name,
			      p_dll_calls[i].attributes, &(afptr[offset]) );

      fill          = (int)(33 - strlen(p_call_prefix) - strlen(func_name));
      if (fill<0) { fill=1; }
      version       = ((flags&GSS_DL_V1)!=0) ? 1 : 2;
      idx	    = FLAGS_TO_STATUS_IDX(flags);

      if (rc==0) {
	 XVEB((V_INFO, p_trclevel-1, "  GSS-API v%u  \"%s%s\"%.*s    (%s)    ok.\n",
		      (Uint)version, p_call_prefix, func_name, (int)fill, space, status[idx] ));
      } else {
	 if ( (flags&GSS_DL_REQ)!=0 ) {
	    final_rc     = rc;
	    XVEB((V_ERR, "  GSS-API v%u  \"%s%s\"%.*s(%s)   %s\n",
		      (Uint)version, p_call_prefix, func_name, (int)fill, space, status[idx],
		      severance[idx] ));
	 } else {
	    XVEB((V_INFO, p_trclevel, "  GSS-API v%u  \"%s%s\"%.*s    (%s)   %s\n",
		      (Uint)version, p_call_prefix, func_name, (int)fill, space, status[idx],
		      severance[idx] ));
	 }
	 (*pp_flags) |= flags;
      }
   }

   return(final_rc);

} /* dll_load_callset() */

