1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 #include "gssapiP_krb5.h"
3 
4 OM_uint32
gss_krb5int_copy_ccache(OM_uint32 * minor_status,gss_cred_id_t * cred_handle,const gss_OID desired_object,const gss_buffer_t value)5 gss_krb5int_copy_ccache(OM_uint32 *minor_status,
6                         gss_cred_id_t *cred_handle,
7                         const gss_OID desired_object,
8                         const gss_buffer_t value)
9 {
10     krb5_gss_cred_id_t k5creds;
11     krb5_error_code code;
12     krb5_context context = NULL;
13     krb5_ccache out_ccache;
14 
15     assert(value->length == sizeof(out_ccache));
16 
17     if (value->length != sizeof(out_ccache))
18         return GSS_S_FAILURE;
19 
20     out_ccache = (krb5_ccache)value->value;
21 
22     /* cred handle will have been validated by gssspi_set_cred_option() */
23     k5creds = (krb5_gss_cred_id_t) *cred_handle;
24     k5_mutex_lock(&k5creds->lock);
25     if (k5creds->usage == GSS_C_ACCEPT) {
26         code = G_BAD_USAGE;
27         goto cleanup;
28     }
29 
30     code = krb5_gss_init_context(&context);
31     if (code)
32         goto cleanup;
33 
34     code = krb5_cc_copy_creds(context, k5creds->ccache, out_ccache);
35 
36 cleanup:
37     k5_mutex_unlock(&k5creds->lock);
38     *minor_status = code;
39     if (context != NULL) {
40         if (code)
41             save_error_info(*minor_status, context);
42         krb5_free_context(context);
43     }
44     return code ? GSS_S_FAILURE : GSS_S_COMPLETE;
45 }
46