1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray * All rights reserved.
5b528cefcSMark Murray *
6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray * modification, are permitted provided that the following conditions
8b528cefcSMark Murray * are met:
9b528cefcSMark Murray *
10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray *
13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray * documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray *
17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray * may be used to endorse or promote products derived from this software
19b528cefcSMark Murray * without specific prior written permission.
20b528cefcSMark Murray *
21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray * SUCH DAMAGE.
32b528cefcSMark Murray */
33b528cefcSMark Murray
34b528cefcSMark Murray #include "krb5_locl.h"
35b528cefcSMark Murray
36b528cefcSMark Murray #define KRB5_KT_VNO_1 1
37b528cefcSMark Murray #define KRB5_KT_VNO_2 2
38b528cefcSMark Murray #define KRB5_KT_VNO KRB5_KT_VNO_2
39b528cefcSMark Murray
40c19800e8SDoug Rabson #define KRB5_KT_FL_JAVA 1
41c19800e8SDoug Rabson
42c19800e8SDoug Rabson
43b528cefcSMark Murray /* file operations -------------------------------------------- */
44b528cefcSMark Murray
45b528cefcSMark Murray struct fkt_data {
46b528cefcSMark Murray char *filename;
47c19800e8SDoug Rabson int flags;
48b528cefcSMark Murray };
49b528cefcSMark Murray
50b528cefcSMark Murray static krb5_error_code
krb5_kt_ret_data(krb5_context context,krb5_storage * sp,krb5_data * data)51adb0ddaeSAssar Westerlund krb5_kt_ret_data(krb5_context context,
52adb0ddaeSAssar Westerlund krb5_storage *sp,
53b528cefcSMark Murray krb5_data *data)
54b528cefcSMark Murray {
55b528cefcSMark Murray int ret;
56b528cefcSMark Murray int16_t size;
57b528cefcSMark Murray ret = krb5_ret_int16(sp, &size);
58b528cefcSMark Murray if(ret)
59b528cefcSMark Murray return ret;
60b528cefcSMark Murray data->length = size;
61b528cefcSMark Murray data->data = malloc(size);
62adb0ddaeSAssar Westerlund if (data->data == NULL) {
63*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
64b528cefcSMark Murray return ENOMEM;
65adb0ddaeSAssar Westerlund }
668373020dSJacques Vidrine ret = krb5_storage_read(sp, data->data, size);
67b528cefcSMark Murray if(ret != size)
68b528cefcSMark Murray return (ret < 0)? errno : KRB5_KT_END;
69b528cefcSMark Murray return 0;
70b528cefcSMark Murray }
71b528cefcSMark Murray
72b528cefcSMark Murray static krb5_error_code
krb5_kt_ret_string(krb5_context context,krb5_storage * sp,heim_general_string * data)73adb0ddaeSAssar Westerlund krb5_kt_ret_string(krb5_context context,
74adb0ddaeSAssar Westerlund krb5_storage *sp,
75c19800e8SDoug Rabson heim_general_string *data)
76b528cefcSMark Murray {
77b528cefcSMark Murray int ret;
78b528cefcSMark Murray int16_t size;
79b528cefcSMark Murray ret = krb5_ret_int16(sp, &size);
80b528cefcSMark Murray if(ret)
81b528cefcSMark Murray return ret;
82b528cefcSMark Murray *data = malloc(size + 1);
83adb0ddaeSAssar Westerlund if (*data == NULL) {
84*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
85b528cefcSMark Murray return ENOMEM;
86adb0ddaeSAssar Westerlund }
878373020dSJacques Vidrine ret = krb5_storage_read(sp, *data, size);
88b528cefcSMark Murray (*data)[size] = '\0';
89b528cefcSMark Murray if(ret != size)
90b528cefcSMark Murray return (ret < 0)? errno : KRB5_KT_END;
91b528cefcSMark Murray return 0;
92b528cefcSMark Murray }
93b528cefcSMark Murray
94b528cefcSMark Murray static krb5_error_code
krb5_kt_store_data(krb5_context context,krb5_storage * sp,krb5_data data)95adb0ddaeSAssar Westerlund krb5_kt_store_data(krb5_context context,
96adb0ddaeSAssar Westerlund krb5_storage *sp,
97b528cefcSMark Murray krb5_data data)
98b528cefcSMark Murray {
99b528cefcSMark Murray int ret;
100b528cefcSMark Murray ret = krb5_store_int16(sp, data.length);
101b528cefcSMark Murray if(ret < 0)
102b528cefcSMark Murray return ret;
1038373020dSJacques Vidrine ret = krb5_storage_write(sp, data.data, data.length);
104*ae771770SStanislav Sedov if(ret != (int)data.length){
105b528cefcSMark Murray if(ret < 0)
106b528cefcSMark Murray return errno;
107b528cefcSMark Murray return KRB5_KT_END;
108b528cefcSMark Murray }
109b528cefcSMark Murray return 0;
110b528cefcSMark Murray }
111b528cefcSMark Murray
112b528cefcSMark Murray static krb5_error_code
krb5_kt_store_string(krb5_storage * sp,heim_general_string data)113b528cefcSMark Murray krb5_kt_store_string(krb5_storage *sp,
114c19800e8SDoug Rabson heim_general_string data)
115b528cefcSMark Murray {
116b528cefcSMark Murray int ret;
117b528cefcSMark Murray size_t len = strlen(data);
118b528cefcSMark Murray ret = krb5_store_int16(sp, len);
119b528cefcSMark Murray if(ret < 0)
120b528cefcSMark Murray return ret;
1218373020dSJacques Vidrine ret = krb5_storage_write(sp, data, len);
122*ae771770SStanislav Sedov if(ret != (int)len){
123b528cefcSMark Murray if(ret < 0)
124b528cefcSMark Murray return errno;
125b528cefcSMark Murray return KRB5_KT_END;
126b528cefcSMark Murray }
127b528cefcSMark Murray return 0;
128b528cefcSMark Murray }
129b528cefcSMark Murray
130b528cefcSMark Murray static krb5_error_code
krb5_kt_ret_keyblock(krb5_context context,struct fkt_data * fkt,krb5_storage * sp,krb5_keyblock * p)131*ae771770SStanislav Sedov krb5_kt_ret_keyblock(krb5_context context,
132*ae771770SStanislav Sedov struct fkt_data *fkt,
133*ae771770SStanislav Sedov krb5_storage *sp,
134*ae771770SStanislav Sedov krb5_keyblock *p)
135b528cefcSMark Murray {
136b528cefcSMark Murray int ret;
137b528cefcSMark Murray int16_t tmp;
138b528cefcSMark Murray
139b528cefcSMark Murray ret = krb5_ret_int16(sp, &tmp); /* keytype + etype */
140*ae771770SStanislav Sedov if(ret) {
141*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
142*ae771770SStanislav Sedov N_("Cant read keyblock from file %s", ""),
143*ae771770SStanislav Sedov fkt->filename);
144*ae771770SStanislav Sedov return ret;
145*ae771770SStanislav Sedov }
146b528cefcSMark Murray p->keytype = tmp;
147adb0ddaeSAssar Westerlund ret = krb5_kt_ret_data(context, sp, &p->keyvalue);
148*ae771770SStanislav Sedov if (ret)
149*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
150*ae771770SStanislav Sedov N_("Cant read keyblock from file %s", ""),
151*ae771770SStanislav Sedov fkt->filename);
152b528cefcSMark Murray return ret;
153b528cefcSMark Murray }
154b528cefcSMark Murray
155b528cefcSMark Murray static krb5_error_code
krb5_kt_store_keyblock(krb5_context context,struct fkt_data * fkt,krb5_storage * sp,krb5_keyblock * p)156adb0ddaeSAssar Westerlund krb5_kt_store_keyblock(krb5_context context,
157*ae771770SStanislav Sedov struct fkt_data *fkt,
158adb0ddaeSAssar Westerlund krb5_storage *sp,
159b528cefcSMark Murray krb5_keyblock *p)
160b528cefcSMark Murray {
161b528cefcSMark Murray int ret;
162b528cefcSMark Murray
163b528cefcSMark Murray ret = krb5_store_int16(sp, p->keytype); /* keytype + etype */
164*ae771770SStanislav Sedov if(ret) {
165*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
166*ae771770SStanislav Sedov N_("Cant store keyblock to file %s", ""),
167*ae771770SStanislav Sedov fkt->filename);
168*ae771770SStanislav Sedov return ret;
169*ae771770SStanislav Sedov }
170adb0ddaeSAssar Westerlund ret = krb5_kt_store_data(context, sp, p->keyvalue);
171*ae771770SStanislav Sedov if (ret)
172*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
173*ae771770SStanislav Sedov N_("Cant store keyblock to file %s", ""),
174*ae771770SStanislav Sedov fkt->filename);
175b528cefcSMark Murray return ret;
176b528cefcSMark Murray }
177b528cefcSMark Murray
178b528cefcSMark Murray
179b528cefcSMark Murray static krb5_error_code
krb5_kt_ret_principal(krb5_context context,struct fkt_data * fkt,krb5_storage * sp,krb5_principal * princ)180adb0ddaeSAssar Westerlund krb5_kt_ret_principal(krb5_context context,
181*ae771770SStanislav Sedov struct fkt_data *fkt,
182adb0ddaeSAssar Westerlund krb5_storage *sp,
183b528cefcSMark Murray krb5_principal *princ)
184b528cefcSMark Murray {
185*ae771770SStanislav Sedov size_t i;
186b528cefcSMark Murray int ret;
187b528cefcSMark Murray krb5_principal p;
188c19800e8SDoug Rabson int16_t len;
189b528cefcSMark Murray
190b528cefcSMark Murray ALLOC(p, 1);
191adb0ddaeSAssar Westerlund if(p == NULL) {
192*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM,
193*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
194b528cefcSMark Murray return ENOMEM;
195adb0ddaeSAssar Westerlund }
196b528cefcSMark Murray
197c19800e8SDoug Rabson ret = krb5_ret_int16(sp, &len);
198c19800e8SDoug Rabson if(ret) {
199*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
200*ae771770SStanislav Sedov N_("Failed decoding length of "
201*ae771770SStanislav Sedov "keytab principal in keytab file %s", ""),
202*ae771770SStanislav Sedov fkt->filename);
203c19800e8SDoug Rabson goto out;
204c19800e8SDoug Rabson }
2058373020dSJacques Vidrine if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
206c19800e8SDoug Rabson len--;
207c19800e8SDoug Rabson if (len < 0) {
208c19800e8SDoug Rabson ret = KRB5_KT_END;
209*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
210*ae771770SStanislav Sedov N_("Keytab principal contains "
211*ae771770SStanislav Sedov "invalid length in keytab %s", ""),
212*ae771770SStanislav Sedov fkt->filename);
213c19800e8SDoug Rabson goto out;
214c19800e8SDoug Rabson }
215adb0ddaeSAssar Westerlund ret = krb5_kt_ret_string(context, sp, &p->realm);
216*ae771770SStanislav Sedov if(ret) {
217*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
218*ae771770SStanislav Sedov N_("Can't read realm from keytab: %s", ""),
219*ae771770SStanislav Sedov fkt->filename);
220c19800e8SDoug Rabson goto out;
221*ae771770SStanislav Sedov }
222c19800e8SDoug Rabson p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val));
223adb0ddaeSAssar Westerlund if(p->name.name_string.val == NULL) {
224c19800e8SDoug Rabson ret = ENOMEM;
225*ae771770SStanislav Sedov krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
226c19800e8SDoug Rabson goto out;
227adb0ddaeSAssar Westerlund }
228c19800e8SDoug Rabson p->name.name_string.len = len;
229b528cefcSMark Murray for(i = 0; i < p->name.name_string.len; i++){
230adb0ddaeSAssar Westerlund ret = krb5_kt_ret_string(context, sp, p->name.name_string.val + i);
231*ae771770SStanislav Sedov if(ret) {
232*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
233*ae771770SStanislav Sedov N_("Can't read principal from "
234*ae771770SStanislav Sedov "keytab: %s", ""),
235*ae771770SStanislav Sedov fkt->filename);
236c19800e8SDoug Rabson goto out;
237b528cefcSMark Murray }
238*ae771770SStanislav Sedov }
239b528cefcSMark Murray if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
240b528cefcSMark Murray p->name.name_type = KRB5_NT_UNKNOWN;
241b528cefcSMark Murray else {
242b528cefcSMark Murray int32_t tmp32;
243b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp32);
244b528cefcSMark Murray p->name.name_type = tmp32;
245*ae771770SStanislav Sedov if (ret) {
246*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
247*ae771770SStanislav Sedov N_("Can't read name-type from "
248*ae771770SStanislav Sedov "keytab: %s", ""),
249*ae771770SStanislav Sedov fkt->filename);
250c19800e8SDoug Rabson goto out;
251b528cefcSMark Murray }
252*ae771770SStanislav Sedov }
253b528cefcSMark Murray *princ = p;
254b528cefcSMark Murray return 0;
255c19800e8SDoug Rabson out:
256c19800e8SDoug Rabson krb5_free_principal(context, p);
257c19800e8SDoug Rabson return ret;
258b528cefcSMark Murray }
259b528cefcSMark Murray
260b528cefcSMark Murray static krb5_error_code
krb5_kt_store_principal(krb5_context context,krb5_storage * sp,krb5_principal p)261adb0ddaeSAssar Westerlund krb5_kt_store_principal(krb5_context context,
262adb0ddaeSAssar Westerlund krb5_storage *sp,
263b528cefcSMark Murray krb5_principal p)
264b528cefcSMark Murray {
265*ae771770SStanislav Sedov size_t i;
266b528cefcSMark Murray int ret;
267b528cefcSMark Murray
268b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
269b528cefcSMark Murray ret = krb5_store_int16(sp, p->name.name_string.len + 1);
270b528cefcSMark Murray else
271b528cefcSMark Murray ret = krb5_store_int16(sp, p->name.name_string.len);
272b528cefcSMark Murray if(ret) return ret;
273b528cefcSMark Murray ret = krb5_kt_store_string(sp, p->realm);
274b528cefcSMark Murray if(ret) return ret;
275b528cefcSMark Murray for(i = 0; i < p->name.name_string.len; i++){
276b528cefcSMark Murray ret = krb5_kt_store_string(sp, p->name.name_string.val[i]);
277adb0ddaeSAssar Westerlund if(ret)
278adb0ddaeSAssar Westerlund return ret;
279b528cefcSMark Murray }
280b528cefcSMark Murray if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
281b528cefcSMark Murray ret = krb5_store_int32(sp, p->name.name_type);
282b528cefcSMark Murray if(ret)
283b528cefcSMark Murray return ret;
284b528cefcSMark Murray }
285b528cefcSMark Murray
286b528cefcSMark Murray return 0;
287b528cefcSMark Murray }
288b528cefcSMark Murray
289*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_resolve(krb5_context context,const char * name,krb5_keytab id)290b528cefcSMark Murray fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
291b528cefcSMark Murray {
292b528cefcSMark Murray struct fkt_data *d;
293adb0ddaeSAssar Westerlund
294b528cefcSMark Murray d = malloc(sizeof(*d));
295adb0ddaeSAssar Westerlund if(d == NULL) {
296*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
297b528cefcSMark Murray return ENOMEM;
298adb0ddaeSAssar Westerlund }
299b528cefcSMark Murray d->filename = strdup(name);
300b528cefcSMark Murray if(d->filename == NULL) {
301b528cefcSMark Murray free(d);
302*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
303b528cefcSMark Murray return ENOMEM;
304b528cefcSMark Murray }
305c19800e8SDoug Rabson d->flags = 0;
306b528cefcSMark Murray id->data = d;
307b528cefcSMark Murray return 0;
308b528cefcSMark Murray }
309b528cefcSMark Murray
310*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_resolve_java14(krb5_context context,const char * name,krb5_keytab id)311c19800e8SDoug Rabson fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id)
312c19800e8SDoug Rabson {
313c19800e8SDoug Rabson krb5_error_code ret;
314c19800e8SDoug Rabson
315c19800e8SDoug Rabson ret = fkt_resolve(context, name, id);
316c19800e8SDoug Rabson if (ret == 0) {
317c19800e8SDoug Rabson struct fkt_data *d = id->data;
318c19800e8SDoug Rabson d->flags |= KRB5_KT_FL_JAVA;
319c19800e8SDoug Rabson }
320c19800e8SDoug Rabson return ret;
321c19800e8SDoug Rabson }
322c19800e8SDoug Rabson
323*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_close(krb5_context context,krb5_keytab id)324b528cefcSMark Murray fkt_close(krb5_context context, krb5_keytab id)
325b528cefcSMark Murray {
326b528cefcSMark Murray struct fkt_data *d = id->data;
327b528cefcSMark Murray free(d->filename);
328b528cefcSMark Murray free(d);
329b528cefcSMark Murray return 0;
330b528cefcSMark Murray }
331b528cefcSMark Murray
332*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_destroy(krb5_context context,krb5_keytab id)333*ae771770SStanislav Sedov fkt_destroy(krb5_context context, krb5_keytab id)
334*ae771770SStanislav Sedov {
335*ae771770SStanislav Sedov struct fkt_data *d = id->data;
336*ae771770SStanislav Sedov _krb5_erase_file(context, d->filename);
337*ae771770SStanislav Sedov return 0;
338*ae771770SStanislav Sedov }
339*ae771770SStanislav Sedov
340*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_get_name(krb5_context context,krb5_keytab id,char * name,size_t namesize)341b528cefcSMark Murray fkt_get_name(krb5_context context,
342b528cefcSMark Murray krb5_keytab id,
343b528cefcSMark Murray char *name,
344b528cefcSMark Murray size_t namesize)
345b528cefcSMark Murray {
346b528cefcSMark Murray /* This function is XXX */
347b528cefcSMark Murray struct fkt_data *d = id->data;
348b528cefcSMark Murray strlcpy(name, d->filename, namesize);
349b528cefcSMark Murray return 0;
350b528cefcSMark Murray }
351b528cefcSMark Murray
352b528cefcSMark Murray static void
storage_set_flags(krb5_context context,krb5_storage * sp,int vno)353b528cefcSMark Murray storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
354b528cefcSMark Murray {
355b528cefcSMark Murray int flags = 0;
356b528cefcSMark Murray switch(vno) {
357b528cefcSMark Murray case KRB5_KT_VNO_1:
358b528cefcSMark Murray flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
359b528cefcSMark Murray flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
360b528cefcSMark Murray flags |= KRB5_STORAGE_HOST_BYTEORDER;
361b528cefcSMark Murray break;
362b528cefcSMark Murray case KRB5_KT_VNO_2:
363b528cefcSMark Murray break;
364b528cefcSMark Murray default:
3658373020dSJacques Vidrine krb5_warnx(context,
3668373020dSJacques Vidrine "storage_set_flags called with bad vno (%d)", vno);
367b528cefcSMark Murray }
368b528cefcSMark Murray krb5_storage_set_flags(sp, flags);
369b528cefcSMark Murray }
370b528cefcSMark Murray
371b528cefcSMark Murray static krb5_error_code
fkt_start_seq_get_int(krb5_context context,krb5_keytab id,int flags,int exclusive,krb5_kt_cursor * c)372b528cefcSMark Murray fkt_start_seq_get_int(krb5_context context,
373b528cefcSMark Murray krb5_keytab id,
374b528cefcSMark Murray int flags,
375c19800e8SDoug Rabson int exclusive,
376b528cefcSMark Murray krb5_kt_cursor *c)
377b528cefcSMark Murray {
378b528cefcSMark Murray int8_t pvno, tag;
379b528cefcSMark Murray krb5_error_code ret;
380b528cefcSMark Murray struct fkt_data *d = id->data;
381b528cefcSMark Murray
382b528cefcSMark Murray c->fd = open (d->filename, flags);
383adb0ddaeSAssar Westerlund if (c->fd < 0) {
384adb0ddaeSAssar Westerlund ret = errno;
385*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
386*ae771770SStanislav Sedov N_("keytab %s open failed: %s", ""),
387*ae771770SStanislav Sedov d->filename, strerror(ret));
388adb0ddaeSAssar Westerlund return ret;
389adb0ddaeSAssar Westerlund }
390*ae771770SStanislav Sedov rk_cloexec(c->fd);
391c19800e8SDoug Rabson ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
392c19800e8SDoug Rabson if (ret) {
393c19800e8SDoug Rabson close(c->fd);
394c19800e8SDoug Rabson return ret;
395c19800e8SDoug Rabson }
396b528cefcSMark Murray c->sp = krb5_storage_from_fd(c->fd);
397c19800e8SDoug Rabson if (c->sp == NULL) {
398c19800e8SDoug Rabson _krb5_xunlock(context, c->fd);
399c19800e8SDoug Rabson close(c->fd);
400*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM,
401*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
402c19800e8SDoug Rabson return ENOMEM;
403c19800e8SDoug Rabson }
4048373020dSJacques Vidrine krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
405b528cefcSMark Murray ret = krb5_ret_int8(c->sp, &pvno);
406b528cefcSMark Murray if(ret) {
407b528cefcSMark Murray krb5_storage_free(c->sp);
408c19800e8SDoug Rabson _krb5_xunlock(context, c->fd);
409b528cefcSMark Murray close(c->fd);
410*ae771770SStanislav Sedov krb5_clear_error_message(context);
411b528cefcSMark Murray return ret;
412b528cefcSMark Murray }
413b528cefcSMark Murray if(pvno != 5) {
414b528cefcSMark Murray krb5_storage_free(c->sp);
415c19800e8SDoug Rabson _krb5_xunlock(context, c->fd);
416b528cefcSMark Murray close(c->fd);
417*ae771770SStanislav Sedov krb5_clear_error_message (context);
418b528cefcSMark Murray return KRB5_KEYTAB_BADVNO;
419b528cefcSMark Murray }
420b528cefcSMark Murray ret = krb5_ret_int8(c->sp, &tag);
421b528cefcSMark Murray if (ret) {
422b528cefcSMark Murray krb5_storage_free(c->sp);
423c19800e8SDoug Rabson _krb5_xunlock(context, c->fd);
424b528cefcSMark Murray close(c->fd);
425*ae771770SStanislav Sedov krb5_clear_error_message(context);
426b528cefcSMark Murray return ret;
427b528cefcSMark Murray }
428b528cefcSMark Murray id->version = tag;
429b528cefcSMark Murray storage_set_flags(context, c->sp, id->version);
430b528cefcSMark Murray return 0;
431b528cefcSMark Murray }
432b528cefcSMark Murray
433*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_start_seq_get(krb5_context context,krb5_keytab id,krb5_kt_cursor * c)434b528cefcSMark Murray fkt_start_seq_get(krb5_context context,
435b528cefcSMark Murray krb5_keytab id,
436b528cefcSMark Murray krb5_kt_cursor *c)
437b528cefcSMark Murray {
438*ae771770SStanislav Sedov return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY | O_CLOEXEC, 0, c);
439b528cefcSMark Murray }
440b528cefcSMark Murray
441b528cefcSMark Murray static krb5_error_code
fkt_next_entry_int(krb5_context context,krb5_keytab id,krb5_keytab_entry * entry,krb5_kt_cursor * cursor,off_t * start,off_t * end)442b528cefcSMark Murray fkt_next_entry_int(krb5_context context,
443b528cefcSMark Murray krb5_keytab id,
444b528cefcSMark Murray krb5_keytab_entry *entry,
445b528cefcSMark Murray krb5_kt_cursor *cursor,
446b528cefcSMark Murray off_t *start,
447b528cefcSMark Murray off_t *end)
448b528cefcSMark Murray {
449*ae771770SStanislav Sedov struct fkt_data *d = id->data;
450b528cefcSMark Murray int32_t len;
451b528cefcSMark Murray int ret;
452b528cefcSMark Murray int8_t tmp8;
453b528cefcSMark Murray int32_t tmp32;
454*ae771770SStanislav Sedov uint32_t utmp32;
4558373020dSJacques Vidrine off_t pos, curpos;
456b528cefcSMark Murray
4578373020dSJacques Vidrine pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
458b528cefcSMark Murray loop:
459b528cefcSMark Murray ret = krb5_ret_int32(cursor->sp, &len);
460b528cefcSMark Murray if (ret)
461b528cefcSMark Murray return ret;
462b528cefcSMark Murray if(len < 0) {
4638373020dSJacques Vidrine pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
464b528cefcSMark Murray goto loop;
465b528cefcSMark Murray }
466*ae771770SStanislav Sedov ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
467b528cefcSMark Murray if (ret)
468b528cefcSMark Murray goto out;
469*ae771770SStanislav Sedov ret = krb5_ret_uint32(cursor->sp, &utmp32);
470*ae771770SStanislav Sedov entry->timestamp = utmp32;
471b528cefcSMark Murray if (ret)
472b528cefcSMark Murray goto out;
473b528cefcSMark Murray ret = krb5_ret_int8(cursor->sp, &tmp8);
474b528cefcSMark Murray if (ret)
475b528cefcSMark Murray goto out;
476b528cefcSMark Murray entry->vno = tmp8;
477*ae771770SStanislav Sedov ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
478b528cefcSMark Murray if (ret)
479b528cefcSMark Murray goto out;
4808373020dSJacques Vidrine /* there might be a 32 bit kvno here
4818373020dSJacques Vidrine * if it's zero, assume that the 8bit one was right,
4828373020dSJacques Vidrine * otherwise trust the new value */
4838373020dSJacques Vidrine curpos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
484c19800e8SDoug Rabson if(len + 4 + pos - curpos >= 4) {
4858373020dSJacques Vidrine ret = krb5_ret_int32(cursor->sp, &tmp32);
486*ae771770SStanislav Sedov if (ret == 0 && tmp32 != 0)
4878373020dSJacques Vidrine entry->vno = tmp32;
4888373020dSJacques Vidrine }
489*ae771770SStanislav Sedov /* there might be a flags field here */
490*ae771770SStanislav Sedov if(len + 4 + pos - curpos >= 8) {
491*ae771770SStanislav Sedov ret = krb5_ret_uint32(cursor->sp, &utmp32);
492*ae771770SStanislav Sedov if (ret == 0)
493*ae771770SStanislav Sedov entry->flags = utmp32;
494*ae771770SStanislav Sedov } else
495*ae771770SStanislav Sedov entry->flags = 0;
496*ae771770SStanislav Sedov
497*ae771770SStanislav Sedov entry->aliases = NULL;
498*ae771770SStanislav Sedov
499b528cefcSMark Murray if(start) *start = pos;
500c19800e8SDoug Rabson if(end) *end = pos + 4 + len;
501b528cefcSMark Murray out:
5028373020dSJacques Vidrine krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
503b528cefcSMark Murray return ret;
504b528cefcSMark Murray }
505b528cefcSMark Murray
506*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_next_entry(krb5_context context,krb5_keytab id,krb5_keytab_entry * entry,krb5_kt_cursor * cursor)507b528cefcSMark Murray fkt_next_entry(krb5_context context,
508b528cefcSMark Murray krb5_keytab id,
509b528cefcSMark Murray krb5_keytab_entry *entry,
510b528cefcSMark Murray krb5_kt_cursor *cursor)
511b528cefcSMark Murray {
512b528cefcSMark Murray return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL);
513b528cefcSMark Murray }
514b528cefcSMark Murray
515*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_end_seq_get(krb5_context context,krb5_keytab id,krb5_kt_cursor * cursor)516b528cefcSMark Murray fkt_end_seq_get(krb5_context context,
517b528cefcSMark Murray krb5_keytab id,
518b528cefcSMark Murray krb5_kt_cursor *cursor)
519b528cefcSMark Murray {
520b528cefcSMark Murray krb5_storage_free(cursor->sp);
521c19800e8SDoug Rabson _krb5_xunlock(context, cursor->fd);
522b528cefcSMark Murray close(cursor->fd);
523b528cefcSMark Murray return 0;
524b528cefcSMark Murray }
525b528cefcSMark Murray
526*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_setup_keytab(krb5_context context,krb5_keytab id,krb5_storage * sp)5278373020dSJacques Vidrine fkt_setup_keytab(krb5_context context,
5288373020dSJacques Vidrine krb5_keytab id,
5298373020dSJacques Vidrine krb5_storage *sp)
5308373020dSJacques Vidrine {
5318373020dSJacques Vidrine krb5_error_code ret;
5328373020dSJacques Vidrine ret = krb5_store_int8(sp, 5);
5338373020dSJacques Vidrine if(ret)
5348373020dSJacques Vidrine return ret;
5358373020dSJacques Vidrine if(id->version == 0)
5368373020dSJacques Vidrine id->version = KRB5_KT_VNO;
5378373020dSJacques Vidrine return krb5_store_int8 (sp, id->version);
5388373020dSJacques Vidrine }
5398373020dSJacques Vidrine
540*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_add_entry(krb5_context context,krb5_keytab id,krb5_keytab_entry * entry)541b528cefcSMark Murray fkt_add_entry(krb5_context context,
542b528cefcSMark Murray krb5_keytab id,
543b528cefcSMark Murray krb5_keytab_entry *entry)
544b528cefcSMark Murray {
545b528cefcSMark Murray int ret;
546b528cefcSMark Murray int fd;
547b528cefcSMark Murray krb5_storage *sp;
548b528cefcSMark Murray struct fkt_data *d = id->data;
549b528cefcSMark Murray krb5_data keytab;
550b528cefcSMark Murray int32_t len;
551b528cefcSMark Murray
552*ae771770SStanislav Sedov fd = open (d->filename, O_RDWR | O_BINARY | O_CLOEXEC);
553b528cefcSMark Murray if (fd < 0) {
554*ae771770SStanislav Sedov fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600);
555adb0ddaeSAssar Westerlund if (fd < 0) {
556adb0ddaeSAssar Westerlund ret = errno;
557*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
558*ae771770SStanislav Sedov N_("open(%s): %s", ""), d->filename,
559adb0ddaeSAssar Westerlund strerror(ret));
560adb0ddaeSAssar Westerlund return ret;
561adb0ddaeSAssar Westerlund }
562*ae771770SStanislav Sedov rk_cloexec(fd);
563*ae771770SStanislav Sedov
564c19800e8SDoug Rabson ret = _krb5_xlock(context, fd, 1, d->filename);
565c19800e8SDoug Rabson if (ret) {
566c19800e8SDoug Rabson close(fd);
567c19800e8SDoug Rabson return ret;
568c19800e8SDoug Rabson }
569b528cefcSMark Murray sp = krb5_storage_from_fd(fd);
5708373020dSJacques Vidrine krb5_storage_set_eof_code(sp, KRB5_KT_END);
5718373020dSJacques Vidrine ret = fkt_setup_keytab(context, id, sp);
572b528cefcSMark Murray if(ret) {
573c19800e8SDoug Rabson goto out;
574b528cefcSMark Murray }
575b528cefcSMark Murray storage_set_flags(context, sp, id->version);
576b528cefcSMark Murray } else {
577b528cefcSMark Murray int8_t pvno, tag;
578*ae771770SStanislav Sedov
579*ae771770SStanislav Sedov rk_cloexec(fd);
580*ae771770SStanislav Sedov
581c19800e8SDoug Rabson ret = _krb5_xlock(context, fd, 1, d->filename);
582c19800e8SDoug Rabson if (ret) {
583c19800e8SDoug Rabson close(fd);
584c19800e8SDoug Rabson return ret;
585c19800e8SDoug Rabson }
586b528cefcSMark Murray sp = krb5_storage_from_fd(fd);
5878373020dSJacques Vidrine krb5_storage_set_eof_code(sp, KRB5_KT_END);
588b528cefcSMark Murray ret = krb5_ret_int8(sp, &pvno);
589b528cefcSMark Murray if(ret) {
5908373020dSJacques Vidrine /* we probably have a zero byte file, so try to set it up
5918373020dSJacques Vidrine properly */
5928373020dSJacques Vidrine ret = fkt_setup_keytab(context, id, sp);
5938373020dSJacques Vidrine if(ret) {
594*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
595*ae771770SStanislav Sedov N_("%s: keytab is corrupted: %s", ""),
5968373020dSJacques Vidrine d->filename, strerror(ret));
597c19800e8SDoug Rabson goto out;
598b528cefcSMark Murray }
5998373020dSJacques Vidrine storage_set_flags(context, sp, id->version);
6008373020dSJacques Vidrine } else {
601b528cefcSMark Murray if(pvno != 5) {
6028373020dSJacques Vidrine ret = KRB5_KEYTAB_BADVNO;
603*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
604*ae771770SStanislav Sedov N_("Bad version in keytab %s", ""),
605*ae771770SStanislav Sedov d->filename);
606c19800e8SDoug Rabson goto out;
607b528cefcSMark Murray }
608b528cefcSMark Murray ret = krb5_ret_int8 (sp, &tag);
609b528cefcSMark Murray if (ret) {
610*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
611*ae771770SStanislav Sedov N_("failed reading tag from "
612*ae771770SStanislav Sedov "keytab %s", ""),
613*ae771770SStanislav Sedov d->filename);
614c19800e8SDoug Rabson goto out;
615b528cefcSMark Murray }
616b528cefcSMark Murray id->version = tag;
617b528cefcSMark Murray storage_set_flags(context, sp, id->version);
618b528cefcSMark Murray }
6198373020dSJacques Vidrine }
620b528cefcSMark Murray
621b528cefcSMark Murray {
622b528cefcSMark Murray krb5_storage *emem;
623b528cefcSMark Murray emem = krb5_storage_emem();
624b528cefcSMark Murray if(emem == NULL) {
625b528cefcSMark Murray ret = ENOMEM;
626*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
627*ae771770SStanislav Sedov N_("malloc: out of memory", ""));
628b528cefcSMark Murray goto out;
629b528cefcSMark Murray }
630adb0ddaeSAssar Westerlund ret = krb5_kt_store_principal(context, emem, entry->principal);
631b528cefcSMark Murray if(ret) {
632*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
633*ae771770SStanislav Sedov N_("Failed storing principal "
634*ae771770SStanislav Sedov "in keytab %s", ""),
635*ae771770SStanislav Sedov d->filename);
636b528cefcSMark Murray krb5_storage_free(emem);
637b528cefcSMark Murray goto out;
638b528cefcSMark Murray }
639b528cefcSMark Murray ret = krb5_store_int32 (emem, entry->timestamp);
640b528cefcSMark Murray if(ret) {
641*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
642*ae771770SStanislav Sedov N_("Failed storing timpstamp "
643*ae771770SStanislav Sedov "in keytab %s", ""),
644*ae771770SStanislav Sedov d->filename);
645b528cefcSMark Murray krb5_storage_free(emem);
646b528cefcSMark Murray goto out;
647b528cefcSMark Murray }
6488373020dSJacques Vidrine ret = krb5_store_int8 (emem, entry->vno % 256);
649b528cefcSMark Murray if(ret) {
650*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
651*ae771770SStanislav Sedov N_("Failed storing kvno "
652*ae771770SStanislav Sedov "in keytab %s", ""),
653*ae771770SStanislav Sedov d->filename);
654b528cefcSMark Murray krb5_storage_free(emem);
655b528cefcSMark Murray goto out;
656b528cefcSMark Murray }
657*ae771770SStanislav Sedov ret = krb5_kt_store_keyblock (context, d, emem, &entry->keyblock);
658b528cefcSMark Murray if(ret) {
659b528cefcSMark Murray krb5_storage_free(emem);
660b528cefcSMark Murray goto out;
661b528cefcSMark Murray }
662c19800e8SDoug Rabson if ((d->flags & KRB5_KT_FL_JAVA) == 0) {
6638373020dSJacques Vidrine ret = krb5_store_int32 (emem, entry->vno);
6648373020dSJacques Vidrine if (ret) {
665*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
666*ae771770SStanislav Sedov N_("Failed storing extended kvno "
667*ae771770SStanislav Sedov "in keytab %s", ""),
668*ae771770SStanislav Sedov d->filename);
669*ae771770SStanislav Sedov krb5_storage_free(emem);
670*ae771770SStanislav Sedov goto out;
671*ae771770SStanislav Sedov }
672*ae771770SStanislav Sedov ret = krb5_store_uint32 (emem, entry->flags);
673*ae771770SStanislav Sedov if (ret) {
674*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
675*ae771770SStanislav Sedov N_("Failed storing extended kvno "
676*ae771770SStanislav Sedov "in keytab %s", ""),
677*ae771770SStanislav Sedov d->filename);
6788373020dSJacques Vidrine krb5_storage_free(emem);
6798373020dSJacques Vidrine goto out;
6808373020dSJacques Vidrine }
681c19800e8SDoug Rabson }
6828373020dSJacques Vidrine
683b528cefcSMark Murray ret = krb5_storage_to_data(emem, &keytab);
684b528cefcSMark Murray krb5_storage_free(emem);
685*ae771770SStanislav Sedov if(ret) {
686*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
687*ae771770SStanislav Sedov N_("Failed converting keytab entry "
688*ae771770SStanislav Sedov "to memory block for keytab %s", ""),
689*ae771770SStanislav Sedov d->filename);
690b528cefcSMark Murray goto out;
691b528cefcSMark Murray }
692*ae771770SStanislav Sedov }
693b528cefcSMark Murray
694b528cefcSMark Murray while(1) {
695b528cefcSMark Murray ret = krb5_ret_int32(sp, &len);
6968373020dSJacques Vidrine if(ret == KRB5_KT_END) {
697b528cefcSMark Murray len = keytab.length;
698b528cefcSMark Murray break;
699b528cefcSMark Murray }
700b528cefcSMark Murray if(len < 0) {
701b528cefcSMark Murray len = -len;
702*ae771770SStanislav Sedov if(len >= (int)keytab.length) {
7038373020dSJacques Vidrine krb5_storage_seek(sp, -4, SEEK_CUR);
704b528cefcSMark Murray break;
705b528cefcSMark Murray }
706b528cefcSMark Murray }
7078373020dSJacques Vidrine krb5_storage_seek(sp, len, SEEK_CUR);
708b528cefcSMark Murray }
709b528cefcSMark Murray ret = krb5_store_int32(sp, len);
710*ae771770SStanislav Sedov if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) {
711b528cefcSMark Murray ret = errno;
712*ae771770SStanislav Sedov krb5_set_error_message(context, ret,
713*ae771770SStanislav Sedov N_("Failed writing keytab block "
714*ae771770SStanislav Sedov "in keytab %s: %s", ""),
715*ae771770SStanislav Sedov d->filename, strerror(ret));
716*ae771770SStanislav Sedov }
717b528cefcSMark Murray memset(keytab.data, 0, keytab.length);
718b528cefcSMark Murray krb5_data_free(&keytab);
719b528cefcSMark Murray out:
720b528cefcSMark Murray krb5_storage_free(sp);
721c19800e8SDoug Rabson _krb5_xunlock(context, fd);
722b528cefcSMark Murray close(fd);
723b528cefcSMark Murray return ret;
724b528cefcSMark Murray }
725b528cefcSMark Murray
726*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
fkt_remove_entry(krb5_context context,krb5_keytab id,krb5_keytab_entry * entry)727b528cefcSMark Murray fkt_remove_entry(krb5_context context,
728b528cefcSMark Murray krb5_keytab id,
729b528cefcSMark Murray krb5_keytab_entry *entry)
730b528cefcSMark Murray {
731b528cefcSMark Murray krb5_keytab_entry e;
732b528cefcSMark Murray krb5_kt_cursor cursor;
733b528cefcSMark Murray off_t pos_start, pos_end;
734b528cefcSMark Murray int found = 0;
7355bda878eSJacques Vidrine krb5_error_code ret;
736b528cefcSMark Murray
737*ae771770SStanislav Sedov ret = fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY | O_CLOEXEC, 1, &cursor);
7385bda878eSJacques Vidrine if(ret != 0)
7395bda878eSJacques Vidrine goto out; /* return other error here? */
740b528cefcSMark Murray while(fkt_next_entry_int(context, id, &e, &cursor,
741b528cefcSMark Murray &pos_start, &pos_end) == 0) {
742b528cefcSMark Murray if(krb5_kt_compare(context, &e, entry->principal,
743b528cefcSMark Murray entry->vno, entry->keyblock.keytype)) {
744b528cefcSMark Murray int32_t len;
745b528cefcSMark Murray unsigned char buf[128];
746b528cefcSMark Murray found = 1;
7478373020dSJacques Vidrine krb5_storage_seek(cursor.sp, pos_start, SEEK_SET);
748b528cefcSMark Murray len = pos_end - pos_start - 4;
749b528cefcSMark Murray krb5_store_int32(cursor.sp, -len);
750b528cefcSMark Murray memset(buf, 0, sizeof(buf));
751b528cefcSMark Murray while(len > 0) {
752*ae771770SStanislav Sedov krb5_storage_write(cursor.sp, buf,
753*ae771770SStanislav Sedov min((size_t)len, sizeof(buf)));
754*ae771770SStanislav Sedov len -= min((size_t)len, sizeof(buf));
755b528cefcSMark Murray }
756b528cefcSMark Murray }
757c19800e8SDoug Rabson krb5_kt_free_entry(context, &e);
758b528cefcSMark Murray }
759b528cefcSMark Murray krb5_kt_end_seq_get(context, id, &cursor);
7605bda878eSJacques Vidrine out:
761adb0ddaeSAssar Westerlund if (!found) {
762*ae771770SStanislav Sedov krb5_clear_error_message (context);
763b528cefcSMark Murray return KRB5_KT_NOTFOUND;
764adb0ddaeSAssar Westerlund }
765b528cefcSMark Murray return 0;
766b528cefcSMark Murray }
767b528cefcSMark Murray
768b528cefcSMark Murray const krb5_kt_ops krb5_fkt_ops = {
769b528cefcSMark Murray "FILE",
770b528cefcSMark Murray fkt_resolve,
771b528cefcSMark Murray fkt_get_name,
772b528cefcSMark Murray fkt_close,
773*ae771770SStanislav Sedov fkt_destroy,
774b528cefcSMark Murray NULL, /* get */
775b528cefcSMark Murray fkt_start_seq_get,
776b528cefcSMark Murray fkt_next_entry,
777b528cefcSMark Murray fkt_end_seq_get,
778b528cefcSMark Murray fkt_add_entry,
779b528cefcSMark Murray fkt_remove_entry
780b528cefcSMark Murray };
781c19800e8SDoug Rabson
782c19800e8SDoug Rabson const krb5_kt_ops krb5_wrfkt_ops = {
783c19800e8SDoug Rabson "WRFILE",
784c19800e8SDoug Rabson fkt_resolve,
785c19800e8SDoug Rabson fkt_get_name,
786c19800e8SDoug Rabson fkt_close,
787*ae771770SStanislav Sedov fkt_destroy,
788c19800e8SDoug Rabson NULL, /* get */
789c19800e8SDoug Rabson fkt_start_seq_get,
790c19800e8SDoug Rabson fkt_next_entry,
791c19800e8SDoug Rabson fkt_end_seq_get,
792c19800e8SDoug Rabson fkt_add_entry,
793c19800e8SDoug Rabson fkt_remove_entry
794c19800e8SDoug Rabson };
795c19800e8SDoug Rabson
796c19800e8SDoug Rabson const krb5_kt_ops krb5_javakt_ops = {
797c19800e8SDoug Rabson "JAVA14",
798c19800e8SDoug Rabson fkt_resolve_java14,
799c19800e8SDoug Rabson fkt_get_name,
800c19800e8SDoug Rabson fkt_close,
801*ae771770SStanislav Sedov fkt_destroy,
802c19800e8SDoug Rabson NULL, /* get */
803c19800e8SDoug Rabson fkt_start_seq_get,
804c19800e8SDoug Rabson fkt_next_entry,
805c19800e8SDoug Rabson fkt_end_seq_get,
806c19800e8SDoug Rabson fkt_add_entry,
807c19800e8SDoug Rabson fkt_remove_entry
808c19800e8SDoug Rabson };
809