etc/services - sync with NetBSD-8
[minix.git] / crypto / external / bsd / heimdal / dist / lib / krb5 / keytab_file.c
blob2abbd9afb3174fd988df6133e7d12a9e824d6f07
1 /* $NetBSD: keytab_file.c,v 1.1.1.2 2014/04/24 12:45:50 pettai Exp $ */
3 /*
4 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "krb5_locl.h"
38 #define KRB5_KT_VNO_1 1
39 #define KRB5_KT_VNO_2 2
40 #define KRB5_KT_VNO KRB5_KT_VNO_2
42 #define KRB5_KT_FL_JAVA 1
45 /* file operations -------------------------------------------- */
47 struct fkt_data {
48 char *filename;
49 int flags;
52 static krb5_error_code
53 krb5_kt_ret_data(krb5_context context,
54 krb5_storage *sp,
55 krb5_data *data)
57 int ret;
58 int16_t size;
59 ret = krb5_ret_int16(sp, &size);
60 if(ret)
61 return ret;
62 data->length = size;
63 data->data = malloc(size);
64 if (data->data == NULL) {
65 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
66 return ENOMEM;
68 ret = krb5_storage_read(sp, data->data, size);
69 if(ret != size)
70 return (ret < 0)? errno : KRB5_KT_END;
71 return 0;
74 static krb5_error_code
75 krb5_kt_ret_string(krb5_context context,
76 krb5_storage *sp,
77 heim_general_string *data)
79 int ret;
80 int16_t size;
81 ret = krb5_ret_int16(sp, &size);
82 if(ret)
83 return ret;
84 *data = malloc(size + 1);
85 if (*data == NULL) {
86 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
87 return ENOMEM;
89 ret = krb5_storage_read(sp, *data, size);
90 (*data)[size] = '\0';
91 if(ret != size)
92 return (ret < 0)? errno : KRB5_KT_END;
93 return 0;
96 static krb5_error_code
97 krb5_kt_store_data(krb5_context context,
98 krb5_storage *sp,
99 krb5_data data)
101 int ret;
102 ret = krb5_store_int16(sp, data.length);
103 if(ret < 0)
104 return ret;
105 ret = krb5_storage_write(sp, data.data, data.length);
106 if(ret != (int)data.length){
107 if(ret < 0)
108 return errno;
109 return KRB5_KT_END;
111 return 0;
114 static krb5_error_code
115 krb5_kt_store_string(krb5_storage *sp,
116 heim_general_string data)
118 int ret;
119 size_t len = strlen(data);
120 ret = krb5_store_int16(sp, len);
121 if(ret < 0)
122 return ret;
123 ret = krb5_storage_write(sp, data, len);
124 if(ret != (int)len){
125 if(ret < 0)
126 return errno;
127 return KRB5_KT_END;
129 return 0;
132 static krb5_error_code
133 krb5_kt_ret_keyblock(krb5_context context,
134 struct fkt_data *fkt,
135 krb5_storage *sp,
136 krb5_keyblock *p)
138 int ret;
139 int16_t tmp;
141 ret = krb5_ret_int16(sp, &tmp); /* keytype + etype */
142 if(ret) {
143 krb5_set_error_message(context, ret,
144 N_("Cant read keyblock from file %s", ""),
145 fkt->filename);
146 return ret;
148 p->keytype = tmp;
149 ret = krb5_kt_ret_data(context, sp, &p->keyvalue);
150 if (ret)
151 krb5_set_error_message(context, ret,
152 N_("Cant read keyblock from file %s", ""),
153 fkt->filename);
154 return ret;
157 static krb5_error_code
158 krb5_kt_store_keyblock(krb5_context context,
159 struct fkt_data *fkt,
160 krb5_storage *sp,
161 krb5_keyblock *p)
163 int ret;
165 ret = krb5_store_int16(sp, p->keytype); /* keytype + etype */
166 if(ret) {
167 krb5_set_error_message(context, ret,
168 N_("Cant store keyblock to file %s", ""),
169 fkt->filename);
170 return ret;
172 ret = krb5_kt_store_data(context, sp, p->keyvalue);
173 if (ret)
174 krb5_set_error_message(context, ret,
175 N_("Cant store keyblock to file %s", ""),
176 fkt->filename);
177 return ret;
181 static krb5_error_code
182 krb5_kt_ret_principal(krb5_context context,
183 struct fkt_data *fkt,
184 krb5_storage *sp,
185 krb5_principal *princ)
187 size_t i;
188 int ret;
189 krb5_principal p;
190 int16_t len;
192 ALLOC(p, 1);
193 if(p == NULL) {
194 krb5_set_error_message(context, ENOMEM,
195 N_("malloc: out of memory", ""));
196 return ENOMEM;
199 ret = krb5_ret_int16(sp, &len);
200 if(ret) {
201 krb5_set_error_message(context, ret,
202 N_("Failed decoding length of "
203 "keytab principal in keytab file %s", ""),
204 fkt->filename);
205 goto out;
207 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
208 len--;
209 if (len < 0) {
210 ret = KRB5_KT_END;
211 krb5_set_error_message(context, ret,
212 N_("Keytab principal contains "
213 "invalid length in keytab %s", ""),
214 fkt->filename);
215 goto out;
217 ret = krb5_kt_ret_string(context, sp, &p->realm);
218 if(ret) {
219 krb5_set_error_message(context, ret,
220 N_("Can't read realm from keytab: %s", ""),
221 fkt->filename);
222 goto out;
224 p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val));
225 if(p->name.name_string.val == NULL) {
226 ret = ENOMEM;
227 krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
228 goto out;
230 p->name.name_string.len = len;
231 for(i = 0; i < p->name.name_string.len; i++){
232 ret = krb5_kt_ret_string(context, sp, p->name.name_string.val + i);
233 if(ret) {
234 krb5_set_error_message(context, ret,
235 N_("Can't read principal from "
236 "keytab: %s", ""),
237 fkt->filename);
238 goto out;
241 if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
242 p->name.name_type = KRB5_NT_UNKNOWN;
243 else {
244 int32_t tmp32;
245 ret = krb5_ret_int32(sp, &tmp32);
246 p->name.name_type = tmp32;
247 if (ret) {
248 krb5_set_error_message(context, ret,
249 N_("Can't read name-type from "
250 "keytab: %s", ""),
251 fkt->filename);
252 goto out;
255 *princ = p;
256 return 0;
257 out:
258 krb5_free_principal(context, p);
259 return ret;
262 static krb5_error_code
263 krb5_kt_store_principal(krb5_context context,
264 krb5_storage *sp,
265 krb5_principal p)
267 size_t i;
268 int ret;
270 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
271 ret = krb5_store_int16(sp, p->name.name_string.len + 1);
272 else
273 ret = krb5_store_int16(sp, p->name.name_string.len);
274 if(ret) return ret;
275 ret = krb5_kt_store_string(sp, p->realm);
276 if(ret) return ret;
277 for(i = 0; i < p->name.name_string.len; i++){
278 ret = krb5_kt_store_string(sp, p->name.name_string.val[i]);
279 if(ret)
280 return ret;
282 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
283 ret = krb5_store_int32(sp, p->name.name_type);
284 if(ret)
285 return ret;
288 return 0;
291 static krb5_error_code KRB5_CALLCONV
292 fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
294 struct fkt_data *d;
296 d = malloc(sizeof(*d));
297 if(d == NULL) {
298 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
299 return ENOMEM;
301 d->filename = strdup(name);
302 if(d->filename == NULL) {
303 free(d);
304 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
305 return ENOMEM;
307 d->flags = 0;
308 id->data = d;
309 return 0;
312 static krb5_error_code KRB5_CALLCONV
313 fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id)
315 krb5_error_code ret;
317 ret = fkt_resolve(context, name, id);
318 if (ret == 0) {
319 struct fkt_data *d = id->data;
320 d->flags |= KRB5_KT_FL_JAVA;
322 return ret;
325 static krb5_error_code KRB5_CALLCONV
326 fkt_close(krb5_context context, krb5_keytab id)
328 struct fkt_data *d = id->data;
329 free(d->filename);
330 free(d);
331 return 0;
334 static krb5_error_code KRB5_CALLCONV
335 fkt_destroy(krb5_context context, krb5_keytab id)
337 struct fkt_data *d = id->data;
338 _krb5_erase_file(context, d->filename);
339 return 0;
342 static krb5_error_code KRB5_CALLCONV
343 fkt_get_name(krb5_context context,
344 krb5_keytab id,
345 char *name,
346 size_t namesize)
348 /* This function is XXX */
349 struct fkt_data *d = id->data;
350 strlcpy(name, d->filename, namesize);
351 return 0;
354 static void
355 storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
357 int flags = 0;
358 switch(vno) {
359 case KRB5_KT_VNO_1:
360 flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
361 flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
362 flags |= KRB5_STORAGE_HOST_BYTEORDER;
363 break;
364 case KRB5_KT_VNO_2:
365 break;
366 default:
367 krb5_warnx(context,
368 "storage_set_flags called with bad vno (%d)", vno);
370 krb5_storage_set_flags(sp, flags);
373 static krb5_error_code
374 fkt_start_seq_get_int(krb5_context context,
375 krb5_keytab id,
376 int flags,
377 int exclusive,
378 krb5_kt_cursor *c)
380 int8_t pvno, tag;
381 krb5_error_code ret;
382 struct fkt_data *d = id->data;
384 c->fd = open (d->filename, flags);
385 if (c->fd < 0) {
386 ret = errno;
387 krb5_set_error_message(context, ret,
388 N_("keytab %s open failed: %s", ""),
389 d->filename, strerror(ret));
390 return ret;
392 rk_cloexec(c->fd);
393 ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
394 if (ret) {
395 close(c->fd);
396 return ret;
398 c->sp = krb5_storage_from_fd(c->fd);
399 if (c->sp == NULL) {
400 _krb5_xunlock(context, c->fd);
401 close(c->fd);
402 krb5_set_error_message(context, ENOMEM,
403 N_("malloc: out of memory", ""));
404 return ENOMEM;
406 krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
407 ret = krb5_ret_int8(c->sp, &pvno);
408 if(ret) {
409 krb5_storage_free(c->sp);
410 _krb5_xunlock(context, c->fd);
411 close(c->fd);
412 krb5_clear_error_message(context);
413 return ret;
415 if(pvno != 5) {
416 krb5_storage_free(c->sp);
417 _krb5_xunlock(context, c->fd);
418 close(c->fd);
419 krb5_clear_error_message (context);
420 return KRB5_KEYTAB_BADVNO;
422 ret = krb5_ret_int8(c->sp, &tag);
423 if (ret) {
424 krb5_storage_free(c->sp);
425 _krb5_xunlock(context, c->fd);
426 close(c->fd);
427 krb5_clear_error_message(context);
428 return ret;
430 id->version = tag;
431 storage_set_flags(context, c->sp, id->version);
432 return 0;
435 static krb5_error_code KRB5_CALLCONV
436 fkt_start_seq_get(krb5_context context,
437 krb5_keytab id,
438 krb5_kt_cursor *c)
440 return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY | O_CLOEXEC, 0, c);
443 static krb5_error_code
444 fkt_next_entry_int(krb5_context context,
445 krb5_keytab id,
446 krb5_keytab_entry *entry,
447 krb5_kt_cursor *cursor,
448 off_t *start,
449 off_t *end)
451 struct fkt_data *d = id->data;
452 int32_t len;
453 int ret;
454 int8_t tmp8;
455 int32_t tmp32;
456 uint32_t utmp32;
457 off_t pos, curpos;
459 pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
460 loop:
461 ret = krb5_ret_int32(cursor->sp, &len);
462 if (ret)
463 return ret;
464 if(len < 0) {
465 pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR);
466 goto loop;
468 ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
469 if (ret)
470 goto out;
471 ret = krb5_ret_uint32(cursor->sp, &utmp32);
472 entry->timestamp = utmp32;
473 if (ret)
474 goto out;
475 ret = krb5_ret_int8(cursor->sp, &tmp8);
476 if (ret)
477 goto out;
478 entry->vno = tmp8;
479 ret = krb5_kt_ret_keyblock (context, d, cursor->sp, &entry->keyblock);
480 if (ret)
481 goto out;
482 /* there might be a 32 bit kvno here
483 * if it's zero, assume that the 8bit one was right,
484 * otherwise trust the new value */
485 curpos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
486 if(len + 4 + pos - curpos >= 4) {
487 ret = krb5_ret_int32(cursor->sp, &tmp32);
488 if (ret == 0 && tmp32 != 0)
489 entry->vno = tmp32;
491 /* there might be a flags field here */
492 if(len + 4 + pos - curpos >= 8) {
493 ret = krb5_ret_uint32(cursor->sp, &utmp32);
494 if (ret == 0)
495 entry->flags = utmp32;
496 } else
497 entry->flags = 0;
499 entry->aliases = NULL;
501 if(start) *start = pos;
502 if(end) *end = pos + 4 + len;
503 out:
504 krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
505 return ret;
508 static krb5_error_code KRB5_CALLCONV
509 fkt_next_entry(krb5_context context,
510 krb5_keytab id,
511 krb5_keytab_entry *entry,
512 krb5_kt_cursor *cursor)
514 return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL);
517 static krb5_error_code KRB5_CALLCONV
518 fkt_end_seq_get(krb5_context context,
519 krb5_keytab id,
520 krb5_kt_cursor *cursor)
522 krb5_storage_free(cursor->sp);
523 _krb5_xunlock(context, cursor->fd);
524 close(cursor->fd);
525 return 0;
528 static krb5_error_code KRB5_CALLCONV
529 fkt_setup_keytab(krb5_context context,
530 krb5_keytab id,
531 krb5_storage *sp)
533 krb5_error_code ret;
534 ret = krb5_store_int8(sp, 5);
535 if(ret)
536 return ret;
537 if(id->version == 0)
538 id->version = KRB5_KT_VNO;
539 return krb5_store_int8 (sp, id->version);
542 static krb5_error_code KRB5_CALLCONV
543 fkt_add_entry(krb5_context context,
544 krb5_keytab id,
545 krb5_keytab_entry *entry)
547 int ret;
548 int fd;
549 krb5_storage *sp;
550 struct fkt_data *d = id->data;
551 krb5_data keytab;
552 int32_t len;
554 fd = open (d->filename, O_RDWR | O_BINARY | O_CLOEXEC);
555 if (fd < 0) {
556 fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600);
557 if (fd < 0) {
558 ret = errno;
559 krb5_set_error_message(context, ret,
560 N_("open(%s): %s", ""), d->filename,
561 strerror(ret));
562 return ret;
564 rk_cloexec(fd);
566 ret = _krb5_xlock(context, fd, 1, d->filename);
567 if (ret) {
568 close(fd);
569 return ret;
571 sp = krb5_storage_from_fd(fd);
572 krb5_storage_set_eof_code(sp, KRB5_KT_END);
573 ret = fkt_setup_keytab(context, id, sp);
574 if(ret) {
575 goto out;
577 storage_set_flags(context, sp, id->version);
578 } else {
579 int8_t pvno, tag;
581 rk_cloexec(fd);
583 ret = _krb5_xlock(context, fd, 1, d->filename);
584 if (ret) {
585 close(fd);
586 return ret;
588 sp = krb5_storage_from_fd(fd);
589 krb5_storage_set_eof_code(sp, KRB5_KT_END);
590 ret = krb5_ret_int8(sp, &pvno);
591 if(ret) {
592 /* we probably have a zero byte file, so try to set it up
593 properly */
594 ret = fkt_setup_keytab(context, id, sp);
595 if(ret) {
596 krb5_set_error_message(context, ret,
597 N_("%s: keytab is corrupted: %s", ""),
598 d->filename, strerror(ret));
599 goto out;
601 storage_set_flags(context, sp, id->version);
602 } else {
603 if(pvno != 5) {
604 ret = KRB5_KEYTAB_BADVNO;
605 krb5_set_error_message(context, ret,
606 N_("Bad version in keytab %s", ""),
607 d->filename);
608 goto out;
610 ret = krb5_ret_int8 (sp, &tag);
611 if (ret) {
612 krb5_set_error_message(context, ret,
613 N_("failed reading tag from "
614 "keytab %s", ""),
615 d->filename);
616 goto out;
618 id->version = tag;
619 storage_set_flags(context, sp, id->version);
624 krb5_storage *emem;
625 emem = krb5_storage_emem();
626 if(emem == NULL) {
627 ret = ENOMEM;
628 krb5_set_error_message(context, ret,
629 N_("malloc: out of memory", ""));
630 goto out;
632 ret = krb5_kt_store_principal(context, emem, entry->principal);
633 if(ret) {
634 krb5_set_error_message(context, ret,
635 N_("Failed storing principal "
636 "in keytab %s", ""),
637 d->filename);
638 krb5_storage_free(emem);
639 goto out;
641 ret = krb5_store_int32 (emem, entry->timestamp);
642 if(ret) {
643 krb5_set_error_message(context, ret,
644 N_("Failed storing timpstamp "
645 "in keytab %s", ""),
646 d->filename);
647 krb5_storage_free(emem);
648 goto out;
650 ret = krb5_store_int8 (emem, entry->vno % 256);
651 if(ret) {
652 krb5_set_error_message(context, ret,
653 N_("Failed storing kvno "
654 "in keytab %s", ""),
655 d->filename);
656 krb5_storage_free(emem);
657 goto out;
659 ret = krb5_kt_store_keyblock (context, d, emem, &entry->keyblock);
660 if(ret) {
661 krb5_storage_free(emem);
662 goto out;
664 if ((d->flags & KRB5_KT_FL_JAVA) == 0) {
665 ret = krb5_store_int32 (emem, entry->vno);
666 if (ret) {
667 krb5_set_error_message(context, ret,
668 N_("Failed storing extended kvno "
669 "in keytab %s", ""),
670 d->filename);
671 krb5_storage_free(emem);
672 goto out;
674 ret = krb5_store_uint32 (emem, entry->flags);
675 if (ret) {
676 krb5_set_error_message(context, ret,
677 N_("Failed storing extended kvno "
678 "in keytab %s", ""),
679 d->filename);
680 krb5_storage_free(emem);
681 goto out;
685 ret = krb5_storage_to_data(emem, &keytab);
686 krb5_storage_free(emem);
687 if(ret) {
688 krb5_set_error_message(context, ret,
689 N_("Failed converting keytab entry "
690 "to memory block for keytab %s", ""),
691 d->filename);
692 goto out;
696 while(1) {
697 ret = krb5_ret_int32(sp, &len);
698 if(ret == KRB5_KT_END) {
699 len = keytab.length;
700 break;
702 if(len < 0) {
703 len = -len;
704 if(len >= (int)keytab.length) {
705 krb5_storage_seek(sp, -4, SEEK_CUR);
706 break;
709 krb5_storage_seek(sp, len, SEEK_CUR);
711 ret = krb5_store_int32(sp, len);
712 if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) {
713 ret = errno;
714 krb5_set_error_message(context, ret,
715 N_("Failed writing keytab block "
716 "in keytab %s: %s", ""),
717 d->filename, strerror(ret));
719 memset(keytab.data, 0, keytab.length);
720 krb5_data_free(&keytab);
721 out:
722 krb5_storage_free(sp);
723 _krb5_xunlock(context, fd);
724 close(fd);
725 return ret;
728 static krb5_error_code KRB5_CALLCONV
729 fkt_remove_entry(krb5_context context,
730 krb5_keytab id,
731 krb5_keytab_entry *entry)
733 krb5_keytab_entry e;
734 krb5_kt_cursor cursor;
735 off_t pos_start, pos_end;
736 int found = 0;
737 krb5_error_code ret;
739 ret = fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY | O_CLOEXEC, 1, &cursor);
740 if(ret != 0)
741 goto out; /* return other error here? */
742 while(fkt_next_entry_int(context, id, &e, &cursor,
743 &pos_start, &pos_end) == 0) {
744 if(krb5_kt_compare(context, &e, entry->principal,
745 entry->vno, entry->keyblock.keytype)) {
746 int32_t len;
747 unsigned char buf[128];
748 found = 1;
749 krb5_storage_seek(cursor.sp, pos_start, SEEK_SET);
750 len = pos_end - pos_start - 4;
751 krb5_store_int32(cursor.sp, -len);
752 memset(buf, 0, sizeof(buf));
753 while(len > 0) {
754 krb5_storage_write(cursor.sp, buf,
755 min((size_t)len, sizeof(buf)));
756 len -= min((size_t)len, sizeof(buf));
759 krb5_kt_free_entry(context, &e);
761 krb5_kt_end_seq_get(context, id, &cursor);
762 out:
763 if (!found) {
764 krb5_clear_error_message (context);
765 return KRB5_KT_NOTFOUND;
767 return 0;
770 const krb5_kt_ops krb5_fkt_ops = {
771 "FILE",
772 fkt_resolve,
773 fkt_get_name,
774 fkt_close,
775 fkt_destroy,
776 NULL, /* get */
777 fkt_start_seq_get,
778 fkt_next_entry,
779 fkt_end_seq_get,
780 fkt_add_entry,
781 fkt_remove_entry
784 const krb5_kt_ops krb5_wrfkt_ops = {
785 "WRFILE",
786 fkt_resolve,
787 fkt_get_name,
788 fkt_close,
789 fkt_destroy,
790 NULL, /* get */
791 fkt_start_seq_get,
792 fkt_next_entry,
793 fkt_end_seq_get,
794 fkt_add_entry,
795 fkt_remove_entry
798 const krb5_kt_ops krb5_javakt_ops = {
799 "JAVA14",
800 fkt_resolve_java14,
801 fkt_get_name,
802 fkt_close,
803 fkt_destroy,
804 NULL, /* get */
805 fkt_start_seq_get,
806 fkt_next_entry,
807 fkt_end_seq_get,
808 fkt_add_entry,
809 fkt_remove_entry