/ lib / gssapi / krb5 / copy_ccache.c
copy_ccache.c
  1  /*
  2   * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
  7   *
  8   * Redistribution and use in source and binary forms, with or without
  9   * modification, are permitted provided that the following conditions
 10   * are met:
 11   *
 12   * 1. Redistributions of source code must retain the above copyright
 13   *    notice, this list of conditions and the following disclaimer.
 14   *
 15   * 2. Redistributions in binary form must reproduce the above copyright
 16   *    notice, this list of conditions and the following disclaimer in the
 17   *    documentation and/or other materials provided with the distribution.
 18   *
 19   * 3. Neither the name of the Institute nor the names of its contributors
 20   *    may be used to endorse or promote products derived from this software
 21   *    without specific prior written permission.
 22   *
 23   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 24   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 25   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 26   * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 27   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 29   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 30   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 31   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 32   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 33   * SUCH DAMAGE.
 34   */
 35  
 36  #include "gsskrb5_locl.h"
 37  
 38  #if 0
 39  OM_uint32
 40  gss_krb5_copy_ccache(OM_uint32 *minor_status,
 41  		     krb5_context context,
 42  		     gss_cred_id_t cred,
 43  		     krb5_ccache out)
 44  {
 45      krb5_error_code kret;
 46  
 47      HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
 48  
 49      if (cred->ccache == NULL) {
 50  	HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
 51  	*minor_status = EINVAL;
 52  	return GSS_S_FAILURE;
 53      }
 54  
 55      kret = krb5_cc_copy_cache(context, cred->ccache, out);
 56      HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
 57      if (kret) {
 58  	*minor_status = kret;
 59  	return GSS_S_FAILURE;
 60      }
 61      *minor_status = 0;
 62      return GSS_S_COMPLETE;
 63  }
 64  #endif
 65  
 66  
 67  OM_uint32
 68  _gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
 69  			  krb5_ccache id,
 70  			  krb5_principal keytab_principal,
 71  			  krb5_keytab keytab,
 72  			  gss_cred_id_t *cred)
 73  {
 74      krb5_context context;
 75      krb5_error_code kret;
 76      gsskrb5_cred handle;
 77      OM_uint32 ret;
 78  
 79      *cred = NULL;
 80  
 81      GSSAPI_KRB5_INIT (&context);
 82  
 83      handle = calloc(1, sizeof(*handle));
 84      if (handle == NULL) {
 85  	_gsskrb5_clear_status ();
 86  	*minor_status = ENOMEM;
 87          return (GSS_S_FAILURE);
 88      }
 89      HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
 90  
 91      handle->usage = 0;
 92  
 93      if (id) {
 94  	char *str;
 95  
 96  	handle->usage |= GSS_C_INITIATE;
 97  
 98  	kret = krb5_cc_get_principal(context, id,
 99  				     &handle->principal);
100  	if (kret) {
101  	    free(handle);
102  	    *minor_status = kret;
103  	    return GSS_S_FAILURE;
104  	}
105  
106  	if (keytab_principal) {
107  	    krb5_boolean match;
108  
109  	    match = krb5_principal_compare(context,
110  					   handle->principal,
111  					   keytab_principal);
112  	    if (match == FALSE) {
113  		krb5_free_principal(context, handle->principal);
114  		free(handle);
115  		_gsskrb5_clear_status ();
116  		*minor_status = EINVAL;
117  		return GSS_S_FAILURE;
118  	    }
119  	}
120  
121  	ret = __gsskrb5_ccache_lifetime(minor_status,
122  					context,
123  					id,
124  					handle->principal,
125  					&handle->endtime);
126  	if (ret != GSS_S_COMPLETE) {
127  	    krb5_free_principal(context, handle->principal);
128  	    free(handle);
129  	    return ret;
130  	}
131  
132  
133  	kret = krb5_cc_get_full_name(context, id, &str);
134  	if (kret)
135  	    goto out;
136  
137  	kret = krb5_cc_resolve(context, str, &handle->ccache);
138  	free(str);
139  	if (kret)
140  	    goto out;
141      }
142  
143  
144      if (keytab) {
145  	char *str;
146  
147  	handle->usage |= GSS_C_ACCEPT;
148  
149  	if (keytab_principal && handle->principal == NULL) {
150  	    kret = krb5_copy_principal(context,
151  				       keytab_principal,
152  				       &handle->principal);
153  	    if (kret)
154  		goto out;
155  	}
156  
157  	kret = krb5_kt_get_full_name(context, keytab, &str);
158  	if (kret)
159  	    goto out;
160  
161  	kret = krb5_kt_resolve(context, str, &handle->keytab);
162  	free(str);
163  	if (kret)
164  	    goto out;
165      }
166  
167  
168      *minor_status = 0;
169      *cred = (gss_cred_id_t)handle;
170      return GSS_S_COMPLETE;
171  
172  out:
173      if (handle->ccache)
174  	krb5_cc_close(context, handle->ccache);
175      if (handle->keytab)
176  	krb5_kt_close(context, handle->keytab);
177      if (handle->principal)
178  	krb5_free_principal(context, handle->principal);
179      HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
180      free(handle);
181      *minor_status = kret;
182      return GSS_S_FAILURE;
183  }