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