1c19800e8SDoug Rabson /*
2c19800e8SDoug Rabson * Copyright (c) 2005, PADL Software Pty Ltd.
3c19800e8SDoug Rabson * All rights reserved.
4c19800e8SDoug Rabson *
5*ae771770SStanislav Sedov * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
6*ae771770SStanislav Sedov *
7c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without
8c19800e8SDoug Rabson * modification, are permitted provided that the following conditions
9c19800e8SDoug Rabson * are met:
10c19800e8SDoug Rabson *
11c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright
12c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer.
13c19800e8SDoug Rabson *
14c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
15c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the
16c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution.
17c19800e8SDoug Rabson *
18c19800e8SDoug Rabson * 3. Neither the name of PADL Software nor the names of its contributors
19c19800e8SDoug Rabson * may be used to endorse or promote products derived from this software
20c19800e8SDoug Rabson * without specific prior written permission.
21c19800e8SDoug Rabson *
22c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
23c19800e8SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25c19800e8SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
26c19800e8SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27c19800e8SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28c19800e8SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29c19800e8SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30c19800e8SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31c19800e8SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32c19800e8SDoug Rabson * SUCH DAMAGE.
33c19800e8SDoug Rabson */
34c19800e8SDoug Rabson
35c19800e8SDoug Rabson #include "krb5_locl.h"
36c19800e8SDoug Rabson
37c19800e8SDoug Rabson #ifdef HAVE_KCM
38c19800e8SDoug Rabson /*
39c19800e8SDoug Rabson * Client library for Kerberos Credentials Manager (KCM) daemon
40c19800e8SDoug Rabson */
41c19800e8SDoug Rabson
42c19800e8SDoug Rabson #include "kcm.h"
43*ae771770SStanislav Sedov #include <heim-ipc.h>
44c19800e8SDoug Rabson
45*ae771770SStanislav Sedov static krb5_error_code
46*ae771770SStanislav Sedov kcm_set_kdc_offset(krb5_context, krb5_ccache, krb5_deltat);
47*ae771770SStanislav Sedov
48*ae771770SStanislav Sedov static const char *kcm_ipc_name = "ANY:org.h5l.kcm";
49c19800e8SDoug Rabson
50c19800e8SDoug Rabson typedef struct krb5_kcmcache {
51c19800e8SDoug Rabson char *name;
52c19800e8SDoug Rabson } krb5_kcmcache;
53c19800e8SDoug Rabson
54*ae771770SStanislav Sedov typedef struct krb5_kcm_cursor {
55*ae771770SStanislav Sedov unsigned long offset;
56*ae771770SStanislav Sedov unsigned long length;
57*ae771770SStanislav Sedov kcmuuid_t *uuids;
58*ae771770SStanislav Sedov } *krb5_kcm_cursor;
59*ae771770SStanislav Sedov
60*ae771770SStanislav Sedov
61c19800e8SDoug Rabson #define KCMCACHE(X) ((krb5_kcmcache *)(X)->data.data)
62c19800e8SDoug Rabson #define CACHENAME(X) (KCMCACHE(X)->name)
63*ae771770SStanislav Sedov #define KCMCURSOR(C) ((krb5_kcm_cursor)(C))
64c19800e8SDoug Rabson
65*ae771770SStanislav Sedov static HEIMDAL_MUTEX kcm_mutex = HEIMDAL_MUTEX_INITIALIZER;
66*ae771770SStanislav Sedov static heim_ipc kcm_ipc = NULL;
67c19800e8SDoug Rabson
68c19800e8SDoug Rabson static krb5_error_code
kcm_send_request(krb5_context context,krb5_storage * request,krb5_data * response_data)69c19800e8SDoug Rabson kcm_send_request(krb5_context context,
70c19800e8SDoug Rabson krb5_storage *request,
71c19800e8SDoug Rabson krb5_data *response_data)
72c19800e8SDoug Rabson {
73*ae771770SStanislav Sedov krb5_error_code ret = 0;
74c19800e8SDoug Rabson krb5_data request_data;
75c19800e8SDoug Rabson
76*ae771770SStanislav Sedov HEIMDAL_MUTEX_lock(&kcm_mutex);
77*ae771770SStanislav Sedov if (kcm_ipc == NULL)
78*ae771770SStanislav Sedov ret = heim_ipc_init_context(kcm_ipc_name, &kcm_ipc);
79*ae771770SStanislav Sedov HEIMDAL_MUTEX_unlock(&kcm_mutex);
80*ae771770SStanislav Sedov if (ret)
81*ae771770SStanislav Sedov return KRB5_CC_NOSUPP;
82c19800e8SDoug Rabson
83c19800e8SDoug Rabson ret = krb5_storage_to_data(request, &request_data);
84c19800e8SDoug Rabson if (ret) {
85*ae771770SStanislav Sedov krb5_clear_error_message(context);
86c19800e8SDoug Rabson return KRB5_CC_NOMEM;
87c19800e8SDoug Rabson }
88c19800e8SDoug Rabson
89*ae771770SStanislav Sedov ret = heim_ipc_call(kcm_ipc, &request_data, response_data, NULL);
90c19800e8SDoug Rabson krb5_data_free(&request_data);
91c19800e8SDoug Rabson
92c19800e8SDoug Rabson if (ret) {
93*ae771770SStanislav Sedov krb5_clear_error_message(context);
94*ae771770SStanislav Sedov ret = KRB5_CC_NOSUPP;
95c19800e8SDoug Rabson }
96c19800e8SDoug Rabson
97c19800e8SDoug Rabson return ret;
98c19800e8SDoug Rabson }
99c19800e8SDoug Rabson
100*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kcm_storage_request(krb5_context context,uint16_t opcode,krb5_storage ** storage_p)101*ae771770SStanislav Sedov krb5_kcm_storage_request(krb5_context context,
102*ae771770SStanislav Sedov uint16_t opcode,
103c19800e8SDoug Rabson krb5_storage **storage_p)
104c19800e8SDoug Rabson {
105c19800e8SDoug Rabson krb5_storage *sp;
106c19800e8SDoug Rabson krb5_error_code ret;
107c19800e8SDoug Rabson
108c19800e8SDoug Rabson *storage_p = NULL;
109c19800e8SDoug Rabson
110c19800e8SDoug Rabson sp = krb5_storage_emem();
111c19800e8SDoug Rabson if (sp == NULL) {
112*ae771770SStanislav Sedov krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", ""));
113c19800e8SDoug Rabson return KRB5_CC_NOMEM;
114c19800e8SDoug Rabson }
115c19800e8SDoug Rabson
116c19800e8SDoug Rabson /* Send MAJOR | VERSION | OPCODE */
117c19800e8SDoug Rabson ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
118c19800e8SDoug Rabson if (ret)
119c19800e8SDoug Rabson goto fail;
120c19800e8SDoug Rabson ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
121c19800e8SDoug Rabson if (ret)
122c19800e8SDoug Rabson goto fail;
123c19800e8SDoug Rabson ret = krb5_store_int16(sp, opcode);
124c19800e8SDoug Rabson if (ret)
125c19800e8SDoug Rabson goto fail;
126c19800e8SDoug Rabson
127c19800e8SDoug Rabson *storage_p = sp;
128c19800e8SDoug Rabson fail:
129c19800e8SDoug Rabson if (ret) {
130*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
131*ae771770SStanislav Sedov N_("Failed to encode KCM request", ""));
132c19800e8SDoug Rabson krb5_storage_free(sp);
133c19800e8SDoug Rabson }
134c19800e8SDoug Rabson
135c19800e8SDoug Rabson return ret;
136c19800e8SDoug Rabson }
137c19800e8SDoug Rabson
138c19800e8SDoug Rabson static krb5_error_code
kcm_alloc(krb5_context context,const char * name,krb5_ccache * id)139c19800e8SDoug Rabson kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
140c19800e8SDoug Rabson {
141c19800e8SDoug Rabson krb5_kcmcache *k;
142c19800e8SDoug Rabson
143c19800e8SDoug Rabson k = malloc(sizeof(*k));
144c19800e8SDoug Rabson if (k == NULL) {
145*ae771770SStanislav Sedov krb5_set_error_message(context, KRB5_CC_NOMEM,
146*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
147c19800e8SDoug Rabson return KRB5_CC_NOMEM;
148c19800e8SDoug Rabson }
149c19800e8SDoug Rabson
150c19800e8SDoug Rabson if (name != NULL) {
151c19800e8SDoug Rabson k->name = strdup(name);
152c19800e8SDoug Rabson if (k->name == NULL) {
153c19800e8SDoug Rabson free(k);
154*ae771770SStanislav Sedov krb5_set_error_message(context, KRB5_CC_NOMEM,
155*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
156c19800e8SDoug Rabson return KRB5_CC_NOMEM;
157c19800e8SDoug Rabson }
158c19800e8SDoug Rabson } else
159c19800e8SDoug Rabson k->name = NULL;
160c19800e8SDoug Rabson
161c19800e8SDoug Rabson (*id)->data.data = k;
162c19800e8SDoug Rabson (*id)->data.length = sizeof(*k);
163c19800e8SDoug Rabson
164c19800e8SDoug Rabson return 0;
165c19800e8SDoug Rabson }
166c19800e8SDoug Rabson
167*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kcm_call(krb5_context context,krb5_storage * request,krb5_storage ** response_p,krb5_data * response_data_p)168*ae771770SStanislav Sedov krb5_kcm_call(krb5_context context,
169c19800e8SDoug Rabson krb5_storage *request,
170c19800e8SDoug Rabson krb5_storage **response_p,
171c19800e8SDoug Rabson krb5_data *response_data_p)
172c19800e8SDoug Rabson {
173c19800e8SDoug Rabson krb5_data response_data;
174c19800e8SDoug Rabson krb5_error_code ret;
175c19800e8SDoug Rabson int32_t status;
176c19800e8SDoug Rabson krb5_storage *response;
177c19800e8SDoug Rabson
178c19800e8SDoug Rabson if (response_p != NULL)
179c19800e8SDoug Rabson *response_p = NULL;
180c19800e8SDoug Rabson
181*ae771770SStanislav Sedov krb5_data_zero(&response_data);
182*ae771770SStanislav Sedov
183*ae771770SStanislav Sedov ret = kcm_send_request(context, request, &response_data);
184*ae771770SStanislav Sedov if (ret)
185c19800e8SDoug Rabson return ret;
186c19800e8SDoug Rabson
187c19800e8SDoug Rabson response = krb5_storage_from_data(&response_data);
188c19800e8SDoug Rabson if (response == NULL) {
189c19800e8SDoug Rabson krb5_data_free(&response_data);
190c19800e8SDoug Rabson return KRB5_CC_IO;
191c19800e8SDoug Rabson }
192c19800e8SDoug Rabson
193c19800e8SDoug Rabson ret = krb5_ret_int32(response, &status);
194c19800e8SDoug Rabson if (ret) {
195c19800e8SDoug Rabson krb5_storage_free(response);
196c19800e8SDoug Rabson krb5_data_free(&response_data);
197c19800e8SDoug Rabson return KRB5_CC_FORMAT;
198c19800e8SDoug Rabson }
199c19800e8SDoug Rabson
200c19800e8SDoug Rabson if (status) {
201c19800e8SDoug Rabson krb5_storage_free(response);
202c19800e8SDoug Rabson krb5_data_free(&response_data);
203c19800e8SDoug Rabson return status;
204c19800e8SDoug Rabson }
205c19800e8SDoug Rabson
206c19800e8SDoug Rabson if (response_p != NULL) {
207c19800e8SDoug Rabson *response_data_p = response_data;
208c19800e8SDoug Rabson *response_p = response;
209c19800e8SDoug Rabson
210c19800e8SDoug Rabson return 0;
211c19800e8SDoug Rabson }
212c19800e8SDoug Rabson
213c19800e8SDoug Rabson krb5_storage_free(response);
214c19800e8SDoug Rabson krb5_data_free(&response_data);
215c19800e8SDoug Rabson
216c19800e8SDoug Rabson return 0;
217c19800e8SDoug Rabson }
218c19800e8SDoug Rabson
219c19800e8SDoug Rabson static void
kcm_free(krb5_context context,krb5_ccache * id)220c19800e8SDoug Rabson kcm_free(krb5_context context, krb5_ccache *id)
221c19800e8SDoug Rabson {
222c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(*id);
223c19800e8SDoug Rabson
224c19800e8SDoug Rabson if (k != NULL) {
225c19800e8SDoug Rabson if (k->name != NULL)
226c19800e8SDoug Rabson free(k->name);
227c19800e8SDoug Rabson memset(k, 0, sizeof(*k));
228c19800e8SDoug Rabson krb5_data_free(&(*id)->data);
229c19800e8SDoug Rabson }
230c19800e8SDoug Rabson }
231c19800e8SDoug Rabson
232c19800e8SDoug Rabson static const char *
kcm_get_name(krb5_context context,krb5_ccache id)233c19800e8SDoug Rabson kcm_get_name(krb5_context context,
234c19800e8SDoug Rabson krb5_ccache id)
235c19800e8SDoug Rabson {
236c19800e8SDoug Rabson return CACHENAME(id);
237c19800e8SDoug Rabson }
238c19800e8SDoug Rabson
239c19800e8SDoug Rabson static krb5_error_code
kcm_resolve(krb5_context context,krb5_ccache * id,const char * res)240c19800e8SDoug Rabson kcm_resolve(krb5_context context, krb5_ccache *id, const char *res)
241c19800e8SDoug Rabson {
242c19800e8SDoug Rabson return kcm_alloc(context, res, id);
243c19800e8SDoug Rabson }
244c19800e8SDoug Rabson
245c19800e8SDoug Rabson /*
246c19800e8SDoug Rabson * Request:
247c19800e8SDoug Rabson *
248c19800e8SDoug Rabson * Response:
249c19800e8SDoug Rabson * NameZ
250c19800e8SDoug Rabson */
251c19800e8SDoug Rabson static krb5_error_code
kcm_gen_new(krb5_context context,krb5_ccache * id)252c19800e8SDoug Rabson kcm_gen_new(krb5_context context, krb5_ccache *id)
253c19800e8SDoug Rabson {
254c19800e8SDoug Rabson krb5_kcmcache *k;
255c19800e8SDoug Rabson krb5_error_code ret;
256c19800e8SDoug Rabson krb5_storage *request, *response;
257c19800e8SDoug Rabson krb5_data response_data;
258c19800e8SDoug Rabson
259c19800e8SDoug Rabson ret = kcm_alloc(context, NULL, id);
260c19800e8SDoug Rabson if (ret)
261c19800e8SDoug Rabson return ret;
262c19800e8SDoug Rabson
263c19800e8SDoug Rabson k = KCMCACHE(*id);
264c19800e8SDoug Rabson
265*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GEN_NEW, &request);
266c19800e8SDoug Rabson if (ret) {
267c19800e8SDoug Rabson kcm_free(context, id);
268c19800e8SDoug Rabson return ret;
269c19800e8SDoug Rabson }
270c19800e8SDoug Rabson
271*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
272c19800e8SDoug Rabson if (ret) {
273c19800e8SDoug Rabson krb5_storage_free(request);
274c19800e8SDoug Rabson kcm_free(context, id);
275c19800e8SDoug Rabson return ret;
276c19800e8SDoug Rabson }
277c19800e8SDoug Rabson
278c19800e8SDoug Rabson ret = krb5_ret_stringz(response, &k->name);
279c19800e8SDoug Rabson if (ret)
280c19800e8SDoug Rabson ret = KRB5_CC_IO;
281c19800e8SDoug Rabson
282c19800e8SDoug Rabson krb5_storage_free(request);
283c19800e8SDoug Rabson krb5_storage_free(response);
284c19800e8SDoug Rabson krb5_data_free(&response_data);
285c19800e8SDoug Rabson
286c19800e8SDoug Rabson if (ret)
287c19800e8SDoug Rabson kcm_free(context, id);
288c19800e8SDoug Rabson
289c19800e8SDoug Rabson return ret;
290c19800e8SDoug Rabson }
291c19800e8SDoug Rabson
292c19800e8SDoug Rabson /*
293c19800e8SDoug Rabson * Request:
294c19800e8SDoug Rabson * NameZ
295c19800e8SDoug Rabson * Principal
296c19800e8SDoug Rabson *
297c19800e8SDoug Rabson * Response:
298c19800e8SDoug Rabson *
299c19800e8SDoug Rabson */
300c19800e8SDoug Rabson static krb5_error_code
kcm_initialize(krb5_context context,krb5_ccache id,krb5_principal primary_principal)301c19800e8SDoug Rabson kcm_initialize(krb5_context context,
302c19800e8SDoug Rabson krb5_ccache id,
303c19800e8SDoug Rabson krb5_principal primary_principal)
304c19800e8SDoug Rabson {
305c19800e8SDoug Rabson krb5_error_code ret;
306c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
307c19800e8SDoug Rabson krb5_storage *request;
308c19800e8SDoug Rabson
309*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_INITIALIZE, &request);
310c19800e8SDoug Rabson if (ret)
311c19800e8SDoug Rabson return ret;
312c19800e8SDoug Rabson
313c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
314c19800e8SDoug Rabson if (ret) {
315c19800e8SDoug Rabson krb5_storage_free(request);
316c19800e8SDoug Rabson return ret;
317c19800e8SDoug Rabson }
318c19800e8SDoug Rabson
319c19800e8SDoug Rabson ret = krb5_store_principal(request, primary_principal);
320c19800e8SDoug Rabson if (ret) {
321c19800e8SDoug Rabson krb5_storage_free(request);
322c19800e8SDoug Rabson return ret;
323c19800e8SDoug Rabson }
324c19800e8SDoug Rabson
325*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
326c19800e8SDoug Rabson
327c19800e8SDoug Rabson krb5_storage_free(request);
328*ae771770SStanislav Sedov
329*ae771770SStanislav Sedov if (context->kdc_sec_offset)
330*ae771770SStanislav Sedov kcm_set_kdc_offset(context, id, context->kdc_sec_offset);
331*ae771770SStanislav Sedov
332c19800e8SDoug Rabson return ret;
333c19800e8SDoug Rabson }
334c19800e8SDoug Rabson
335c19800e8SDoug Rabson static krb5_error_code
kcm_close(krb5_context context,krb5_ccache id)336c19800e8SDoug Rabson kcm_close(krb5_context context,
337c19800e8SDoug Rabson krb5_ccache id)
338c19800e8SDoug Rabson {
339c19800e8SDoug Rabson kcm_free(context, &id);
340c19800e8SDoug Rabson return 0;
341c19800e8SDoug Rabson }
342c19800e8SDoug Rabson
343c19800e8SDoug Rabson /*
344c19800e8SDoug Rabson * Request:
345c19800e8SDoug Rabson * NameZ
346c19800e8SDoug Rabson *
347c19800e8SDoug Rabson * Response:
348c19800e8SDoug Rabson *
349c19800e8SDoug Rabson */
350c19800e8SDoug Rabson static krb5_error_code
kcm_destroy(krb5_context context,krb5_ccache id)351c19800e8SDoug Rabson kcm_destroy(krb5_context context,
352c19800e8SDoug Rabson krb5_ccache id)
353c19800e8SDoug Rabson {
354c19800e8SDoug Rabson krb5_error_code ret;
355c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
356c19800e8SDoug Rabson krb5_storage *request;
357c19800e8SDoug Rabson
358*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_DESTROY, &request);
359c19800e8SDoug Rabson if (ret)
360c19800e8SDoug Rabson return ret;
361c19800e8SDoug Rabson
362c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
363c19800e8SDoug Rabson if (ret) {
364c19800e8SDoug Rabson krb5_storage_free(request);
365c19800e8SDoug Rabson return ret;
366c19800e8SDoug Rabson }
367c19800e8SDoug Rabson
368*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
369c19800e8SDoug Rabson
370c19800e8SDoug Rabson krb5_storage_free(request);
371c19800e8SDoug Rabson return ret;
372c19800e8SDoug Rabson }
373c19800e8SDoug Rabson
374c19800e8SDoug Rabson /*
375c19800e8SDoug Rabson * Request:
376c19800e8SDoug Rabson * NameZ
377c19800e8SDoug Rabson * Creds
378c19800e8SDoug Rabson *
379c19800e8SDoug Rabson * Response:
380c19800e8SDoug Rabson *
381c19800e8SDoug Rabson */
382c19800e8SDoug Rabson static krb5_error_code
kcm_store_cred(krb5_context context,krb5_ccache id,krb5_creds * creds)383c19800e8SDoug Rabson kcm_store_cred(krb5_context context,
384c19800e8SDoug Rabson krb5_ccache id,
385c19800e8SDoug Rabson krb5_creds *creds)
386c19800e8SDoug Rabson {
387c19800e8SDoug Rabson krb5_error_code ret;
388c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
389c19800e8SDoug Rabson krb5_storage *request;
390c19800e8SDoug Rabson
391*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_STORE, &request);
392c19800e8SDoug Rabson if (ret)
393c19800e8SDoug Rabson return ret;
394c19800e8SDoug Rabson
395c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
396c19800e8SDoug Rabson if (ret) {
397c19800e8SDoug Rabson krb5_storage_free(request);
398c19800e8SDoug Rabson return ret;
399c19800e8SDoug Rabson }
400c19800e8SDoug Rabson
401c19800e8SDoug Rabson ret = krb5_store_creds(request, creds);
402c19800e8SDoug Rabson if (ret) {
403c19800e8SDoug Rabson krb5_storage_free(request);
404c19800e8SDoug Rabson return ret;
405c19800e8SDoug Rabson }
406c19800e8SDoug Rabson
407*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
408c19800e8SDoug Rabson
409c19800e8SDoug Rabson krb5_storage_free(request);
410c19800e8SDoug Rabson return ret;
411c19800e8SDoug Rabson }
412c19800e8SDoug Rabson
413*ae771770SStanislav Sedov #if 0
414c19800e8SDoug Rabson /*
415c19800e8SDoug Rabson * Request:
416c19800e8SDoug Rabson * NameZ
417c19800e8SDoug Rabson * WhichFields
418c19800e8SDoug Rabson * MatchCreds
419c19800e8SDoug Rabson *
420c19800e8SDoug Rabson * Response:
421c19800e8SDoug Rabson * Creds
422c19800e8SDoug Rabson *
423c19800e8SDoug Rabson */
424c19800e8SDoug Rabson static krb5_error_code
425c19800e8SDoug Rabson kcm_retrieve(krb5_context context,
426c19800e8SDoug Rabson krb5_ccache id,
427c19800e8SDoug Rabson krb5_flags which,
428c19800e8SDoug Rabson const krb5_creds *mcred,
429c19800e8SDoug Rabson krb5_creds *creds)
430c19800e8SDoug Rabson {
431c19800e8SDoug Rabson krb5_error_code ret;
432c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
433c19800e8SDoug Rabson krb5_storage *request, *response;
434c19800e8SDoug Rabson krb5_data response_data;
435c19800e8SDoug Rabson
436*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_RETRIEVE, &request);
437c19800e8SDoug Rabson if (ret)
438c19800e8SDoug Rabson return ret;
439c19800e8SDoug Rabson
440c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
441c19800e8SDoug Rabson if (ret) {
442c19800e8SDoug Rabson krb5_storage_free(request);
443c19800e8SDoug Rabson return ret;
444c19800e8SDoug Rabson }
445c19800e8SDoug Rabson
446c19800e8SDoug Rabson ret = krb5_store_int32(request, which);
447c19800e8SDoug Rabson if (ret) {
448c19800e8SDoug Rabson krb5_storage_free(request);
449c19800e8SDoug Rabson return ret;
450c19800e8SDoug Rabson }
451c19800e8SDoug Rabson
452c19800e8SDoug Rabson ret = krb5_store_creds_tag(request, rk_UNCONST(mcred));
453c19800e8SDoug Rabson if (ret) {
454c19800e8SDoug Rabson krb5_storage_free(request);
455c19800e8SDoug Rabson return ret;
456c19800e8SDoug Rabson }
457c19800e8SDoug Rabson
458*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
459c19800e8SDoug Rabson if (ret) {
460c19800e8SDoug Rabson krb5_storage_free(request);
461c19800e8SDoug Rabson return ret;
462c19800e8SDoug Rabson }
463c19800e8SDoug Rabson
464c19800e8SDoug Rabson ret = krb5_ret_creds(response, creds);
465c19800e8SDoug Rabson if (ret)
466c19800e8SDoug Rabson ret = KRB5_CC_IO;
467c19800e8SDoug Rabson
468c19800e8SDoug Rabson krb5_storage_free(request);
469c19800e8SDoug Rabson krb5_storage_free(response);
470c19800e8SDoug Rabson krb5_data_free(&response_data);
471c19800e8SDoug Rabson
472c19800e8SDoug Rabson return ret;
473c19800e8SDoug Rabson }
474*ae771770SStanislav Sedov #endif
475c19800e8SDoug Rabson
476c19800e8SDoug Rabson /*
477c19800e8SDoug Rabson * Request:
478c19800e8SDoug Rabson * NameZ
479c19800e8SDoug Rabson *
480c19800e8SDoug Rabson * Response:
481c19800e8SDoug Rabson * Principal
482c19800e8SDoug Rabson */
483c19800e8SDoug Rabson static krb5_error_code
kcm_get_principal(krb5_context context,krb5_ccache id,krb5_principal * principal)484c19800e8SDoug Rabson kcm_get_principal(krb5_context context,
485c19800e8SDoug Rabson krb5_ccache id,
486c19800e8SDoug Rabson krb5_principal *principal)
487c19800e8SDoug Rabson {
488c19800e8SDoug Rabson krb5_error_code ret;
489c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
490c19800e8SDoug Rabson krb5_storage *request, *response;
491c19800e8SDoug Rabson krb5_data response_data;
492c19800e8SDoug Rabson
493*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_PRINCIPAL, &request);
494c19800e8SDoug Rabson if (ret)
495c19800e8SDoug Rabson return ret;
496c19800e8SDoug Rabson
497c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
498c19800e8SDoug Rabson if (ret) {
499c19800e8SDoug Rabson krb5_storage_free(request);
500c19800e8SDoug Rabson return ret;
501c19800e8SDoug Rabson }
502c19800e8SDoug Rabson
503*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
504c19800e8SDoug Rabson if (ret) {
505c19800e8SDoug Rabson krb5_storage_free(request);
506c19800e8SDoug Rabson return ret;
507c19800e8SDoug Rabson }
508c19800e8SDoug Rabson
509c19800e8SDoug Rabson ret = krb5_ret_principal(response, principal);
510c19800e8SDoug Rabson if (ret)
511c19800e8SDoug Rabson ret = KRB5_CC_IO;
512c19800e8SDoug Rabson
513c19800e8SDoug Rabson krb5_storage_free(request);
514c19800e8SDoug Rabson krb5_storage_free(response);
515c19800e8SDoug Rabson krb5_data_free(&response_data);
516c19800e8SDoug Rabson
517c19800e8SDoug Rabson return ret;
518c19800e8SDoug Rabson }
519c19800e8SDoug Rabson
520c19800e8SDoug Rabson /*
521c19800e8SDoug Rabson * Request:
522c19800e8SDoug Rabson * NameZ
523c19800e8SDoug Rabson *
524c19800e8SDoug Rabson * Response:
525c19800e8SDoug Rabson * Cursor
526c19800e8SDoug Rabson *
527c19800e8SDoug Rabson */
528c19800e8SDoug Rabson static krb5_error_code
kcm_get_first(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)529c19800e8SDoug Rabson kcm_get_first (krb5_context context,
530c19800e8SDoug Rabson krb5_ccache id,
531c19800e8SDoug Rabson krb5_cc_cursor *cursor)
532c19800e8SDoug Rabson {
533c19800e8SDoug Rabson krb5_error_code ret;
534*ae771770SStanislav Sedov krb5_kcm_cursor c;
535c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
536c19800e8SDoug Rabson krb5_storage *request, *response;
537c19800e8SDoug Rabson krb5_data response_data;
538c19800e8SDoug Rabson
539*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_CRED_UUID_LIST, &request);
540c19800e8SDoug Rabson if (ret)
541c19800e8SDoug Rabson return ret;
542c19800e8SDoug Rabson
543c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
544c19800e8SDoug Rabson if (ret) {
545c19800e8SDoug Rabson krb5_storage_free(request);
546c19800e8SDoug Rabson return ret;
547c19800e8SDoug Rabson }
548c19800e8SDoug Rabson
549*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
550c19800e8SDoug Rabson krb5_storage_free(request);
551c19800e8SDoug Rabson if (ret)
552c19800e8SDoug Rabson return ret;
553c19800e8SDoug Rabson
554*ae771770SStanislav Sedov c = calloc(1, sizeof(*c));
555*ae771770SStanislav Sedov if (c == NULL) {
556*ae771770SStanislav Sedov ret = ENOMEM;
557*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
558*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
559*ae771770SStanislav Sedov return ret;
560*ae771770SStanislav Sedov }
561c19800e8SDoug Rabson
562*ae771770SStanislav Sedov while (1) {
563*ae771770SStanislav Sedov ssize_t sret;
564*ae771770SStanislav Sedov kcmuuid_t uuid;
565*ae771770SStanislav Sedov void *ptr;
566*ae771770SStanislav Sedov
567*ae771770SStanislav Sedov sret = krb5_storage_read(response, &uuid, sizeof(uuid));
568*ae771770SStanislav Sedov if (sret == 0) {
569*ae771770SStanislav Sedov ret = 0;
570*ae771770SStanislav Sedov break;
571*ae771770SStanislav Sedov } else if (sret != sizeof(uuid)) {
572*ae771770SStanislav Sedov ret = EINVAL;
573*ae771770SStanislav Sedov break;
574*ae771770SStanislav Sedov }
575*ae771770SStanislav Sedov
576*ae771770SStanislav Sedov ptr = realloc(c->uuids, sizeof(c->uuids[0]) * (c->length + 1));
577*ae771770SStanislav Sedov if (ptr == NULL) {
578*ae771770SStanislav Sedov free(c->uuids);
579*ae771770SStanislav Sedov free(c);
580*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM,
581*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
582*ae771770SStanislav Sedov return ENOMEM;
583*ae771770SStanislav Sedov }
584*ae771770SStanislav Sedov c->uuids = ptr;
585*ae771770SStanislav Sedov
586*ae771770SStanislav Sedov memcpy(&c->uuids[c->length], &uuid, sizeof(uuid));
587*ae771770SStanislav Sedov c->length += 1;
588*ae771770SStanislav Sedov }
589*ae771770SStanislav Sedov
590*ae771770SStanislav Sedov krb5_storage_free(response);
591*ae771770SStanislav Sedov krb5_data_free(&response_data);
592*ae771770SStanislav Sedov
593*ae771770SStanislav Sedov if (ret) {
594*ae771770SStanislav Sedov free(c->uuids);
595*ae771770SStanislav Sedov free(c);
596*ae771770SStanislav Sedov return ret;
597*ae771770SStanislav Sedov }
598*ae771770SStanislav Sedov
599*ae771770SStanislav Sedov *cursor = c;
600c19800e8SDoug Rabson
601c19800e8SDoug Rabson return 0;
602c19800e8SDoug Rabson }
603c19800e8SDoug Rabson
604c19800e8SDoug Rabson /*
605c19800e8SDoug Rabson * Request:
606c19800e8SDoug Rabson * NameZ
607c19800e8SDoug Rabson * Cursor
608c19800e8SDoug Rabson *
609c19800e8SDoug Rabson * Response:
610c19800e8SDoug Rabson * Creds
611c19800e8SDoug Rabson */
612c19800e8SDoug Rabson static krb5_error_code
kcm_get_next(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor,krb5_creds * creds)613c19800e8SDoug Rabson kcm_get_next (krb5_context context,
614c19800e8SDoug Rabson krb5_ccache id,
615c19800e8SDoug Rabson krb5_cc_cursor *cursor,
616c19800e8SDoug Rabson krb5_creds *creds)
617c19800e8SDoug Rabson {
618c19800e8SDoug Rabson krb5_error_code ret;
619c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
620*ae771770SStanislav Sedov krb5_kcm_cursor c = KCMCURSOR(*cursor);
621c19800e8SDoug Rabson krb5_storage *request, *response;
622c19800e8SDoug Rabson krb5_data response_data;
623*ae771770SStanislav Sedov ssize_t sret;
624c19800e8SDoug Rabson
625*ae771770SStanislav Sedov again:
626*ae771770SStanislav Sedov
627*ae771770SStanislav Sedov if (c->offset >= c->length)
628*ae771770SStanislav Sedov return KRB5_CC_END;
629*ae771770SStanislav Sedov
630*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_CRED_BY_UUID, &request);
631c19800e8SDoug Rabson if (ret)
632c19800e8SDoug Rabson return ret;
633c19800e8SDoug Rabson
634c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
635c19800e8SDoug Rabson if (ret) {
636c19800e8SDoug Rabson krb5_storage_free(request);
637c19800e8SDoug Rabson return ret;
638c19800e8SDoug Rabson }
639c19800e8SDoug Rabson
640*ae771770SStanislav Sedov sret = krb5_storage_write(request,
641*ae771770SStanislav Sedov &c->uuids[c->offset],
642*ae771770SStanislav Sedov sizeof(c->uuids[c->offset]));
643*ae771770SStanislav Sedov c->offset++;
644*ae771770SStanislav Sedov if (sret != sizeof(c->uuids[c->offset])) {
645c19800e8SDoug Rabson krb5_storage_free(request);
646*ae771770SStanislav Sedov krb5_clear_error_message(context);
647*ae771770SStanislav Sedov return ENOMEM;
648c19800e8SDoug Rabson }
649c19800e8SDoug Rabson
650*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
651c19800e8SDoug Rabson krb5_storage_free(request);
652*ae771770SStanislav Sedov if (ret == KRB5_CC_END) {
653*ae771770SStanislav Sedov goto again;
654c19800e8SDoug Rabson }
655c19800e8SDoug Rabson
656c19800e8SDoug Rabson ret = krb5_ret_creds(response, creds);
657c19800e8SDoug Rabson if (ret)
658c19800e8SDoug Rabson ret = KRB5_CC_IO;
659c19800e8SDoug Rabson
660c19800e8SDoug Rabson krb5_storage_free(response);
661c19800e8SDoug Rabson krb5_data_free(&response_data);
662c19800e8SDoug Rabson
663c19800e8SDoug Rabson return ret;
664c19800e8SDoug Rabson }
665c19800e8SDoug Rabson
666c19800e8SDoug Rabson /*
667c19800e8SDoug Rabson * Request:
668c19800e8SDoug Rabson * NameZ
669c19800e8SDoug Rabson * Cursor
670c19800e8SDoug Rabson *
671c19800e8SDoug Rabson * Response:
672c19800e8SDoug Rabson *
673c19800e8SDoug Rabson */
674c19800e8SDoug Rabson static krb5_error_code
kcm_end_get(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)675c19800e8SDoug Rabson kcm_end_get (krb5_context context,
676c19800e8SDoug Rabson krb5_ccache id,
677c19800e8SDoug Rabson krb5_cc_cursor *cursor)
678c19800e8SDoug Rabson {
679*ae771770SStanislav Sedov krb5_kcm_cursor c = KCMCURSOR(*cursor);
680c19800e8SDoug Rabson
681*ae771770SStanislav Sedov free(c->uuids);
682*ae771770SStanislav Sedov free(c);
683c19800e8SDoug Rabson
684c19800e8SDoug Rabson *cursor = NULL;
685c19800e8SDoug Rabson
686*ae771770SStanislav Sedov return 0;
687c19800e8SDoug Rabson }
688c19800e8SDoug Rabson
689c19800e8SDoug Rabson /*
690c19800e8SDoug Rabson * Request:
691c19800e8SDoug Rabson * NameZ
692c19800e8SDoug Rabson * WhichFields
693c19800e8SDoug Rabson * MatchCreds
694c19800e8SDoug Rabson *
695c19800e8SDoug Rabson * Response:
696c19800e8SDoug Rabson *
697c19800e8SDoug Rabson */
698c19800e8SDoug Rabson static krb5_error_code
kcm_remove_cred(krb5_context context,krb5_ccache id,krb5_flags which,krb5_creds * cred)699c19800e8SDoug Rabson kcm_remove_cred(krb5_context context,
700c19800e8SDoug Rabson krb5_ccache id,
701c19800e8SDoug Rabson krb5_flags which,
702c19800e8SDoug Rabson krb5_creds *cred)
703c19800e8SDoug Rabson {
704c19800e8SDoug Rabson krb5_error_code ret;
705c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
706c19800e8SDoug Rabson krb5_storage *request;
707c19800e8SDoug Rabson
708*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_REMOVE_CRED, &request);
709c19800e8SDoug Rabson if (ret)
710c19800e8SDoug Rabson return ret;
711c19800e8SDoug Rabson
712c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
713c19800e8SDoug Rabson if (ret) {
714c19800e8SDoug Rabson krb5_storage_free(request);
715c19800e8SDoug Rabson return ret;
716c19800e8SDoug Rabson }
717c19800e8SDoug Rabson
718c19800e8SDoug Rabson ret = krb5_store_int32(request, which);
719c19800e8SDoug Rabson if (ret) {
720c19800e8SDoug Rabson krb5_storage_free(request);
721c19800e8SDoug Rabson return ret;
722c19800e8SDoug Rabson }
723c19800e8SDoug Rabson
724c19800e8SDoug Rabson ret = krb5_store_creds_tag(request, cred);
725c19800e8SDoug Rabson if (ret) {
726c19800e8SDoug Rabson krb5_storage_free(request);
727c19800e8SDoug Rabson return ret;
728c19800e8SDoug Rabson }
729c19800e8SDoug Rabson
730*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
731c19800e8SDoug Rabson
732c19800e8SDoug Rabson krb5_storage_free(request);
733c19800e8SDoug Rabson return ret;
734c19800e8SDoug Rabson }
735c19800e8SDoug Rabson
736c19800e8SDoug Rabson static krb5_error_code
kcm_set_flags(krb5_context context,krb5_ccache id,krb5_flags flags)737c19800e8SDoug Rabson kcm_set_flags(krb5_context context,
738c19800e8SDoug Rabson krb5_ccache id,
739c19800e8SDoug Rabson krb5_flags flags)
740c19800e8SDoug Rabson {
741c19800e8SDoug Rabson krb5_error_code ret;
742c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
743c19800e8SDoug Rabson krb5_storage *request;
744c19800e8SDoug Rabson
745*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_SET_FLAGS, &request);
746c19800e8SDoug Rabson if (ret)
747c19800e8SDoug Rabson return ret;
748c19800e8SDoug Rabson
749c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
750c19800e8SDoug Rabson if (ret) {
751c19800e8SDoug Rabson krb5_storage_free(request);
752c19800e8SDoug Rabson return ret;
753c19800e8SDoug Rabson }
754c19800e8SDoug Rabson
755c19800e8SDoug Rabson ret = krb5_store_int32(request, flags);
756c19800e8SDoug Rabson if (ret) {
757c19800e8SDoug Rabson krb5_storage_free(request);
758c19800e8SDoug Rabson return ret;
759c19800e8SDoug Rabson }
760c19800e8SDoug Rabson
761*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
762c19800e8SDoug Rabson
763c19800e8SDoug Rabson krb5_storage_free(request);
764c19800e8SDoug Rabson return ret;
765c19800e8SDoug Rabson }
766c19800e8SDoug Rabson
767*ae771770SStanislav Sedov static int
kcm_get_version(krb5_context context,krb5_ccache id)768c19800e8SDoug Rabson kcm_get_version(krb5_context context,
769c19800e8SDoug Rabson krb5_ccache id)
770c19800e8SDoug Rabson {
771c19800e8SDoug Rabson return 0;
772c19800e8SDoug Rabson }
773c19800e8SDoug Rabson
774*ae771770SStanislav Sedov /*
775*ae771770SStanislav Sedov * Send nothing
776*ae771770SStanislav Sedov * get back list of uuids
777*ae771770SStanislav Sedov */
778*ae771770SStanislav Sedov
779c19800e8SDoug Rabson static krb5_error_code
kcm_get_cache_first(krb5_context context,krb5_cc_cursor * cursor)780*ae771770SStanislav Sedov kcm_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
781c19800e8SDoug Rabson {
782*ae771770SStanislav Sedov krb5_error_code ret;
783*ae771770SStanislav Sedov krb5_kcm_cursor c;
784*ae771770SStanislav Sedov krb5_storage *request, *response;
785*ae771770SStanislav Sedov krb5_data response_data;
786*ae771770SStanislav Sedov
787*ae771770SStanislav Sedov *cursor = NULL;
788*ae771770SStanislav Sedov
789*ae771770SStanislav Sedov c = calloc(1, sizeof(*c));
790*ae771770SStanislav Sedov if (c == NULL) {
791*ae771770SStanislav Sedov ret = ENOMEM;
792*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
793*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
794*ae771770SStanislav Sedov goto out;
795*ae771770SStanislav Sedov }
796*ae771770SStanislav Sedov
797*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_CACHE_UUID_LIST, &request);
798*ae771770SStanislav Sedov if (ret)
799*ae771770SStanislav Sedov goto out;
800*ae771770SStanislav Sedov
801*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
802*ae771770SStanislav Sedov krb5_storage_free(request);
803*ae771770SStanislav Sedov if (ret)
804*ae771770SStanislav Sedov goto out;
805*ae771770SStanislav Sedov
806*ae771770SStanislav Sedov while (1) {
807*ae771770SStanislav Sedov ssize_t sret;
808*ae771770SStanislav Sedov kcmuuid_t uuid;
809*ae771770SStanislav Sedov void *ptr;
810*ae771770SStanislav Sedov
811*ae771770SStanislav Sedov sret = krb5_storage_read(response, &uuid, sizeof(uuid));
812*ae771770SStanislav Sedov if (sret == 0) {
813*ae771770SStanislav Sedov ret = 0;
814*ae771770SStanislav Sedov break;
815*ae771770SStanislav Sedov } else if (sret != sizeof(uuid)) {
816*ae771770SStanislav Sedov ret = EINVAL;
817*ae771770SStanislav Sedov goto out;
818*ae771770SStanislav Sedov }
819*ae771770SStanislav Sedov
820*ae771770SStanislav Sedov ptr = realloc(c->uuids, sizeof(c->uuids[0]) * (c->length + 1));
821*ae771770SStanislav Sedov if (ptr == NULL) {
822*ae771770SStanislav Sedov ret = ENOMEM;
823*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
824*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
825*ae771770SStanislav Sedov goto out;
826*ae771770SStanislav Sedov }
827*ae771770SStanislav Sedov c->uuids = ptr;
828*ae771770SStanislav Sedov
829*ae771770SStanislav Sedov memcpy(&c->uuids[c->length], &uuid, sizeof(uuid));
830*ae771770SStanislav Sedov c->length += 1;
831*ae771770SStanislav Sedov }
832*ae771770SStanislav Sedov
833*ae771770SStanislav Sedov krb5_storage_free(response);
834*ae771770SStanislav Sedov krb5_data_free(&response_data);
835*ae771770SStanislav Sedov
836*ae771770SStanislav Sedov out:
837*ae771770SStanislav Sedov if (ret && c) {
838*ae771770SStanislav Sedov free(c->uuids);
839*ae771770SStanislav Sedov free(c);
840*ae771770SStanislav Sedov } else
841*ae771770SStanislav Sedov *cursor = c;
842*ae771770SStanislav Sedov
843*ae771770SStanislav Sedov return ret;
844*ae771770SStanislav Sedov }
845*ae771770SStanislav Sedov
846*ae771770SStanislav Sedov /*
847*ae771770SStanislav Sedov * Send uuid
848*ae771770SStanislav Sedov * Recv cache name
849*ae771770SStanislav Sedov */
850*ae771770SStanislav Sedov
851*ae771770SStanislav Sedov static krb5_error_code
kcm_get_cache_next(krb5_context context,krb5_cc_cursor cursor,const krb5_cc_ops * ops,krb5_ccache * id)852*ae771770SStanislav Sedov kcm_get_cache_next(krb5_context context, krb5_cc_cursor cursor, const krb5_cc_ops *ops, krb5_ccache *id)
853*ae771770SStanislav Sedov {
854*ae771770SStanislav Sedov krb5_error_code ret;
855*ae771770SStanislav Sedov krb5_kcm_cursor c = KCMCURSOR(cursor);
856*ae771770SStanislav Sedov krb5_storage *request, *response;
857*ae771770SStanislav Sedov krb5_data response_data;
858*ae771770SStanislav Sedov ssize_t sret;
859*ae771770SStanislav Sedov char *name;
860*ae771770SStanislav Sedov
861*ae771770SStanislav Sedov *id = NULL;
862*ae771770SStanislav Sedov
863*ae771770SStanislav Sedov again:
864*ae771770SStanislav Sedov
865*ae771770SStanislav Sedov if (c->offset >= c->length)
866*ae771770SStanislav Sedov return KRB5_CC_END;
867*ae771770SStanislav Sedov
868*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_CACHE_BY_UUID, &request);
869*ae771770SStanislav Sedov if (ret)
870*ae771770SStanislav Sedov return ret;
871*ae771770SStanislav Sedov
872*ae771770SStanislav Sedov sret = krb5_storage_write(request,
873*ae771770SStanislav Sedov &c->uuids[c->offset],
874*ae771770SStanislav Sedov sizeof(c->uuids[c->offset]));
875*ae771770SStanislav Sedov c->offset++;
876*ae771770SStanislav Sedov if (sret != sizeof(c->uuids[c->offset])) {
877*ae771770SStanislav Sedov krb5_storage_free(request);
878*ae771770SStanislav Sedov krb5_clear_error_message(context);
879*ae771770SStanislav Sedov return ENOMEM;
880*ae771770SStanislav Sedov }
881*ae771770SStanislav Sedov
882*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
883*ae771770SStanislav Sedov krb5_storage_free(request);
884*ae771770SStanislav Sedov if (ret == KRB5_CC_END)
885*ae771770SStanislav Sedov goto again;
886*ae771770SStanislav Sedov
887*ae771770SStanislav Sedov ret = krb5_ret_stringz(response, &name);
888*ae771770SStanislav Sedov krb5_storage_free(response);
889*ae771770SStanislav Sedov krb5_data_free(&response_data);
890*ae771770SStanislav Sedov
891*ae771770SStanislav Sedov if (ret == 0) {
892*ae771770SStanislav Sedov ret = _krb5_cc_allocate(context, ops, id);
893*ae771770SStanislav Sedov if (ret == 0)
894*ae771770SStanislav Sedov ret = kcm_alloc(context, name, id);
895*ae771770SStanislav Sedov krb5_xfree(name);
896*ae771770SStanislav Sedov }
897*ae771770SStanislav Sedov
898*ae771770SStanislav Sedov return ret;
899c19800e8SDoug Rabson }
900c19800e8SDoug Rabson
901c19800e8SDoug Rabson static krb5_error_code
kcm_get_cache_next_kcm(krb5_context context,krb5_cc_cursor cursor,krb5_ccache * id)902*ae771770SStanislav Sedov kcm_get_cache_next_kcm(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
903c19800e8SDoug Rabson {
904*ae771770SStanislav Sedov #ifndef KCM_IS_API_CACHE
905*ae771770SStanislav Sedov return kcm_get_cache_next(context, cursor, &krb5_kcm_ops, id);
906*ae771770SStanislav Sedov #else
907*ae771770SStanislav Sedov return KRB5_CC_END;
908*ae771770SStanislav Sedov #endif
909*ae771770SStanislav Sedov }
910*ae771770SStanislav Sedov
911*ae771770SStanislav Sedov static krb5_error_code
kcm_get_cache_next_api(krb5_context context,krb5_cc_cursor cursor,krb5_ccache * id)912*ae771770SStanislav Sedov kcm_get_cache_next_api(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
913*ae771770SStanislav Sedov {
914*ae771770SStanislav Sedov return kcm_get_cache_next(context, cursor, &krb5_akcm_ops, id);
915*ae771770SStanislav Sedov }
916*ae771770SStanislav Sedov
917*ae771770SStanislav Sedov
918*ae771770SStanislav Sedov static krb5_error_code
kcm_end_cache_get(krb5_context context,krb5_cc_cursor cursor)919*ae771770SStanislav Sedov kcm_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
920*ae771770SStanislav Sedov {
921*ae771770SStanislav Sedov krb5_kcm_cursor c = KCMCURSOR(cursor);
922*ae771770SStanislav Sedov
923*ae771770SStanislav Sedov free(c->uuids);
924*ae771770SStanislav Sedov free(c);
925*ae771770SStanislav Sedov return 0;
926*ae771770SStanislav Sedov }
927*ae771770SStanislav Sedov
928*ae771770SStanislav Sedov
929*ae771770SStanislav Sedov static krb5_error_code
kcm_move(krb5_context context,krb5_ccache from,krb5_ccache to)930*ae771770SStanislav Sedov kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
931*ae771770SStanislav Sedov {
932*ae771770SStanislav Sedov krb5_error_code ret;
933*ae771770SStanislav Sedov krb5_kcmcache *oldk = KCMCACHE(from);
934*ae771770SStanislav Sedov krb5_kcmcache *newk = KCMCACHE(to);
935*ae771770SStanislav Sedov krb5_storage *request;
936*ae771770SStanislav Sedov
937*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_MOVE_CACHE, &request);
938*ae771770SStanislav Sedov if (ret)
939*ae771770SStanislav Sedov return ret;
940*ae771770SStanislav Sedov
941*ae771770SStanislav Sedov ret = krb5_store_stringz(request, oldk->name);
942*ae771770SStanislav Sedov if (ret) {
943*ae771770SStanislav Sedov krb5_storage_free(request);
944*ae771770SStanislav Sedov return ret;
945*ae771770SStanislav Sedov }
946*ae771770SStanislav Sedov
947*ae771770SStanislav Sedov ret = krb5_store_stringz(request, newk->name);
948*ae771770SStanislav Sedov if (ret) {
949*ae771770SStanislav Sedov krb5_storage_free(request);
950*ae771770SStanislav Sedov return ret;
951*ae771770SStanislav Sedov }
952*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
953*ae771770SStanislav Sedov
954*ae771770SStanislav Sedov krb5_storage_free(request);
955*ae771770SStanislav Sedov return ret;
956*ae771770SStanislav Sedov }
957*ae771770SStanislav Sedov
958*ae771770SStanislav Sedov static krb5_error_code
kcm_get_default_name(krb5_context context,const krb5_cc_ops * ops,const char * defstr,char ** str)959*ae771770SStanislav Sedov kcm_get_default_name(krb5_context context, const krb5_cc_ops *ops,
960*ae771770SStanislav Sedov const char *defstr, char **str)
961*ae771770SStanislav Sedov {
962*ae771770SStanislav Sedov krb5_error_code ret;
963*ae771770SStanislav Sedov krb5_storage *request, *response;
964*ae771770SStanislav Sedov krb5_data response_data;
965*ae771770SStanislav Sedov char *name;
966*ae771770SStanislav Sedov
967*ae771770SStanislav Sedov *str = NULL;
968*ae771770SStanislav Sedov
969*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_DEFAULT_CACHE, &request);
970*ae771770SStanislav Sedov if (ret)
971*ae771770SStanislav Sedov return ret;
972*ae771770SStanislav Sedov
973*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
974*ae771770SStanislav Sedov krb5_storage_free(request);
975*ae771770SStanislav Sedov if (ret)
976*ae771770SStanislav Sedov return _krb5_expand_default_cc_name(context, defstr, str);
977*ae771770SStanislav Sedov
978*ae771770SStanislav Sedov ret = krb5_ret_stringz(response, &name);
979*ae771770SStanislav Sedov krb5_storage_free(response);
980*ae771770SStanislav Sedov krb5_data_free(&response_data);
981*ae771770SStanislav Sedov if (ret)
982*ae771770SStanislav Sedov return ret;
983*ae771770SStanislav Sedov
984*ae771770SStanislav Sedov asprintf(str, "%s:%s", ops->prefix, name);
985*ae771770SStanislav Sedov free(name);
986*ae771770SStanislav Sedov if (str == NULL)
987*ae771770SStanislav Sedov return ENOMEM;
988*ae771770SStanislav Sedov
989*ae771770SStanislav Sedov return 0;
990*ae771770SStanislav Sedov }
991*ae771770SStanislav Sedov
992*ae771770SStanislav Sedov static krb5_error_code
kcm_get_default_name_api(krb5_context context,char ** str)993*ae771770SStanislav Sedov kcm_get_default_name_api(krb5_context context, char **str)
994*ae771770SStanislav Sedov {
995*ae771770SStanislav Sedov return kcm_get_default_name(context, &krb5_akcm_ops,
996*ae771770SStanislav Sedov KRB5_DEFAULT_CCNAME_KCM_API, str);
997*ae771770SStanislav Sedov }
998*ae771770SStanislav Sedov
999*ae771770SStanislav Sedov static krb5_error_code
kcm_get_default_name_kcm(krb5_context context,char ** str)1000*ae771770SStanislav Sedov kcm_get_default_name_kcm(krb5_context context, char **str)
1001*ae771770SStanislav Sedov {
1002*ae771770SStanislav Sedov return kcm_get_default_name(context, &krb5_kcm_ops,
1003*ae771770SStanislav Sedov KRB5_DEFAULT_CCNAME_KCM_KCM, str);
1004*ae771770SStanislav Sedov }
1005*ae771770SStanislav Sedov
1006*ae771770SStanislav Sedov static krb5_error_code
kcm_set_default(krb5_context context,krb5_ccache id)1007*ae771770SStanislav Sedov kcm_set_default(krb5_context context, krb5_ccache id)
1008*ae771770SStanislav Sedov {
1009*ae771770SStanislav Sedov krb5_error_code ret;
1010*ae771770SStanislav Sedov krb5_storage *request;
1011*ae771770SStanislav Sedov krb5_kcmcache *k = KCMCACHE(id);
1012*ae771770SStanislav Sedov
1013*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_SET_DEFAULT_CACHE, &request);
1014*ae771770SStanislav Sedov if (ret)
1015*ae771770SStanislav Sedov return ret;
1016*ae771770SStanislav Sedov
1017*ae771770SStanislav Sedov ret = krb5_store_stringz(request, k->name);
1018*ae771770SStanislav Sedov if (ret) {
1019*ae771770SStanislav Sedov krb5_storage_free(request);
1020*ae771770SStanislav Sedov return ret;
1021*ae771770SStanislav Sedov }
1022*ae771770SStanislav Sedov
1023*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
1024*ae771770SStanislav Sedov krb5_storage_free(request);
1025*ae771770SStanislav Sedov
1026*ae771770SStanislav Sedov return ret;
1027*ae771770SStanislav Sedov }
1028*ae771770SStanislav Sedov
1029*ae771770SStanislav Sedov static krb5_error_code
kcm_lastchange(krb5_context context,krb5_ccache id,krb5_timestamp * mtime)1030*ae771770SStanislav Sedov kcm_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
1031*ae771770SStanislav Sedov {
1032*ae771770SStanislav Sedov *mtime = time(NULL);
1033*ae771770SStanislav Sedov return 0;
1034*ae771770SStanislav Sedov }
1035*ae771770SStanislav Sedov
1036*ae771770SStanislav Sedov static krb5_error_code
kcm_set_kdc_offset(krb5_context context,krb5_ccache id,krb5_deltat kdc_offset)1037*ae771770SStanislav Sedov kcm_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
1038*ae771770SStanislav Sedov {
1039*ae771770SStanislav Sedov krb5_kcmcache *k = KCMCACHE(id);
1040*ae771770SStanislav Sedov krb5_error_code ret;
1041*ae771770SStanislav Sedov krb5_storage *request;
1042*ae771770SStanislav Sedov
1043*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_SET_KDC_OFFSET, &request);
1044*ae771770SStanislav Sedov if (ret)
1045*ae771770SStanislav Sedov return ret;
1046*ae771770SStanislav Sedov
1047*ae771770SStanislav Sedov ret = krb5_store_stringz(request, k->name);
1048*ae771770SStanislav Sedov if (ret) {
1049*ae771770SStanislav Sedov krb5_storage_free(request);
1050*ae771770SStanislav Sedov return ret;
1051*ae771770SStanislav Sedov }
1052*ae771770SStanislav Sedov ret = krb5_store_int32(request, kdc_offset);
1053*ae771770SStanislav Sedov if (ret) {
1054*ae771770SStanislav Sedov krb5_storage_free(request);
1055*ae771770SStanislav Sedov return ret;
1056*ae771770SStanislav Sedov }
1057*ae771770SStanislav Sedov
1058*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
1059*ae771770SStanislav Sedov krb5_storage_free(request);
1060*ae771770SStanislav Sedov
1061*ae771770SStanislav Sedov return ret;
1062*ae771770SStanislav Sedov }
1063*ae771770SStanislav Sedov
1064*ae771770SStanislav Sedov static krb5_error_code
kcm_get_kdc_offset(krb5_context context,krb5_ccache id,krb5_deltat * kdc_offset)1065*ae771770SStanislav Sedov kcm_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset)
1066*ae771770SStanislav Sedov {
1067*ae771770SStanislav Sedov krb5_kcmcache *k = KCMCACHE(id);
1068*ae771770SStanislav Sedov krb5_error_code ret;
1069*ae771770SStanislav Sedov krb5_storage *request, *response;
1070*ae771770SStanislav Sedov krb5_data response_data;
1071*ae771770SStanislav Sedov int32_t offset;
1072*ae771770SStanislav Sedov
1073*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_KDC_OFFSET, &request);
1074*ae771770SStanislav Sedov if (ret)
1075*ae771770SStanislav Sedov return ret;
1076*ae771770SStanislav Sedov
1077*ae771770SStanislav Sedov ret = krb5_store_stringz(request, k->name);
1078*ae771770SStanislav Sedov if (ret) {
1079*ae771770SStanislav Sedov krb5_storage_free(request);
1080*ae771770SStanislav Sedov return ret;
1081*ae771770SStanislav Sedov }
1082*ae771770SStanislav Sedov
1083*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, &response, &response_data);
1084*ae771770SStanislav Sedov krb5_storage_free(request);
1085*ae771770SStanislav Sedov if (ret)
1086*ae771770SStanislav Sedov return ret;
1087*ae771770SStanislav Sedov
1088*ae771770SStanislav Sedov ret = krb5_ret_int32(response, &offset);
1089*ae771770SStanislav Sedov krb5_storage_free(response);
1090*ae771770SStanislav Sedov krb5_data_free(&response_data);
1091*ae771770SStanislav Sedov if (ret)
1092*ae771770SStanislav Sedov return ret;
1093*ae771770SStanislav Sedov
1094*ae771770SStanislav Sedov *kdc_offset = offset;
1095*ae771770SStanislav Sedov
1096*ae771770SStanislav Sedov return 0;
1097c19800e8SDoug Rabson }
1098c19800e8SDoug Rabson
1099c19800e8SDoug Rabson /**
1100c19800e8SDoug Rabson * Variable containing the KCM based credential cache implemention.
1101c19800e8SDoug Rabson *
1102c19800e8SDoug Rabson * @ingroup krb5_ccache
1103c19800e8SDoug Rabson */
1104c19800e8SDoug Rabson
1105*ae771770SStanislav Sedov KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops = {
1106*ae771770SStanislav Sedov KRB5_CC_OPS_VERSION,
1107c19800e8SDoug Rabson "KCM",
1108c19800e8SDoug Rabson kcm_get_name,
1109c19800e8SDoug Rabson kcm_resolve,
1110c19800e8SDoug Rabson kcm_gen_new,
1111c19800e8SDoug Rabson kcm_initialize,
1112c19800e8SDoug Rabson kcm_destroy,
1113c19800e8SDoug Rabson kcm_close,
1114c19800e8SDoug Rabson kcm_store_cred,
1115*ae771770SStanislav Sedov NULL /* kcm_retrieve */,
1116c19800e8SDoug Rabson kcm_get_principal,
1117c19800e8SDoug Rabson kcm_get_first,
1118c19800e8SDoug Rabson kcm_get_next,
1119c19800e8SDoug Rabson kcm_end_get,
1120c19800e8SDoug Rabson kcm_remove_cred,
1121c19800e8SDoug Rabson kcm_set_flags,
1122c19800e8SDoug Rabson kcm_get_version,
1123*ae771770SStanislav Sedov kcm_get_cache_first,
1124*ae771770SStanislav Sedov kcm_get_cache_next_kcm,
1125*ae771770SStanislav Sedov kcm_end_cache_get,
1126c19800e8SDoug Rabson kcm_move,
1127*ae771770SStanislav Sedov kcm_get_default_name_kcm,
1128*ae771770SStanislav Sedov kcm_set_default,
1129*ae771770SStanislav Sedov kcm_lastchange,
1130*ae771770SStanislav Sedov kcm_set_kdc_offset,
1131*ae771770SStanislav Sedov kcm_get_kdc_offset
1132c19800e8SDoug Rabson };
1133c19800e8SDoug Rabson
1134*ae771770SStanislav Sedov KRB5_LIB_VARIABLE const krb5_cc_ops krb5_akcm_ops = {
1135*ae771770SStanislav Sedov KRB5_CC_OPS_VERSION,
1136*ae771770SStanislav Sedov "API",
1137*ae771770SStanislav Sedov kcm_get_name,
1138*ae771770SStanislav Sedov kcm_resolve,
1139*ae771770SStanislav Sedov kcm_gen_new,
1140*ae771770SStanislav Sedov kcm_initialize,
1141*ae771770SStanislav Sedov kcm_destroy,
1142*ae771770SStanislav Sedov kcm_close,
1143*ae771770SStanislav Sedov kcm_store_cred,
1144*ae771770SStanislav Sedov NULL /* kcm_retrieve */,
1145*ae771770SStanislav Sedov kcm_get_principal,
1146*ae771770SStanislav Sedov kcm_get_first,
1147*ae771770SStanislav Sedov kcm_get_next,
1148*ae771770SStanislav Sedov kcm_end_get,
1149*ae771770SStanislav Sedov kcm_remove_cred,
1150*ae771770SStanislav Sedov kcm_set_flags,
1151*ae771770SStanislav Sedov kcm_get_version,
1152*ae771770SStanislav Sedov kcm_get_cache_first,
1153*ae771770SStanislav Sedov kcm_get_cache_next_api,
1154*ae771770SStanislav Sedov kcm_end_cache_get,
1155*ae771770SStanislav Sedov kcm_move,
1156*ae771770SStanislav Sedov kcm_get_default_name_api,
1157*ae771770SStanislav Sedov kcm_set_default,
1158*ae771770SStanislav Sedov kcm_lastchange,
1159*ae771770SStanislav Sedov NULL,
1160*ae771770SStanislav Sedov NULL
1161*ae771770SStanislav Sedov };
1162*ae771770SStanislav Sedov
1163*ae771770SStanislav Sedov
1164*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
_krb5_kcm_is_running(krb5_context context)1165c19800e8SDoug Rabson _krb5_kcm_is_running(krb5_context context)
1166c19800e8SDoug Rabson {
1167c19800e8SDoug Rabson krb5_error_code ret;
1168c19800e8SDoug Rabson krb5_ccache_data ccdata;
1169c19800e8SDoug Rabson krb5_ccache id = &ccdata;
1170c19800e8SDoug Rabson krb5_boolean running;
1171c19800e8SDoug Rabson
1172c19800e8SDoug Rabson ret = kcm_alloc(context, NULL, &id);
1173c19800e8SDoug Rabson if (ret)
1174c19800e8SDoug Rabson return 0;
1175c19800e8SDoug Rabson
1176c19800e8SDoug Rabson running = (_krb5_kcm_noop(context, id) == 0);
1177c19800e8SDoug Rabson
1178c19800e8SDoug Rabson kcm_free(context, &id);
1179c19800e8SDoug Rabson
1180c19800e8SDoug Rabson return running;
1181c19800e8SDoug Rabson }
1182c19800e8SDoug Rabson
1183c19800e8SDoug Rabson /*
1184c19800e8SDoug Rabson * Request:
1185c19800e8SDoug Rabson *
1186c19800e8SDoug Rabson * Response:
1187c19800e8SDoug Rabson *
1188c19800e8SDoug Rabson */
1189*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_kcm_noop(krb5_context context,krb5_ccache id)1190c19800e8SDoug Rabson _krb5_kcm_noop(krb5_context context,
1191c19800e8SDoug Rabson krb5_ccache id)
1192c19800e8SDoug Rabson {
1193c19800e8SDoug Rabson krb5_error_code ret;
1194c19800e8SDoug Rabson krb5_storage *request;
1195c19800e8SDoug Rabson
1196*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_NOOP, &request);
1197c19800e8SDoug Rabson if (ret)
1198c19800e8SDoug Rabson return ret;
1199c19800e8SDoug Rabson
1200*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
1201c19800e8SDoug Rabson
1202c19800e8SDoug Rabson krb5_storage_free(request);
1203c19800e8SDoug Rabson return ret;
1204c19800e8SDoug Rabson }
1205c19800e8SDoug Rabson
1206c19800e8SDoug Rabson
1207c19800e8SDoug Rabson /*
1208c19800e8SDoug Rabson * Request:
1209c19800e8SDoug Rabson * NameZ
1210c19800e8SDoug Rabson * ServerPrincipalPresent
1211c19800e8SDoug Rabson * ServerPrincipal OPTIONAL
1212c19800e8SDoug Rabson * Key
1213c19800e8SDoug Rabson *
1214c19800e8SDoug Rabson * Repsonse:
1215c19800e8SDoug Rabson *
1216c19800e8SDoug Rabson */
1217*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_kcm_get_initial_ticket(krb5_context context,krb5_ccache id,krb5_principal server,krb5_keyblock * key)1218c19800e8SDoug Rabson _krb5_kcm_get_initial_ticket(krb5_context context,
1219c19800e8SDoug Rabson krb5_ccache id,
1220c19800e8SDoug Rabson krb5_principal server,
1221c19800e8SDoug Rabson krb5_keyblock *key)
1222c19800e8SDoug Rabson {
1223c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
1224*ae771770SStanislav Sedov krb5_error_code ret;
1225c19800e8SDoug Rabson krb5_storage *request;
1226c19800e8SDoug Rabson
1227*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
1228c19800e8SDoug Rabson if (ret)
1229c19800e8SDoug Rabson return ret;
1230c19800e8SDoug Rabson
1231c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
1232c19800e8SDoug Rabson if (ret) {
1233c19800e8SDoug Rabson krb5_storage_free(request);
1234c19800e8SDoug Rabson return ret;
1235c19800e8SDoug Rabson }
1236c19800e8SDoug Rabson
1237c19800e8SDoug Rabson ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
1238c19800e8SDoug Rabson if (ret) {
1239c19800e8SDoug Rabson krb5_storage_free(request);
1240c19800e8SDoug Rabson return ret;
1241c19800e8SDoug Rabson }
1242c19800e8SDoug Rabson
1243c19800e8SDoug Rabson if (server != NULL) {
1244c19800e8SDoug Rabson ret = krb5_store_principal(request, server);
1245c19800e8SDoug Rabson if (ret) {
1246c19800e8SDoug Rabson krb5_storage_free(request);
1247c19800e8SDoug Rabson return ret;
1248c19800e8SDoug Rabson }
1249c19800e8SDoug Rabson }
1250c19800e8SDoug Rabson
1251c19800e8SDoug Rabson ret = krb5_store_keyblock(request, *key);
1252c19800e8SDoug Rabson if (ret) {
1253c19800e8SDoug Rabson krb5_storage_free(request);
1254c19800e8SDoug Rabson return ret;
1255c19800e8SDoug Rabson }
1256c19800e8SDoug Rabson
1257*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
1258c19800e8SDoug Rabson
1259c19800e8SDoug Rabson krb5_storage_free(request);
1260c19800e8SDoug Rabson return ret;
1261c19800e8SDoug Rabson }
1262c19800e8SDoug Rabson
1263c19800e8SDoug Rabson
1264c19800e8SDoug Rabson /*
1265c19800e8SDoug Rabson * Request:
1266c19800e8SDoug Rabson * NameZ
1267c19800e8SDoug Rabson * KDCFlags
1268c19800e8SDoug Rabson * EncryptionType
1269c19800e8SDoug Rabson * ServerPrincipal
1270c19800e8SDoug Rabson *
1271c19800e8SDoug Rabson * Repsonse:
1272c19800e8SDoug Rabson *
1273c19800e8SDoug Rabson */
1274*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_kcm_get_ticket(krb5_context context,krb5_ccache id,krb5_kdc_flags flags,krb5_enctype enctype,krb5_principal server)1275c19800e8SDoug Rabson _krb5_kcm_get_ticket(krb5_context context,
1276c19800e8SDoug Rabson krb5_ccache id,
1277c19800e8SDoug Rabson krb5_kdc_flags flags,
1278c19800e8SDoug Rabson krb5_enctype enctype,
1279c19800e8SDoug Rabson krb5_principal server)
1280c19800e8SDoug Rabson {
1281c19800e8SDoug Rabson krb5_error_code ret;
1282c19800e8SDoug Rabson krb5_kcmcache *k = KCMCACHE(id);
1283c19800e8SDoug Rabson krb5_storage *request;
1284c19800e8SDoug Rabson
1285*ae771770SStanislav Sedov ret = krb5_kcm_storage_request(context, KCM_OP_GET_TICKET, &request);
1286c19800e8SDoug Rabson if (ret)
1287c19800e8SDoug Rabson return ret;
1288c19800e8SDoug Rabson
1289c19800e8SDoug Rabson ret = krb5_store_stringz(request, k->name);
1290c19800e8SDoug Rabson if (ret) {
1291c19800e8SDoug Rabson krb5_storage_free(request);
1292c19800e8SDoug Rabson return ret;
1293c19800e8SDoug Rabson }
1294c19800e8SDoug Rabson
1295c19800e8SDoug Rabson ret = krb5_store_int32(request, flags.i);
1296c19800e8SDoug Rabson if (ret) {
1297c19800e8SDoug Rabson krb5_storage_free(request);
1298c19800e8SDoug Rabson return ret;
1299c19800e8SDoug Rabson }
1300c19800e8SDoug Rabson
1301c19800e8SDoug Rabson ret = krb5_store_int32(request, enctype);
1302c19800e8SDoug Rabson if (ret) {
1303c19800e8SDoug Rabson krb5_storage_free(request);
1304c19800e8SDoug Rabson return ret;
1305c19800e8SDoug Rabson }
1306c19800e8SDoug Rabson
1307c19800e8SDoug Rabson ret = krb5_store_principal(request, server);
1308c19800e8SDoug Rabson if (ret) {
1309c19800e8SDoug Rabson krb5_storage_free(request);
1310c19800e8SDoug Rabson return ret;
1311c19800e8SDoug Rabson }
1312c19800e8SDoug Rabson
1313*ae771770SStanislav Sedov ret = krb5_kcm_call(context, request, NULL, NULL);
1314c19800e8SDoug Rabson
1315c19800e8SDoug Rabson krb5_storage_free(request);
1316c19800e8SDoug Rabson return ret;
1317c19800e8SDoug Rabson }
1318c19800e8SDoug Rabson
1319c19800e8SDoug Rabson #endif /* HAVE_KCM */
1320