2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A#include "gssapiP_krb5.h"
2N/A
2N/AOM_uint32 KRB5_CALLCONV
2N/Agss_krb5int_copy_ccache(OM_uint32 *minor_status,
2N/A gss_cred_id_t cred_handle,
2N/A const gss_OID desired_object,
2N/A const gss_buffer_t value)
2N/A{
2N/A krb5_gss_cred_id_t k5creds;
2N/A krb5_cc_cursor cursor;
2N/A krb5_creds creds;
2N/A krb5_error_code code;
2N/A krb5_context context;
2N/A krb5_ccache out_ccache;
2N/A
2N/A assert(value->length == sizeof(out_ccache));
2N/A
2N/A if (value->length != sizeof(out_ccache))
2N/A return GSS_S_FAILURE;
2N/A
2N/A out_ccache = (krb5_ccache)value->value;
2N/A
2N/A /* cred handle will have been validated by gssspi_set_cred_option() */
2N/A
2N/A k5creds = (krb5_gss_cred_id_t) cred_handle;
2N/A code = k5_mutex_lock(&k5creds->lock);
2N/A if (code) {
2N/A *minor_status = code;
2N/A return GSS_S_FAILURE;
2N/A }
2N/A if (k5creds->usage == GSS_C_ACCEPT) {
2N/A k5_mutex_unlock(&k5creds->lock);
2N/A *minor_status = (OM_uint32) G_BAD_USAGE;
2N/A return(GSS_S_FAILURE);
2N/A }
2N/A
2N/A code = krb5_gss_init_context(&context);
2N/A if (code) {
2N/A k5_mutex_unlock(&k5creds->lock);
2N/A *minor_status = code;
2N/A return GSS_S_FAILURE;
2N/A }
2N/A
2N/A code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor);
2N/A if (code) {
2N/A k5_mutex_unlock(&k5creds->lock);
2N/A *minor_status = code;
2N/A save_error_info(*minor_status, context);
2N/A krb5_free_context(context);
2N/A return(GSS_S_FAILURE);
2N/A }
2N/A while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor,
2N/A &creds)) {
2N/A code = krb5_cc_store_cred(context, out_ccache, &creds);
2N/A krb5_free_cred_contents(context, &creds);
2N/A }
2N/A krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
2N/A k5_mutex_unlock(&k5creds->lock);
2N/A *minor_status = code;
2N/A if (code)
2N/A save_error_info(*minor_status, context);
2N/A krb5_free_context(context);
2N/A return code ? GSS_S_FAILURE : GSS_S_COMPLETE;
2N/A}