xref: /freebsd/crypto/heimdal/lib/krb5/store.c (revision adb0ddaeac0a71a08d6af3a711387b59efcc94b6)
1b528cefcSMark Murray /*
2adb0ddaeSAssar Westerlund  * Copyright (c) 1997-2001 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 
36adb0ddaeSAssar Westerlund RCSID("$Id: store.c,v 1.35 2001/05/11 13:01:43 joda Exp $");
37adb0ddaeSAssar Westerlund 
38adb0ddaeSAssar Westerlund #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
39adb0ddaeSAssar Westerlund #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
40adb0ddaeSAssar Westerlund #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
41adb0ddaeSAssar Westerlund #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
42adb0ddaeSAssar Westerlund 			       krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
43b528cefcSMark Murray 
44b528cefcSMark Murray void
45b528cefcSMark Murray krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
46b528cefcSMark Murray {
47b528cefcSMark Murray     sp->flags |= flags;
48b528cefcSMark Murray }
49b528cefcSMark Murray 
50b528cefcSMark Murray void
51b528cefcSMark Murray krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
52b528cefcSMark Murray {
53b528cefcSMark Murray     sp->flags &= ~flags;
54b528cefcSMark Murray }
55b528cefcSMark Murray 
56b528cefcSMark Murray krb5_boolean
57b528cefcSMark Murray krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
58b528cefcSMark Murray {
59b528cefcSMark Murray     return (sp->flags & flags) == flags;
60b528cefcSMark Murray }
61b528cefcSMark Murray 
62adb0ddaeSAssar Westerlund void
63adb0ddaeSAssar Westerlund krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
64adb0ddaeSAssar Westerlund {
65adb0ddaeSAssar Westerlund     sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
66adb0ddaeSAssar Westerlund     sp->flags |= byteorder;
67adb0ddaeSAssar Westerlund }
68adb0ddaeSAssar Westerlund 
69adb0ddaeSAssar Westerlund krb5_flags
70adb0ddaeSAssar Westerlund krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder)
71adb0ddaeSAssar Westerlund {
72adb0ddaeSAssar Westerlund     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
73adb0ddaeSAssar Westerlund }
74adb0ddaeSAssar Westerlund 
75adb0ddaeSAssar Westerlund 
76b528cefcSMark Murray ssize_t
77b528cefcSMark Murray _krb5_put_int(void *buffer, unsigned long value, size_t size)
78b528cefcSMark Murray {
79b528cefcSMark Murray     unsigned char *p = buffer;
80b528cefcSMark Murray     int i;
81b528cefcSMark Murray     for (i = size - 1; i >= 0; i--) {
82b528cefcSMark Murray 	p[i] = value & 0xff;
83b528cefcSMark Murray 	value >>= 8;
84b528cefcSMark Murray     }
85b528cefcSMark Murray     return size;
86b528cefcSMark Murray }
87b528cefcSMark Murray 
88b528cefcSMark Murray ssize_t
89b528cefcSMark Murray _krb5_get_int(void *buffer, unsigned long *value, size_t size)
90b528cefcSMark Murray {
91b528cefcSMark Murray     unsigned char *p = buffer;
92b528cefcSMark Murray     unsigned long v = 0;
93b528cefcSMark Murray     int i;
94b528cefcSMark Murray     for (i = 0; i < size; i++)
95b528cefcSMark Murray 	v = (v << 8) + p[i];
96b528cefcSMark Murray     *value = v;
97b528cefcSMark Murray     return size;
98b528cefcSMark Murray }
99b528cefcSMark Murray 
100b528cefcSMark Murray krb5_error_code
101b528cefcSMark Murray krb5_storage_free(krb5_storage *sp)
102b528cefcSMark Murray {
103b528cefcSMark Murray     if(sp->free)
104b528cefcSMark Murray 	(*sp->free)(sp);
105b528cefcSMark Murray     free(sp->data);
106b528cefcSMark Murray     free(sp);
107b528cefcSMark Murray     return 0;
108b528cefcSMark Murray }
109b528cefcSMark Murray 
110b528cefcSMark Murray krb5_error_code
111b528cefcSMark Murray krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
112b528cefcSMark Murray {
113b528cefcSMark Murray     off_t pos;
114b528cefcSMark Murray     size_t size;
115b528cefcSMark Murray     krb5_error_code ret;
116b528cefcSMark Murray 
117b528cefcSMark Murray     pos = sp->seek(sp, 0, SEEK_CUR);
118b528cefcSMark Murray     size = (size_t)sp->seek(sp, 0, SEEK_END);
119b528cefcSMark Murray     ret = krb5_data_alloc (data, size);
120b528cefcSMark Murray     if (ret) {
121b528cefcSMark Murray 	sp->seek(sp, pos, SEEK_SET);
122b528cefcSMark Murray 	return ret;
123b528cefcSMark Murray     }
124b528cefcSMark Murray     if (size) {
125b528cefcSMark Murray 	sp->seek(sp, 0, SEEK_SET);
126b528cefcSMark Murray 	sp->fetch(sp, data->data, data->length);
127b528cefcSMark Murray 	sp->seek(sp, pos, SEEK_SET);
128b528cefcSMark Murray     }
129b528cefcSMark Murray     return 0;
130b528cefcSMark Murray }
131b528cefcSMark Murray 
132b528cefcSMark Murray static krb5_error_code
133b528cefcSMark Murray krb5_store_int(krb5_storage *sp,
134b528cefcSMark Murray 	       int32_t value,
135b528cefcSMark Murray 	       size_t len)
136b528cefcSMark Murray {
137b528cefcSMark Murray     int ret;
138adb0ddaeSAssar Westerlund     unsigned char v[16];
139b528cefcSMark Murray 
140adb0ddaeSAssar Westerlund     if(len > sizeof(v))
141adb0ddaeSAssar Westerlund 	return EINVAL;
142b528cefcSMark Murray     _krb5_put_int(v, value, len);
143b528cefcSMark Murray     ret = sp->store(sp, v, len);
144b528cefcSMark Murray     if (ret != len)
145b528cefcSMark Murray 	return (ret<0)?errno:KRB5_CC_END;
146b528cefcSMark Murray     return 0;
147b528cefcSMark Murray }
148b528cefcSMark Murray 
149b528cefcSMark Murray krb5_error_code
150b528cefcSMark Murray krb5_store_int32(krb5_storage *sp,
151b528cefcSMark Murray 		 int32_t value)
152b528cefcSMark Murray {
153adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
154b528cefcSMark Murray 	value = htonl(value);
155adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
156adb0ddaeSAssar Westerlund 	value = bswap32(value);
157b528cefcSMark Murray     return krb5_store_int(sp, value, 4);
158b528cefcSMark Murray }
159b528cefcSMark Murray 
160b528cefcSMark Murray static krb5_error_code
161b528cefcSMark Murray krb5_ret_int(krb5_storage *sp,
162b528cefcSMark Murray 	     int32_t *value,
163b528cefcSMark Murray 	     size_t len)
164b528cefcSMark Murray {
165b528cefcSMark Murray     int ret;
166b528cefcSMark Murray     unsigned char v[4];
167b528cefcSMark Murray     unsigned long w;
168b528cefcSMark Murray     ret = sp->fetch(sp, v, len);
169b528cefcSMark Murray     if(ret != len)
170b528cefcSMark Murray 	return (ret<0)?errno:KRB5_CC_END;
171b528cefcSMark Murray     _krb5_get_int(v, &w, len);
172b528cefcSMark Murray     *value = w;
173b528cefcSMark Murray     return 0;
174b528cefcSMark Murray }
175b528cefcSMark Murray 
176b528cefcSMark Murray krb5_error_code
177b528cefcSMark Murray krb5_ret_int32(krb5_storage *sp,
178b528cefcSMark Murray 	       int32_t *value)
179b528cefcSMark Murray {
180b528cefcSMark Murray     krb5_error_code ret = krb5_ret_int(sp, value, 4);
181b528cefcSMark Murray     if(ret)
182b528cefcSMark Murray 	return ret;
183adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
184adb0ddaeSAssar Westerlund 	*value = htonl(*value);
185adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
186adb0ddaeSAssar Westerlund 	*value = bswap32(*value);
187b528cefcSMark Murray     return 0;
188b528cefcSMark Murray }
189b528cefcSMark Murray 
190b528cefcSMark Murray krb5_error_code
191b528cefcSMark Murray krb5_store_int16(krb5_storage *sp,
192b528cefcSMark Murray 		 int16_t value)
193b528cefcSMark Murray {
194adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
195b528cefcSMark Murray 	value = htons(value);
196adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
197adb0ddaeSAssar Westerlund 	value = bswap16(value);
198b528cefcSMark Murray     return krb5_store_int(sp, value, 2);
199b528cefcSMark Murray }
200b528cefcSMark Murray 
201b528cefcSMark Murray krb5_error_code
202b528cefcSMark Murray krb5_ret_int16(krb5_storage *sp,
203b528cefcSMark Murray 	       int16_t *value)
204b528cefcSMark Murray {
205b528cefcSMark Murray     int32_t v;
206b528cefcSMark Murray     int ret;
207b528cefcSMark Murray     ret = krb5_ret_int(sp, &v, 2);
208b528cefcSMark Murray     if(ret)
209b528cefcSMark Murray 	return ret;
210b528cefcSMark Murray     *value = v;
211adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
212adb0ddaeSAssar Westerlund 	*value = htons(*value);
213adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
214adb0ddaeSAssar Westerlund 	*value = bswap16(*value);
215b528cefcSMark Murray     return 0;
216b528cefcSMark Murray }
217b528cefcSMark Murray 
218b528cefcSMark Murray krb5_error_code
219b528cefcSMark Murray krb5_store_int8(krb5_storage *sp,
220b528cefcSMark Murray 		int8_t value)
221b528cefcSMark Murray {
222b528cefcSMark Murray     int ret;
223b528cefcSMark Murray 
224b528cefcSMark Murray     ret = sp->store(sp, &value, sizeof(value));
225b528cefcSMark Murray     if (ret != sizeof(value))
226b528cefcSMark Murray 	return (ret<0)?errno:KRB5_CC_END;
227b528cefcSMark Murray     return 0;
228b528cefcSMark Murray }
229b528cefcSMark Murray 
230b528cefcSMark Murray krb5_error_code
231b528cefcSMark Murray krb5_ret_int8(krb5_storage *sp,
232b528cefcSMark Murray 	      int8_t *value)
233b528cefcSMark Murray {
234b528cefcSMark Murray     int ret;
235b528cefcSMark Murray 
236b528cefcSMark Murray     ret = sp->fetch(sp, value, sizeof(*value));
237b528cefcSMark Murray     if (ret != sizeof(*value))
238b528cefcSMark Murray 	return (ret<0)?errno:KRB5_CC_END;
239b528cefcSMark Murray     return 0;
240b528cefcSMark Murray }
241b528cefcSMark Murray 
242b528cefcSMark Murray krb5_error_code
243b528cefcSMark Murray krb5_store_data(krb5_storage *sp,
244b528cefcSMark Murray 		krb5_data data)
245b528cefcSMark Murray {
246b528cefcSMark Murray     int ret;
247b528cefcSMark Murray     ret = krb5_store_int32(sp, data.length);
248b528cefcSMark Murray     if(ret < 0)
249b528cefcSMark Murray 	return ret;
250b528cefcSMark Murray     ret = sp->store(sp, data.data, data.length);
251b528cefcSMark Murray     if(ret != data.length){
252b528cefcSMark Murray 	if(ret < 0)
253b528cefcSMark Murray 	    return errno;
254b528cefcSMark Murray 	return KRB5_CC_END;
255b528cefcSMark Murray     }
256b528cefcSMark Murray     return 0;
257b528cefcSMark Murray }
258b528cefcSMark Murray 
259b528cefcSMark Murray krb5_error_code
260b528cefcSMark Murray krb5_ret_data(krb5_storage *sp,
261b528cefcSMark Murray 	      krb5_data *data)
262b528cefcSMark Murray {
263b528cefcSMark Murray     int ret;
264b528cefcSMark Murray     int32_t size;
265b528cefcSMark Murray 
266b528cefcSMark Murray     ret = krb5_ret_int32(sp, &size);
267b528cefcSMark Murray     if(ret)
268b528cefcSMark Murray 	return ret;
269b528cefcSMark Murray     ret = krb5_data_alloc (data, size);
270b528cefcSMark Murray     if (ret)
271b528cefcSMark Murray 	return ret;
272b528cefcSMark Murray     if (size) {
273b528cefcSMark Murray 	ret = sp->fetch(sp, data->data, size);
274b528cefcSMark Murray 	if(ret != size)
275b528cefcSMark Murray 	    return (ret < 0)? errno : KRB5_CC_END;
276b528cefcSMark Murray     }
277b528cefcSMark Murray     return 0;
278b528cefcSMark Murray }
279b528cefcSMark Murray 
280b528cefcSMark Murray krb5_error_code
281b528cefcSMark Murray krb5_store_string(krb5_storage *sp, const char *s)
282b528cefcSMark Murray {
283b528cefcSMark Murray     krb5_data data;
284b528cefcSMark Murray     data.length = strlen(s);
285b528cefcSMark Murray     data.data = (void*)s;
286b528cefcSMark Murray     return krb5_store_data(sp, data);
287b528cefcSMark Murray }
288b528cefcSMark Murray 
289b528cefcSMark Murray krb5_error_code
290b528cefcSMark Murray krb5_ret_string(krb5_storage *sp,
291b528cefcSMark Murray 		char **string)
292b528cefcSMark Murray {
293b528cefcSMark Murray     int ret;
294b528cefcSMark Murray     krb5_data data;
295b528cefcSMark Murray     ret = krb5_ret_data(sp, &data);
296b528cefcSMark Murray     if(ret)
297b528cefcSMark Murray 	return ret;
298b528cefcSMark Murray     *string = realloc(data.data, data.length + 1);
299b528cefcSMark Murray     if(*string == NULL){
300b528cefcSMark Murray 	free(data.data);
301b528cefcSMark Murray 	return ENOMEM;
302b528cefcSMark Murray     }
303b528cefcSMark Murray     (*string)[data.length] = 0;
304b528cefcSMark Murray     return 0;
305b528cefcSMark Murray }
306b528cefcSMark Murray 
307b528cefcSMark Murray krb5_error_code
3085e9cd1aeSAssar Westerlund krb5_store_stringz(krb5_storage *sp, const char *s)
309b528cefcSMark Murray {
310b528cefcSMark Murray     size_t len = strlen(s) + 1;
311b528cefcSMark Murray     ssize_t ret;
312b528cefcSMark Murray 
313b528cefcSMark Murray     ret = sp->store(sp, s, len);
314b528cefcSMark Murray     if(ret != len) {
315b528cefcSMark Murray 	if(ret < 0)
316b528cefcSMark Murray 	    return ret;
317b528cefcSMark Murray 	else
318b528cefcSMark Murray 	    return KRB5_CC_END;
319b528cefcSMark Murray     }
320b528cefcSMark Murray     return 0;
321b528cefcSMark Murray }
322b528cefcSMark Murray 
323b528cefcSMark Murray krb5_error_code
324b528cefcSMark Murray krb5_ret_stringz(krb5_storage *sp,
325b528cefcSMark Murray 		char **string)
326b528cefcSMark Murray {
327b528cefcSMark Murray     char c;
328b528cefcSMark Murray     char *s = NULL;
329b528cefcSMark Murray     size_t len = 0;
330b528cefcSMark Murray     ssize_t ret;
331b528cefcSMark Murray 
332b528cefcSMark Murray     while((ret = sp->fetch(sp, &c, 1)) == 1){
333b528cefcSMark Murray 	char *tmp;
334b528cefcSMark Murray 
335b528cefcSMark Murray 	len++;
336b528cefcSMark Murray 	tmp = realloc (s, len);
337b528cefcSMark Murray 	if (tmp == NULL) {
338b528cefcSMark Murray 	    free (s);
339b528cefcSMark Murray 	    return ENOMEM;
340b528cefcSMark Murray 	}
341b528cefcSMark Murray 	s = tmp;
342b528cefcSMark Murray 	s[len - 1] = c;
343b528cefcSMark Murray 	if(c == 0)
344b528cefcSMark Murray 	    break;
345b528cefcSMark Murray     }
346b528cefcSMark Murray     if(ret != 1){
347b528cefcSMark Murray 	free(s);
348b528cefcSMark Murray 	if(ret == 0)
349b528cefcSMark Murray 	    return KRB5_CC_END;
350b528cefcSMark Murray 	return ret;
351b528cefcSMark Murray     }
352b528cefcSMark Murray     *string = s;
353b528cefcSMark Murray     return 0;
354b528cefcSMark Murray }
355b528cefcSMark Murray 
356b528cefcSMark Murray 
357b528cefcSMark Murray krb5_error_code
358b528cefcSMark Murray krb5_store_principal(krb5_storage *sp,
359b528cefcSMark Murray 		     krb5_principal p)
360b528cefcSMark Murray {
361b528cefcSMark Murray     int i;
362b528cefcSMark Murray     int ret;
363b528cefcSMark Murray 
364b528cefcSMark Murray     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
365b528cefcSMark Murray     ret = krb5_store_int32(sp, p->name.name_type);
366b528cefcSMark Murray     if(ret) return ret;
367b528cefcSMark Murray     }
368b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
369b528cefcSMark Murray 	ret = krb5_store_int32(sp, p->name.name_string.len + 1);
370b528cefcSMark Murray     else
371b528cefcSMark Murray     ret = krb5_store_int32(sp, p->name.name_string.len);
372b528cefcSMark Murray 
373b528cefcSMark Murray     if(ret) return ret;
374b528cefcSMark Murray     ret = krb5_store_string(sp, p->realm);
375b528cefcSMark Murray     if(ret) return ret;
376b528cefcSMark Murray     for(i = 0; i < p->name.name_string.len; i++){
377b528cefcSMark Murray 	ret = krb5_store_string(sp, p->name.name_string.val[i]);
378b528cefcSMark Murray 	if(ret) return ret;
379b528cefcSMark Murray     }
380b528cefcSMark Murray     return 0;
381b528cefcSMark Murray }
382b528cefcSMark Murray 
383b528cefcSMark Murray krb5_error_code
384b528cefcSMark Murray krb5_ret_principal(krb5_storage *sp,
385b528cefcSMark Murray 		   krb5_principal *princ)
386b528cefcSMark Murray {
387b528cefcSMark Murray     int i;
388b528cefcSMark Murray     int ret;
389b528cefcSMark Murray     krb5_principal p;
390b528cefcSMark Murray     int32_t type;
391b528cefcSMark Murray     int32_t ncomp;
392b528cefcSMark Murray 
393b528cefcSMark Murray     p = calloc(1, sizeof(*p));
394b528cefcSMark Murray     if(p == NULL)
395b528cefcSMark Murray 	return ENOMEM;
396b528cefcSMark Murray 
397b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
398b528cefcSMark Murray 	type = KRB5_NT_UNKNOWN;
399b528cefcSMark Murray     else 	if((ret = krb5_ret_int32(sp, &type))){
400b528cefcSMark Murray 	free(p);
401b528cefcSMark Murray 	return ret;
402b528cefcSMark Murray     }
403b528cefcSMark Murray     if((ret = krb5_ret_int32(sp, &ncomp))){
404b528cefcSMark Murray 	free(p);
405b528cefcSMark Murray 	return ret;
406b528cefcSMark Murray     }
407b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
408b528cefcSMark Murray 	ncomp--;
409b528cefcSMark Murray     p->name.name_type = type;
410b528cefcSMark Murray     p->name.name_string.len = ncomp;
411b528cefcSMark Murray     ret = krb5_ret_string(sp, &p->realm);
412b528cefcSMark Murray     if(ret) return ret;
413b528cefcSMark Murray     p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
414b528cefcSMark Murray     if(p->name.name_string.val == NULL){
415b528cefcSMark Murray 	free(p->realm);
416b528cefcSMark Murray 	return ENOMEM;
417b528cefcSMark Murray     }
418b528cefcSMark Murray     for(i = 0; i < ncomp; i++){
419b528cefcSMark Murray 	ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
420b528cefcSMark Murray 	if(ret) return ret; /* XXX */
421b528cefcSMark Murray     }
422b528cefcSMark Murray     *princ = p;
423b528cefcSMark Murray     return 0;
424b528cefcSMark Murray }
425b528cefcSMark Murray 
426b528cefcSMark Murray krb5_error_code
427b528cefcSMark Murray krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
428b528cefcSMark Murray {
429b528cefcSMark Murray     int ret;
430b528cefcSMark Murray     ret = krb5_store_int16(sp, p.keytype);
431b528cefcSMark Murray     if(ret) return ret;
432b528cefcSMark Murray 
433b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
434b528cefcSMark Murray 	/* this should really be enctype, but it is the same as
435b528cefcSMark Murray            keytype nowadays */
436b528cefcSMark Murray     ret = krb5_store_int16(sp, p.keytype);
437b528cefcSMark Murray     if(ret) return ret;
438b528cefcSMark Murray     }
439b528cefcSMark Murray 
440b528cefcSMark Murray     ret = krb5_store_data(sp, p.keyvalue);
441b528cefcSMark Murray     return ret;
442b528cefcSMark Murray }
443b528cefcSMark Murray 
444b528cefcSMark Murray krb5_error_code
445b528cefcSMark Murray krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
446b528cefcSMark Murray {
447b528cefcSMark Murray     int ret;
448b528cefcSMark Murray     int16_t tmp;
449b528cefcSMark Murray 
450b528cefcSMark Murray     ret = krb5_ret_int16(sp, &tmp);
451b528cefcSMark Murray     if(ret) return ret;
452b528cefcSMark Murray     p->keytype = tmp;
453b528cefcSMark Murray 
454b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
455b528cefcSMark Murray     ret = krb5_ret_int16(sp, &tmp);
456b528cefcSMark Murray     if(ret) return ret;
457b528cefcSMark Murray     }
458b528cefcSMark Murray 
459b528cefcSMark Murray     ret = krb5_ret_data(sp, &p->keyvalue);
460b528cefcSMark Murray     return ret;
461b528cefcSMark Murray }
462b528cefcSMark Murray 
463b528cefcSMark Murray krb5_error_code
464b528cefcSMark Murray krb5_store_times(krb5_storage *sp, krb5_times times)
465b528cefcSMark Murray {
466b528cefcSMark Murray     int ret;
467b528cefcSMark Murray     ret = krb5_store_int32(sp, times.authtime);
468b528cefcSMark Murray     if(ret) return ret;
469b528cefcSMark Murray     ret = krb5_store_int32(sp, times.starttime);
470b528cefcSMark Murray     if(ret) return ret;
471b528cefcSMark Murray     ret = krb5_store_int32(sp, times.endtime);
472b528cefcSMark Murray     if(ret) return ret;
473b528cefcSMark Murray     ret = krb5_store_int32(sp, times.renew_till);
474b528cefcSMark Murray     return ret;
475b528cefcSMark Murray }
476b528cefcSMark Murray 
477b528cefcSMark Murray krb5_error_code
478b528cefcSMark Murray krb5_ret_times(krb5_storage *sp, krb5_times *times)
479b528cefcSMark Murray {
480b528cefcSMark Murray     int ret;
481b528cefcSMark Murray     int32_t tmp;
482b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
483b528cefcSMark Murray     times->authtime = tmp;
484b528cefcSMark Murray     if(ret) return ret;
485b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
486b528cefcSMark Murray     times->starttime = tmp;
487b528cefcSMark Murray     if(ret) return ret;
488b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
489b528cefcSMark Murray     times->endtime = tmp;
490b528cefcSMark Murray     if(ret) return ret;
491b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
492b528cefcSMark Murray     times->renew_till = tmp;
493b528cefcSMark Murray     return ret;
494b528cefcSMark Murray }
495b528cefcSMark Murray 
496b528cefcSMark Murray krb5_error_code
497b528cefcSMark Murray krb5_store_address(krb5_storage *sp, krb5_address p)
498b528cefcSMark Murray {
499b528cefcSMark Murray     int ret;
500b528cefcSMark Murray     ret = krb5_store_int16(sp, p.addr_type);
501b528cefcSMark Murray     if(ret) return ret;
502b528cefcSMark Murray     ret = krb5_store_data(sp, p.address);
503b528cefcSMark Murray     return ret;
504b528cefcSMark Murray }
505b528cefcSMark Murray 
506b528cefcSMark Murray krb5_error_code
507b528cefcSMark Murray krb5_ret_address(krb5_storage *sp, krb5_address *adr)
508b528cefcSMark Murray {
509b528cefcSMark Murray     int16_t t;
510b528cefcSMark Murray     int ret;
511b528cefcSMark Murray     ret = krb5_ret_int16(sp, &t);
512b528cefcSMark Murray     if(ret) return ret;
513b528cefcSMark Murray     adr->addr_type = t;
514b528cefcSMark Murray     ret = krb5_ret_data(sp, &adr->address);
515b528cefcSMark Murray     return ret;
516b528cefcSMark Murray }
517b528cefcSMark Murray 
518b528cefcSMark Murray krb5_error_code
519b528cefcSMark Murray krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
520b528cefcSMark Murray {
521b528cefcSMark Murray     int i;
522b528cefcSMark Murray     int ret;
523b528cefcSMark Murray     ret = krb5_store_int32(sp, p.len);
524b528cefcSMark Murray     if(ret) return ret;
525b528cefcSMark Murray     for(i = 0; i<p.len; i++){
526b528cefcSMark Murray 	ret = krb5_store_address(sp, p.val[i]);
527b528cefcSMark Murray 	if(ret) break;
528b528cefcSMark Murray     }
529b528cefcSMark Murray     return ret;
530b528cefcSMark Murray }
531b528cefcSMark Murray 
532b528cefcSMark Murray krb5_error_code
533b528cefcSMark Murray krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
534b528cefcSMark Murray {
535b528cefcSMark Murray     int i;
536b528cefcSMark Murray     int ret;
537b528cefcSMark Murray     int32_t tmp;
538b528cefcSMark Murray 
539b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
540b528cefcSMark Murray     if(ret) return ret;
541b528cefcSMark Murray     adr->len = tmp;
542b528cefcSMark Murray     ALLOC(adr->val, adr->len);
543b528cefcSMark Murray     for(i = 0; i < adr->len; i++){
544b528cefcSMark Murray 	ret = krb5_ret_address(sp, &adr->val[i]);
545b528cefcSMark Murray 	if(ret) break;
546b528cefcSMark Murray     }
547b528cefcSMark Murray     return ret;
548b528cefcSMark Murray }
549b528cefcSMark Murray 
550b528cefcSMark Murray krb5_error_code
551b528cefcSMark Murray krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
552b528cefcSMark Murray {
553b528cefcSMark Murray     krb5_error_code ret;
554b528cefcSMark Murray     int i;
555b528cefcSMark Murray     ret = krb5_store_int32(sp, auth.len);
556b528cefcSMark Murray     if(ret) return ret;
557b528cefcSMark Murray     for(i = 0; i < auth.len; i++){
558b528cefcSMark Murray 	ret = krb5_store_int16(sp, auth.val[i].ad_type);
559b528cefcSMark Murray 	if(ret) break;
560b528cefcSMark Murray 	ret = krb5_store_data(sp, auth.val[i].ad_data);
561b528cefcSMark Murray 	if(ret) break;
562b528cefcSMark Murray     }
563b528cefcSMark Murray     return 0;
564b528cefcSMark Murray }
565b528cefcSMark Murray 
566b528cefcSMark Murray krb5_error_code
567b528cefcSMark Murray krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
568b528cefcSMark Murray {
569b528cefcSMark Murray     krb5_error_code ret;
570b528cefcSMark Murray     int32_t tmp;
571b528cefcSMark Murray     int16_t tmp2;
572b528cefcSMark Murray     int i;
573b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
574b528cefcSMark Murray     if(ret) return ret;
575b528cefcSMark Murray     ALLOC_SEQ(auth, tmp);
576b528cefcSMark Murray     for(i = 0; i < tmp; i++){
577b528cefcSMark Murray 	ret = krb5_ret_int16(sp, &tmp2);
578b528cefcSMark Murray 	if(ret) break;
579b528cefcSMark Murray 	auth->val[i].ad_type = tmp2;
580b528cefcSMark Murray 	ret = krb5_ret_data(sp, &auth->val[i].ad_data);
581b528cefcSMark Murray 	if(ret) break;
582b528cefcSMark Murray     }
583b528cefcSMark Murray     return ret;
584b528cefcSMark Murray }
585b528cefcSMark Murray 
5865e9cd1aeSAssar Westerlund /*
5875e9cd1aeSAssar Westerlund  * store `creds' on `sp' returning error or zero
5885e9cd1aeSAssar Westerlund  */
5895e9cd1aeSAssar Westerlund 
590b528cefcSMark Murray krb5_error_code
591b528cefcSMark Murray krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
592b528cefcSMark Murray {
5935e9cd1aeSAssar Westerlund     int ret;
5945e9cd1aeSAssar Westerlund 
5955e9cd1aeSAssar Westerlund     ret = krb5_store_principal(sp, creds->client);
5965e9cd1aeSAssar Westerlund     if (ret)
5975e9cd1aeSAssar Westerlund 	return ret;
5985e9cd1aeSAssar Westerlund     ret = krb5_store_principal(sp, creds->server);
5995e9cd1aeSAssar Westerlund     if (ret)
6005e9cd1aeSAssar Westerlund 	return ret;
6015e9cd1aeSAssar Westerlund     ret = krb5_store_keyblock(sp, creds->session);
6025e9cd1aeSAssar Westerlund     if (ret)
6035e9cd1aeSAssar Westerlund 	return ret;
6045e9cd1aeSAssar Westerlund     ret = krb5_store_times(sp, creds->times);
6055e9cd1aeSAssar Westerlund     if (ret)
6065e9cd1aeSAssar Westerlund 	return ret;
6075e9cd1aeSAssar Westerlund     ret = krb5_store_int8(sp, 0);  /* this is probably the
608b528cefcSMark Murray 				enc-tkt-in-skey bit from KDCOptions */
6095e9cd1aeSAssar Westerlund     if (ret)
6105e9cd1aeSAssar Westerlund 	return ret;
6115e9cd1aeSAssar Westerlund     ret = krb5_store_int32(sp, creds->flags.i);
6125e9cd1aeSAssar Westerlund     if (ret)
6135e9cd1aeSAssar Westerlund 	return ret;
6145e9cd1aeSAssar Westerlund     ret = krb5_store_addrs(sp, creds->addresses);
6155e9cd1aeSAssar Westerlund     if (ret)
6165e9cd1aeSAssar Westerlund 	return ret;
6175e9cd1aeSAssar Westerlund     ret = krb5_store_authdata(sp, creds->authdata);
6185e9cd1aeSAssar Westerlund     if (ret)
6195e9cd1aeSAssar Westerlund 	return ret;
6205e9cd1aeSAssar Westerlund     ret = krb5_store_data(sp, creds->ticket);
6215e9cd1aeSAssar Westerlund     if (ret)
6225e9cd1aeSAssar Westerlund 	return ret;
6235e9cd1aeSAssar Westerlund     ret = krb5_store_data(sp, creds->second_ticket);
6245e9cd1aeSAssar Westerlund     if (ret)
6255e9cd1aeSAssar Westerlund 	return ret;
626b528cefcSMark Murray     return 0;
627b528cefcSMark Murray }
628b528cefcSMark Murray 
629b528cefcSMark Murray krb5_error_code
630b528cefcSMark Murray krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
631b528cefcSMark Murray {
632b528cefcSMark Murray     krb5_error_code ret;
633b528cefcSMark Murray     int8_t dummy8;
634b528cefcSMark Murray     int32_t dummy32;
635b528cefcSMark Murray 
636b528cefcSMark Murray     memset(creds, 0, sizeof(*creds));
637b528cefcSMark Murray     ret = krb5_ret_principal (sp,  &creds->client);
638b528cefcSMark Murray     if(ret) goto cleanup;
639b528cefcSMark Murray     ret = krb5_ret_principal (sp,  &creds->server);
640b528cefcSMark Murray     if(ret) goto cleanup;
641b528cefcSMark Murray     ret = krb5_ret_keyblock (sp,  &creds->session);
642b528cefcSMark Murray     if(ret) goto cleanup;
643b528cefcSMark Murray     ret = krb5_ret_times (sp,  &creds->times);
644b528cefcSMark Murray     if(ret) goto cleanup;
645b528cefcSMark Murray     ret = krb5_ret_int8 (sp,  &dummy8);
646b528cefcSMark Murray     if(ret) goto cleanup;
647b528cefcSMark Murray     ret = krb5_ret_int32 (sp,  &dummy32);
648b528cefcSMark Murray     if(ret) goto cleanup;
649b528cefcSMark Murray     creds->flags.i = dummy32;
650b528cefcSMark Murray     ret = krb5_ret_addrs (sp,  &creds->addresses);
651b528cefcSMark Murray     if(ret) goto cleanup;
652b528cefcSMark Murray     ret = krb5_ret_authdata (sp,  &creds->authdata);
653b528cefcSMark Murray     if(ret) goto cleanup;
654b528cefcSMark Murray     ret = krb5_ret_data (sp,  &creds->ticket);
655b528cefcSMark Murray     if(ret) goto cleanup;
656b528cefcSMark Murray     ret = krb5_ret_data (sp,  &creds->second_ticket);
657b528cefcSMark Murray cleanup:
658b528cefcSMark Murray     if(ret)
659b528cefcSMark Murray #if 0
660b528cefcSMark Murray 	krb5_free_creds_contents(context, creds) /* XXX */
661b528cefcSMark Murray #endif
662b528cefcSMark Murray 	    ;
663b528cefcSMark Murray     return ret;
664b528cefcSMark Murray }
665