1*5e01956fSGlenn Barry /*
2*5e01956fSGlenn Barry  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3*5e01956fSGlenn Barry  */
47c478bd9Sstevel@tonic-gate 
5ab9b2e15Sgtb #include "gssapiP_krb5.h"
67c478bd9Sstevel@tonic-gate 
7ab9b2e15Sgtb OM_uint32 KRB5_CALLCONV
gss_krb5int_copy_ccache(minor_status,cred_handle,out_ccache)8ab9b2e15Sgtb gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache)
97c478bd9Sstevel@tonic-gate      OM_uint32 *minor_status;
107c478bd9Sstevel@tonic-gate      gss_cred_id_t cred_handle;
117c478bd9Sstevel@tonic-gate      krb5_ccache out_ccache;
127c478bd9Sstevel@tonic-gate {
13ab9b2e15Sgtb    OM_uint32 stat;
147c478bd9Sstevel@tonic-gate    krb5_gss_cred_id_t k5creds;
157c478bd9Sstevel@tonic-gate    krb5_cc_cursor cursor;
167c478bd9Sstevel@tonic-gate    krb5_creds creds;
177c478bd9Sstevel@tonic-gate    krb5_error_code code;
18ab9b2e15Sgtb    krb5_context context;
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate    /* validate the cred handle */
21ab9b2e15Sgtb    stat = krb5_gss_validate_cred(minor_status, cred_handle);
22ab9b2e15Sgtb    if (stat)
23ab9b2e15Sgtb        return(stat);
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate    k5creds = (krb5_gss_cred_id_t) cred_handle;
26ab9b2e15Sgtb    code = k5_mutex_lock(&k5creds->lock);
27ab9b2e15Sgtb    if (code) {
28ab9b2e15Sgtb        *minor_status = code;
29ab9b2e15Sgtb        return GSS_S_FAILURE;
30ab9b2e15Sgtb    }
317c478bd9Sstevel@tonic-gate    if (k5creds->usage == GSS_C_ACCEPT) {
32ab9b2e15Sgtb        k5_mutex_unlock(&k5creds->lock);
337c478bd9Sstevel@tonic-gate        *minor_status = (OM_uint32) G_BAD_USAGE;
34ab9b2e15Sgtb        return(GSS_S_FAILURE);
357c478bd9Sstevel@tonic-gate    }
367c478bd9Sstevel@tonic-gate 
37ab9b2e15Sgtb    code = krb5_gss_init_context(&context);
38ab9b2e15Sgtb    if (code) {
39ab9b2e15Sgtb        k5_mutex_unlock(&k5creds->lock);
40ab9b2e15Sgtb        *minor_status = code;
41ab9b2e15Sgtb        return GSS_S_FAILURE;
42ab9b2e15Sgtb    }
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate    code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor);
457c478bd9Sstevel@tonic-gate    if (code) {
46ab9b2e15Sgtb        k5_mutex_unlock(&k5creds->lock);
477c478bd9Sstevel@tonic-gate        *minor_status = code;
48*5e01956fSGlenn Barry        save_error_info(*minor_status, context);
49ab9b2e15Sgtb        krb5_free_context(context);
50ab9b2e15Sgtb        return(GSS_S_FAILURE);
517c478bd9Sstevel@tonic-gate    }
527c478bd9Sstevel@tonic-gate    while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds))
537c478bd9Sstevel@tonic-gate        code = krb5_cc_store_cred(context, out_ccache, &creds);
547c478bd9Sstevel@tonic-gate    krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
55ab9b2e15Sgtb    k5_mutex_unlock(&k5creds->lock);
56ab9b2e15Sgtb    krb5_free_context(context);
577c478bd9Sstevel@tonic-gate    if (code) {
587c478bd9Sstevel@tonic-gate        *minor_status = code;
59*5e01956fSGlenn Barry        save_error_info(*minor_status, context);
60ab9b2e15Sgtb        return(GSS_S_FAILURE);
617c478bd9Sstevel@tonic-gate    } else {
627c478bd9Sstevel@tonic-gate        *minor_status = 0;
63ab9b2e15Sgtb        return(GSS_S_COMPLETE);
647c478bd9Sstevel@tonic-gate    }
657c478bd9Sstevel@tonic-gate }
66