xref: /netbsd-src/crypto/external/bsd/heimdal/dist/kcm/glue.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
1*afab4e30Schristos /*	$NetBSD: glue.c,v 1.4 2023/06/19 21:41:41 christos Exp $	*/
2ca1c9b0cSelric 
3ca1c9b0cSelric /*
4ca1c9b0cSelric  * Copyright (c) 2005, PADL Software Pty Ltd.
5ca1c9b0cSelric  * All rights reserved.
6ca1c9b0cSelric  *
7ca1c9b0cSelric  * Redistribution and use in source and binary forms, with or without
8ca1c9b0cSelric  * modification, are permitted provided that the following conditions
9ca1c9b0cSelric  * are met:
10ca1c9b0cSelric  *
11ca1c9b0cSelric  * 1. Redistributions of source code must retain the above copyright
12ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer.
13ca1c9b0cSelric  *
14ca1c9b0cSelric  * 2. Redistributions in binary form must reproduce the above copyright
15ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer in the
16ca1c9b0cSelric  *    documentation and/or other materials provided with the distribution.
17ca1c9b0cSelric  *
18ca1c9b0cSelric  * 3. Neither the name of PADL Software nor the names of its contributors
19ca1c9b0cSelric  *    may be used to endorse or promote products derived from this software
20ca1c9b0cSelric  *    without specific prior written permission.
21ca1c9b0cSelric  *
22ca1c9b0cSelric  * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
23ca1c9b0cSelric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24ca1c9b0cSelric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25ca1c9b0cSelric  * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
26ca1c9b0cSelric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27ca1c9b0cSelric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28ca1c9b0cSelric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29ca1c9b0cSelric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30ca1c9b0cSelric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31ca1c9b0cSelric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32ca1c9b0cSelric  * SUCH DAMAGE.
33ca1c9b0cSelric  */
34ca1c9b0cSelric 
35ca1c9b0cSelric #include "kcm_locl.h"
36ca1c9b0cSelric 
37*afab4e30Schristos __RCSID("$NetBSD: glue.c,v 1.4 2023/06/19 21:41:41 christos Exp $");
38ca1c9b0cSelric 
39ca1c9b0cSelric /*
40ca1c9b0cSelric  * Server-side loopback glue for credentials cache operations; this
41ca1c9b0cSelric  * must be initialized with kcm_internal_ccache(), it is not for real
42ca1c9b0cSelric  * use. This entire file assumes the cache is locked, it does not do
43ca1c9b0cSelric  * any concurrency checking for multithread applications.
44ca1c9b0cSelric  */
45ca1c9b0cSelric 
46ca1c9b0cSelric #define KCMCACHE(X)	((kcm_ccache)(X)->data.data)
47ca1c9b0cSelric #define CACHENAME(X)	(KCMCACHE(X)->name)
48ca1c9b0cSelric 
49ca1c9b0cSelric static const char *
kcmss_get_name(krb5_context context,krb5_ccache id)50ca1c9b0cSelric kcmss_get_name(krb5_context context,
51ca1c9b0cSelric 	       krb5_ccache id)
52ca1c9b0cSelric {
53ca1c9b0cSelric     return CACHENAME(id);
54ca1c9b0cSelric }
55ca1c9b0cSelric 
56ca1c9b0cSelric static krb5_error_code
kcmss_resolve(krb5_context context,krb5_ccache * id,const char * res)57ca1c9b0cSelric kcmss_resolve(krb5_context context, krb5_ccache *id, const char *res)
58ca1c9b0cSelric {
59ca1c9b0cSelric     return KRB5_FCC_INTERNAL;
60ca1c9b0cSelric }
61ca1c9b0cSelric 
62ca1c9b0cSelric static krb5_error_code
kcmss_gen_new(krb5_context context,krb5_ccache * id)63ca1c9b0cSelric kcmss_gen_new(krb5_context context, krb5_ccache *id)
64ca1c9b0cSelric {
65ca1c9b0cSelric     return KRB5_FCC_INTERNAL;
66ca1c9b0cSelric }
67ca1c9b0cSelric 
68ca1c9b0cSelric static krb5_error_code
kcmss_initialize(krb5_context context,krb5_ccache id,krb5_principal primary_principal)69ca1c9b0cSelric kcmss_initialize(krb5_context context,
70ca1c9b0cSelric 		 krb5_ccache id,
71ca1c9b0cSelric 		 krb5_principal primary_principal)
72ca1c9b0cSelric {
73ca1c9b0cSelric     krb5_error_code ret;
74ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
75ca1c9b0cSelric 
76ca1c9b0cSelric     KCM_ASSERT_VALID(c);
77ca1c9b0cSelric 
78ca1c9b0cSelric     ret = kcm_zero_ccache_data_internal(context, c);
79ca1c9b0cSelric     if (ret)
80ca1c9b0cSelric 	return ret;
81ca1c9b0cSelric 
82ca1c9b0cSelric     ret = krb5_copy_principal(context, primary_principal,
83ca1c9b0cSelric 			      &c->client);
84ca1c9b0cSelric 
85ca1c9b0cSelric     return ret;
86ca1c9b0cSelric }
87ca1c9b0cSelric 
88ca1c9b0cSelric static krb5_error_code
kcmss_close(krb5_context context,krb5_ccache id)89ca1c9b0cSelric kcmss_close(krb5_context context,
90ca1c9b0cSelric 	    krb5_ccache id)
91ca1c9b0cSelric {
92ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
93ca1c9b0cSelric 
94ca1c9b0cSelric     KCM_ASSERT_VALID(c);
95ca1c9b0cSelric 
96ca1c9b0cSelric     id->data.data = NULL;
97ca1c9b0cSelric     id->data.length = 0;
98ca1c9b0cSelric 
99ca1c9b0cSelric     return 0;
100ca1c9b0cSelric }
101ca1c9b0cSelric 
102ca1c9b0cSelric static krb5_error_code
kcmss_destroy(krb5_context context,krb5_ccache id)103ca1c9b0cSelric kcmss_destroy(krb5_context context,
104ca1c9b0cSelric 	      krb5_ccache id)
105ca1c9b0cSelric {
106ca1c9b0cSelric     krb5_error_code ret;
107ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
108ca1c9b0cSelric 
109ca1c9b0cSelric     KCM_ASSERT_VALID(c);
110ca1c9b0cSelric 
111ca1c9b0cSelric     ret = kcm_ccache_destroy(context, CACHENAME(id));
112ca1c9b0cSelric 
113ca1c9b0cSelric     return ret;
114ca1c9b0cSelric }
115ca1c9b0cSelric 
116ca1c9b0cSelric static krb5_error_code
kcmss_store_cred(krb5_context context,krb5_ccache id,krb5_creds * creds)117ca1c9b0cSelric kcmss_store_cred(krb5_context context,
118ca1c9b0cSelric 		 krb5_ccache id,
119ca1c9b0cSelric 		 krb5_creds *creds)
120ca1c9b0cSelric {
121ca1c9b0cSelric     krb5_error_code ret;
122ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
123ca1c9b0cSelric     krb5_creds *tmp;
124ca1c9b0cSelric 
125ca1c9b0cSelric     KCM_ASSERT_VALID(c);
126ca1c9b0cSelric 
127ca1c9b0cSelric     ret = kcm_ccache_store_cred_internal(context, c, creds, 1, &tmp);
128ca1c9b0cSelric 
129ca1c9b0cSelric     return ret;
130ca1c9b0cSelric }
131ca1c9b0cSelric 
132ca1c9b0cSelric static krb5_error_code
kcmss_retrieve(krb5_context context,krb5_ccache id,krb5_flags which,const krb5_creds * mcred,krb5_creds * creds)133ca1c9b0cSelric kcmss_retrieve(krb5_context context,
134ca1c9b0cSelric 	       krb5_ccache id,
135ca1c9b0cSelric 	       krb5_flags which,
136ca1c9b0cSelric 	       const krb5_creds *mcred,
137ca1c9b0cSelric 	       krb5_creds *creds)
138ca1c9b0cSelric {
139ca1c9b0cSelric     krb5_error_code ret;
140ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
141ca1c9b0cSelric     krb5_creds *credp;
142ca1c9b0cSelric 
143ca1c9b0cSelric     KCM_ASSERT_VALID(c);
144ca1c9b0cSelric 
145ca1c9b0cSelric     ret = kcm_ccache_retrieve_cred_internal(context, c, which,
146ca1c9b0cSelric 					    mcred, &credp);
147ca1c9b0cSelric     if (ret)
148ca1c9b0cSelric 	return ret;
149ca1c9b0cSelric 
150ca1c9b0cSelric     ret = krb5_copy_creds_contents(context, credp, creds);
151ca1c9b0cSelric     if (ret)
152ca1c9b0cSelric 	return ret;
153ca1c9b0cSelric 
154ca1c9b0cSelric     return 0;
155ca1c9b0cSelric }
156ca1c9b0cSelric 
157ca1c9b0cSelric static krb5_error_code
kcmss_get_principal(krb5_context context,krb5_ccache id,krb5_principal * principal)158ca1c9b0cSelric kcmss_get_principal(krb5_context context,
159ca1c9b0cSelric 		    krb5_ccache id,
160ca1c9b0cSelric 		    krb5_principal *principal)
161ca1c9b0cSelric {
162ca1c9b0cSelric     krb5_error_code ret;
163ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
164ca1c9b0cSelric 
165ca1c9b0cSelric     KCM_ASSERT_VALID(c);
166ca1c9b0cSelric 
167ca1c9b0cSelric     ret = krb5_copy_principal(context, c->client,
168ca1c9b0cSelric 			      principal);
169ca1c9b0cSelric 
170ca1c9b0cSelric     return ret;
171ca1c9b0cSelric }
172ca1c9b0cSelric 
173ca1c9b0cSelric static krb5_error_code
kcmss_get_first(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)174ca1c9b0cSelric kcmss_get_first (krb5_context context,
175ca1c9b0cSelric 		 krb5_ccache id,
176ca1c9b0cSelric 		 krb5_cc_cursor *cursor)
177ca1c9b0cSelric {
178ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
179ca1c9b0cSelric 
180ca1c9b0cSelric     KCM_ASSERT_VALID(c);
181ca1c9b0cSelric 
182ca1c9b0cSelric     *cursor = c->creds;
183ca1c9b0cSelric 
184ca1c9b0cSelric     return (*cursor == NULL) ? KRB5_CC_END : 0;
185ca1c9b0cSelric }
186ca1c9b0cSelric 
187ca1c9b0cSelric static krb5_error_code
kcmss_get_next(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor,krb5_creds * creds)188ca1c9b0cSelric kcmss_get_next (krb5_context context,
189ca1c9b0cSelric 		krb5_ccache id,
190ca1c9b0cSelric 		krb5_cc_cursor *cursor,
191ca1c9b0cSelric 		krb5_creds *creds)
192ca1c9b0cSelric {
193ca1c9b0cSelric     krb5_error_code ret;
194ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
195ca1c9b0cSelric 
196ca1c9b0cSelric     KCM_ASSERT_VALID(c);
197ca1c9b0cSelric 
198ca1c9b0cSelric     ret = krb5_copy_creds_contents(context,
199ca1c9b0cSelric 				   &((struct kcm_creds *)cursor)->cred,
200ca1c9b0cSelric 				   creds);
201ca1c9b0cSelric     if (ret)
202ca1c9b0cSelric 	return ret;
203ca1c9b0cSelric 
204ca1c9b0cSelric     *cursor = ((struct kcm_creds *)cursor)->next;
205ca1c9b0cSelric     if (*cursor == 0)
206ca1c9b0cSelric 	ret = KRB5_CC_END;
207ca1c9b0cSelric 
208ca1c9b0cSelric     return ret;
209ca1c9b0cSelric }
210ca1c9b0cSelric 
211ca1c9b0cSelric static krb5_error_code
kcmss_end_get(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)212ca1c9b0cSelric kcmss_end_get (krb5_context context,
213ca1c9b0cSelric 	       krb5_ccache id,
214ca1c9b0cSelric 	       krb5_cc_cursor *cursor)
215ca1c9b0cSelric {
216ca1c9b0cSelric     *cursor = NULL;
217ca1c9b0cSelric     return 0;
218ca1c9b0cSelric }
219ca1c9b0cSelric 
220ca1c9b0cSelric static krb5_error_code
kcmss_remove_cred(krb5_context context,krb5_ccache id,krb5_flags which,krb5_creds * cred)221ca1c9b0cSelric kcmss_remove_cred(krb5_context context,
222ca1c9b0cSelric 		  krb5_ccache id,
223ca1c9b0cSelric 		  krb5_flags which,
224ca1c9b0cSelric 		  krb5_creds *cred)
225ca1c9b0cSelric {
226ca1c9b0cSelric     krb5_error_code ret;
227ca1c9b0cSelric     kcm_ccache c = KCMCACHE(id);
228ca1c9b0cSelric 
229ca1c9b0cSelric     KCM_ASSERT_VALID(c);
230ca1c9b0cSelric 
231ca1c9b0cSelric     ret = kcm_ccache_remove_cred_internal(context, c, which, cred);
232ca1c9b0cSelric 
233ca1c9b0cSelric     return ret;
234ca1c9b0cSelric }
235ca1c9b0cSelric 
236ca1c9b0cSelric static krb5_error_code
kcmss_set_flags(krb5_context context,krb5_ccache id,krb5_flags flags)237ca1c9b0cSelric kcmss_set_flags(krb5_context context,
238ca1c9b0cSelric 		krb5_ccache id,
239ca1c9b0cSelric 		krb5_flags flags)
240ca1c9b0cSelric {
241ca1c9b0cSelric     return 0;
242ca1c9b0cSelric }
243ca1c9b0cSelric 
244ca1c9b0cSelric static krb5_error_code
kcmss_get_version(krb5_context context,krb5_ccache id)245ca1c9b0cSelric kcmss_get_version(krb5_context context,
246ca1c9b0cSelric 		  krb5_ccache id)
247ca1c9b0cSelric {
248ca1c9b0cSelric     return 0;
249ca1c9b0cSelric }
250ca1c9b0cSelric 
251db50f768Schristos static krb5_error_code
kcmss_get_kdc_sec_offset(krb5_context context,krb5_ccache id,krb5_deltat * t)252db50f768Schristos kcmss_get_kdc_sec_offset(krb5_context context,
253db50f768Schristos 			 krb5_ccache id,
254db50f768Schristos 			 krb5_deltat *t)
255db50f768Schristos {
256db50f768Schristos     kcm_ccache c = KCMCACHE(id);
257db50f768Schristos 
258db50f768Schristos     KCM_ASSERT_VALID(c);
259db50f768Schristos 
260db50f768Schristos     *t = c->kdc_offset;
261db50f768Schristos 
262db50f768Schristos     return 0;
263db50f768Schristos }
264db50f768Schristos 
265db50f768Schristos static krb5_error_code
kcmss_set_kdc_sec_offset(krb5_context context,krb5_ccache id,krb5_deltat t)266db50f768Schristos kcmss_set_kdc_sec_offset(krb5_context context,
267db50f768Schristos 			 krb5_ccache id, krb5_deltat t)
268db50f768Schristos {
269db50f768Schristos     kcm_ccache c = KCMCACHE(id);
270db50f768Schristos 
271db50f768Schristos     KCM_ASSERT_VALID(c);
272db50f768Schristos 
273db50f768Schristos     c->kdc_offset = t;
274db50f768Schristos 
275db50f768Schristos     return 0;
276db50f768Schristos }
277db50f768Schristos 
278ca1c9b0cSelric static const krb5_cc_ops krb5_kcmss_ops = {
279db50f768Schristos     .version =		KRB5_CC_OPS_VERSION,
280db50f768Schristos     .prefix =		"KCM",
281db50f768Schristos     .get_name =		kcmss_get_name,
282db50f768Schristos     .resolve =		kcmss_resolve,
283db50f768Schristos     .gen_new =		kcmss_gen_new,
284db50f768Schristos     .init =		kcmss_initialize,
285db50f768Schristos     .destroy =		kcmss_destroy,
286db50f768Schristos     .close =		kcmss_close,
287db50f768Schristos     .store =		kcmss_store_cred,
288db50f768Schristos     .retrieve =		kcmss_retrieve,
289db50f768Schristos     .get_princ =	kcmss_get_principal,
290db50f768Schristos     .get_first =	kcmss_get_first,
291db50f768Schristos     .get_next =		kcmss_get_next,
292db50f768Schristos     .end_get =		kcmss_end_get,
293db50f768Schristos     .remove_cred =	kcmss_remove_cred,
294db50f768Schristos     .set_flags =	kcmss_set_flags,
295db50f768Schristos     .get_version =	kcmss_get_version,
296db50f768Schristos     .get_cache_first =	NULL,
297db50f768Schristos     .get_cache_next =	NULL,
298db50f768Schristos     .end_cache_get =	NULL,
299db50f768Schristos     .move =		NULL,
300db50f768Schristos     .get_default_name =	NULL,
301db50f768Schristos     .set_default =	NULL,
302db50f768Schristos     .lastchange =	NULL,
303db50f768Schristos     .set_kdc_offset =	kcmss_set_kdc_sec_offset,
304db50f768Schristos     .get_kdc_offset =	kcmss_get_kdc_sec_offset,
305ca1c9b0cSelric };
306ca1c9b0cSelric 
307ca1c9b0cSelric krb5_error_code
kcm_internal_ccache(krb5_context context,kcm_ccache c,krb5_ccache id)308ca1c9b0cSelric kcm_internal_ccache(krb5_context context,
309ca1c9b0cSelric 		    kcm_ccache c,
310ca1c9b0cSelric 		    krb5_ccache id)
311ca1c9b0cSelric {
312ca1c9b0cSelric     id->ops = &krb5_kcmss_ops;
313ca1c9b0cSelric     id->data.length = sizeof(*c);
314ca1c9b0cSelric     id->data.data = c;
315ca1c9b0cSelric 
316ca1c9b0cSelric     return 0;
317ca1c9b0cSelric }
318ca1c9b0cSelric 
319