xref: /titanic_41/usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
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