1 /*
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
4
5 #include "gssapiP_krb5.h"
6
7 OM_uint32 KRB5_CALLCONV
gss_krb5int_copy_ccache(minor_status,cred_handle,out_ccache)8 gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache)
9 OM_uint32 *minor_status;
10 gss_cred_id_t cred_handle;
11 krb5_ccache out_ccache;
12 {
13 OM_uint32 stat;
14 krb5_gss_cred_id_t k5creds;
15 krb5_cc_cursor cursor;
16 krb5_creds creds;
17 krb5_error_code code;
18 krb5_context context;
19
20 /* validate the cred handle */
21 stat = krb5_gss_validate_cred(minor_status, cred_handle);
22 if (stat)
23 return(stat);
24
25 k5creds = (krb5_gss_cred_id_t) cred_handle;
26 code = k5_mutex_lock(&k5creds->lock);
27 if (code) {
28 *minor_status = code;
29 return GSS_S_FAILURE;
30 }
31 if (k5creds->usage == GSS_C_ACCEPT) {
32 k5_mutex_unlock(&k5creds->lock);
33 *minor_status = (OM_uint32) G_BAD_USAGE;
34 return(GSS_S_FAILURE);
35 }
36
37 code = krb5_gss_init_context(&context);
38 if (code) {
39 k5_mutex_unlock(&k5creds->lock);
40 *minor_status = code;
41 return GSS_S_FAILURE;
42 }
43
44 code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor);
45 if (code) {
46 k5_mutex_unlock(&k5creds->lock);
47 *minor_status = code;
48 save_error_info(*minor_status, context);
49 krb5_free_context(context);
50 return(GSS_S_FAILURE);
51 }
52 while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds))
53 code = krb5_cc_store_cred(context, out_ccache, &creds);
54 krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
55 k5_mutex_unlock(&k5creds->lock);
56 krb5_free_context(context);
57 if (code) {
58 *minor_status = code;
59 save_error_info(*minor_status, context);
60 return(GSS_S_FAILURE);
61 } else {
62 *minor_status = 0;
63 return(GSS_S_COMPLETE);
64 }
65 }
66