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