1178825Sdfr/*
2178825Sdfr * Copyright (c) 2005, PADL Software Pty Ltd.
3178825Sdfr * All rights reserved.
4178825Sdfr *
5178825Sdfr * Redistribution and use in source and binary forms, with or without
6178825Sdfr * modification, are permitted provided that the following conditions
7178825Sdfr * are met:
8178825Sdfr *
9178825Sdfr * 1. Redistributions of source code must retain the above copyright
10178825Sdfr *    notice, this list of conditions and the following disclaimer.
11178825Sdfr *
12178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
13178825Sdfr *    notice, this list of conditions and the following disclaimer in the
14178825Sdfr *    documentation and/or other materials provided with the distribution.
15178825Sdfr *
16178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors
17178825Sdfr *    may be used to endorse or promote products derived from this software
18178825Sdfr *    without specific prior written permission.
19178825Sdfr *
20178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30178825Sdfr * SUCH DAMAGE.
31178825Sdfr */
32178825Sdfr
33178825Sdfr#include "kcm_locl.h"
34178825Sdfr
35233294SstasRCSID("$Id$");
36178825Sdfr
37178825Sdfr/*
38178825Sdfr * Server-side loopback glue for credentials cache operations; this
39178825Sdfr * must be initialized with kcm_internal_ccache(), it is not for real
40178825Sdfr * use. This entire file assumes the cache is locked, it does not do
41178825Sdfr * any concurrency checking for multithread applications.
42178825Sdfr */
43178825Sdfr
44178825Sdfr#define KCMCACHE(X)	((kcm_ccache)(X)->data.data)
45178825Sdfr#define CACHENAME(X)	(KCMCACHE(X)->name)
46178825Sdfr
47178825Sdfrstatic const char *
48178825Sdfrkcmss_get_name(krb5_context context,
49178825Sdfr	       krb5_ccache id)
50178825Sdfr{
51178825Sdfr    return CACHENAME(id);
52178825Sdfr}
53178825Sdfr
54178825Sdfrstatic krb5_error_code
55178825Sdfrkcmss_resolve(krb5_context context, krb5_ccache *id, const char *res)
56178825Sdfr{
57178825Sdfr    return KRB5_FCC_INTERNAL;
58178825Sdfr}
59178825Sdfr
60178825Sdfrstatic krb5_error_code
61178825Sdfrkcmss_gen_new(krb5_context context, krb5_ccache *id)
62178825Sdfr{
63178825Sdfr    return KRB5_FCC_INTERNAL;
64178825Sdfr}
65178825Sdfr
66178825Sdfrstatic krb5_error_code
67178825Sdfrkcmss_initialize(krb5_context context,
68178825Sdfr		 krb5_ccache id,
69178825Sdfr		 krb5_principal primary_principal)
70178825Sdfr{
71178825Sdfr    krb5_error_code ret;
72178825Sdfr    kcm_ccache c = KCMCACHE(id);
73178825Sdfr
74178825Sdfr    KCM_ASSERT_VALID(c);
75178825Sdfr
76178825Sdfr    ret = kcm_zero_ccache_data_internal(context, c);
77178825Sdfr    if (ret)
78178825Sdfr	return ret;
79178825Sdfr
80178825Sdfr    ret = krb5_copy_principal(context, primary_principal,
81178825Sdfr			      &c->client);
82178825Sdfr
83178825Sdfr    return ret;
84178825Sdfr}
85178825Sdfr
86178825Sdfrstatic krb5_error_code
87178825Sdfrkcmss_close(krb5_context context,
88178825Sdfr	    krb5_ccache id)
89178825Sdfr{
90178825Sdfr    kcm_ccache c = KCMCACHE(id);
91178825Sdfr
92178825Sdfr    KCM_ASSERT_VALID(c);
93178825Sdfr
94178825Sdfr    id->data.data = NULL;
95178825Sdfr    id->data.length = 0;
96178825Sdfr
97178825Sdfr    return 0;
98178825Sdfr}
99178825Sdfr
100178825Sdfrstatic krb5_error_code
101178825Sdfrkcmss_destroy(krb5_context context,
102178825Sdfr	      krb5_ccache id)
103178825Sdfr{
104178825Sdfr    krb5_error_code ret;
105178825Sdfr    kcm_ccache c = KCMCACHE(id);
106178825Sdfr
107178825Sdfr    KCM_ASSERT_VALID(c);
108178825Sdfr
109178825Sdfr    ret = kcm_ccache_destroy(context, CACHENAME(id));
110178825Sdfr
111178825Sdfr    return ret;
112178825Sdfr}
113178825Sdfr
114178825Sdfrstatic krb5_error_code
115178825Sdfrkcmss_store_cred(krb5_context context,
116178825Sdfr		 krb5_ccache id,
117178825Sdfr		 krb5_creds *creds)
118178825Sdfr{
119178825Sdfr    krb5_error_code ret;
120178825Sdfr    kcm_ccache c = KCMCACHE(id);
121178825Sdfr    krb5_creds *tmp;
122178825Sdfr
123178825Sdfr    KCM_ASSERT_VALID(c);
124178825Sdfr
125178825Sdfr    ret = kcm_ccache_store_cred_internal(context, c, creds, 1, &tmp);
126178825Sdfr
127178825Sdfr    return ret;
128178825Sdfr}
129178825Sdfr
130178825Sdfrstatic krb5_error_code
131178825Sdfrkcmss_retrieve(krb5_context context,
132178825Sdfr	       krb5_ccache id,
133178825Sdfr	       krb5_flags which,
134178825Sdfr	       const krb5_creds *mcred,
135178825Sdfr	       krb5_creds *creds)
136178825Sdfr{
137178825Sdfr    krb5_error_code ret;
138178825Sdfr    kcm_ccache c = KCMCACHE(id);
139178825Sdfr    krb5_creds *credp;
140178825Sdfr
141178825Sdfr    KCM_ASSERT_VALID(c);
142178825Sdfr
143178825Sdfr    ret = kcm_ccache_retrieve_cred_internal(context, c, which,
144178825Sdfr					    mcred, &credp);
145178825Sdfr    if (ret)
146178825Sdfr	return ret;
147178825Sdfr
148178825Sdfr    ret = krb5_copy_creds_contents(context, credp, creds);
149178825Sdfr    if (ret)
150178825Sdfr	return ret;
151178825Sdfr
152178825Sdfr    return 0;
153178825Sdfr}
154178825Sdfr
155178825Sdfrstatic krb5_error_code
156178825Sdfrkcmss_get_principal(krb5_context context,
157178825Sdfr		    krb5_ccache id,
158178825Sdfr		    krb5_principal *principal)
159178825Sdfr{
160178825Sdfr    krb5_error_code ret;
161178825Sdfr    kcm_ccache c = KCMCACHE(id);
162178825Sdfr
163178825Sdfr    KCM_ASSERT_VALID(c);
164178825Sdfr
165178825Sdfr    ret = krb5_copy_principal(context, c->client,
166178825Sdfr			      principal);
167178825Sdfr
168178825Sdfr    return ret;
169178825Sdfr}
170178825Sdfr
171178825Sdfrstatic krb5_error_code
172178825Sdfrkcmss_get_first (krb5_context context,
173178825Sdfr		 krb5_ccache id,
174178825Sdfr		 krb5_cc_cursor *cursor)
175178825Sdfr{
176178825Sdfr    kcm_ccache c = KCMCACHE(id);
177178825Sdfr
178178825Sdfr    KCM_ASSERT_VALID(c);
179178825Sdfr
180178825Sdfr    *cursor = c->creds;
181178825Sdfr
182178825Sdfr    return (*cursor == NULL) ? KRB5_CC_END : 0;
183178825Sdfr}
184178825Sdfr
185178825Sdfrstatic krb5_error_code
186178825Sdfrkcmss_get_next (krb5_context context,
187178825Sdfr		krb5_ccache id,
188178825Sdfr		krb5_cc_cursor *cursor,
189178825Sdfr		krb5_creds *creds)
190178825Sdfr{
191178825Sdfr    krb5_error_code ret;
192178825Sdfr    kcm_ccache c = KCMCACHE(id);
193178825Sdfr
194178825Sdfr    KCM_ASSERT_VALID(c);
195178825Sdfr
196178825Sdfr    ret = krb5_copy_creds_contents(context,
197178825Sdfr				   &((struct kcm_creds *)cursor)->cred,
198178825Sdfr				   creds);
199178825Sdfr    if (ret)
200178825Sdfr	return ret;
201178825Sdfr
202178825Sdfr    *cursor = ((struct kcm_creds *)cursor)->next;
203178825Sdfr    if (*cursor == 0)
204178825Sdfr	ret = KRB5_CC_END;
205178825Sdfr
206178825Sdfr    return ret;
207178825Sdfr}
208178825Sdfr
209178825Sdfrstatic krb5_error_code
210178825Sdfrkcmss_end_get (krb5_context context,
211178825Sdfr	       krb5_ccache id,
212178825Sdfr	       krb5_cc_cursor *cursor)
213178825Sdfr{
214178825Sdfr    *cursor = NULL;
215178825Sdfr    return 0;
216178825Sdfr}
217178825Sdfr
218178825Sdfrstatic krb5_error_code
219178825Sdfrkcmss_remove_cred(krb5_context context,
220178825Sdfr		  krb5_ccache id,
221178825Sdfr		  krb5_flags which,
222178825Sdfr		  krb5_creds *cred)
223178825Sdfr{
224178825Sdfr    krb5_error_code ret;
225178825Sdfr    kcm_ccache c = KCMCACHE(id);
226178825Sdfr
227178825Sdfr    KCM_ASSERT_VALID(c);
228178825Sdfr
229178825Sdfr    ret = kcm_ccache_remove_cred_internal(context, c, which, cred);
230178825Sdfr
231178825Sdfr    return ret;
232178825Sdfr}
233178825Sdfr
234178825Sdfrstatic krb5_error_code
235178825Sdfrkcmss_set_flags(krb5_context context,
236178825Sdfr		krb5_ccache id,
237178825Sdfr		krb5_flags flags)
238178825Sdfr{
239178825Sdfr    return 0;
240178825Sdfr}
241178825Sdfr
242178825Sdfrstatic krb5_error_code
243178825Sdfrkcmss_get_version(krb5_context context,
244178825Sdfr		  krb5_ccache id)
245178825Sdfr{
246178825Sdfr    return 0;
247178825Sdfr}
248178825Sdfr
249178825Sdfrstatic const krb5_cc_ops krb5_kcmss_ops = {
250233294Sstas    KRB5_CC_OPS_VERSION,
251178825Sdfr    "KCM",
252178825Sdfr    kcmss_get_name,
253178825Sdfr    kcmss_resolve,
254178825Sdfr    kcmss_gen_new,
255178825Sdfr    kcmss_initialize,
256178825Sdfr    kcmss_destroy,
257178825Sdfr    kcmss_close,
258178825Sdfr    kcmss_store_cred,
259178825Sdfr    kcmss_retrieve,
260178825Sdfr    kcmss_get_principal,
261178825Sdfr    kcmss_get_first,
262178825Sdfr    kcmss_get_next,
263178825Sdfr    kcmss_end_get,
264178825Sdfr    kcmss_remove_cred,
265178825Sdfr    kcmss_set_flags,
266178825Sdfr    kcmss_get_version
267178825Sdfr};
268178825Sdfr
269178825Sdfrkrb5_error_code
270178825Sdfrkcm_internal_ccache(krb5_context context,
271178825Sdfr		    kcm_ccache c,
272178825Sdfr		    krb5_ccache id)
273178825Sdfr{
274178825Sdfr    id->ops = &krb5_kcmss_ops;
275178825Sdfr    id->data.length = sizeof(*c);
276178825Sdfr    id->data.data = c;
277178825Sdfr
278178825Sdfr    return 0;
279178825Sdfr}
280178825Sdfr
281