Home | History | Annotate | Download | only in mech
      1 /*
      2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 /*
      6  * Copyright 1993 by OpenVision Technologies, Inc.
      7  *
      8  * Permission to use, copy, modify, distribute, and sell this software
      9  * and its documentation for any purpose is hereby granted without fee,
     10  * provided that the above copyright notice appears in all copies and
     11  * that both that copyright notice and this permission notice appear in
     12  * supporting documentation, and that the name of OpenVision not be used
     13  * in advertising or publicity pertaining to distribution of the software
     14  * without specific, written prior permission. OpenVision makes no
     15  * representations about the suitability of this software for any
     16  * purpose.  It is provided "as is" without express or implied warranty.
     17  *
     18  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     19  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     20  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     21  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     22  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     23  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     24  * PERFORMANCE OF THIS SOFTWARE.
     25  */
     26 
     27 /*
     28  * $Id: krb5_gss_glue.c 18262 2006-06-29 04:38:48Z tlyu $
     29  */
     30 
     31 #include "gssapiP_krb5.h"
     32 #include "mglueP.h"
     33 #include <syslog.h>
     34 
     35 /** mechglue wrappers **/
     36 
     37 static OM_uint32 k5glue_acquire_cred
     38 (void *, OM_uint32*,       /* minor_status */
     39             gss_name_t,       /* desired_name */
     40             OM_uint32,        /* time_req */
     41             gss_OID_set,      /* desired_mechs */
     42             gss_cred_usage_t, /* cred_usage */
     43             gss_cred_id_t*,   /* output_cred_handle */
     44             gss_OID_set*,     /* actual_mechs */
     45             OM_uint32*        /* time_rec */
     46            );
     47 
     48 static OM_uint32 k5glue_release_cred
     49 (void *, OM_uint32*,       /* minor_status */
     50             gss_cred_id_t*    /* cred_handle */
     51            );
     52 
     53 static OM_uint32 k5glue_init_sec_context
     54 (void *, OM_uint32*,       /* minor_status */
     55             gss_cred_id_t,    /* claimant_cred_handle */
     56             gss_ctx_id_t*,    /* context_handle */
     57             gss_name_t,       /* target_name */
     58             gss_OID,          /* mech_type */
     59             OM_uint32,        /* req_flags */
     60             OM_uint32,        /* time_req */
     61             gss_channel_bindings_t,
     62                               /* input_chan_bindings */
     63             gss_buffer_t,     /* input_token */
     64             gss_OID*,         /* actual_mech_type */
     65             gss_buffer_t,     /* output_token */
     66             OM_uint32*,       /* ret_flags */
     67             OM_uint32*        /* time_rec */
     68            );
     69 
     70 static OM_uint32 k5glue_accept_sec_context
     71 (void *, OM_uint32*,       /* minor_status */
     72             gss_ctx_id_t*,    /* context_handle */
     73             gss_cred_id_t,    /* verifier_cred_handle */
     74             gss_buffer_t,     /* input_token_buffer */
     75             gss_channel_bindings_t,
     76                               /* input_chan_bindings */
     77             gss_name_t*,      /* src_name */
     78             gss_OID*,         /* mech_type */
     79             gss_buffer_t,     /* output_token */
     80             OM_uint32*,       /* ret_flags */
     81             OM_uint32*,       /* time_rec */
     82             gss_cred_id_t*    /* delegated_cred_handle */
     83            );
     84 
     85 static OM_uint32 k5glue_process_context_token
     86 (void *, OM_uint32*,       /* minor_status */
     87             gss_ctx_id_t,     /* context_handle */
     88             gss_buffer_t      /* token_buffer */
     89            );
     90 
     91 static OM_uint32 k5glue_delete_sec_context
     92 (void *, OM_uint32*,       /* minor_status */
     93             gss_ctx_id_t*,    /* context_handle */
     94             gss_buffer_t      /* output_token */
     95            );
     96 
     97 static OM_uint32 k5glue_context_time
     98 (void *, OM_uint32*,       /* minor_status */
     99             gss_ctx_id_t,     /* context_handle */
    100             OM_uint32*        /* time_rec */
    101            );
    102 
    103 static OM_uint32 k5glue_sign
    104 (void *, OM_uint32*,       /* minor_status */
    105             gss_ctx_id_t,     /* context_handle */
    106             int,              /* qop_req */
    107             gss_buffer_t,     /* message_buffer */
    108             gss_buffer_t      /* message_token */
    109            );
    110 
    111 static OM_uint32 k5glue_verify
    112 (void *, OM_uint32*,       /* minor_status */
    113             gss_ctx_id_t,     /* context_handle */
    114             gss_buffer_t,     /* message_buffer */
    115             gss_buffer_t,     /* token_buffer */
    116             int*              /* qop_state */
    117            );
    118 
    119 /* EXPORT DELETE START */
    120 static OM_uint32 k5glue_seal
    121 (void *, OM_uint32*,       /* minor_status */
    122             gss_ctx_id_t,     /* context_handle */
    123             int,              /* conf_req_flag */
    124             int,              /* qop_req */
    125             gss_buffer_t,     /* input_message_buffer */
    126             int*,             /* conf_state */
    127             gss_buffer_t      /* output_message_buffer */
    128            );
    129 
    130 static OM_uint32 k5glue_unseal
    131 (void *, OM_uint32*,       /* minor_status */
    132             gss_ctx_id_t,     /* context_handle */
    133             gss_buffer_t,     /* input_message_buffer */
    134             gss_buffer_t,     /* output_message_buffer */
    135             int*,             /* conf_state */
    136             int*              /* qop_state */
    137            );
    138 /* EXPORT DELETE END */
    139 
    140 static OM_uint32 k5glue_display_status
    141 (void *, OM_uint32*,       /* minor_status */
    142             OM_uint32,        /* status_value */
    143             int,              /* status_type */
    144             gss_OID,          /* mech_type */
    145             OM_uint32*,       /* message_context */
    146             gss_buffer_t      /* status_string */
    147            );
    148 
    149 static OM_uint32 k5glue_indicate_mechs
    150 (void *, OM_uint32*,       /* minor_status */
    151             gss_OID_set*      /* mech_set */
    152            );
    153 
    154 static OM_uint32 k5glue_compare_name
    155 (void *, OM_uint32*,       /* minor_status */
    156             gss_name_t,       /* name1 */
    157             gss_name_t,       /* name2 */
    158             int*              /* name_equal */
    159            );
    160 
    161 static OM_uint32 k5glue_display_name
    162 (void *, OM_uint32*,      /* minor_status */
    163             gss_name_t,      /* input_name */
    164             gss_buffer_t,    /* output_name_buffer */
    165             gss_OID*         /* output_name_type */
    166            );
    167 
    168 static OM_uint32 k5glue_import_name
    169 (void *, OM_uint32*,       /* minor_status */
    170             gss_buffer_t,     /* input_name_buffer */
    171             gss_OID,          /* input_name_type */
    172             gss_name_t*       /* output_name */
    173            );
    174 
    175 static OM_uint32 k5glue_release_name
    176 (void *, OM_uint32*,       /* minor_status */
    177             gss_name_t*       /* input_name */
    178            );
    179 
    180 static OM_uint32 k5glue_inquire_cred
    181 (void *, OM_uint32 *,      /* minor_status */
    182             gss_cred_id_t,    /* cred_handle */
    183             gss_name_t *,     /* name */
    184             OM_uint32 *,      /* lifetime */
    185             gss_cred_usage_t*,/* cred_usage */
    186             gss_OID_set *     /* mechanisms */
    187            );
    188 
    189 static OM_uint32 k5glue_inquire_context
    190 (void *, OM_uint32*,       /* minor_status */
    191 	    gss_ctx_id_t,     /* context_handle */
    192 	    gss_name_t*,      /* initiator_name */
    193 	    gss_name_t*,      /* acceptor_name */
    194 	    OM_uint32*,       /* lifetime_rec */
    195 	    gss_OID*,         /* mech_type */
    196 	    OM_uint32*,       /* ret_flags */
    197 	    int*,             /* locally_initiated */
    198 	    int*              /* open */
    199 	   );
    200 
    201 #if 0
    202 /* New V2 entry points */
    203 static OM_uint32 k5glue_get_mic
    204 (void *, OM_uint32 *,		/* minor_status */
    205 	    gss_ctx_id_t,		/* context_handle */
    206 	    gss_qop_t,			/* qop_req */
    207 	    gss_buffer_t,		/* message_buffer */
    208 	    gss_buffer_t		/* message_token */
    209 	   );
    210 
    211 static OM_uint32 k5glue_verify_mic
    212 (void *, OM_uint32 *,		/* minor_status */
    213 	    gss_ctx_id_t,		/* context_handle */
    214 	    gss_buffer_t,		/* message_buffer */
    215 	    gss_buffer_t,		/* message_token */
    216 	    gss_qop_t *			/* qop_state */
    217 	   );
    218 
    219 static OM_uint32 k5glue_wrap
    220 (void *, OM_uint32 *,		/* minor_status */
    221 	    gss_ctx_id_t,		/* context_handle */
    222 	    int,			/* conf_req_flag */
    223 	    gss_qop_t,			/* qop_req */
    224 	    gss_buffer_t,		/* input_message_buffer */
    225 	    int *,			/* conf_state */
    226 	    gss_buffer_t		/* output_message_buffer */
    227 	   );
    228 
    229 static OM_uint32 k5glue_unwrap
    230 (void *, OM_uint32 *,		/* minor_status */
    231 	    gss_ctx_id_t,		/* context_handle */
    232 	    gss_buffer_t,		/* input_message_buffer */
    233 	    gss_buffer_t,		/* output_message_buffer */
    234 	    int *,			/* conf_state */
    235 	    gss_qop_t *			/* qop_state */
    236 	   );
    237 #endif
    238 
    239 static OM_uint32 k5glue_wrap_size_limit
    240 (void *, OM_uint32 *,		/* minor_status */
    241 	    gss_ctx_id_t,		/* context_handle */
    242 	    int,			/* conf_req_flag */
    243 	    gss_qop_t,			/* qop_req */
    244 	    OM_uint32,			/* req_output_size */
    245 	    OM_uint32 *			/* max_input_size */
    246 	   );
    247 
    248 #if 0
    249 static OM_uint32 k5glue_import_name_object
    250 (void *, OM_uint32 *,		/* minor_status */
    251 	    void *,			/* input_name */
    252 	    gss_OID,			/* input_name_type */
    253 	    gss_name_t *		/* output_name */
    254 	   );
    255 
    256 static OM_uint32 k5glue_export_name_object
    257 (void *, OM_uint32 *,		/* minor_status */
    258 	    gss_name_t,			/* input_name */
    259 	    gss_OID,			/* desired_name_type */
    260 	    void * *			/* output_name */
    261 	   );
    262 #endif
    263 
    264 static OM_uint32 k5glue_add_cred
    265 (void *, OM_uint32 *,		/* minor_status */
    266 	    gss_cred_id_t,		/* input_cred_handle */
    267 	    gss_name_t,			/* desired_name */
    268 	    gss_OID,			/* desired_mech */
    269 	    gss_cred_usage_t,		/* cred_usage */
    270 	    OM_uint32,			/* initiator_time_req */
    271 	    OM_uint32,			/* acceptor_time_req */
    272 	    gss_cred_id_t *,		/* output_cred_handle */
    273 	    gss_OID_set *,		/* actual_mechs */
    274 	    OM_uint32 *,		/* initiator_time_rec */
    275 	    OM_uint32 *			/* acceptor_time_rec */
    276 	   );
    277 
    278 static OM_uint32 k5glue_inquire_cred_by_mech
    279 (void *, OM_uint32  *,		/* minor_status */
    280 	    gss_cred_id_t,		/* cred_handle */
    281 	    gss_OID,			/* mech_type */
    282 	    gss_name_t *,		/* name */
    283 	    OM_uint32 *,		/* initiator_lifetime */
    284 	    OM_uint32 *,		/* acceptor_lifetime */
    285 	    gss_cred_usage_t * 		/* cred_usage */
    286 	   );
    287 
    288 static OM_uint32 k5glue_export_sec_context
    289 (void *, OM_uint32 *,		/* minor_status */
    290 	    gss_ctx_id_t *,		/* context_handle */
    291 	    gss_buffer_t		/* interprocess_token */
    292 	    );
    293 
    294 static OM_uint32 k5glue_import_sec_context
    295 (void *, OM_uint32 *,		/* minor_status */
    296 	    gss_buffer_t,		/* interprocess_token */
    297 	    gss_ctx_id_t *		/* context_handle */
    298 	    );
    299 
    300 krb5_error_code k5glue_ser_init(krb5_context);
    301 
    302 static OM_uint32 k5glue_internal_release_oid
    303 (void *, OM_uint32 *,		/* minor_status */
    304 	    gss_OID *			/* oid */
    305 	   );
    306 
    307 static OM_uint32 k5glue_inquire_names_for_mech
    308 (void *, OM_uint32 *,		/* minor_status */
    309 	    gss_OID,			/* mechanism */
    310 	    gss_OID_set *		/* name_types */
    311 	   );
    312 
    313 #if 0
    314 static OM_uint32 k5glue_canonicalize_name
    315 (void *, OM_uint32  *,		/* minor_status */
    316 	    const gss_name_t,		/* input_name */
    317 	    const gss_OID,		/* mech_type */
    318 	    gss_name_t *		/* output_name */
    319 	 );
    320 #endif
    321 
    322 static OM_uint32 k5glue_export_name
    323 (void *, OM_uint32  *,		/* minor_status */
    324 	    const gss_name_t,		/* input_name */
    325 	    gss_buffer_t		/* exported_name */
    326 	 );
    327 
    328 /* SUNW15resync - Solaris specific */
    329 static OM_uint32 k5glue_store_cred (
    330 	    void *,
    331 	    OM_uint32 *,            /* minor_status */
    332 	    const gss_cred_id_t,    /* input_cred */
    333 	    gss_cred_usage_t,       /* cred_usage */
    334 	    const gss_OID,          /* desired_mech */
    335 	    OM_uint32,              /* overwrite_cred */
    336 	    OM_uint32,              /* default_cred */
    337 	    gss_OID_set *,          /* elements_stored */
    338 	    gss_cred_usage_t *      /* cred_usage_stored */
    339 	   );
    340 
    341 /* SUNW17PACresync - this decl not needed in MIT but is for Sol */
    342 /* Note code is in gsspi_krb5.c */
    343 OM_uint32 krb5_gss_inquire_sec_context_by_oid(
    344 	OM_uint32 *,
    345 	const gss_ctx_id_t,
    346 	const gss_OID,
    347 	gss_buffer_set_t *);
    348 
    349 static OM_uint32
    350 k5glue_userok(
    351 		    void *,		/* context */
    352 		    OM_uint32 *,	/* minor_status */
    353 		    const gss_name_t,	/* pname */
    354 		    const char *,	/* local user */
    355 		    int *		/* user ok? */
    356 	/* */);
    357 
    358 static OM_uint32
    359 k5glue_pname_to_uid(
    360 		    void *,		/* context */
    361 		    OM_uint32 *,	/* minor_status */
    362 		    const gss_name_t,	/* pname */
    363 		    uid_t *		/* uid */
    364 	/* */);
    365 
    366 
    367 
    368 
    369 #if 0
    370 static OM_uint32 k5glue_duplicate_name
    371 (void *, OM_uint32  *,		/* minor_status */
    372 	    const gss_name_t,		/* input_name */
    373 	    gss_name_t *		/* dest_name */
    374 	 );
    375 #endif
    376 
    377 #if 0
    378 static OM_uint32 k5glue_validate_cred
    379 (void *, OM_uint32 *,		/* minor_status */
    380 	    gss_cred_id_t		/* cred */
    381          );
    382 #endif
    383 
    384 #if 0
    385 /*
    386  * SUNW15resync
    387  * Solaris can't use the KRB5_GSS_CONFIG_INIT macro because of the src
    388  * slicing&dicing needs of the "nightly -SD" build.  When it goes away,
    389  * we should use it assuming MIT still uses it then.
    390  */
    391 
    392 /*
    393  * The krb5 mechanism provides two mech OIDs; use this initializer to
    394  * ensure that both dispatch tables contain identical function
    395  * pointers.
    396  */
    397 #define KRB5_GSS_CONFIG_INIT				\
    398     NULL,						\
    399     ...
    400 #endif
    401 
    402 
    403 static struct gss_config krb5_mechanism = {
    404 #if 0 /* Solaris Kerberos */
    405     100, "kerberos_v5",
    406 #endif
    407     { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID },
    408     NULL,
    409     k5glue_acquire_cred,
    410     k5glue_release_cred,
    411     k5glue_init_sec_context,
    412     k5glue_accept_sec_context,
    413 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    414     k5glue_unseal,
    415 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    416     k5glue_process_context_token,
    417     k5glue_delete_sec_context,
    418     k5glue_context_time,
    419     k5glue_display_status,
    420     k5glue_indicate_mechs,
    421     k5glue_compare_name,
    422     k5glue_display_name,
    423     k5glue_import_name,
    424     k5glue_release_name,
    425     k5glue_inquire_cred,
    426     k5glue_add_cred,
    427 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    428     k5glue_seal,
    429 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    430     k5glue_export_sec_context,
    431     k5glue_import_sec_context,
    432     k5glue_inquire_cred_by_mech,
    433     k5glue_inquire_names_for_mech,
    434     k5glue_inquire_context,
    435     k5glue_internal_release_oid,
    436     k5glue_wrap_size_limit,
    437     k5glue_pname_to_uid,
    438     k5glue_userok,
    439     k5glue_export_name,
    440 /* EXPORT DELETE START */
    441 /* CRYPT DELETE START */
    442 #if 0
    443 /* CRYPT DELETE END */
    444     k5glue_seal,
    445     k5glue_unseal,
    446 /* CRYPT DELETE START */
    447 #endif
    448 /* CRYPT DELETE END */
    449 /* EXPORT DELETE END */
    450     k5glue_sign,
    451     k5glue_verify,
    452     k5glue_store_cred,
    453     krb5_gss_inquire_sec_context_by_oid
    454 };
    455 
    456 static struct gss_config krb5_mechanism_old = {
    457 #if 0 /* Solaris Kerberos */
    458     200, "kerberos_v5 (pre-RFC OID)",
    459 #endif
    460     { GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID },
    461     NULL,
    462     k5glue_acquire_cred,
    463     k5glue_release_cred,
    464     k5glue_init_sec_context,
    465     k5glue_accept_sec_context,
    466 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    467     k5glue_unseal,
    468 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    469     k5glue_process_context_token,
    470     k5glue_delete_sec_context,
    471     k5glue_context_time,
    472     k5glue_display_status,
    473     k5glue_indicate_mechs,
    474     k5glue_compare_name,
    475     k5glue_display_name,
    476     k5glue_import_name,
    477     k5glue_release_name,
    478     k5glue_inquire_cred,
    479     k5glue_add_cred,
    480 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    481     k5glue_seal,
    482 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    483     k5glue_export_sec_context,
    484     k5glue_import_sec_context,
    485     k5glue_inquire_cred_by_mech,
    486     k5glue_inquire_names_for_mech,
    487     k5glue_inquire_context,
    488     k5glue_internal_release_oid,
    489     k5glue_wrap_size_limit,
    490     k5glue_pname_to_uid,
    491     k5glue_userok,
    492     k5glue_export_name,
    493 /* EXPORT DELETE START */
    494 /* CRYPT DELETE START */
    495 #if 0
    496 /* CRYPT DELETE END */
    497     k5glue_seal,
    498     k5glue_unseal,
    499 /* CRYPT DELETE START */
    500 #endif
    501 /* CRYPT DELETE END */
    502 /* EXPORT DELETE END */
    503     k5glue_sign,
    504     k5glue_verify,
    505     k5glue_store_cred,
    506     krb5_gss_inquire_sec_context_by_oid
    507 };
    508 
    509 static struct gss_config krb5_mechanism_wrong = {
    510 #if 0 /* Solaris Kerberos */
    511     300, "kerberos_v5 (wrong OID)",
    512 #endif
    513     { GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID },
    514     NULL,
    515     k5glue_acquire_cred,
    516     k5glue_release_cred,
    517     k5glue_init_sec_context,
    518     k5glue_accept_sec_context,
    519 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    520     k5glue_unseal,
    521 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    522     k5glue_process_context_token,
    523     k5glue_delete_sec_context,
    524     k5glue_context_time,
    525     k5glue_display_status,
    526     k5glue_indicate_mechs,
    527     k5glue_compare_name,
    528     k5glue_display_name,
    529     k5glue_import_name,
    530     k5glue_release_name,
    531     k5glue_inquire_cred,
    532     k5glue_add_cred,
    533 /* EXPORT DELETE START */ /* CRYPT DELETE START */
    534     k5glue_seal,
    535 /* EXPORT DELETE END */ /* CRYPT DELETE END */
    536     k5glue_export_sec_context,
    537     k5glue_import_sec_context,
    538     k5glue_inquire_cred_by_mech,
    539     k5glue_inquire_names_for_mech,
    540     k5glue_inquire_context,
    541     k5glue_internal_release_oid,
    542     k5glue_wrap_size_limit,
    543     k5glue_pname_to_uid,
    544     k5glue_userok,
    545     k5glue_export_name,
    546 /* EXPORT DELETE START */
    547 /* CRYPT DELETE START */
    548 #if 0
    549 /* CRYPT DELETE END */
    550     k5glue_seal,
    551     k5glue_unseal,
    552 /* CRYPT DELETE START */
    553 #endif
    554 /* CRYPT DELETE END */
    555 /* EXPORT DELETE END */
    556     k5glue_sign,
    557     k5glue_verify,
    558     k5glue_store_cred,
    559     krb5_gss_inquire_sec_context_by_oid
    560 };
    561 
    562 static gss_mechanism krb5_mech_configs[] = {
    563     &krb5_mechanism, &krb5_mechanism_old, &krb5_mechanism_wrong, NULL
    564 };
    565 
    566 #ifdef MS_BUG_TEST
    567 static gss_mechanism krb5_mech_configs_hack[] = {
    568     &krb5_mechanism, &krb5_mechanism_old, NULL
    569 };
    570 #endif
    571 
    572 #if 1
    573 #define gssint_get_mech_configs krb5_gss_get_mech_configs
    574 #endif
    575 
    576 gss_mechanism *
    577 gssint_get_mech_configs(void)
    578 {
    579 #ifdef MS_BUG_TEST
    580     char *envstr = getenv("MS_FORCE_NO_MSOID");
    581 
    582     if (envstr != NULL && strcmp(envstr, "1") == 0) {
    583 	return krb5_mech_configs_hack;
    584     }
    585 #endif
    586     return krb5_mech_configs;
    587 }
    588 
    589 static OM_uint32
    590 k5glue_accept_sec_context(ctx, minor_status, context_handle, verifier_cred_handle,
    591 		       input_token, input_chan_bindings, src_name, mech_type,
    592 		       output_token, ret_flags, time_rec, delegated_cred_handle)
    593     void *ctx;
    594      OM_uint32 *minor_status;
    595      gss_ctx_id_t *context_handle;
    596      gss_cred_id_t verifier_cred_handle;
    597      gss_buffer_t input_token;
    598      gss_channel_bindings_t input_chan_bindings;
    599      gss_name_t *src_name;
    600      gss_OID *mech_type;
    601      gss_buffer_t output_token;
    602      OM_uint32 *ret_flags;
    603      OM_uint32 *time_rec;
    604      gss_cred_id_t *delegated_cred_handle;
    605 {
    606    return(krb5_gss_accept_sec_context(minor_status,
    607 				      context_handle,
    608 				      verifier_cred_handle,
    609 				      input_token,
    610 				      input_chan_bindings,
    611 				      src_name,
    612 				      mech_type,
    613 				      output_token,
    614 				      ret_flags,
    615 				      time_rec,
    616 				      delegated_cred_handle));
    617 }
    618 
    619 static OM_uint32
    620 k5glue_acquire_cred(ctx, minor_status, desired_name, time_req, desired_mechs,
    621 		 cred_usage, output_cred_handle, actual_mechs, time_rec)
    622     void *ctx;
    623      OM_uint32 *minor_status;
    624      gss_name_t desired_name;
    625      OM_uint32 time_req;
    626      gss_OID_set desired_mechs;
    627      gss_cred_usage_t cred_usage;
    628      gss_cred_id_t *output_cred_handle;
    629      gss_OID_set *actual_mechs;
    630      OM_uint32 *time_rec;
    631 {
    632    return(krb5_gss_acquire_cred(minor_status,
    633 				desired_name,
    634 				time_req,
    635 				desired_mechs,
    636 				cred_usage,
    637 				output_cred_handle,
    638 				actual_mechs,
    639 				time_rec));
    640 }
    641 
    642 /* V2 */
    643 static OM_uint32
    644 k5glue_add_cred(ctx, minor_status, input_cred_handle, desired_name, desired_mech,
    645 	     cred_usage, initiator_time_req, acceptor_time_req,
    646 	     output_cred_handle, actual_mechs, initiator_time_rec,
    647 	     acceptor_time_rec)
    648     void *ctx;
    649     OM_uint32		 *minor_status;
    650     gss_cred_id_t	input_cred_handle;
    651     gss_name_t		desired_name;
    652     gss_OID		desired_mech;
    653     gss_cred_usage_t	cred_usage;
    654     OM_uint32		initiator_time_req;
    655     OM_uint32		acceptor_time_req;
    656     gss_cred_id_t	 *output_cred_handle;
    657     gss_OID_set		 *actual_mechs;
    658     OM_uint32		 *initiator_time_rec;
    659     OM_uint32		 *acceptor_time_rec;
    660 {
    661     return(krb5_gss_add_cred(minor_status, input_cred_handle, desired_name,
    662 			     desired_mech, cred_usage, initiator_time_req,
    663 			     acceptor_time_req, output_cred_handle,
    664 			     actual_mechs, initiator_time_rec,
    665 			     acceptor_time_rec));
    666 }
    667 
    668 #if 0
    669 /* V2 */
    670 static OM_uint32
    671 k5glue_add_oid_set_member(ctx, minor_status, member_oid, oid_set)
    672     void *ctx;
    673     OM_uint32	 *minor_status;
    674     gss_OID	member_oid;
    675     gss_OID_set	 *oid_set;
    676 {
    677     return(generic_gss_add_oid_set_member(minor_status, member_oid, oid_set));
    678 }
    679 #endif
    680 
    681 static OM_uint32
    682 k5glue_compare_name(ctx, minor_status, name1, name2, name_equal)
    683     void *ctx;
    684      OM_uint32 *minor_status;
    685      gss_name_t name1;
    686      gss_name_t name2;
    687      int *name_equal;
    688 {
    689    return(krb5_gss_compare_name(minor_status, name1,
    690 				name2, name_equal));
    691 }
    692 
    693 static OM_uint32
    694 k5glue_context_time(ctx, minor_status, context_handle, time_rec)
    695     void *ctx;
    696      OM_uint32 *minor_status;
    697      gss_ctx_id_t context_handle;
    698      OM_uint32 *time_rec;
    699 {
    700    return(krb5_gss_context_time(minor_status, context_handle,
    701 				time_rec));
    702 }
    703 
    704 #if 0
    705 /* V2 */
    706 static OM_uint32
    707 k5glue_create_empty_oid_set(ctx, minor_status, oid_set)
    708     void *ctx;
    709     OM_uint32	 *minor_status;
    710     gss_OID_set	 *oid_set;
    711 {
    712     return(generic_gss_create_empty_oid_set(minor_status, oid_set));
    713 }
    714 #endif
    715 
    716 static OM_uint32
    717 k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token)
    718     void *ctx;
    719      OM_uint32 *minor_status;
    720      gss_ctx_id_t *context_handle;
    721      gss_buffer_t output_token;
    722 {
    723    return(krb5_gss_delete_sec_context(minor_status,
    724 				      context_handle, output_token));
    725 }
    726 
    727 static OM_uint32
    728 k5glue_display_name(ctx, minor_status, input_name, output_name_buffer, output_name_type)
    729     void *ctx;
    730      OM_uint32 *minor_status;
    731      gss_name_t input_name;
    732      gss_buffer_t output_name_buffer;
    733      gss_OID *output_name_type;
    734 {
    735    return(krb5_gss_display_name(minor_status, input_name,
    736 				output_name_buffer, output_name_type));
    737 }
    738 
    739 static OM_uint32
    740 k5glue_display_status(ctx, minor_status, status_value, status_type,
    741 		   mech_type, message_context, status_string)
    742     void *ctx;
    743      OM_uint32 *minor_status;
    744      OM_uint32 status_value;
    745      int status_type;
    746      gss_OID mech_type;
    747      OM_uint32 *message_context;
    748      gss_buffer_t status_string;
    749 {
    750    return(krb5_gss_display_status(minor_status, status_value,
    751 				  status_type, mech_type, message_context,
    752 				  status_string));
    753 }
    754 
    755 /* V2 */
    756 static OM_uint32
    757 k5glue_export_sec_context(ctx, minor_status, context_handle, interprocess_token)
    758     void *ctx;
    759      OM_uint32		 *minor_status;
    760      gss_ctx_id_t	 *context_handle;
    761      gss_buffer_t	interprocess_token;
    762 {
    763    return(krb5_gss_export_sec_context(minor_status,
    764 				      context_handle,
    765 				      interprocess_token));
    766 }
    767 
    768 #if 0
    769 /* V2 */
    770 static OM_uint32
    771 k5glue_get_mic(ctx, minor_status, context_handle, qop_req,
    772 	    message_buffer, message_token)
    773     void *ctx;
    774      OM_uint32		 *minor_status;
    775      gss_ctx_id_t	context_handle;
    776      gss_qop_t		qop_req;
    777      gss_buffer_t	message_buffer;
    778      gss_buffer_t	message_token;
    779 {
    780     return(krb5_gss_get_mic(minor_status, context_handle,
    781 			    qop_req, message_buffer, message_token));
    782 }
    783 #endif
    784 
    785 static OM_uint32
    786 k5glue_import_name(ctx, minor_status, input_name_buffer, input_name_type, output_name)
    787     void *ctx;
    788      OM_uint32 *minor_status;
    789      gss_buffer_t input_name_buffer;
    790      gss_OID input_name_type;
    791      gss_name_t *output_name;
    792 {
    793 #if 0
    794     OM_uint32 err;
    795     err = gssint_initialize_library();
    796     if (err) {
    797 	*minor_status = err;
    798 	return GSS_S_FAILURE;
    799     }
    800 #endif
    801     return(krb5_gss_import_name(minor_status, input_name_buffer,
    802 				input_name_type, output_name));
    803 }
    804 
    805 /* V2 */
    806 static OM_uint32
    807 k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle)
    808     void *ctx;
    809      OM_uint32		 *minor_status;
    810      gss_buffer_t	interprocess_token;
    811      gss_ctx_id_t	 *context_handle;
    812 {
    813    return(krb5_gss_import_sec_context(minor_status,
    814 				      interprocess_token,
    815 				      context_handle));
    816 }
    817 
    818 static OM_uint32
    819 k5glue_indicate_mechs(ctx, minor_status, mech_set)
    820     void *ctx;
    821      OM_uint32 *minor_status;
    822      gss_OID_set *mech_set;
    823 {
    824    return(krb5_gss_indicate_mechs(minor_status, mech_set));
    825 }
    826 
    827 static OM_uint32
    828 k5glue_init_sec_context(ctx, minor_status, claimant_cred_handle, context_handle,
    829 		     target_name, mech_type, req_flags, time_req,
    830 		     input_chan_bindings, input_token, actual_mech_type,
    831 		     output_token, ret_flags, time_rec)
    832     void *ctx;
    833      OM_uint32 *minor_status;
    834      gss_cred_id_t claimant_cred_handle;
    835      gss_ctx_id_t *context_handle;
    836      gss_name_t target_name;
    837      gss_OID mech_type;
    838      OM_uint32 req_flags;
    839      OM_uint32 time_req;
    840      gss_channel_bindings_t input_chan_bindings;
    841      gss_buffer_t input_token;
    842      gss_OID *actual_mech_type;
    843      gss_buffer_t output_token;
    844      OM_uint32 *ret_flags;
    845      OM_uint32 *time_rec;
    846 {
    847    return(krb5_gss_init_sec_context(minor_status,
    848 				    claimant_cred_handle, context_handle,
    849 				    target_name, mech_type, req_flags,
    850 				    time_req, input_chan_bindings, input_token,
    851 				    actual_mech_type, output_token, ret_flags,
    852 				    time_rec));
    853 }
    854 
    855 static OM_uint32
    856 k5glue_inquire_context(ctx, minor_status, context_handle, initiator_name, acceptor_name,
    857 		    lifetime_rec, mech_type, ret_flags,
    858 		    locally_initiated, open)
    859     void *ctx;
    860      OM_uint32 *minor_status;
    861      gss_ctx_id_t context_handle;
    862      gss_name_t *initiator_name;
    863      gss_name_t *acceptor_name;
    864      OM_uint32 *lifetime_rec;
    865      gss_OID *mech_type;
    866      OM_uint32 *ret_flags;
    867      int *locally_initiated;
    868      int *open;
    869 {
    870    return(krb5_gss_inquire_context(minor_status, context_handle,
    871 				   initiator_name, acceptor_name, lifetime_rec,
    872 				   mech_type, ret_flags, locally_initiated,
    873 				   open));
    874 }
    875 
    876 static OM_uint32
    877 k5glue_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret,
    878 		 cred_usage, mechanisms)
    879     void *ctx;
    880      OM_uint32 *minor_status;
    881      gss_cred_id_t cred_handle;
    882      gss_name_t *name;
    883      OM_uint32 *lifetime_ret;
    884      gss_cred_usage_t *cred_usage;
    885      gss_OID_set *mechanisms;
    886 {
    887    return(krb5_gss_inquire_cred(minor_status, cred_handle,
    888 				name, lifetime_ret, cred_usage, mechanisms));
    889 }
    890 
    891 /* V2 */
    892 static OM_uint32
    893 k5glue_inquire_cred_by_mech(ctx, minor_status, cred_handle, mech_type, name,
    894 			 initiator_lifetime, acceptor_lifetime, cred_usage)
    895     void *ctx;
    896      OM_uint32		 *minor_status;
    897      gss_cred_id_t	cred_handle;
    898      gss_OID		mech_type;
    899      gss_name_t		 *name;
    900      OM_uint32		 *initiator_lifetime;
    901      OM_uint32		 *acceptor_lifetime;
    902      gss_cred_usage_t	 *cred_usage;
    903 {
    904    return(krb5_gss_inquire_cred_by_mech(minor_status, cred_handle,
    905 					mech_type, name, initiator_lifetime,
    906 					acceptor_lifetime, cred_usage));
    907 }
    908 
    909 /* V2 */
    910 static OM_uint32
    911 k5glue_inquire_names_for_mech(ctx, minor_status, mechanism, name_types)
    912     void *ctx;
    913     OM_uint32	 *minor_status;
    914     gss_OID	mechanism;
    915     gss_OID_set	 *name_types;
    916 {
    917     return(krb5_gss_inquire_names_for_mech(minor_status,
    918 					   mechanism,
    919 					   name_types));
    920 }
    921 
    922 #if 0
    923 /* V2 */
    924 static OM_uint32
    925 k5glue_oid_to_str(ctx, minor_status, oid, oid_str)
    926     void *ctx;
    927     OM_uint32		 *minor_status;
    928     gss_OID		oid;
    929     gss_buffer_t	oid_str;
    930 {
    931     return(generic_gss_oid_to_str(minor_status, oid, oid_str));
    932 }
    933 #endif
    934 
    935 static OM_uint32
    936 k5glue_process_context_token(ctx, minor_status, context_handle, token_buffer)
    937     void *ctx;
    938      OM_uint32 *minor_status;
    939      gss_ctx_id_t context_handle;
    940      gss_buffer_t token_buffer;
    941 {
    942    return(krb5_gss_process_context_token(minor_status,
    943 					 context_handle, token_buffer));
    944 }
    945 
    946 static OM_uint32
    947 k5glue_release_cred(ctx, minor_status, cred_handle)
    948     void *ctx;
    949      OM_uint32 *minor_status;
    950      gss_cred_id_t *cred_handle;
    951 {
    952    return(krb5_gss_release_cred(minor_status, cred_handle));
    953 }
    954 
    955 static OM_uint32
    956 k5glue_release_name(ctx, minor_status, input_name)
    957     void *ctx;
    958      OM_uint32 *minor_status;
    959      gss_name_t *input_name;
    960 {
    961    return(krb5_gss_release_name(minor_status, input_name));
    962 }
    963 
    964 #if 0
    965 static OM_uint32
    966 k5glue_release_buffer(ctx, minor_status, buffer)
    967     void *ctx;
    968      OM_uint32 *minor_status;
    969      gss_buffer_t buffer;
    970 {
    971    return(generic_gss_release_buffer(minor_status,
    972 				     buffer));
    973 }
    974 #endif
    975 
    976 /* V2 */
    977 static OM_uint32
    978 k5glue_internal_release_oid(ctx, minor_status, oid)
    979     void *ctx;
    980      OM_uint32	 *minor_status;
    981      gss_OID	 *oid;
    982 {
    983     return(krb5_gss_internal_release_oid(minor_status, oid));
    984 }
    985 
    986 #if 0
    987 static OM_uint32
    988 k5glue_release_oid_set(ctx, minor_status, set)
    989     void *ctx;
    990      OM_uint32 * minor_status;
    991      gss_OID_set *set;
    992 {
    993    return(generic_gss_release_oid_set(minor_status, set));
    994 }
    995 #endif
    996 
    997 /* EXPORT DELETE START */
    998 /* V1 only */
    999 static OM_uint32
   1000 k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req,
   1001 	 input_message_buffer, conf_state, output_message_buffer)
   1002     void *ctx;
   1003      OM_uint32 *minor_status;
   1004      gss_ctx_id_t context_handle;
   1005      int conf_req_flag;
   1006      int qop_req;
   1007      gss_buffer_t input_message_buffer;
   1008      int *conf_state;
   1009      gss_buffer_t output_message_buffer;
   1010 {
   1011    return(krb5_gss_seal(minor_status, context_handle,
   1012 			conf_req_flag, qop_req, input_message_buffer,
   1013 			conf_state, output_message_buffer));
   1014 }
   1015 /* EXPORT DELETE END */
   1016 
   1017 static OM_uint32
   1018 k5glue_sign(ctx, minor_status, context_handle,
   1019 	      qop_req, message_buffer,
   1020 	      message_token)
   1021     void *ctx;
   1022      OM_uint32 *minor_status;
   1023      gss_ctx_id_t context_handle;
   1024      int qop_req;
   1025      gss_buffer_t message_buffer;
   1026      gss_buffer_t message_token;
   1027 {
   1028    return(krb5_gss_sign(minor_status, context_handle,
   1029 			qop_req, message_buffer, message_token));
   1030 }
   1031 
   1032 #if 0
   1033 /* V2 */
   1034 static OM_uint32
   1035 k5glue_verify_mic(ctx, minor_status, context_handle,
   1036 	       message_buffer, token_buffer, qop_state)
   1037     void *ctx;
   1038      OM_uint32		 *minor_status;
   1039      gss_ctx_id_t	context_handle;
   1040      gss_buffer_t	message_buffer;
   1041      gss_buffer_t	token_buffer;
   1042      gss_qop_t		 *qop_state;
   1043 {
   1044     return(krb5_gss_verify_mic(minor_status, context_handle,
   1045 			       message_buffer, token_buffer, qop_state));
   1046 }
   1047 
   1048 /* V2 */
   1049 static OM_uint32
   1050 k5glue_wrap(ctx, minor_status, context_handle, conf_req_flag, qop_req,
   1051 	 input_message_buffer, conf_state, output_message_buffer)
   1052     void *ctx;
   1053     OM_uint32		 *minor_status;
   1054     gss_ctx_id_t	context_handle;
   1055     int			conf_req_flag;
   1056     gss_qop_t		qop_req;
   1057     gss_buffer_t	input_message_buffer;
   1058     int			 *conf_state;
   1059     gss_buffer_t	output_message_buffer;
   1060 {
   1061     return(krb5_gss_wrap(minor_status, context_handle, conf_req_flag, qop_req,
   1062 			 input_message_buffer, conf_state,
   1063 			 output_message_buffer));
   1064 }
   1065 
   1066 /* V2 */
   1067 static OM_uint32
   1068 k5glue_str_to_oid(ctx, minor_status, oid_str, oid)
   1069     void *ctx;
   1070     OM_uint32		 *minor_status;
   1071     gss_buffer_t	oid_str;
   1072     gss_OID		 *oid;
   1073 {
   1074     return(generic_gss_str_to_oid(minor_status, oid_str, oid));
   1075 }
   1076 
   1077 /* V2 */
   1078 static OM_uint32
   1079 k5glue_test_oid_set_member(ctx, minor_status, member, set, present)
   1080     void *ctx;
   1081     OM_uint32	 *minor_status;
   1082     gss_OID	member;
   1083     gss_OID_set	set;
   1084     int		 *present;
   1085 {
   1086     return(generic_gss_test_oid_set_member(minor_status, member, set,
   1087 					   present));
   1088 }
   1089 #endif
   1090 
   1091 /* EXPORT DELETE START */
   1092 /* V1 only */
   1093 static OM_uint32
   1094 k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer,
   1095 	   output_message_buffer, conf_state, qop_state)
   1096     void *ctx;
   1097      OM_uint32 *minor_status;
   1098      gss_ctx_id_t context_handle;
   1099      gss_buffer_t input_message_buffer;
   1100      gss_buffer_t output_message_buffer;
   1101      int *conf_state;
   1102      int *qop_state;
   1103 {
   1104    return(krb5_gss_unseal(minor_status, context_handle,
   1105 			  input_message_buffer, output_message_buffer,
   1106 			  conf_state, qop_state));
   1107 }
   1108 /* EXPORT DELETE END */
   1109 
   1110 #if 0
   1111 /* V2 */
   1112 static OM_uint32
   1113 k5glue_unwrap(ctx, minor_status, context_handle, input_message_buffer,
   1114 	   output_message_buffer, conf_state, qop_state)
   1115     void *ctx;
   1116     OM_uint32		 *minor_status;
   1117     gss_ctx_id_t	context_handle;
   1118     gss_buffer_t	input_message_buffer;
   1119     gss_buffer_t	output_message_buffer;
   1120     int			 *conf_state;
   1121     gss_qop_t		 *qop_state;
   1122 {
   1123     return(krb5_gss_unwrap(minor_status, context_handle, input_message_buffer,
   1124 			   output_message_buffer, conf_state, qop_state));
   1125 }
   1126 #endif
   1127 
   1128 /* V1 only */
   1129 static OM_uint32
   1130 k5glue_verify(ctx, minor_status, context_handle, message_buffer,
   1131 	   token_buffer, qop_state)
   1132     void *ctx;
   1133      OM_uint32 *minor_status;
   1134      gss_ctx_id_t context_handle;
   1135      gss_buffer_t message_buffer;
   1136      gss_buffer_t token_buffer;
   1137      int *qop_state;
   1138 {
   1139    return(krb5_gss_verify(minor_status,
   1140 			  context_handle,
   1141 			  message_buffer,
   1142 			  token_buffer,
   1143 			  qop_state));
   1144 }
   1145 
   1146 /* V2 interface */
   1147 static OM_uint32
   1148 k5glue_wrap_size_limit(ctx, minor_status, context_handle, conf_req_flag,
   1149 		    qop_req, req_output_size, max_input_size)
   1150     void *ctx;
   1151     OM_uint32		 *minor_status;
   1152     gss_ctx_id_t	context_handle;
   1153     int			conf_req_flag;
   1154     gss_qop_t		qop_req;
   1155     OM_uint32		req_output_size;
   1156     OM_uint32		 *max_input_size;
   1157 {
   1158    return(krb5_gss_wrap_size_limit(minor_status, context_handle,
   1159 				   conf_req_flag, qop_req,
   1160 				   req_output_size, max_input_size));
   1161 }
   1162 
   1163 #if 0
   1164 /* V2 interface */
   1165 static OM_uint32
   1166 k5glue_canonicalize_name(ctx, minor_status, input_name, mech_type, output_name)
   1167     void *ctx;
   1168 	OM_uint32  *minor_status;
   1169 	const gss_name_t input_name;
   1170 	const gss_OID mech_type;
   1171 	gss_name_t *output_name;
   1172 {
   1173 	return krb5_gss_canonicalize_name(minor_status, input_name,
   1174 					  mech_type, output_name);
   1175 }
   1176 #endif
   1177 
   1178 /* V2 interface */
   1179 static OM_uint32
   1180 k5glue_export_name(ctx, minor_status, input_name, exported_name)
   1181     void *ctx;
   1182 	OM_uint32  *minor_status;
   1183 	const gss_name_t input_name;
   1184 	gss_buffer_t exported_name;
   1185 {
   1186 	return krb5_gss_export_name(minor_status, input_name, exported_name);
   1187 }
   1188 
   1189 /* SUNW15resync - this is not in the MIT mech (lib) yet */
   1190 static OM_uint32
   1191 k5glue_store_cred(ctx, minor_status, input_cred, cred_usage, desired_mech,
   1192 			overwrite_cred, default_cred, elements_stored,
   1193 			cred_usage_stored)
   1194 void *ctx;
   1195 OM_uint32 *minor_status;
   1196 const gss_cred_id_t input_cred;
   1197 gss_cred_usage_t cred_usage;
   1198 gss_OID desired_mech;
   1199 OM_uint32 overwrite_cred;
   1200 OM_uint32 default_cred;
   1201 gss_OID_set *elements_stored;
   1202 gss_cred_usage_t *cred_usage_stored;
   1203 {
   1204   return(krb5_gss_store_cred(minor_status, input_cred,
   1205 			    cred_usage, desired_mech,
   1206 			    overwrite_cred, default_cred, elements_stored,
   1207 			    cred_usage_stored));
   1208 }
   1209 
   1210 static OM_uint32
   1211 k5glue_userok(
   1212 		    void *ctxt,		/* context */
   1213 		    OM_uint32 *minor,	/* minor_status */
   1214 		    const gss_name_t pname,	/* pname */
   1215 		    const char *user,	/* local user */
   1216 		    int *user_ok		/* user ok? */
   1217 	/* */)
   1218 {
   1219   return(krb5_gss_userok(minor, pname, user, user_ok));
   1220 }
   1221 
   1222 static OM_uint32
   1223 k5glue_pname_to_uid(
   1224 		    void *ctxt,		/* context */
   1225 		    OM_uint32 *minor,	/* minor_status */
   1226 		    const gss_name_t pname,	/* pname */
   1227 		    uid_t *uidOut		/* uid */
   1228 	/* */)
   1229 {
   1230   return (krb5_pname_to_uid(minor, pname, uidOut));
   1231 }
   1232 
   1233 
   1234 
   1235 #if 0
   1236 /* V2 interface */
   1237 static OM_uint32
   1238 k5glue_duplicate_name(ctx, minor_status, input_name, dest_name)
   1239     void *ctx;
   1240 	OM_uint32  *minor_status;
   1241 	const gss_name_t input_name;
   1242 	gss_name_t *dest_name;
   1243 {
   1244 	return krb5_gss_duplicate_name(minor_status, input_name, dest_name);
   1245 }
   1246 #endif
   1247 
   1248 
   1249 OM_uint32 KRB5_CALLCONV
   1250 gss_krb5_copy_ccache(
   1251     OM_uint32 *minor_status,
   1252     gss_cred_id_t cred_handle,
   1253     krb5_ccache out_ccache)
   1254 {
   1255     gss_union_cred_t ucred;
   1256     gss_cred_id_t mcred;
   1257 
   1258     ucred = (gss_union_cred_t)cred_handle;
   1259 
   1260     mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type);
   1261     if (mcred != GSS_C_NO_CREDENTIAL)
   1262 	return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache);
   1263 
   1264     mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type);
   1265     if (mcred != GSS_C_NO_CREDENTIAL)
   1266 	return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache);
   1267 
   1268     return GSS_S_DEFECTIVE_CREDENTIAL;
   1269 }
   1270 
   1271 OM_uint32 KRB5_CALLCONV
   1272 gss_krb5_set_allowable_enctypes(
   1273     OM_uint32 *minor_status,
   1274     gss_cred_id_t cred,
   1275     OM_uint32 num_ktypes,
   1276     krb5_enctype *ktypes)
   1277 {
   1278     gss_union_cred_t ucred;
   1279     gss_cred_id_t mcred;
   1280 
   1281     ucred = (gss_union_cred_t)cred;
   1282     mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type);
   1283     if (mcred != GSS_C_NO_CREDENTIAL)
   1284 	return gss_krb5int_set_allowable_enctypes(minor_status, mcred,
   1285 						  num_ktypes, ktypes);
   1286 
   1287     mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type);
   1288     if (mcred != GSS_C_NO_CREDENTIAL)
   1289 	return gss_krb5int_set_allowable_enctypes(minor_status, mcred,
   1290 						  num_ktypes, ktypes);
   1291 
   1292     return GSS_S_DEFECTIVE_CREDENTIAL;
   1293 }
   1294 
   1295 /*
   1296  * Glue routine for returning the mechanism-specific credential from a
   1297  * external union credential.
   1298  */
   1299 /* SUNW15resync - in MIT 1.5, it's in g_glue.c (libgss) but we don't
   1300   want to link against libgss so we put it here since we need it in the mech */
   1301 gss_cred_id_t
   1302 gssint_get_mechanism_cred(union_cred, mech_type)
   1303     gss_union_cred_t    union_cred;
   1304     gss_OID             mech_type;
   1305 {
   1306     int         i;
   1307 
   1308     if (union_cred == (gss_union_cred_t) GSS_C_NO_CREDENTIAL)
   1309         return GSS_C_NO_CREDENTIAL;
   1310 
   1311     for (i=0; i < union_cred->count; i++) {
   1312         if (g_OID_equal(mech_type, &union_cred->mechs_array[i]))
   1313             return union_cred->cred_array[i];
   1314     }
   1315     return GSS_C_NO_CREDENTIAL;
   1316 }
   1317 
   1318 
   1319 
   1320 /*
   1321  * entry point for the gss layer,
   1322  * called "krb5_gss_initialize()" in MIT 1.2.1
   1323  */
   1324 /* SUNW15resync - this used to be in k5mech.c */
   1325 gss_mechanism
   1326 gss_mech_initialize(oid)
   1327      const gss_OID oid;
   1328 {
   1329     /*
   1330      * Solaris Kerberos: We also want to use the same functions for KRB5 as
   1331      * we do for the MS KRB5 (krb5_mechanism_wrong).  So both are valid.
   1332      */
   1333     /* ensure that the requested oid matches our oid */
   1334     if (oid == NULL || (!g_OID_equal(oid, &krb5_mechanism.mech_type) &&
   1335 	!g_OID_equal(oid, &krb5_mechanism_wrong.mech_type))) {
   1336       (void) syslog(LOG_INFO, "krb5mech: gss_mech_initialize: bad oid");
   1337       return (NULL);
   1338     }
   1339 
   1340 #if 0 /* SUNW15resync - no longer needed(?) */
   1341     if (krb5_gss_get_context(&(krb5_mechanism.context)) !=
   1342 	GSS_S_COMPLETE)
   1343       return (NULL);
   1344 #endif
   1345 
   1346     return (&krb5_mechanism);
   1347 }
   1348 
   1349 /*
   1350  * This API should go away and be replaced with an accessor
   1351  * into a gss_name_t.
   1352  */
   1353 OM_uint32 KRB5_CALLCONV
   1354 gsskrb5_extract_authz_data_from_sec_context(
   1355     OM_uint32 *minor_status,
   1356     gss_ctx_id_t context_handle,
   1357     int ad_type,
   1358     gss_buffer_t ad_data)
   1359 {
   1360     gss_OID_desc req_oid;
   1361     unsigned char oid_buf[GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH + 6];
   1362     OM_uint32 major_status;
   1363     gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
   1364 
   1365     if (ad_data == NULL)
   1366         return GSS_S_CALL_INACCESSIBLE_WRITE;
   1367 
   1368     req_oid.elements = oid_buf;
   1369     req_oid.length = sizeof(oid_buf);
   1370 
   1371     major_status = generic_gss_oid_compose(minor_status,
   1372                                            GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID,
   1373                                            GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH,
   1374                                            ad_type,
   1375                                            &req_oid);
   1376     if (GSS_ERROR(major_status))
   1377         return major_status;
   1378 
   1379     major_status = gss_inquire_sec_context_by_oid(minor_status,
   1380                                                   context_handle,
   1381                                                   (gss_OID)&req_oid,
   1382                                                   &data_set);
   1383     if (major_status != GSS_S_COMPLETE) {
   1384         return major_status;
   1385     }
   1386 
   1387     /*
   1388      * SUNW17PACresync / Solaris Kerberos
   1389      * MIT17 allows only count==1 which is correct for pre-Win2008 but
   1390      * our testing with Win2008 shows count==2 and Win7 count==3.
   1391      */
   1392     if ((data_set == GSS_C_NO_BUFFER_SET) || (data_set->count == 0)) {
   1393 	    gss_release_buffer_set(minor_status, &data_set);
   1394 	    return GSS_S_FAILURE;
   1395     }
   1396 
   1397     ad_data->length = data_set->elements[0].length;
   1398     ad_data->value = malloc(ad_data->length);
   1399     if (!ad_data->value) {
   1400 	    gss_release_buffer_set(minor_status, &data_set);
   1401 	    return ENOMEM;
   1402     }
   1403     bcopy(data_set->elements[0].value, ad_data->value, ad_data->length);
   1404 
   1405     gss_release_buffer_set(minor_status, &data_set);
   1406 
   1407     return GSS_S_COMPLETE;
   1408 }
   1409 
   1410 
   1411 OM_uint32 KRB5_CALLCONV
   1412 gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
   1413                                           gss_ctx_id_t context_handle,
   1414                                           krb5_timestamp *authtime)
   1415 {
   1416     static const gss_OID_desc req_oid = {
   1417         GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH,
   1418         GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID };
   1419     OM_uint32 major_status;
   1420     gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
   1421 
   1422     if (authtime == NULL)
   1423         return GSS_S_CALL_INACCESSIBLE_WRITE;
   1424 
   1425     major_status = gss_inquire_sec_context_by_oid(minor_status,
   1426                                                   context_handle,
   1427                                                   (gss_OID)&req_oid,
   1428                                                   &data_set);
   1429     if (major_status != GSS_S_COMPLETE)
   1430         return major_status;
   1431 
   1432     if (data_set == GSS_C_NO_BUFFER_SET ||
   1433         data_set->count != 1 ||
   1434         data_set->elements[0].length != sizeof(*authtime)) {
   1435         *minor_status = EINVAL;
   1436         return GSS_S_FAILURE;
   1437     }
   1438 
   1439     *authtime = *((krb5_timestamp *)data_set->elements[0].value);
   1440 
   1441     gss_release_buffer_set(minor_status, &data_set);
   1442 
   1443     *minor_status = 0;
   1444 
   1445     return GSS_S_COMPLETE;
   1446 }
   1447