17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 53dba6097Smp153739 * Common Development and Distribution License (the "License"). 63dba6097Smp153739 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*5e01956fSGlenn Barry * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 267c478bd9Sstevel@tonic-gate * glue routine for gss_acquire_cred 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate #include <mechglueP.h> 29*5e01956fSGlenn Barry #include "gssapiP_generic.h" 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #endif 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <errno.h> 367c478bd9Sstevel@tonic-gate #include <time.h> 37ab9b2e15Sgtb 387c478bd9Sstevel@tonic-gate /* local functions */ 397c478bd9Sstevel@tonic-gate static gss_OID_set create_actual_mechs(const gss_OID, int); 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate static gss_OID_set 427c478bd9Sstevel@tonic-gate create_actual_mechs(mechs_array, count) 437c478bd9Sstevel@tonic-gate const gss_OID mechs_array; 447c478bd9Sstevel@tonic-gate int count; 457c478bd9Sstevel@tonic-gate { 467c478bd9Sstevel@tonic-gate gss_OID_set actual_mechs; 477c478bd9Sstevel@tonic-gate int i; 487c478bd9Sstevel@tonic-gate OM_uint32 minor; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate actual_mechs = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)); 517c478bd9Sstevel@tonic-gate if (!actual_mechs) 527c478bd9Sstevel@tonic-gate return (NULL); 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate actual_mechs->elements = (gss_OID) 557c478bd9Sstevel@tonic-gate malloc(sizeof (gss_OID_desc) * count); 567c478bd9Sstevel@tonic-gate if (!actual_mechs->elements) { 577c478bd9Sstevel@tonic-gate free(actual_mechs); 587c478bd9Sstevel@tonic-gate return (NULL); 597c478bd9Sstevel@tonic-gate } 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate actual_mechs->count = 0; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) { 647c478bd9Sstevel@tonic-gate actual_mechs->elements[i].elements = (void *) 657c478bd9Sstevel@tonic-gate malloc(mechs_array[i].length); 667c478bd9Sstevel@tonic-gate if (actual_mechs->elements[i].elements == NULL) { 677c478bd9Sstevel@tonic-gate (void) gss_release_oid_set(&minor, &actual_mechs); 687c478bd9Sstevel@tonic-gate return (NULL); 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate g_OID_copy(&actual_mechs->elements[i], &mechs_array[i]); 717c478bd9Sstevel@tonic-gate actual_mechs->count++; 727c478bd9Sstevel@tonic-gate } 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate return (actual_mechs); 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate 77503a2b89SPeter Shoults static OM_uint32 78503a2b89SPeter Shoults val_acq_cred_args( 79503a2b89SPeter Shoults OM_uint32 *minor_status, 80*5e01956fSGlenn Barry /*LINTED*/ 81*5e01956fSGlenn Barry gss_name_t desired_name, 82*5e01956fSGlenn Barry /*LINTED*/ 83*5e01956fSGlenn Barry OM_uint32 time_req, 84*5e01956fSGlenn Barry /*LINTED*/ 85*5e01956fSGlenn Barry gss_OID_set desired_mechs, 86*5e01956fSGlenn Barry int cred_usage, 87503a2b89SPeter Shoults gss_cred_id_t *output_cred_handle, 88503a2b89SPeter Shoults gss_OID_set *actual_mechs, 89503a2b89SPeter Shoults OM_uint32 *time_rec) 90503a2b89SPeter Shoults { 91503a2b89SPeter Shoults 92503a2b89SPeter Shoults /* Initialize outputs. */ 93503a2b89SPeter Shoults 94503a2b89SPeter Shoults if (minor_status != NULL) 95503a2b89SPeter Shoults *minor_status = 0; 96503a2b89SPeter Shoults 97503a2b89SPeter Shoults if (output_cred_handle != NULL) 98503a2b89SPeter Shoults *output_cred_handle = GSS_C_NO_CREDENTIAL; 99503a2b89SPeter Shoults 100503a2b89SPeter Shoults if (actual_mechs != NULL) 101503a2b89SPeter Shoults *actual_mechs = GSS_C_NULL_OID_SET; 102503a2b89SPeter Shoults 103503a2b89SPeter Shoults if (time_rec != NULL) 104503a2b89SPeter Shoults *time_rec = 0; 105503a2b89SPeter Shoults 106503a2b89SPeter Shoults /* Validate arguments. */ 107503a2b89SPeter Shoults 108503a2b89SPeter Shoults if (minor_status == NULL) 109503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE); 110503a2b89SPeter Shoults 111503a2b89SPeter Shoults if (output_cred_handle == NULL) 112503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE); 113503a2b89SPeter Shoults 114*5e01956fSGlenn Barry if (cred_usage != GSS_C_ACCEPT 115*5e01956fSGlenn Barry && cred_usage != GSS_C_INITIATE 116*5e01956fSGlenn Barry && cred_usage != GSS_C_BOTH) { 117*5e01956fSGlenn Barry if (minor_status) { 118*5e01956fSGlenn Barry *minor_status = EINVAL; 119*5e01956fSGlenn Barry map_errcode(minor_status); 120*5e01956fSGlenn Barry } 121*5e01956fSGlenn Barry return GSS_S_FAILURE; 122*5e01956fSGlenn Barry } 123*5e01956fSGlenn Barry 124503a2b89SPeter Shoults return (GSS_S_COMPLETE); 125503a2b89SPeter Shoults } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate OM_uint32 1287c478bd9Sstevel@tonic-gate gss_acquire_cred(minor_status, 1297c478bd9Sstevel@tonic-gate desired_name, 1307c478bd9Sstevel@tonic-gate time_req, 1317c478bd9Sstevel@tonic-gate desired_mechs, 1327c478bd9Sstevel@tonic-gate cred_usage, 1337c478bd9Sstevel@tonic-gate output_cred_handle, 1347c478bd9Sstevel@tonic-gate actual_mechs, 1357c478bd9Sstevel@tonic-gate time_rec) 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate OM_uint32 * minor_status; 1387c478bd9Sstevel@tonic-gate const gss_name_t desired_name; 1397c478bd9Sstevel@tonic-gate OM_uint32 time_req; 1407c478bd9Sstevel@tonic-gate const gss_OID_set desired_mechs; 1417c478bd9Sstevel@tonic-gate int cred_usage; 1427c478bd9Sstevel@tonic-gate gss_cred_id_t *output_cred_handle; 1437c478bd9Sstevel@tonic-gate gss_OID_set * actual_mechs; 1447c478bd9Sstevel@tonic-gate OM_uint32 * time_rec; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate OM_uint32 major = GSS_S_FAILURE; 1487c478bd9Sstevel@tonic-gate OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE; 1497c478bd9Sstevel@tonic-gate gss_OID_set_desc default_OID_set; 1507c478bd9Sstevel@tonic-gate gss_OID_set mechs; 1517c478bd9Sstevel@tonic-gate gss_OID_desc default_OID; 1527c478bd9Sstevel@tonic-gate gss_mechanism mech; 153*5e01956fSGlenn Barry unsigned int i; 1547c478bd9Sstevel@tonic-gate gss_union_cred_t creds; 1557c478bd9Sstevel@tonic-gate 156503a2b89SPeter Shoults major = val_acq_cred_args(minor_status, 157*5e01956fSGlenn Barry desired_name, 158*5e01956fSGlenn Barry time_req, 159*5e01956fSGlenn Barry desired_mechs, 160*5e01956fSGlenn Barry cred_usage, 161503a2b89SPeter Shoults output_cred_handle, 162503a2b89SPeter Shoults actual_mechs, 163503a2b89SPeter Shoults time_rec); 164503a2b89SPeter Shoults if (major != GSS_S_COMPLETE) 165503a2b89SPeter Shoults return (major); 1667c478bd9Sstevel@tonic-gate 167503a2b89SPeter Shoults /* Initial value needed below. */ 168503a2b89SPeter Shoults major = GSS_S_FAILURE; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an 1727c478bd9Sstevel@tonic-gate * appropriate default. We use the first mechanism in the 1737c478bd9Sstevel@tonic-gate * mechansim list as the default. This set is created with 1747c478bd9Sstevel@tonic-gate * statics thus needs not be freed 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate if (desired_mechs == GSS_C_NULL_OID_SET) { 1777c478bd9Sstevel@tonic-gate mech = __gss_get_mechanism(NULL); 1787c478bd9Sstevel@tonic-gate if (mech == NULL) 1797c478bd9Sstevel@tonic-gate return (GSS_S_BAD_MECH); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate mechs = &default_OID_set; 1827c478bd9Sstevel@tonic-gate default_OID_set.count = 1; 1837c478bd9Sstevel@tonic-gate default_OID_set.elements = &default_OID; 1847c478bd9Sstevel@tonic-gate default_OID.length = mech->mech_type.length; 1857c478bd9Sstevel@tonic-gate default_OID.elements = mech->mech_type.elements; 1867c478bd9Sstevel@tonic-gate } else 1877c478bd9Sstevel@tonic-gate mechs = desired_mechs; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate if (mechs->count == NULL) 1907c478bd9Sstevel@tonic-gate return (GSS_S_BAD_MECH); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate /* allocate the output credential structure */ 1937c478bd9Sstevel@tonic-gate creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc)); 1947c478bd9Sstevel@tonic-gate if (creds == NULL) 1957c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* initialize to 0s */ 1987c478bd9Sstevel@tonic-gate (void) memset(creds, 0, sizeof (gss_union_cred_desc)); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* for each requested mech attempt to obtain a credential */ 2017c478bd9Sstevel@tonic-gate for (i = 0; i < mechs->count; i++) { 2027c478bd9Sstevel@tonic-gate major = gss_add_cred(minor_status, (gss_cred_id_t)creds, 2037c478bd9Sstevel@tonic-gate desired_name, 2047c478bd9Sstevel@tonic-gate &mechs->elements[i], 2057c478bd9Sstevel@tonic-gate cred_usage, time_req, time_req, NULL, 2067c478bd9Sstevel@tonic-gate NULL, &initTimeOut, &acceptTimeOut); 2077c478bd9Sstevel@tonic-gate if (major == GSS_S_COMPLETE) { 2087c478bd9Sstevel@tonic-gate /* update the credential's time */ 2097c478bd9Sstevel@tonic-gate if (cred_usage == GSS_C_ACCEPT) { 2107c478bd9Sstevel@tonic-gate if (outTime > acceptTimeOut) 2117c478bd9Sstevel@tonic-gate outTime = acceptTimeOut; 2127c478bd9Sstevel@tonic-gate } else if (cred_usage == GSS_C_INITIATE) { 2137c478bd9Sstevel@tonic-gate if (outTime > initTimeOut) 2147c478bd9Sstevel@tonic-gate outTime = initTimeOut; 2157c478bd9Sstevel@tonic-gate } else { 2167c478bd9Sstevel@tonic-gate /* 2177c478bd9Sstevel@tonic-gate * time_rec is the lesser of the 2187c478bd9Sstevel@tonic-gate * init/accept times 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate if (initTimeOut > acceptTimeOut) 2217c478bd9Sstevel@tonic-gate outTime = (outTime > acceptTimeOut) ? 2227c478bd9Sstevel@tonic-gate acceptTimeOut : outTime; 2237c478bd9Sstevel@tonic-gate else 2247c478bd9Sstevel@tonic-gate outTime = (outTime > initTimeOut) ? 2257c478bd9Sstevel@tonic-gate initTimeOut : outTime; 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate } /* for */ 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* ensure that we have at least one credential element */ 2317c478bd9Sstevel@tonic-gate if (creds->count < 1) { 2327c478bd9Sstevel@tonic-gate free(creds); 2337c478bd9Sstevel@tonic-gate return (major); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * fill in output parameters 2387c478bd9Sstevel@tonic-gate * setup the actual mechs output parameter 2397c478bd9Sstevel@tonic-gate */ 2407c478bd9Sstevel@tonic-gate if (actual_mechs != NULL) { 2417c478bd9Sstevel@tonic-gate if ((*actual_mechs = create_actual_mechs(creds->mechs_array, 2427c478bd9Sstevel@tonic-gate creds->count)) == NULL) { 2437c478bd9Sstevel@tonic-gate (void) gss_release_cred(minor_status, 2447c478bd9Sstevel@tonic-gate (gss_cred_id_t *)&creds); 2457c478bd9Sstevel@tonic-gate *minor_status = 0; 2467c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate if (time_rec) 2517c478bd9Sstevel@tonic-gate *time_rec = outTime; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate *output_cred_handle = (gss_cred_id_t)creds; 2557c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 258503a2b89SPeter Shoults static OM_uint32 259503a2b89SPeter Shoults val_add_cred_args( 260503a2b89SPeter Shoults OM_uint32 *minor_status, 261503a2b89SPeter Shoults gss_cred_id_t input_cred_handle, 262*5e01956fSGlenn Barry /*LINTED*/ 263*5e01956fSGlenn Barry gss_name_t desired_name, 264*5e01956fSGlenn Barry /*LINTED*/ 265*5e01956fSGlenn Barry gss_OID desired_mech, 266*5e01956fSGlenn Barry gss_cred_usage_t cred_usage, 267*5e01956fSGlenn Barry /*LINTED*/ 268*5e01956fSGlenn Barry OM_uint32 initiator_time_req, 269*5e01956fSGlenn Barry /*LINTED*/ 270*5e01956fSGlenn Barry OM_uint32 acceptor_time_req, 271503a2b89SPeter Shoults gss_cred_id_t *output_cred_handle, 272503a2b89SPeter Shoults gss_OID_set *actual_mechs, 273503a2b89SPeter Shoults OM_uint32 *initiator_time_rec, 274503a2b89SPeter Shoults OM_uint32 *acceptor_time_rec) 275503a2b89SPeter Shoults { 276503a2b89SPeter Shoults 277503a2b89SPeter Shoults /* Initialize outputs. */ 278503a2b89SPeter Shoults 279503a2b89SPeter Shoults if (minor_status != NULL) 280503a2b89SPeter Shoults *minor_status = 0; 281503a2b89SPeter Shoults 282503a2b89SPeter Shoults if (output_cred_handle != NULL) 283503a2b89SPeter Shoults *output_cred_handle = GSS_C_NO_CREDENTIAL; 284503a2b89SPeter Shoults 285503a2b89SPeter Shoults if (actual_mechs != NULL) 286503a2b89SPeter Shoults *actual_mechs = GSS_C_NO_OID_SET; 287503a2b89SPeter Shoults 288503a2b89SPeter Shoults if (acceptor_time_rec != NULL) 289503a2b89SPeter Shoults *acceptor_time_rec = 0; 290503a2b89SPeter Shoults 291503a2b89SPeter Shoults if (initiator_time_rec != NULL) 292503a2b89SPeter Shoults *initiator_time_rec = 0; 293503a2b89SPeter Shoults /* Validate arguments. */ 294503a2b89SPeter Shoults 295503a2b89SPeter Shoults if (minor_status == NULL) 296503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE); 297503a2b89SPeter Shoults 298503a2b89SPeter Shoults if (input_cred_handle == GSS_C_NO_CREDENTIAL && 299503a2b89SPeter Shoults output_cred_handle == NULL) 300503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED); 301503a2b89SPeter Shoults 302*5e01956fSGlenn Barry if (cred_usage != GSS_C_ACCEPT 303*5e01956fSGlenn Barry && cred_usage != GSS_C_INITIATE 304*5e01956fSGlenn Barry && cred_usage != GSS_C_BOTH) { 305*5e01956fSGlenn Barry if (minor_status) { 306*5e01956fSGlenn Barry *minor_status = EINVAL; 307*5e01956fSGlenn Barry map_errcode(minor_status); 308*5e01956fSGlenn Barry } 309*5e01956fSGlenn Barry return GSS_S_FAILURE; 310*5e01956fSGlenn Barry } 311*5e01956fSGlenn Barry 312503a2b89SPeter Shoults return (GSS_S_COMPLETE); 313503a2b89SPeter Shoults } 314503a2b89SPeter Shoults 3157c478bd9Sstevel@tonic-gate /* V2 INTERFACE */ 3167c478bd9Sstevel@tonic-gate OM_uint32 3177c478bd9Sstevel@tonic-gate gss_add_cred(minor_status, input_cred_handle, 3187c478bd9Sstevel@tonic-gate desired_name, desired_mech, cred_usage, 3197c478bd9Sstevel@tonic-gate initiator_time_req, acceptor_time_req, 3207c478bd9Sstevel@tonic-gate output_cred_handle, actual_mechs, 3217c478bd9Sstevel@tonic-gate initiator_time_rec, acceptor_time_rec) 3227c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 3237c478bd9Sstevel@tonic-gate const gss_cred_id_t input_cred_handle; 3247c478bd9Sstevel@tonic-gate const gss_name_t desired_name; 3257c478bd9Sstevel@tonic-gate const gss_OID desired_mech; 3267c478bd9Sstevel@tonic-gate gss_cred_usage_t cred_usage; 3277c478bd9Sstevel@tonic-gate OM_uint32 initiator_time_req; 3287c478bd9Sstevel@tonic-gate OM_uint32 acceptor_time_req; 3297c478bd9Sstevel@tonic-gate gss_cred_id_t *output_cred_handle; 3307c478bd9Sstevel@tonic-gate gss_OID_set *actual_mechs; 3317c478bd9Sstevel@tonic-gate OM_uint32 *initiator_time_rec; 3327c478bd9Sstevel@tonic-gate OM_uint32 *acceptor_time_rec; 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate OM_uint32 status, time_req, time_rec, temp_minor_status; 3357c478bd9Sstevel@tonic-gate gss_mechanism mech; 3367c478bd9Sstevel@tonic-gate gss_union_name_t union_name = NULL; 3377c478bd9Sstevel@tonic-gate gss_union_cred_t union_cred, new_union_cred; 3387c478bd9Sstevel@tonic-gate gss_name_t internal_name = GSS_C_NO_NAME; 3397c478bd9Sstevel@tonic-gate gss_name_t allocated_name = GSS_C_NO_NAME; 3407c478bd9Sstevel@tonic-gate gss_cred_id_t cred = NULL; 3417c478bd9Sstevel@tonic-gate gss_OID new_mechs_array = NULL; 3427c478bd9Sstevel@tonic-gate gss_cred_id_t *new_cred_array = NULL; 3437c478bd9Sstevel@tonic-gate 344503a2b89SPeter Shoults status = val_add_cred_args(minor_status, 345503a2b89SPeter Shoults input_cred_handle, 346*5e01956fSGlenn Barry desired_name, 347*5e01956fSGlenn Barry desired_mech, 348*5e01956fSGlenn Barry cred_usage, 349*5e01956fSGlenn Barry initiator_time_req, 350*5e01956fSGlenn Barry acceptor_time_req, 351503a2b89SPeter Shoults output_cred_handle, 352503a2b89SPeter Shoults actual_mechs, 353503a2b89SPeter Shoults initiator_time_rec, 354503a2b89SPeter Shoults acceptor_time_rec); 355503a2b89SPeter Shoults if (status != GSS_S_COMPLETE) 356503a2b89SPeter Shoults return (status); 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate mech = __gss_get_mechanism(desired_mech); 3597c478bd9Sstevel@tonic-gate if (!mech) 3607c478bd9Sstevel@tonic-gate return (GSS_S_BAD_MECH); 3617c478bd9Sstevel@tonic-gate else if (!mech->gss_acquire_cred) 3627c478bd9Sstevel@tonic-gate return (GSS_S_UNAVAILABLE); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (input_cred_handle == GSS_C_NO_CREDENTIAL) { 3657c478bd9Sstevel@tonic-gate union_cred = malloc(sizeof (gss_union_cred_desc)); 3667c478bd9Sstevel@tonic-gate if (union_cred == NULL) 3677c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate (void) memset(union_cred, 0, sizeof (gss_union_cred_desc)); 3707c478bd9Sstevel@tonic-gate } else { 371354d1447Swyllys /* Input Cred is non-NULL */ 3727c478bd9Sstevel@tonic-gate union_cred = (gss_union_cred_t)input_cred_handle; 3737c478bd9Sstevel@tonic-gate 374354d1447Swyllys if (__gss_get_mechanism_cred(union_cred, desired_mech) != 375354d1447Swyllys GSS_C_NO_CREDENTIAL) { 376354d1447Swyllys status = GSS_S_DUPLICATE_ELEMENT; 377354d1447Swyllys goto errout; 378354d1447Swyllys } 379354d1447Swyllys 380354d1447Swyllys /* 381354d1447Swyllys * If no name was given, determine the name from the 382354d1447Swyllys * existing credential. 383354d1447Swyllys */ 384354d1447Swyllys if (desired_name == GSS_C_NO_NAME) { 385354d1447Swyllys if (gss_import_name(minor_status, 386354d1447Swyllys &union_cred->auxinfo.name, 387354d1447Swyllys union_cred->auxinfo.name_type, 388354d1447Swyllys &allocated_name) == GSS_S_COMPLETE && 389354d1447Swyllys (gss_canonicalize_name(minor_status, 390354d1447Swyllys allocated_name, 391354d1447Swyllys &mech->mech_type, 392354d1447Swyllys NULL) == GSS_S_COMPLETE)) { 393354d1447Swyllys internal_name = allocated_name; 394354d1447Swyllys } 395354d1447Swyllys } /* else, get the name from the desired_name below */ 396354d1447Swyllys } 397354d1447Swyllys if (desired_name != GSS_C_NO_NAME) { 3987c478bd9Sstevel@tonic-gate /* may need to create a mechanism specific name */ 3997c478bd9Sstevel@tonic-gate union_name = (gss_union_name_t)desired_name; 400354d1447Swyllys 4017c478bd9Sstevel@tonic-gate if (union_name->mech_type && 4027c478bd9Sstevel@tonic-gate g_OID_equal(union_name->mech_type, 4037c478bd9Sstevel@tonic-gate &mech->mech_type)) 4047c478bd9Sstevel@tonic-gate internal_name = union_name->mech_name; 4057c478bd9Sstevel@tonic-gate else { 4067c478bd9Sstevel@tonic-gate if (__gss_import_internal_name(minor_status, 4077c478bd9Sstevel@tonic-gate &mech->mech_type, union_name, 408354d1447Swyllys &allocated_name) != GSS_S_COMPLETE) { 409354d1447Swyllys status = GSS_S_BAD_NAME; 410354d1447Swyllys goto errout; 411354d1447Swyllys } 4127c478bd9Sstevel@tonic-gate internal_name = allocated_name; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate if (cred_usage == GSS_C_ACCEPT) 4177c478bd9Sstevel@tonic-gate time_req = acceptor_time_req; 4187c478bd9Sstevel@tonic-gate else if (cred_usage == GSS_C_INITIATE) 4197c478bd9Sstevel@tonic-gate time_req = initiator_time_req; 4207c478bd9Sstevel@tonic-gate else if (cred_usage == GSS_C_BOTH) 4217c478bd9Sstevel@tonic-gate time_req = (acceptor_time_req > initiator_time_req) ? 4227c478bd9Sstevel@tonic-gate acceptor_time_req : initiator_time_req; 423*5e01956fSGlenn Barry else 424*5e01956fSGlenn Barry time_req = 0; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate status = mech->gss_acquire_cred(mech->context, minor_status, 4277c478bd9Sstevel@tonic-gate internal_name, time_req, 4287c478bd9Sstevel@tonic-gate GSS_C_NULL_OID_SET, cred_usage, 4297c478bd9Sstevel@tonic-gate &cred, NULL, &time_rec); 4307c478bd9Sstevel@tonic-gate 431*5e01956fSGlenn Barry if (status != GSS_S_COMPLETE) { 432*5e01956fSGlenn Barry map_error(minor_status, mech); 4337c478bd9Sstevel@tonic-gate goto errout; 434*5e01956fSGlenn Barry } 4357c478bd9Sstevel@tonic-gate 436354d1447Swyllys /* may need to set credential auxinfo structure */ 4377c478bd9Sstevel@tonic-gate if (union_cred->auxinfo.creation_time == 0) { 4387c478bd9Sstevel@tonic-gate union_cred->auxinfo.creation_time = time(NULL); 4397c478bd9Sstevel@tonic-gate union_cred->auxinfo.time_rec = time_rec; 4407c478bd9Sstevel@tonic-gate union_cred->auxinfo.cred_usage = cred_usage; 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate /* 4433dba6097Smp153739 * If internal_name is GSS_C_NO_NAME a cred with no associated 4443dba6097Smp153739 * name was requested: don't set auxinfo.name or auxinfo.name_type. 4457c478bd9Sstevel@tonic-gate */ 4463dba6097Smp153739 if (internal_name != GSS_C_NO_NAME) { 4477c478bd9Sstevel@tonic-gate if ((status = mech->gss_display_name(mech->context, 4487c478bd9Sstevel@tonic-gate &temp_minor_status, internal_name, 4497c478bd9Sstevel@tonic-gate &union_cred->auxinfo.name, 4507c478bd9Sstevel@tonic-gate &union_cred->auxinfo.name_type)) != 4517c478bd9Sstevel@tonic-gate GSS_S_COMPLETE) 4527c478bd9Sstevel@tonic-gate goto errout; 4537c478bd9Sstevel@tonic-gate } 4543dba6097Smp153739 } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate /* now add the new credential elements */ 4577c478bd9Sstevel@tonic-gate new_mechs_array = (gss_OID) 4587c478bd9Sstevel@tonic-gate malloc(sizeof (gss_OID_desc) * (union_cred->count+1)); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate new_cred_array = (gss_cred_id_t *) 4617c478bd9Sstevel@tonic-gate malloc(sizeof (gss_cred_id_t) * (union_cred->count+1)); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if (!new_mechs_array || !new_cred_array) { 4647c478bd9Sstevel@tonic-gate status = GSS_S_FAILURE; 4657c478bd9Sstevel@tonic-gate goto errout; 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate if (acceptor_time_rec) 4697c478bd9Sstevel@tonic-gate if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) 4707c478bd9Sstevel@tonic-gate *acceptor_time_rec = time_rec; 4717c478bd9Sstevel@tonic-gate if (initiator_time_rec) 4727c478bd9Sstevel@tonic-gate if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) 4737c478bd9Sstevel@tonic-gate *initiator_time_rec = time_rec; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * OK, expand the mechanism array and the credential array 4777c478bd9Sstevel@tonic-gate */ 4787c478bd9Sstevel@tonic-gate (void) memcpy(new_mechs_array, union_cred->mechs_array, 4797c478bd9Sstevel@tonic-gate sizeof (gss_OID_desc) * union_cred->count); 4807c478bd9Sstevel@tonic-gate (void) memcpy(new_cred_array, union_cred->cred_array, 4817c478bd9Sstevel@tonic-gate sizeof (gss_cred_id_t) * union_cred->count); 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate new_cred_array[union_cred->count] = cred; 4847c478bd9Sstevel@tonic-gate if ((new_mechs_array[union_cred->count].elements = 4857c478bd9Sstevel@tonic-gate malloc(mech->mech_type.length)) == NULL) 4867c478bd9Sstevel@tonic-gate goto errout; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate g_OID_copy(&new_mechs_array[union_cred->count], 4897c478bd9Sstevel@tonic-gate &mech->mech_type); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate if (actual_mechs) { 4927c478bd9Sstevel@tonic-gate *actual_mechs = create_actual_mechs(new_mechs_array, 4937c478bd9Sstevel@tonic-gate union_cred->count + 1); 4947c478bd9Sstevel@tonic-gate if (*actual_mechs == NULL) { 4957c478bd9Sstevel@tonic-gate free(new_mechs_array[union_cred->count].elements); 4967c478bd9Sstevel@tonic-gate goto errout; 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate if (output_cred_handle == NULL) { 5017c478bd9Sstevel@tonic-gate free(union_cred->mechs_array); 5027c478bd9Sstevel@tonic-gate free(union_cred->cred_array); 5037c478bd9Sstevel@tonic-gate new_union_cred = union_cred; 5047c478bd9Sstevel@tonic-gate } else { 5057c478bd9Sstevel@tonic-gate new_union_cred = malloc(sizeof (gss_union_cred_desc)); 5067c478bd9Sstevel@tonic-gate if (new_union_cred == NULL) { 5077c478bd9Sstevel@tonic-gate free(new_mechs_array[union_cred->count].elements); 5087c478bd9Sstevel@tonic-gate goto errout; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate *new_union_cred = *union_cred; 5117c478bd9Sstevel@tonic-gate *output_cred_handle = (gss_cred_id_t)new_union_cred; 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate new_union_cred->mechs_array = new_mechs_array; 5157c478bd9Sstevel@tonic-gate new_union_cred->cred_array = new_cred_array; 5167c478bd9Sstevel@tonic-gate new_union_cred->count++; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* We're done with the internal name. Free it if we allocated it. */ 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate if (allocated_name) 5217c478bd9Sstevel@tonic-gate (void) __gss_release_internal_name(&temp_minor_status, 5227c478bd9Sstevel@tonic-gate &mech->mech_type, 5237c478bd9Sstevel@tonic-gate &allocated_name); 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate errout: 5287c478bd9Sstevel@tonic-gate if (new_mechs_array) 5297c478bd9Sstevel@tonic-gate free(new_mechs_array); 5307c478bd9Sstevel@tonic-gate if (new_cred_array) 5317c478bd9Sstevel@tonic-gate free(new_cred_array); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate if (cred != NULL && mech->gss_release_cred) 5347c478bd9Sstevel@tonic-gate mech->gss_release_cred(mech->context, 5357c478bd9Sstevel@tonic-gate &temp_minor_status, &cred); 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate if (allocated_name) 5387c478bd9Sstevel@tonic-gate (void) __gss_release_internal_name(&temp_minor_status, 5397c478bd9Sstevel@tonic-gate &mech->mech_type, 5407c478bd9Sstevel@tonic-gate &allocated_name); 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred) { 5437c478bd9Sstevel@tonic-gate if (union_cred->auxinfo.name.value) 5447c478bd9Sstevel@tonic-gate free(union_cred->auxinfo.name.value); 5457c478bd9Sstevel@tonic-gate free(union_cred); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate return (status); 5497c478bd9Sstevel@tonic-gate } 550