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