Home | History | Annotate | Download | only in mech
      1 /*
      2  * Copyright 2000 by the Massachusetts Institute of Technology.
      3  * All Rights Reserved.
      4  *
      5  * Export of this software from the United States of America may
      6  *   require a specific license from the United States Government.
      7  *   It is the responsibility of any person or organization contemplating
      8  *   export to obtain such a license before exporting.
      9  *
     10  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     11  * distribute this software and its documentation for any purpose and
     12  * without fee is hereby granted, provided that the above copyright
     13  * notice appear in all copies and that both that copyright notice and
     14  * this permission notice appear in supporting documentation, and that
     15  * the name of M.I.T. not be used in advertising or publicity pertaining
     16  * to distribution of the software without specific, written prior
     17  * permission.  Furthermore if you modify this software you must label
     18  * your software as modified software and not distribute it in such a
     19  * fashion that it might be confused with the original M.I.T. software.
     20  * M.I.T. makes no representations about the suitability of
     21  * this software for any purpose.  It is provided "as is" without express
     22  * or implied warranty.
     23  *
     24  */
     25 /*
     26  * Copyright 1993 by OpenVision Technologies, Inc.
     27  *
     28  * Permission to use, copy, modify, distribute, and sell this software
     29  * and its documentation for any purpose is hereby granted without fee,
     30  * provided that the above copyright notice appears in all copies and
     31  * that both that copyright notice and this permission notice appear in
     32  * supporting documentation, and that the name of OpenVision not be used
     33  * in advertising or publicity pertaining to distribution of the software
     34  * without specific, written prior permission. OpenVision makes no
     35  * representations about the suitability of this software for any
     36  * purpose.  It is provided "as is" without express or implied warranty.
     37  *
     38  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     39  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     40  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     41  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     42  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     43  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     44  * PERFORMANCE OF THIS SOFTWARE.
     45  */
     46 
     47 /*
     48  * Copyright (C) 1998 by the FundsXpress, INC.
     49  *
     50  * All rights reserved.
     51  *
     52  * Export of this software from the United States of America may require
     53  * a specific license from the United States Government.  It is the
     54  * responsibility of any person or organization contemplating export to
     55  * obtain such a license before exporting.
     56  *
     57  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     58  * distribute this software and its documentation for any purpose and
     59  * without fee is hereby granted, provided that the above copyright
     60  * notice appear in all copies and that both that copyright notice and
     61  * this permission notice appear in supporting documentation, and that
     62  * the name of FundsXpress. not be used in advertising or publicity pertaining
     63  * to distribution of the software without specific, written prior
     64  * permission.  FundsXpress makes no representations about the suitability of
     65  * this software for any purpose.  It is provided "as is" without express
     66  * or implied warranty.
     67  *
     68  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
     69  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     70  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     71  */
     72 
     73 #include "gssapiP_krb5.h"
     74 #include "mglueP.h"
     75 
     76 OM_uint32
     77 krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
     78 		      cred_usage, mechanisms)
     79      OM_uint32 *minor_status;
     80      gss_cred_id_t cred_handle;
     81      gss_name_t *name;
     82      OM_uint32 *lifetime_ret;
     83      gss_cred_usage_t *cred_usage;
     84      gss_OID_set *mechanisms;
     85 {
     86    krb5_context context;
     87    krb5_gss_cred_id_t cred;
     88    krb5_error_code code;
     89    krb5_timestamp now;
     90    krb5_deltat lifetime;
     91    krb5_principal ret_name;
     92    gss_OID_set mechs;
     93    OM_uint32 ret;
     94 
     95    ret = GSS_S_FAILURE;
     96    ret_name = NULL;
     97 
     98    code = krb5_gss_init_context(&context);
     99    if (code) {
    100        *minor_status = code;
    101        return GSS_S_FAILURE;
    102    }
    103 
    104    if (name) *name = NULL;
    105    if (mechanisms) *mechanisms = NULL;
    106 
    107    /* check for default credential */
    108    /*SUPPRESS 29*/
    109    if (cred_handle == GSS_C_NO_CREDENTIAL) {
    110       OM_uint32 major;
    111 
    112       if ((major = kg_get_defcred(minor_status, (gss_cred_id_t *)&cred)) &&
    113 	  GSS_ERROR(major)) {
    114 	 krb5_free_context(context);
    115 	 return(major);
    116       }
    117    } else {
    118       OM_uint32 major;
    119 
    120       major = krb5_gss_validate_cred(minor_status, cred_handle);
    121       if (GSS_ERROR(major)) {
    122 	  krb5_free_context(context);
    123 	  return(major);
    124       }
    125       cred = (krb5_gss_cred_id_t) cred_handle;
    126    }
    127 
    128    if ((code = krb5_timeofday(context, &now))) {
    129       *minor_status = code;
    130       ret = GSS_S_FAILURE;
    131       goto fail;
    132    }
    133 
    134    code = k5_mutex_lock(&cred->lock);
    135    if (code != 0) {
    136        *minor_status = code;
    137        ret = GSS_S_FAILURE;
    138        goto fail;
    139    }
    140    if (cred->tgt_expire > 0) {
    141        if ((lifetime = cred->tgt_expire - now) < 0)
    142 	   lifetime = 0;
    143    }
    144    else
    145        lifetime = GSS_C_INDEFINITE;
    146 
    147    if (name) {
    148       if (cred->princ &&
    149 	  (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
    150 	 k5_mutex_unlock(&cred->lock);
    151 	 *minor_status = code;
    152 	 ret = GSS_S_FAILURE;
    153 	 goto fail;
    154       }
    155    }
    156 
    157    if (mechanisms) {
    158        /* Solaris Kerberos */
    159        if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status,
    160 							    &mechs)) ||
    161 	   (cred->prerfc_mech &&
    162 	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
    163 							  (const gss_OID) gss_mech_krb5_old,
    164 							   &mechs))) ||
    165 	   (cred->rfc_mech &&
    166 	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
    167 							  (const gss_OID) gss_mech_krb5,
    168 							   &mechs)))) {
    169 	   k5_mutex_unlock(&cred->lock);
    170 	   if (ret_name)
    171 	       krb5_free_principal(context, ret_name);
    172 	   /* *minor_status set above */
    173 	   goto fail;
    174        }
    175    }
    176 
    177    if (name) {
    178       if (ret_name != NULL && ! kg_save_name((gss_name_t) ret_name)) {
    179 	 k5_mutex_unlock(&cred->lock);
    180 	 if (cred_handle == GSS_C_NO_CREDENTIAL)
    181 	     krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
    182 
    183 	 (void) gss_release_oid_set(minor_status, &mechs);
    184 	 krb5_free_principal(context, ret_name);
    185 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
    186 	 krb5_free_context(context);
    187 	 return(GSS_S_FAILURE);
    188       }
    189       if (ret_name != NULL)
    190 	  *name = (gss_name_t) ret_name;
    191       else
    192 	  *name = GSS_C_NO_NAME;
    193    }
    194 
    195    if (lifetime_ret)
    196       *lifetime_ret = lifetime;
    197 
    198    if (cred_usage)
    199       *cred_usage = cred->usage;
    200    k5_mutex_unlock(&cred->lock);
    201 
    202    if (mechanisms)
    203       *mechanisms = mechs;
    204 
    205    if (cred_handle == GSS_C_NO_CREDENTIAL)
    206        krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
    207 
    208    krb5_free_context(context);
    209    *minor_status = 0;
    210    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
    211 fail:
    212    if (cred_handle == GSS_C_NO_CREDENTIAL) {
    213        OM_uint32 tmp_min_stat;
    214 
    215        krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred);
    216    }
    217    krb5_free_context(context);
    218    return ret;
    219 }
    220 
    221 /* V2 interface */
    222 OM_uint32
    223 krb5_gss_inquire_cred_by_mech(minor_status, cred_handle,
    224 			      mech_type, name, initiator_lifetime,
    225 			      acceptor_lifetime, cred_usage)
    226     OM_uint32		*minor_status;
    227     gss_cred_id_t	cred_handle;
    228     gss_OID		mech_type;
    229     gss_name_t		*name;
    230     OM_uint32		*initiator_lifetime;
    231     OM_uint32		*acceptor_lifetime;
    232     gss_cred_usage_t *cred_usage;
    233 {
    234     krb5_gss_cred_id_t	cred;
    235     OM_uint32		lifetime;
    236     OM_uint32		mstat;
    237 
    238     /*
    239      * We only know how to handle our own creds.
    240      */
    241     if ((mech_type != GSS_C_NULL_OID) &&
    242 	!g_OID_equal(gss_mech_krb5_old, mech_type) &&
    243 	!g_OID_equal(gss_mech_krb5, mech_type)) {
    244 	*minor_status = 0;
    245 	return(GSS_S_NO_CRED);
    246     }
    247 
    248     cred = (krb5_gss_cred_id_t) cred_handle;
    249     mstat = krb5_gss_inquire_cred(minor_status,
    250 				  cred_handle,
    251 				  name,
    252 				  &lifetime,
    253 				  cred_usage,
    254 				  (gss_OID_set *) NULL);
    255     if (mstat == GSS_S_COMPLETE) {
    256 	if (cred &&
    257 	    ((cred->usage == GSS_C_INITIATE) ||
    258 	     (cred->usage == GSS_C_BOTH)) &&
    259 	    initiator_lifetime)
    260 	    *initiator_lifetime = lifetime;
    261 	if (cred &&
    262 	    ((cred->usage == GSS_C_ACCEPT) ||
    263 	     (cred->usage == GSS_C_BOTH)) &&
    264 	    acceptor_lifetime)
    265 	    *acceptor_lifetime = lifetime;
    266     }
    267     return(mstat);
    268 }
    269 
    270