Fix make dist missing files (#228)
[heimdal.git] / lib / krb5 / store.c
blobc7355f6861bc56232d2ee24b9a22883fc992e8e0
1 /*
2 * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "krb5_locl.h"
35 #include "store-int.h"
37 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
38 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
39 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
40 #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
41 krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
43 /**
44 * Add the flags on a storage buffer by or-ing in the flags to the buffer.
46 * @param sp the storage buffer to set the flags on
47 * @param flags the flags to set
49 * @ingroup krb5_storage
52 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
53 krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
55 sp->flags |= flags;
58 /**
59 * Clear the flags on a storage buffer
61 * @param sp the storage buffer to clear the flags on
62 * @param flags the flags to clear
64 * @ingroup krb5_storage
67 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
68 krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
70 sp->flags &= ~flags;
73 /**
74 * Return true or false depending on if the storage flags is set or
75 * not. NB testing for the flag 0 always return true.
77 * @param sp the storage buffer to check flags on
78 * @param flags The flags to test for
80 * @return true if all the flags are set, false if not.
82 * @ingroup krb5_storage
85 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
86 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
88 return (sp->flags & flags) == flags;
91 /**
92 * Set the new byte order of the storage buffer.
94 * @param sp the storage buffer to set the byte order for.
95 * @param byteorder the new byte order.
97 * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
98 * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
100 * @ingroup krb5_storage
103 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
104 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
106 sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
107 sp->flags |= byteorder;
111 * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
113 * @ingroup krb5_storage
116 KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
117 krb5_storage_get_byteorder(krb5_storage *sp)
119 return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
123 * Set the max alloc value
125 * @param sp the storage buffer set the max allow for
126 * @param size maximum size to allocate, use 0 to remove limit
128 * @ingroup krb5_storage
131 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
132 krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
134 sp->max_alloc = size;
137 /* don't allocate unresonable amount of memory */
138 static krb5_error_code
139 size_too_large(krb5_storage *sp, size_t size)
141 if (sp->max_alloc && sp->max_alloc < size)
142 return HEIM_ERR_TOO_BIG;
143 return 0;
146 static krb5_error_code
147 size_too_large_num(krb5_storage *sp, size_t count, size_t size)
149 if (sp->max_alloc == 0 || size == 0)
150 return 0;
151 size = sp->max_alloc / size;
152 if (size < count)
153 return HEIM_ERR_TOO_BIG;
154 return 0;
158 * Seek to a new offset.
160 * @param sp the storage buffer to seek in.
161 * @param offset the offset to seek
162 * @param whence relateive searching, SEEK_CUR from the current
163 * position, SEEK_END from the end, SEEK_SET absolute from the start.
165 * @return The new current offset
167 * @ingroup krb5_storage
170 KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
171 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
173 return (*sp->seek)(sp, offset, whence);
177 * Truncate the storage buffer in sp to offset.
179 * @param sp the storage buffer to truncate.
180 * @param offset the offset to truncate too.
182 * @return An Kerberos 5 error code.
184 * @ingroup krb5_storage
187 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
188 krb5_storage_truncate(krb5_storage *sp, off_t offset)
190 return (*sp->trunc)(sp, offset);
194 * Sync the storage buffer to its backing store. If there is no
195 * backing store this function will return success.
197 * @param sp the storage buffer to sync
199 * @return A Kerberos 5 error code
201 * @ingroup krb5_storage
204 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
205 krb5_storage_fsync(krb5_storage *sp)
207 if (sp->fsync != NULL)
208 return sp->fsync(sp);
209 return 0;
213 * Read to the storage buffer.
215 * @param sp the storage buffer to read from
216 * @param buf the buffer to store the data in
217 * @param len the length to read
219 * @return The length of data read (can be shorter then len), or negative on error.
221 * @ingroup krb5_storage
224 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
225 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
227 return sp->fetch(sp, buf, len);
231 * Write to the storage buffer.
233 * @param sp the storage buffer to write to
234 * @param buf the buffer to write to the storage buffer
235 * @param len the length to write
237 * @return The length of data written (can be shorter then len), or negative on error.
239 * @ingroup krb5_storage
242 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
243 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
245 return sp->store(sp, buf, len);
249 * Set the return code that will be used when end of storage is reached.
251 * @param sp the storage
252 * @param code the error code to return on end of storage
254 * @ingroup krb5_storage
257 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
258 krb5_storage_set_eof_code(krb5_storage *sp, int code)
260 sp->eof_code = code;
264 * Get the return code that will be used when end of storage is reached.
266 * @param sp the storage
268 * @return storage error code
270 * @ingroup krb5_storage
273 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
274 krb5_storage_get_eof_code(krb5_storage *sp)
276 return sp->eof_code;
280 * Free a krb5 storage.
282 * @param sp the storage to free.
284 * @return An Kerberos 5 error code.
286 * @ingroup krb5_storage
289 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
290 krb5_storage_free(krb5_storage *sp)
292 if (sp == NULL)
293 return 0;
294 if(sp->free)
295 (*sp->free)(sp);
296 free(sp->data);
297 free(sp);
298 return 0;
302 * Copy the contnent of storage
304 * @param sp the storage to copy to a data
305 * @param data the copied data, free with krb5_data_free()
307 * @return 0 for success, or a Kerberos 5 error code on failure.
309 * @ingroup krb5_storage
312 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
313 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
315 off_t pos, size;
316 krb5_error_code ret;
318 pos = sp->seek(sp, 0, SEEK_CUR);
319 if (pos < 0)
320 return HEIM_ERR_NOT_SEEKABLE;
321 size = sp->seek(sp, 0, SEEK_END);
322 ret = size_too_large(sp, size);
323 if (ret)
324 return ret;
325 ret = krb5_data_alloc(data, size);
326 if (ret) {
327 sp->seek(sp, pos, SEEK_SET);
328 return ret;
330 if (size) {
331 sp->seek(sp, 0, SEEK_SET);
332 sp->fetch(sp, data->data, data->length);
333 sp->seek(sp, pos, SEEK_SET);
335 return 0;
338 static krb5_error_code
339 krb5_store_int(krb5_storage *sp,
340 int64_t value,
341 size_t len)
343 int ret;
344 unsigned char v[8];
346 if (len > sizeof(v))
347 return EINVAL;
348 _krb5_put_int(v, value, len);
349 ret = sp->store(sp, v, len);
350 if (ret < 0)
351 return errno;
352 if ((size_t)ret != len)
353 return sp->eof_code;
354 return 0;
358 * Store a int32 to storage, byte order is controlled by the settings
359 * on the storage, see krb5_storage_set_byteorder().
361 * @param sp the storage to write too
362 * @param value the value to store
364 * @return 0 for success, or a Kerberos 5 error code on failure.
366 * @ingroup krb5_storage
369 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
370 krb5_store_int32(krb5_storage *sp,
371 int32_t value)
373 if(BYTEORDER_IS_HOST(sp))
374 value = htonl(value);
375 else if(BYTEORDER_IS_LE(sp))
376 value = bswap32(value);
377 return krb5_store_int(sp, value, 4);
381 * Store a int64 to storage, byte order is controlled by the settings
382 * on the storage, see krb5_storage_set_byteorder().
384 * @param sp the storage to write too
385 * @param value the value to store
387 * @return 0 for success, or a Kerberos 5 error code on failure.
389 * @ingroup krb5_storage
392 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
393 krb5_store_int64(krb5_storage *sp,
394 int64_t value)
396 if (BYTEORDER_IS_HOST(sp))
397 #ifdef WORDS_BIGENDIAN
399 #else
400 value = bswap64(value); /* There's no ntohll() */
401 #endif
402 else if (BYTEORDER_IS_LE(sp))
403 value = bswap64(value);
404 return krb5_store_int(sp, value, 8);
408 * Store a uint32 to storage, byte order is controlled by the settings
409 * on the storage, see krb5_storage_set_byteorder().
411 * @param sp the storage to write too
412 * @param value the value to store
414 * @return 0 for success, or a Kerberos 5 error code on failure.
416 * @ingroup krb5_storage
419 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
420 krb5_store_uint32(krb5_storage *sp,
421 uint32_t value)
423 return krb5_store_int32(sp, (int32_t)value);
427 * Store a uint64 to storage, byte order is controlled by the settings
428 * on the storage, see krb5_storage_set_byteorder().
430 * @param sp the storage to write too
431 * @param value the value to store
433 * @return 0 for success, or a Kerberos 5 error code on failure.
435 * @ingroup krb5_storage
438 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
439 krb5_store_uint64(krb5_storage *sp,
440 uint64_t value)
442 return krb5_store_int64(sp, (int64_t)value);
445 static krb5_error_code
446 krb5_ret_int(krb5_storage *sp,
447 int64_t *value,
448 size_t len)
450 int ret;
451 unsigned char v[8];
452 uint64_t w;
453 *value = 0; /* quiets warnings */
454 ret = sp->fetch(sp, v, len);
455 if (ret < 0)
456 return errno;
457 if ((size_t)ret != len)
458 return sp->eof_code;
459 _krb5_get_int64(v, &w, len);
460 *value = w;
461 return 0;
465 * Read a int64 from storage, byte order is controlled by the settings
466 * on the storage, see krb5_storage_set_byteorder().
468 * @param sp the storage to write too
469 * @param value the value read from the buffer
471 * @return 0 for success, or a Kerberos 5 error code on failure.
473 * @ingroup krb5_storage
476 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
477 krb5_ret_int64(krb5_storage *sp,
478 int64_t *value)
480 krb5_error_code ret = krb5_ret_int(sp, value, 8);
481 if(ret)
482 return ret;
483 if(BYTEORDER_IS_HOST(sp))
484 #ifdef WORDS_BIGENDIAN
486 #else
487 *value = bswap64(*value); /* There's no ntohll() */
488 #endif
489 else if(BYTEORDER_IS_LE(sp))
490 *value = bswap64(*value);
491 return 0;
495 * Read a uint64 from storage, byte order is controlled by the settings
496 * on the storage, see krb5_storage_set_byteorder().
498 * @param sp the storage to write too
499 * @param value the value read from the buffer
501 * @return 0 for success, or a Kerberos 5 error code on failure.
503 * @ingroup krb5_storage
506 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
507 krb5_ret_uint64(krb5_storage *sp,
508 uint64_t *value)
510 krb5_error_code ret;
511 int64_t v;
513 ret = krb5_ret_int64(sp, &v);
514 if (ret == 0)
515 *value = (uint64_t)v;
517 return ret;
521 * Read a int32 from storage, byte order is controlled by the settings
522 * on the storage, see krb5_storage_set_byteorder().
524 * @param sp the storage to write too
525 * @param value the value read from the buffer
527 * @return 0 for success, or a Kerberos 5 error code on failure.
529 * @ingroup krb5_storage
532 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
533 krb5_ret_int32(krb5_storage *sp,
534 int32_t *value)
536 int64_t v;
538 krb5_error_code ret = krb5_ret_int(sp, &v, 4);
539 if (ret)
540 return ret;
541 *value = v;
542 if (BYTEORDER_IS_HOST(sp))
543 *value = htonl(*value);
544 else if (BYTEORDER_IS_LE(sp))
545 *value = bswap32(*value);
546 return 0;
550 * Read a uint32 from storage, byte order is controlled by the settings
551 * on the storage, see krb5_storage_set_byteorder().
553 * @param sp the storage to write too
554 * @param value the value read from the buffer
556 * @return 0 for success, or a Kerberos 5 error code on failure.
558 * @ingroup krb5_storage
561 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
562 krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
564 krb5_error_code ret;
565 int32_t v;
567 ret = krb5_ret_int32(sp, &v);
568 if (ret == 0)
569 *value = (uint32_t)v;
571 return ret;
575 * Store a int16 to storage, byte order is controlled by the settings
576 * on the storage, see krb5_storage_set_byteorder().
578 * @param sp the storage to write too
579 * @param value the value to store
581 * @return 0 for success, or a Kerberos 5 error code on failure.
583 * @ingroup krb5_storage
586 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
587 krb5_store_int16(krb5_storage *sp,
588 int16_t value)
590 if(BYTEORDER_IS_HOST(sp))
591 value = htons(value);
592 else if(BYTEORDER_IS_LE(sp))
593 value = bswap16(value);
594 return krb5_store_int(sp, value, 2);
598 * Store a uint16 to storage, byte order is controlled by the settings
599 * on the storage, see krb5_storage_set_byteorder().
601 * @param sp the storage to write too
602 * @param value the value to store
604 * @return 0 for success, or a Kerberos 5 error code on failure.
606 * @ingroup krb5_storage
609 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
610 krb5_store_uint16(krb5_storage *sp,
611 uint16_t value)
613 return krb5_store_int16(sp, (int16_t)value);
617 * Read a int16 from storage, byte order is controlled by the settings
618 * on the storage, see krb5_storage_set_byteorder().
620 * @param sp the storage to write too
621 * @param value the value read from the buffer
623 * @return 0 for success, or a Kerberos 5 error code on failure.
625 * @ingroup krb5_storage
628 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
629 krb5_ret_int16(krb5_storage *sp,
630 int16_t *value)
632 int64_t v;
633 int ret;
634 ret = krb5_ret_int(sp, &v, 2);
635 if(ret)
636 return ret;
637 *value = v;
638 if(BYTEORDER_IS_HOST(sp))
639 *value = htons(*value);
640 else if(BYTEORDER_IS_LE(sp))
641 *value = bswap16(*value);
642 return 0;
646 * Read a int16 from storage, byte order is controlled by the settings
647 * on the storage, see krb5_storage_set_byteorder().
649 * @param sp the storage to write too
650 * @param value the value read from the buffer
652 * @return 0 for success, or a Kerberos 5 error code on failure.
654 * @ingroup krb5_storage
657 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
658 krb5_ret_uint16(krb5_storage *sp,
659 uint16_t *value)
661 krb5_error_code ret;
662 int16_t v;
664 ret = krb5_ret_int16(sp, &v);
665 if (ret == 0)
666 *value = (uint16_t)v;
668 return ret;
672 * Store a int8 to storage.
674 * @param sp the storage to write too
675 * @param value the value to store
677 * @return 0 for success, or a Kerberos 5 error code on failure.
679 * @ingroup krb5_storage
682 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
683 krb5_store_int8(krb5_storage *sp,
684 int8_t value)
686 int ret;
688 ret = sp->store(sp, &value, sizeof(value));
689 if (ret != sizeof(value))
690 return (ret<0)?errno:sp->eof_code;
691 return 0;
695 * Store a uint8 to storage.
697 * @param sp the storage to write too
698 * @param value the value to store
700 * @return 0 for success, or a Kerberos 5 error code on failure.
702 * @ingroup krb5_storage
705 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
706 krb5_store_uint8(krb5_storage *sp,
707 uint8_t value)
709 return krb5_store_int8(sp, (int8_t)value);
713 * Read a int8 from storage
715 * @param sp the storage to write too
716 * @param value the value read from the buffer
718 * @return 0 for success, or a Kerberos 5 error code on failure.
720 * @ingroup krb5_storage
723 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
724 krb5_ret_int8(krb5_storage *sp,
725 int8_t *value)
727 int ret;
729 ret = sp->fetch(sp, value, sizeof(*value));
730 if (ret != sizeof(*value))
731 return (ret<0)?errno:sp->eof_code;
732 return 0;
736 * Read a uint8 from storage
738 * @param sp the storage to write too
739 * @param value the value read from the buffer
741 * @return 0 for success, or a Kerberos 5 error code on failure.
743 * @ingroup krb5_storage
746 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
747 krb5_ret_uint8(krb5_storage *sp,
748 uint8_t *value)
750 krb5_error_code ret;
751 int8_t v;
753 ret = krb5_ret_int8(sp, &v);
754 if (ret == 0)
755 *value = (uint8_t)v;
757 return ret;
761 * Store a data to the storage. The data is stored with an int32 as
762 * lenght plus the data (not padded).
764 * @param sp the storage buffer to write to
765 * @param data the buffer to store.
767 * @return 0 on success, a Kerberos 5 error code on failure.
769 * @ingroup krb5_storage
772 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
773 krb5_store_data(krb5_storage *sp,
774 krb5_data data)
776 int ret;
777 ret = krb5_store_int32(sp, data.length);
778 if(ret < 0)
779 return ret;
780 ret = sp->store(sp, data.data, data.length);
781 if(ret < 0)
782 return errno;
783 if((size_t)ret != data.length)
784 return sp->eof_code;
785 return 0;
789 * Parse a data from the storage.
791 * @param sp the storage buffer to read from
792 * @param data the parsed data
794 * @return 0 on success, a Kerberos 5 error code on failure.
796 * @ingroup krb5_storage
799 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
800 krb5_ret_data(krb5_storage *sp,
801 krb5_data *data)
803 int ret;
804 int32_t size;
806 ret = krb5_ret_int32(sp, &size);
807 if(ret)
808 return ret;
809 ret = size_too_large(sp, size);
810 if (ret)
811 return ret;
812 ret = krb5_data_alloc (data, size);
813 if (ret)
814 return ret;
815 if (size) {
816 ret = sp->fetch(sp, data->data, size);
817 if(ret != size) {
818 krb5_data_free(data);
819 return (ret < 0)? errno : sp->eof_code;
822 return 0;
826 * Store a string to the buffer. The data is formated as an len:uint32
827 * plus the string itself (not padded).
829 * @param sp the storage buffer to write to
830 * @param s the string to store.
832 * @return 0 on success, a Kerberos 5 error code on failure.
834 * @ingroup krb5_storage
837 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
838 krb5_store_string(krb5_storage *sp, const char *s)
840 krb5_data data;
841 data.length = strlen(s);
842 data.data = rk_UNCONST(s);
843 return krb5_store_data(sp, data);
847 * Parse a string from the storage.
849 * @param sp the storage buffer to read from
850 * @param string the parsed string
852 * @return 0 on success, a Kerberos 5 error code on failure.
854 * @ingroup krb5_storage
858 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
859 krb5_ret_string(krb5_storage *sp,
860 char **string)
862 int ret;
863 krb5_data data;
864 ret = krb5_ret_data(sp, &data);
865 if(ret)
866 return ret;
867 *string = realloc(data.data, data.length + 1);
868 if(*string == NULL){
869 free(data.data);
870 return ENOMEM;
872 (*string)[data.length] = 0;
873 return 0;
877 * Store a zero terminated string to the buffer. The data is stored
878 * one character at a time until a NUL is stored.
880 * @param sp the storage buffer to write to
881 * @param s the string to store.
883 * @return 0 on success, a Kerberos 5 error code on failure.
885 * @ingroup krb5_storage
888 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
889 krb5_store_stringz(krb5_storage *sp, const char *s)
891 size_t len = strlen(s) + 1;
892 ssize_t ret;
894 ret = sp->store(sp, s, len);
895 if(ret < 0)
896 return ret;
897 if((size_t)ret != len)
898 return sp->eof_code;
899 return 0;
903 * Parse zero terminated string from the storage.
905 * @param sp the storage buffer to read from
906 * @param string the parsed string
908 * @return 0 on success, a Kerberos 5 error code on failure.
910 * @ingroup krb5_storage
913 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
914 krb5_ret_stringz(krb5_storage *sp,
915 char **string)
917 char c;
918 char *s = NULL;
919 size_t len = 0;
920 ssize_t ret;
922 while((ret = sp->fetch(sp, &c, 1)) == 1){
923 krb5_error_code eret;
924 char *tmp;
926 len++;
927 eret = size_too_large(sp, len);
928 if (eret) {
929 free(s);
930 return eret;
932 tmp = realloc (s, len);
933 if (tmp == NULL) {
934 free (s);
935 return ENOMEM;
937 s = tmp;
938 s[len - 1] = c;
939 if(c == 0)
940 break;
942 if(ret != 1){
943 free(s);
944 if(ret == 0)
945 return sp->eof_code;
946 return ret;
948 *string = s;
949 return 0;
952 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
953 krb5_store_stringnl(krb5_storage *sp, const char *s)
955 size_t len = strlen(s);
956 ssize_t ret;
958 ret = sp->store(sp, s, len);
959 if(ret < 0)
960 return ret;
961 if((size_t)ret != len)
962 return sp->eof_code;
963 ret = sp->store(sp, "\n", 1);
964 if(ret != 1) {
965 if(ret < 0)
966 return ret;
967 else
968 return sp->eof_code;
971 return 0;
975 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
976 krb5_ret_stringnl(krb5_storage *sp,
977 char **string)
979 int expect_nl = 0;
980 char c;
981 char *s = NULL;
982 size_t len = 0;
983 ssize_t ret;
985 while((ret = sp->fetch(sp, &c, 1)) == 1){
986 krb5_error_code eret;
987 char *tmp;
989 if (c == '\r') {
990 expect_nl = 1;
991 continue;
993 if (expect_nl && c != '\n') {
994 free(s);
995 return KRB5_BADMSGTYPE;
998 len++;
999 eret = size_too_large(sp, len);
1000 if (eret) {
1001 free(s);
1002 return eret;
1004 tmp = realloc (s, len);
1005 if (tmp == NULL) {
1006 free (s);
1007 return ENOMEM;
1009 s = tmp;
1010 if(c == '\n') {
1011 s[len - 1] = '\0';
1012 break;
1014 s[len - 1] = c;
1016 if(ret != 1){
1017 free(s);
1018 if(ret == 0)
1019 return sp->eof_code;
1020 return ret;
1022 *string = s;
1023 return 0;
1027 * Write a principal block to storage.
1029 * @param sp the storage buffer to write to
1030 * @param p the principal block to write.
1032 * @return 0 on success, a Kerberos 5 error code on failure.
1034 * @ingroup krb5_storage
1037 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1038 krb5_store_principal(krb5_storage *sp,
1039 krb5_const_principal p)
1041 size_t i;
1042 int ret;
1044 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
1045 ret = krb5_store_int32(sp, p->name.name_type);
1046 if(ret) return ret;
1048 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1049 ret = krb5_store_int32(sp, p->name.name_string.len + 1);
1050 else
1051 ret = krb5_store_int32(sp, p->name.name_string.len);
1053 if(ret) return ret;
1054 ret = krb5_store_string(sp, p->realm);
1055 if(ret) return ret;
1056 for(i = 0; i < p->name.name_string.len; i++){
1057 ret = krb5_store_string(sp, p->name.name_string.val[i]);
1058 if(ret) return ret;
1060 return 0;
1064 * Parse principal from the storage.
1066 * @param sp the storage buffer to read from
1067 * @param princ the parsed principal
1069 * @return 0 on success, a Kerberos 5 error code on failure.
1071 * @ingroup krb5_storage
1074 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1075 krb5_ret_principal(krb5_storage *sp,
1076 krb5_principal *princ)
1078 int i;
1079 int ret;
1080 krb5_principal p;
1081 int32_t type;
1082 int32_t ncomp;
1084 p = calloc(1, sizeof(*p));
1085 if(p == NULL)
1086 return ENOMEM;
1088 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
1089 type = KRB5_NT_UNKNOWN;
1090 else if((ret = krb5_ret_int32(sp, &type))){
1091 free(p);
1092 return ret;
1094 if((ret = krb5_ret_int32(sp, &ncomp))){
1095 free(p);
1096 return ret;
1098 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1099 ncomp--;
1100 if (ncomp < 0) {
1101 free(p);
1102 return EINVAL;
1104 ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
1105 if (ret) {
1106 free(p);
1107 return ret;
1109 p->name.name_type = type;
1110 p->name.name_string.len = ncomp;
1111 ret = krb5_ret_string(sp, &p->realm);
1112 if(ret) {
1113 free(p);
1114 return ret;
1116 p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
1117 if(p->name.name_string.val == NULL && ncomp != 0){
1118 free(p->realm);
1119 free(p);
1120 return ENOMEM;
1122 for(i = 0; i < ncomp; i++){
1123 ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
1124 if(ret) {
1125 while (i >= 0)
1126 free(p->name.name_string.val[i--]);
1127 free(p->realm);
1128 free(p);
1129 return ret;
1132 *princ = p;
1133 return 0;
1137 * Store a keyblock to the storage.
1139 * @param sp the storage buffer to write to
1140 * @param p the keyblock to write
1142 * @return 0 on success, a Kerberos 5 error code on failure.
1144 * @ingroup krb5_storage
1147 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1148 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
1150 int ret;
1151 ret = krb5_store_int16(sp, p.keytype);
1152 if(ret) return ret;
1154 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1155 /* this should really be enctype, but it is the same as
1156 keytype nowadays */
1157 ret = krb5_store_int16(sp, p.keytype);
1158 if(ret) return ret;
1161 ret = krb5_store_data(sp, p.keyvalue);
1162 return ret;
1166 * Read a keyblock from the storage.
1168 * @param sp the storage buffer to write to
1169 * @param p the keyblock read from storage, free using krb5_free_keyblock()
1171 * @return 0 on success, a Kerberos 5 error code on failure.
1173 * @ingroup krb5_storage
1176 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1177 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
1179 int ret;
1180 int16_t tmp;
1182 ret = krb5_ret_int16(sp, &tmp);
1183 if(ret) return ret;
1184 p->keytype = tmp;
1186 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1187 ret = krb5_ret_int16(sp, &tmp);
1188 if(ret) return ret;
1191 ret = krb5_ret_data(sp, &p->keyvalue);
1192 return ret;
1196 * Write a times block to storage.
1198 * @param sp the storage buffer to write to
1199 * @param times the times block to write.
1201 * @return 0 on success, a Kerberos 5 error code on failure.
1203 * @ingroup krb5_storage
1206 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1207 krb5_store_times(krb5_storage *sp, krb5_times times)
1209 int ret;
1210 ret = krb5_store_int32(sp, times.authtime);
1211 if(ret) return ret;
1212 ret = krb5_store_int32(sp, times.starttime);
1213 if(ret) return ret;
1214 ret = krb5_store_int32(sp, times.endtime);
1215 if(ret) return ret;
1216 ret = krb5_store_int32(sp, times.renew_till);
1217 return ret;
1221 * Read a times block from the storage.
1223 * @param sp the storage buffer to write to
1224 * @param times the times block read from storage
1226 * @return 0 on success, a Kerberos 5 error code on failure.
1228 * @ingroup krb5_storage
1231 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1232 krb5_ret_times(krb5_storage *sp, krb5_times *times)
1234 int ret;
1235 int32_t tmp;
1236 ret = krb5_ret_int32(sp, &tmp);
1237 times->authtime = tmp;
1238 if(ret) return ret;
1239 ret = krb5_ret_int32(sp, &tmp);
1240 times->starttime = tmp;
1241 if(ret) return ret;
1242 ret = krb5_ret_int32(sp, &tmp);
1243 times->endtime = tmp;
1244 if(ret) return ret;
1245 ret = krb5_ret_int32(sp, &tmp);
1246 times->renew_till = tmp;
1247 return ret;
1251 * Write a address block to storage.
1253 * @param sp the storage buffer to write to
1254 * @param p the address block to write.
1256 * @return 0 on success, a Kerberos 5 error code on failure.
1258 * @ingroup krb5_storage
1261 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1262 krb5_store_address(krb5_storage *sp, krb5_address p)
1264 int ret;
1265 ret = krb5_store_int16(sp, p.addr_type);
1266 if(ret) return ret;
1267 ret = krb5_store_data(sp, p.address);
1268 return ret;
1272 * Read a address block from the storage.
1274 * @param sp the storage buffer to write to
1275 * @param adr the address block read from storage
1277 * @return 0 on success, a Kerberos 5 error code on failure.
1279 * @ingroup krb5_storage
1282 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1283 krb5_ret_address(krb5_storage *sp, krb5_address *adr)
1285 int16_t t;
1286 int ret;
1287 ret = krb5_ret_int16(sp, &t);
1288 if(ret) return ret;
1289 adr->addr_type = t;
1290 ret = krb5_ret_data(sp, &adr->address);
1291 return ret;
1295 * Write a addresses block to storage.
1297 * @param sp the storage buffer to write to
1298 * @param p the addresses block to write.
1300 * @return 0 on success, a Kerberos 5 error code on failure.
1302 * @ingroup krb5_storage
1305 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1306 krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
1308 size_t i;
1309 int ret;
1310 ret = krb5_store_int32(sp, p.len);
1311 if(ret) return ret;
1312 for(i = 0; i<p.len; i++){
1313 ret = krb5_store_address(sp, p.val[i]);
1314 if(ret) break;
1316 return ret;
1320 * Read a addresses block from the storage.
1322 * @param sp the storage buffer to write to
1323 * @param adr the addresses block read from storage
1325 * @return 0 on success, a Kerberos 5 error code on failure.
1327 * @ingroup krb5_storage
1330 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1331 krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
1333 size_t i;
1334 int ret;
1335 int32_t tmp;
1337 ret = krb5_ret_int32(sp, &tmp);
1338 if(ret) return ret;
1339 ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
1340 if (ret) return ret;
1341 adr->len = tmp;
1342 ALLOC(adr->val, adr->len);
1343 if (adr->val == NULL && adr->len != 0)
1344 return ENOMEM;
1345 for(i = 0; i < adr->len; i++){
1346 ret = krb5_ret_address(sp, &adr->val[i]);
1347 if(ret) break;
1349 return ret;
1353 * Write a auth data block to storage.
1355 * @param sp the storage buffer to write to
1356 * @param auth the auth data block to write.
1358 * @return 0 on success, a Kerberos 5 error code on failure.
1360 * @ingroup krb5_storage
1363 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1364 krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
1366 krb5_error_code ret;
1367 size_t i;
1368 ret = krb5_store_int32(sp, auth.len);
1369 if(ret) return ret;
1370 for(i = 0; i < auth.len; i++){
1371 ret = krb5_store_int16(sp, auth.val[i].ad_type);
1372 if(ret) break;
1373 ret = krb5_store_data(sp, auth.val[i].ad_data);
1374 if(ret) break;
1376 return 0;
1380 * Read a auth data from the storage.
1382 * @param sp the storage buffer to write to
1383 * @param auth the auth data block read from storage
1385 * @return 0 on success, a Kerberos 5 error code on failure.
1387 * @ingroup krb5_storage
1390 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1391 krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
1393 krb5_error_code ret;
1394 int32_t tmp;
1395 int16_t tmp2;
1396 int i;
1397 ret = krb5_ret_int32(sp, &tmp);
1398 if(ret) return ret;
1399 ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
1400 if (ret) return ret;
1401 ALLOC_SEQ(auth, tmp);
1402 if (auth->val == NULL && tmp != 0)
1403 return ENOMEM;
1404 for(i = 0; i < tmp; i++){
1405 ret = krb5_ret_int16(sp, &tmp2);
1406 if(ret) break;
1407 auth->val[i].ad_type = tmp2;
1408 ret = krb5_ret_data(sp, &auth->val[i].ad_data);
1409 if(ret) break;
1411 return ret;
1414 static int32_t
1415 bitswap32(int32_t b)
1417 int32_t r = 0;
1418 int i;
1419 for (i = 0; i < 32; i++) {
1420 r = r << 1 | (b & 1);
1421 b = b >> 1;
1423 return r;
1427 * Write a credentials block to storage.
1429 * @param sp the storage buffer to write to
1430 * @param creds the creds block to write.
1432 * @return 0 on success, a Kerberos 5 error code on failure.
1434 * @ingroup krb5_storage
1437 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1438 krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
1440 int ret;
1442 ret = krb5_store_principal(sp, creds->client);
1443 if(ret)
1444 return ret;
1445 ret = krb5_store_principal(sp, creds->server);
1446 if(ret)
1447 return ret;
1448 ret = krb5_store_keyblock(sp, creds->session);
1449 if(ret)
1450 return ret;
1451 ret = krb5_store_times(sp, creds->times);
1452 if(ret)
1453 return ret;
1454 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1455 if(ret)
1456 return ret;
1457 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1458 if(ret)
1459 return ret;
1460 ret = krb5_store_addrs(sp, creds->addresses);
1461 if(ret)
1462 return ret;
1463 ret = krb5_store_authdata(sp, creds->authdata);
1464 if(ret)
1465 return ret;
1466 ret = krb5_store_data(sp, creds->ticket);
1467 if(ret)
1468 return ret;
1469 ret = krb5_store_data(sp, creds->second_ticket);
1470 return ret;
1474 * Read a credentials block from the storage.
1476 * @param sp the storage buffer to write to
1477 * @param creds the credentials block read from storage
1479 * @return 0 on success, a Kerberos 5 error code on failure.
1481 * @ingroup krb5_storage
1484 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1485 krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
1487 krb5_error_code ret;
1488 int8_t dummy8;
1489 int32_t dummy32;
1491 memset(creds, 0, sizeof(*creds));
1492 ret = krb5_ret_principal (sp, &creds->client);
1493 if(ret) goto cleanup;
1494 ret = krb5_ret_principal (sp, &creds->server);
1495 if(ret) goto cleanup;
1496 ret = krb5_ret_keyblock (sp, &creds->session);
1497 if(ret) goto cleanup;
1498 ret = krb5_ret_times (sp, &creds->times);
1499 if(ret) goto cleanup;
1500 ret = krb5_ret_int8 (sp, &dummy8);
1501 if(ret) goto cleanup;
1502 ret = krb5_ret_int32 (sp, &dummy32);
1503 if(ret) goto cleanup;
1504 creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1505 ret = krb5_ret_addrs (sp, &creds->addresses);
1506 if(ret) goto cleanup;
1507 ret = krb5_ret_authdata (sp, &creds->authdata);
1508 if(ret) goto cleanup;
1509 ret = krb5_ret_data (sp, &creds->ticket);
1510 if(ret) goto cleanup;
1511 ret = krb5_ret_data (sp, &creds->second_ticket);
1512 cleanup:
1513 if(ret) {
1514 #if 0
1515 krb5_free_cred_contents(context, creds); /* XXX */
1516 #endif
1518 return ret;
1521 #define SC_CLIENT_PRINCIPAL 0x0001
1522 #define SC_SERVER_PRINCIPAL 0x0002
1523 #define SC_SESSION_KEY 0x0004
1524 #define SC_TICKET 0x0008
1525 #define SC_SECOND_TICKET 0x0010
1526 #define SC_AUTHDATA 0x0020
1527 #define SC_ADDRESSES 0x0040
1530 * Write a tagged credentials block to storage.
1532 * @param sp the storage buffer to write to
1533 * @param creds the creds block to write.
1535 * @return 0 on success, a Kerberos 5 error code on failure.
1537 * @ingroup krb5_storage
1540 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1541 krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
1543 int ret;
1544 int32_t header = 0;
1546 if (creds->client)
1547 header |= SC_CLIENT_PRINCIPAL;
1548 if (creds->server)
1549 header |= SC_SERVER_PRINCIPAL;
1550 if (creds->session.keytype != ETYPE_NULL)
1551 header |= SC_SESSION_KEY;
1552 if (creds->ticket.data)
1553 header |= SC_TICKET;
1554 if (creds->second_ticket.length)
1555 header |= SC_SECOND_TICKET;
1556 if (creds->authdata.len)
1557 header |= SC_AUTHDATA;
1558 if (creds->addresses.len)
1559 header |= SC_ADDRESSES;
1561 ret = krb5_store_int32(sp, header);
1562 if (ret)
1563 return ret;
1565 if (creds->client) {
1566 ret = krb5_store_principal(sp, creds->client);
1567 if(ret)
1568 return ret;
1571 if (creds->server) {
1572 ret = krb5_store_principal(sp, creds->server);
1573 if(ret)
1574 return ret;
1577 if (creds->session.keytype != ETYPE_NULL) {
1578 ret = krb5_store_keyblock(sp, creds->session);
1579 if(ret)
1580 return ret;
1583 ret = krb5_store_times(sp, creds->times);
1584 if(ret)
1585 return ret;
1586 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1587 if(ret)
1588 return ret;
1590 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1591 if(ret)
1592 return ret;
1594 if (creds->addresses.len) {
1595 ret = krb5_store_addrs(sp, creds->addresses);
1596 if(ret)
1597 return ret;
1600 if (creds->authdata.len) {
1601 ret = krb5_store_authdata(sp, creds->authdata);
1602 if(ret)
1603 return ret;
1606 if (creds->ticket.data) {
1607 ret = krb5_store_data(sp, creds->ticket);
1608 if(ret)
1609 return ret;
1612 if (creds->second_ticket.data) {
1613 ret = krb5_store_data(sp, creds->second_ticket);
1614 if (ret)
1615 return ret;
1618 return ret;
1622 * Read a tagged credentials block from the storage.
1624 * @param sp the storage buffer to write to
1625 * @param creds the credentials block read from storage
1627 * @return 0 on success, a Kerberos 5 error code on failure.
1629 * @ingroup krb5_storage
1632 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1633 krb5_ret_creds_tag(krb5_storage *sp,
1634 krb5_creds *creds)
1636 krb5_error_code ret;
1637 int8_t dummy8;
1638 int32_t dummy32, header;
1640 memset(creds, 0, sizeof(*creds));
1642 ret = krb5_ret_int32 (sp, &header);
1643 if (ret) goto cleanup;
1645 if (header & SC_CLIENT_PRINCIPAL) {
1646 ret = krb5_ret_principal (sp, &creds->client);
1647 if(ret) goto cleanup;
1649 if (header & SC_SERVER_PRINCIPAL) {
1650 ret = krb5_ret_principal (sp, &creds->server);
1651 if(ret) goto cleanup;
1653 if (header & SC_SESSION_KEY) {
1654 ret = krb5_ret_keyblock (sp, &creds->session);
1655 if(ret) goto cleanup;
1657 ret = krb5_ret_times (sp, &creds->times);
1658 if(ret) goto cleanup;
1659 ret = krb5_ret_int8 (sp, &dummy8);
1660 if(ret) goto cleanup;
1661 ret = krb5_ret_int32 (sp, &dummy32);
1662 if(ret) goto cleanup;
1663 creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1664 if (header & SC_ADDRESSES) {
1665 ret = krb5_ret_addrs (sp, &creds->addresses);
1666 if(ret) goto cleanup;
1668 if (header & SC_AUTHDATA) {
1669 ret = krb5_ret_authdata (sp, &creds->authdata);
1670 if(ret) goto cleanup;
1672 if (header & SC_TICKET) {
1673 ret = krb5_ret_data (sp, &creds->ticket);
1674 if(ret) goto cleanup;
1676 if (header & SC_SECOND_TICKET) {
1677 ret = krb5_ret_data (sp, &creds->second_ticket);
1678 if(ret) goto cleanup;
1681 cleanup:
1682 if(ret) {
1683 #if 0
1684 krb5_free_cred_contents(context, creds); /* XXX */
1685 #endif
1687 return ret;