1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * glue routine for gss_inquire_cred 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <mechglueP.h> 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <time.h> 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate OM_uint32 40*7c478bd9Sstevel@tonic-gate gss_inquire_cred(minor_status, 41*7c478bd9Sstevel@tonic-gate cred_handle, 42*7c478bd9Sstevel@tonic-gate name, 43*7c478bd9Sstevel@tonic-gate lifetime, 44*7c478bd9Sstevel@tonic-gate cred_usage, 45*7c478bd9Sstevel@tonic-gate mechanisms) 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 48*7c478bd9Sstevel@tonic-gate const gss_cred_id_t cred_handle; 49*7c478bd9Sstevel@tonic-gate gss_name_t *name; 50*7c478bd9Sstevel@tonic-gate OM_uint32 *lifetime; 51*7c478bd9Sstevel@tonic-gate int *cred_usage; 52*7c478bd9Sstevel@tonic-gate gss_OID_set *mechanisms; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate OM_uint32 status, elapsed_time, temp_minor_status; 56*7c478bd9Sstevel@tonic-gate gss_union_cred_t union_cred; 57*7c478bd9Sstevel@tonic-gate gss_mechanism mech; 58*7c478bd9Sstevel@tonic-gate gss_name_t internal_name; 59*7c478bd9Sstevel@tonic-gate int i; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* check parms and set to defaults */ 62*7c478bd9Sstevel@tonic-gate if (minor_status == NULL) 63*7c478bd9Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_WRITE); 64*7c478bd9Sstevel@tonic-gate *minor_status = 0; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate if (name) 67*7c478bd9Sstevel@tonic-gate *name = NULL; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate if (mechanisms) 70*7c478bd9Sstevel@tonic-gate *mechanisms = NULL; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate if (cred_handle == GSS_C_NO_CREDENTIAL) { 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * No credential was supplied. This means we can't get a mechanism 75*7c478bd9Sstevel@tonic-gate * pointer to call the mechanism specific gss_inquire_cred. 76*7c478bd9Sstevel@tonic-gate * So, call get_mechanism with an arguement of GSS_C_NULL_OID. 77*7c478bd9Sstevel@tonic-gate * get_mechanism will return the first mechanism in the mech 78*7c478bd9Sstevel@tonic-gate * array, which becomes the default mechanism. 79*7c478bd9Sstevel@tonic-gate */ 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate if ((mech = __gss_get_mechanism(GSS_C_NULL_OID)) == NULL) 82*7c478bd9Sstevel@tonic-gate return (GSS_S_DEFECTIVE_CREDENTIAL); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate if (!mech->gss_inquire_cred) 85*7c478bd9Sstevel@tonic-gate return (GSS_S_UNAVAILABLE); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate status = mech->gss_inquire_cred(mech->context, minor_status, 88*7c478bd9Sstevel@tonic-gate GSS_C_NO_CREDENTIAL, 89*7c478bd9Sstevel@tonic-gate name ? &internal_name : NULL, 90*7c478bd9Sstevel@tonic-gate lifetime, cred_usage, 91*7c478bd9Sstevel@tonic-gate mechanisms); 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) 94*7c478bd9Sstevel@tonic-gate return (status); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate if (name) { 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate * Convert internal_name into a union_name equivalent. 99*7c478bd9Sstevel@tonic-gate */ 100*7c478bd9Sstevel@tonic-gate status = __gss_convert_name_to_union_name( 101*7c478bd9Sstevel@tonic-gate &temp_minor_status, mech, 102*7c478bd9Sstevel@tonic-gate internal_name, name); 103*7c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) { 104*7c478bd9Sstevel@tonic-gate *minor_status = temp_minor_status; 105*7c478bd9Sstevel@tonic-gate if (mechanisms && *mechanisms) { 106*7c478bd9Sstevel@tonic-gate (void) gss_release_oid_set( 107*7c478bd9Sstevel@tonic-gate &temp_minor_status, 108*7c478bd9Sstevel@tonic-gate mechanisms); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate return (status); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate /* get the cred_handle cast as a union_credentials structure */ 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate union_cred = (gss_union_cred_t)cred_handle; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* 121*7c478bd9Sstevel@tonic-gate * get the information out of the union_cred structure that was 122*7c478bd9Sstevel@tonic-gate * placed there during gss_acquire_cred. 123*7c478bd9Sstevel@tonic-gate */ 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate if (cred_usage != NULL) 126*7c478bd9Sstevel@tonic-gate *cred_usage = union_cred->auxinfo.cred_usage; 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate if (lifetime != NULL) { 129*7c478bd9Sstevel@tonic-gate elapsed_time = time(0) - union_cred->auxinfo.creation_time; 130*7c478bd9Sstevel@tonic-gate *lifetime = union_cred->auxinfo.time_rec < elapsed_time ? 0 : 131*7c478bd9Sstevel@tonic-gate union_cred->auxinfo.time_rec - elapsed_time; 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * if name is non_null, 136*7c478bd9Sstevel@tonic-gate * call gss_import_name() followed by gss_canonicalize_name() 137*7c478bd9Sstevel@tonic-gate * to get a mechanism specific name passed back to the caller. 138*7c478bd9Sstevel@tonic-gate * If this call fails, return failure to our caller. 139*7c478bd9Sstevel@tonic-gate * XXX The cred_handle may contain an array of mechanism OID's 140*7c478bd9Sstevel@tonic-gate * but we only return the MN for the first mechanism to the caller. 141*7c478bd9Sstevel@tonic-gate * In theory, we should modify this to provide an array of MN's 142*7c478bd9Sstevel@tonic-gate * one per mechanism back to the caller. 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if (name != NULL) { 146*7c478bd9Sstevel@tonic-gate if ((gss_import_name(minor_status, 147*7c478bd9Sstevel@tonic-gate &union_cred->auxinfo.name, 148*7c478bd9Sstevel@tonic-gate union_cred->auxinfo.name_type, 149*7c478bd9Sstevel@tonic-gate name) != GSS_S_COMPLETE) || 150*7c478bd9Sstevel@tonic-gate (gss_canonicalize_name(minor_status, *name, 151*7c478bd9Sstevel@tonic-gate &union_cred->mechs_array[0], 152*7c478bd9Sstevel@tonic-gate NULL) != GSS_S_COMPLETE)) { 153*7c478bd9Sstevel@tonic-gate status = GSS_S_DEFECTIVE_CREDENTIAL; 154*7c478bd9Sstevel@tonic-gate goto error; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* 159*7c478bd9Sstevel@tonic-gate * copy the mechanism set in union_cred into an OID set and return in 160*7c478bd9Sstevel@tonic-gate * the mechanisms parameter. 161*7c478bd9Sstevel@tonic-gate */ 162*7c478bd9Sstevel@tonic-gate if (mechanisms != NULL) { 163*7c478bd9Sstevel@tonic-gate status = GSS_S_FAILURE; 164*7c478bd9Sstevel@tonic-gate *mechanisms = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)); 165*7c478bd9Sstevel@tonic-gate if (*mechanisms == NULL) 166*7c478bd9Sstevel@tonic-gate goto error; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate (*mechanisms)->count = 0; 169*7c478bd9Sstevel@tonic-gate (*mechanisms)->elements = 170*7c478bd9Sstevel@tonic-gate (gss_OID) malloc(sizeof (gss_OID_desc) * 171*7c478bd9Sstevel@tonic-gate union_cred->count); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if ((*mechanisms)->elements == NULL) { 174*7c478bd9Sstevel@tonic-gate free(*mechanisms); 175*7c478bd9Sstevel@tonic-gate *mechanisms = NULL; 176*7c478bd9Sstevel@tonic-gate goto error; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate for (i = 0; i < union_cred->count; i++) { 180*7c478bd9Sstevel@tonic-gate (*mechanisms)->elements[i].elements = (void *) 181*7c478bd9Sstevel@tonic-gate malloc(union_cred->mechs_array[i].length); 182*7c478bd9Sstevel@tonic-gate if ((*mechanisms)->elements[i].elements == NULL) 183*7c478bd9Sstevel@tonic-gate goto error; 184*7c478bd9Sstevel@tonic-gate g_OID_copy(&(*mechanisms)->elements[i], 185*7c478bd9Sstevel@tonic-gate &union_cred->mechs_array[i]); 186*7c478bd9Sstevel@tonic-gate (*mechanisms)->count++; 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate error: 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * cleanup any allocated memory - we can just call 195*7c478bd9Sstevel@tonic-gate * gss_release_oid_set, because the set is constructed so that 196*7c478bd9Sstevel@tonic-gate * count always references the currently copied number of 197*7c478bd9Sstevel@tonic-gate * elements. 198*7c478bd9Sstevel@tonic-gate */ 199*7c478bd9Sstevel@tonic-gate if (mechanisms && *mechanisms != NULL) 200*7c478bd9Sstevel@tonic-gate (void) gss_release_oid_set(&temp_minor_status, mechanisms); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate if (name && *name != NULL) 203*7c478bd9Sstevel@tonic-gate (void) gss_release_name(&temp_minor_status, name); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate return (status); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate OM_uint32 209*7c478bd9Sstevel@tonic-gate gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, 210*7c478bd9Sstevel@tonic-gate initiator_lifetime, acceptor_lifetime, cred_usage) 211*7c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 212*7c478bd9Sstevel@tonic-gate const gss_cred_id_t cred_handle; 213*7c478bd9Sstevel@tonic-gate const gss_OID mech_type; 214*7c478bd9Sstevel@tonic-gate gss_name_t *name; 215*7c478bd9Sstevel@tonic-gate OM_uint32 *initiator_lifetime; 216*7c478bd9Sstevel@tonic-gate OM_uint32 *acceptor_lifetime; 217*7c478bd9Sstevel@tonic-gate gss_cred_usage_t *cred_usage; 218*7c478bd9Sstevel@tonic-gate { 219*7c478bd9Sstevel@tonic-gate gss_union_cred_t union_cred; 220*7c478bd9Sstevel@tonic-gate gss_cred_id_t mech_cred; 221*7c478bd9Sstevel@tonic-gate gss_mechanism mech; 222*7c478bd9Sstevel@tonic-gate OM_uint32 status, temp_minor_status; 223*7c478bd9Sstevel@tonic-gate gss_name_t internal_name; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate mech = __gss_get_mechanism(mech_type); 227*7c478bd9Sstevel@tonic-gate if (!mech) 228*7c478bd9Sstevel@tonic-gate return (GSS_S_BAD_MECH); 229*7c478bd9Sstevel@tonic-gate if (!mech->gss_inquire_cred_by_mech) 230*7c478bd9Sstevel@tonic-gate return (GSS_S_UNAVAILABLE); 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate union_cred = (gss_union_cred_t)cred_handle; 233*7c478bd9Sstevel@tonic-gate mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); 234*7c478bd9Sstevel@tonic-gate if (mech_cred == NULL) 235*7c478bd9Sstevel@tonic-gate return (GSS_S_DEFECTIVE_CREDENTIAL); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate status = mech->gss_inquire_cred_by_mech(mech->context, minor_status, 238*7c478bd9Sstevel@tonic-gate mech_cred, mech_type, 239*7c478bd9Sstevel@tonic-gate name ? &internal_name : NULL, 240*7c478bd9Sstevel@tonic-gate initiator_lifetime, 241*7c478bd9Sstevel@tonic-gate acceptor_lifetime, cred_usage); 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) 244*7c478bd9Sstevel@tonic-gate return (status); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if (name) { 247*7c478bd9Sstevel@tonic-gate /* 248*7c478bd9Sstevel@tonic-gate * Convert internal_name into a union_name equivalent. 249*7c478bd9Sstevel@tonic-gate */ 250*7c478bd9Sstevel@tonic-gate status = __gss_convert_name_to_union_name( 251*7c478bd9Sstevel@tonic-gate &temp_minor_status, mech, 252*7c478bd9Sstevel@tonic-gate internal_name, name); 253*7c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) { 254*7c478bd9Sstevel@tonic-gate *minor_status = temp_minor_status; 255*7c478bd9Sstevel@tonic-gate return (status); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 260*7c478bd9Sstevel@tonic-gate } 261