1178825Sdfr/*
2178825Sdfr * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska H�gskolan
3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden).
4178825Sdfr * All rights reserved.
5178825Sdfr *
6178825Sdfr * Redistribution and use in source and binary forms, with or without
7178825Sdfr * modification, are permitted provided that the following conditions
8178825Sdfr * are met:
9178825Sdfr *
10178825Sdfr * 1. Redistributions of source code must retain the above copyright
11178825Sdfr *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
14178825Sdfr *    notice, this list of conditions and the following disclaimer in the
15178825Sdfr *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17178825Sdfr * 3. Neither the name of the Institute nor the names of its contributors
18178825Sdfr *    may be used to endorse or promote products derived from this software
19178825Sdfr *    without specific prior written permission.
20178825Sdfr *
21178825Sdfr * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31178825Sdfr * SUCH DAMAGE.
32178825Sdfr */
33178825Sdfr
34178825Sdfr#include "krb5/gsskrb5_locl.h"
35178825Sdfr
36178825SdfrRCSID("$Id: copy_ccache.c 20688 2007-05-17 18:44:31Z lha $");
37178825Sdfr
38178825Sdfr#if 0
39178825SdfrOM_uint32
40178825Sdfrgss_krb5_copy_ccache(OM_uint32 *minor_status,
41178825Sdfr		     krb5_context context,
42178825Sdfr		     gss_cred_id_t cred,
43178825Sdfr		     krb5_ccache out)
44178825Sdfr{
45178825Sdfr    krb5_error_code kret;
46178825Sdfr
47178825Sdfr    HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
48178825Sdfr
49178825Sdfr    if (cred->ccache == NULL) {
50178825Sdfr	HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
51178825Sdfr	*minor_status = EINVAL;
52178825Sdfr	return GSS_S_FAILURE;
53178825Sdfr    }
54178825Sdfr
55178825Sdfr    kret = krb5_cc_copy_cache(context, cred->ccache, out);
56178825Sdfr    HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
57178825Sdfr    if (kret) {
58178825Sdfr	*minor_status = kret;
59178825Sdfr	return GSS_S_FAILURE;
60178825Sdfr    }
61178825Sdfr    *minor_status = 0;
62178825Sdfr    return GSS_S_COMPLETE;
63178825Sdfr}
64178825Sdfr#endif
65178825Sdfr
66178825Sdfr
67178825SdfrOM_uint32
68178825Sdfr_gsskrb5_import_cred(OM_uint32 *minor_status,
69178825Sdfr		     krb5_ccache id,
70178825Sdfr		     krb5_principal keytab_principal,
71178825Sdfr		     krb5_keytab keytab,
72178825Sdfr		     gss_cred_id_t *cred)
73178825Sdfr{
74178825Sdfr    krb5_context context;
75178825Sdfr    krb5_error_code kret;
76178825Sdfr    gsskrb5_cred handle;
77178825Sdfr    OM_uint32 ret;
78178825Sdfr
79178825Sdfr    *cred = NULL;
80178825Sdfr
81178825Sdfr    GSSAPI_KRB5_INIT (&context);
82178825Sdfr
83178825Sdfr    handle = calloc(1, sizeof(*handle));
84178825Sdfr    if (handle == NULL) {
85178825Sdfr	_gsskrb5_clear_status ();
86178825Sdfr	*minor_status = ENOMEM;
87178825Sdfr        return (GSS_S_FAILURE);
88178825Sdfr    }
89178825Sdfr    HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
90178825Sdfr
91178825Sdfr    handle->usage = 0;
92178825Sdfr
93178825Sdfr    if (id) {
94178825Sdfr	char *str;
95178825Sdfr
96178825Sdfr	handle->usage |= GSS_C_INITIATE;
97178825Sdfr
98178825Sdfr	kret = krb5_cc_get_principal(context, id,
99178825Sdfr				     &handle->principal);
100178825Sdfr	if (kret) {
101178825Sdfr	    free(handle);
102178825Sdfr	    *minor_status = kret;
103178825Sdfr	    return GSS_S_FAILURE;
104178825Sdfr	}
105178825Sdfr
106178825Sdfr	if (keytab_principal) {
107178825Sdfr	    krb5_boolean match;
108178825Sdfr
109178825Sdfr	    match = krb5_principal_compare(context,
110178825Sdfr					   handle->principal,
111178825Sdfr					   keytab_principal);
112178825Sdfr	    if (match == FALSE) {
113178825Sdfr		krb5_free_principal(context, handle->principal);
114178825Sdfr		free(handle);
115178825Sdfr		_gsskrb5_clear_status ();
116178825Sdfr		*minor_status = EINVAL;
117178825Sdfr		return GSS_S_FAILURE;
118178825Sdfr	    }
119178825Sdfr	}
120178825Sdfr
121178825Sdfr	ret = __gsskrb5_ccache_lifetime(minor_status,
122178825Sdfr					context,
123178825Sdfr					id,
124178825Sdfr					handle->principal,
125178825Sdfr					&handle->lifetime);
126178825Sdfr	if (ret != GSS_S_COMPLETE) {
127178825Sdfr	    krb5_free_principal(context, handle->principal);
128178825Sdfr	    free(handle);
129178825Sdfr	    return ret;
130178825Sdfr	}
131178825Sdfr
132178825Sdfr
133178825Sdfr	kret = krb5_cc_get_full_name(context, id, &str);
134178825Sdfr	if (kret)
135178825Sdfr	    goto out;
136178825Sdfr
137178825Sdfr	kret = krb5_cc_resolve(context, str, &handle->ccache);
138178825Sdfr	free(str);
139178825Sdfr	if (kret)
140178825Sdfr	    goto out;
141178825Sdfr    }
142178825Sdfr
143178825Sdfr
144178825Sdfr    if (keytab) {
145178825Sdfr	char *str;
146178825Sdfr
147178825Sdfr	handle->usage |= GSS_C_ACCEPT;
148178825Sdfr
149178825Sdfr	if (keytab_principal && handle->principal == NULL) {
150178825Sdfr	    kret = krb5_copy_principal(context,
151178825Sdfr				       keytab_principal,
152178825Sdfr				       &handle->principal);
153178825Sdfr	    if (kret)
154178825Sdfr		goto out;
155178825Sdfr	}
156178825Sdfr
157178825Sdfr	kret = krb5_kt_get_full_name(context, keytab, &str);
158178825Sdfr	if (kret)
159178825Sdfr	    goto out;
160178825Sdfr
161178825Sdfr	kret = krb5_kt_resolve(context, str, &handle->keytab);
162178825Sdfr	free(str);
163178825Sdfr	if (kret)
164178825Sdfr	    goto out;
165178825Sdfr    }
166178825Sdfr
167178825Sdfr
168178825Sdfr    if (id || keytab) {
169178825Sdfr	ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
170178825Sdfr	if (ret == GSS_S_COMPLETE)
171178825Sdfr	    ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
172178825Sdfr					 &handle->mechanisms);
173178825Sdfr	if (ret != GSS_S_COMPLETE) {
174178825Sdfr	    kret = *minor_status;
175178825Sdfr	    goto out;
176178825Sdfr	}
177178825Sdfr    }
178178825Sdfr
179178825Sdfr    *minor_status = 0;
180178825Sdfr    *cred = (gss_cred_id_t)handle;
181178825Sdfr    return GSS_S_COMPLETE;
182178825Sdfr
183178825Sdfrout:
184178825Sdfr    gss_release_oid_set(minor_status, &handle->mechanisms);
185178825Sdfr    if (handle->ccache)
186178825Sdfr	krb5_cc_close(context, handle->ccache);
187178825Sdfr    if (handle->keytab)
188178825Sdfr	krb5_kt_close(context, handle->keytab);
189178825Sdfr    if (handle->principal)
190178825Sdfr	krb5_free_principal(context, handle->principal);
191178825Sdfr    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
192178825Sdfr    free(handle);
193178825Sdfr    *minor_status = kret;
194178825Sdfr    return GSS_S_FAILURE;
195178825Sdfr}
196