1*54925bf6Swillf /*
2*54925bf6Swillf * lib/kdb/kdb_xdr.c
3*54925bf6Swillf *
4*54925bf6Swillf * Copyright 1995 by the Massachusetts Institute of Technology.
5*54925bf6Swillf * All Rights Reserved.
6*54925bf6Swillf *
7*54925bf6Swillf * Export of this software from the United States of America may
8*54925bf6Swillf * require a specific license from the United States Government.
9*54925bf6Swillf * It is the responsibility of any person or organization contemplating
10*54925bf6Swillf * export to obtain such a license before exporting.
11*54925bf6Swillf *
12*54925bf6Swillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*54925bf6Swillf * distribute this software and its documentation for any purpose and
14*54925bf6Swillf * without fee is hereby granted, provided that the above copyright
15*54925bf6Swillf * notice appear in all copies and that both that copyright notice and
16*54925bf6Swillf * this permission notice appear in supporting documentation, and that
17*54925bf6Swillf * the name of M.I.T. not be used in advertising or publicity pertaining
18*54925bf6Swillf * to distribution of the software without specific, written prior
19*54925bf6Swillf * permission. Furthermore if you modify this software you must label
20*54925bf6Swillf * your software as modified software and not distribute it in such a
21*54925bf6Swillf * fashion that it might be confused with the original M.I.T. software.
22*54925bf6Swillf * M.I.T. makes no representations about the suitability of
23*54925bf6Swillf * this software for any purpose. It is provided "as is" without express
24*54925bf6Swillf * or implied warranty.
25*54925bf6Swillf *
26*54925bf6Swillf */
27*54925bf6Swillf
28*54925bf6Swillf #include "k5-int.h"
29*54925bf6Swillf #include <string.h>
30*54925bf6Swillf #include <stdio.h>
31*54925bf6Swillf #include <errno.h>
32*54925bf6Swillf #include "kdb_xdr.h"
33*54925bf6Swillf
34*54925bf6Swillf krb5_error_code
krb5_encode_princ_dbkey(context,key,principal)35*54925bf6Swillf krb5_encode_princ_dbkey(context, key, principal)
36*54925bf6Swillf krb5_context context;
37*54925bf6Swillf krb5_data *key;
38*54925bf6Swillf krb5_const_principal principal;
39*54925bf6Swillf {
40*54925bf6Swillf char *princ_name;
41*54925bf6Swillf krb5_error_code retval;
42*54925bf6Swillf
43*54925bf6Swillf if (!(retval = krb5_unparse_name(context, principal, &princ_name))) {
44*54925bf6Swillf /* need to store the NULL for decoding */
45*54925bf6Swillf key->length = strlen(princ_name)+1;
46*54925bf6Swillf key->data = princ_name;
47*54925bf6Swillf }
48*54925bf6Swillf return(retval);
49*54925bf6Swillf }
50*54925bf6Swillf
51*54925bf6Swillf void
krb5_free_princ_dbkey(context,key)52*54925bf6Swillf krb5_free_princ_dbkey(context, key)
53*54925bf6Swillf krb5_context context;
54*54925bf6Swillf krb5_data *key;
55*54925bf6Swillf {
56*54925bf6Swillf (void) krb5_free_data_contents(context, key);
57*54925bf6Swillf }
58*54925bf6Swillf
59*54925bf6Swillf krb5_error_code
krb5_encode_princ_contents(context,content,entry)60*54925bf6Swillf krb5_encode_princ_contents(context, content, entry)
61*54925bf6Swillf krb5_context context;
62*54925bf6Swillf krb5_data * content;
63*54925bf6Swillf krb5_db_entry * entry;
64*54925bf6Swillf {
65*54925bf6Swillf int i, j;
66*54925bf6Swillf unsigned int unparse_princ_size;
67*54925bf6Swillf char * unparse_princ;
68*54925bf6Swillf char * nextloc;
69*54925bf6Swillf krb5_tl_data * tl_data;
70*54925bf6Swillf krb5_error_code retval;
71*54925bf6Swillf krb5_int16 psize16;
72*54925bf6Swillf
73*54925bf6Swillf /*
74*54925bf6Swillf * Generate one lump of data from the krb5_db_entry.
75*54925bf6Swillf * This data must be independent of byte order of the machine,
76*54925bf6Swillf * compact and extensible.
77*54925bf6Swillf */
78*54925bf6Swillf
79*54925bf6Swillf /*
80*54925bf6Swillf * First allocate enough space for all the data.
81*54925bf6Swillf * Need 2 bytes for the length of the base structure
82*54925bf6Swillf * then 36 [ 8 * 4 + 2 * 2] bytes for the base information
83*54925bf6Swillf * [ attributes, max_life, max_renewable_life, expiration,
84*54925bf6Swillf * pw_expiration, last_success, last_failed, fail_auth_count ]
85*54925bf6Swillf * [ n_key_data, n_tl_data ]
86*54925bf6Swillf * then XX bytes [ e_length ] for the extra data [ e_data ]
87*54925bf6Swillf * then XX bytes [ 2 for length + length for string ] for the principal,
88*54925bf6Swillf * then (4 [type + length] + tl_data_length) bytes per tl_data
89*54925bf6Swillf * then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data
90*54925bf6Swillf */
91*54925bf6Swillf content->length = entry->len + entry->e_length;
92*54925bf6Swillf
93*54925bf6Swillf if ((retval = krb5_unparse_name(context, entry->princ, &unparse_princ)))
94*54925bf6Swillf return(retval);
95*54925bf6Swillf
96*54925bf6Swillf unparse_princ_size = strlen(unparse_princ) + 1;
97*54925bf6Swillf content->length += unparse_princ_size;
98*54925bf6Swillf content->length += 2;
99*54925bf6Swillf
100*54925bf6Swillf i = 0;
101*54925bf6Swillf /* tl_data is a linked list */
102*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
103*54925bf6Swillf content->length += tl_data->tl_data_length;
104*54925bf6Swillf content->length += 4; /* type, length */
105*54925bf6Swillf i++;
106*54925bf6Swillf }
107*54925bf6Swillf
108*54925bf6Swillf if (i != entry->n_tl_data) {
109*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
110*54925bf6Swillf goto epc_error;
111*54925bf6Swillf }
112*54925bf6Swillf
113*54925bf6Swillf /* key_data is an array */
114*54925bf6Swillf for (i = 0; i < entry->n_key_data; i++) {
115*54925bf6Swillf content->length += 4; /* Version, KVNO */
116*54925bf6Swillf for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
117*54925bf6Swillf content->length += entry->key_data[i].key_data_length[j];
118*54925bf6Swillf content->length += 4; /* type + length */
119*54925bf6Swillf }
120*54925bf6Swillf }
121*54925bf6Swillf
122*54925bf6Swillf if ((content->data = malloc(content->length)) == NULL) {
123*54925bf6Swillf retval = ENOMEM;
124*54925bf6Swillf goto epc_error;
125*54925bf6Swillf }
126*54925bf6Swillf
127*54925bf6Swillf /*
128*54925bf6Swillf * Now we go through entry again, this time copying data
129*54925bf6Swillf * These first entries are always saved regardless of version
130*54925bf6Swillf */
131*54925bf6Swillf nextloc = content->data;
132*54925bf6Swillf
133*54925bf6Swillf /* Base Length */
134*54925bf6Swillf krb5_kdb_encode_int16(entry->len, nextloc);
135*54925bf6Swillf nextloc += 2;
136*54925bf6Swillf
137*54925bf6Swillf /* Attributes */
138*54925bf6Swillf krb5_kdb_encode_int32(entry->attributes, nextloc);
139*54925bf6Swillf nextloc += 4;
140*54925bf6Swillf
141*54925bf6Swillf /* Max Life */
142*54925bf6Swillf krb5_kdb_encode_int32(entry->max_life, nextloc);
143*54925bf6Swillf nextloc += 4;
144*54925bf6Swillf
145*54925bf6Swillf /* Max Renewable Life */
146*54925bf6Swillf krb5_kdb_encode_int32(entry->max_renewable_life, nextloc);
147*54925bf6Swillf nextloc += 4;
148*54925bf6Swillf
149*54925bf6Swillf /* When the client expires */
150*54925bf6Swillf krb5_kdb_encode_int32(entry->expiration, nextloc);
151*54925bf6Swillf nextloc += 4;
152*54925bf6Swillf
153*54925bf6Swillf /* When its passwd expires */
154*54925bf6Swillf krb5_kdb_encode_int32(entry->pw_expiration, nextloc);
155*54925bf6Swillf nextloc += 4;
156*54925bf6Swillf
157*54925bf6Swillf /* Last successful passwd */
158*54925bf6Swillf krb5_kdb_encode_int32(entry->last_success, nextloc);
159*54925bf6Swillf nextloc += 4;
160*54925bf6Swillf
161*54925bf6Swillf /* Last failed passwd attempt */
162*54925bf6Swillf krb5_kdb_encode_int32(entry->last_failed, nextloc);
163*54925bf6Swillf nextloc += 4;
164*54925bf6Swillf
165*54925bf6Swillf /* # of failed passwd attempt */
166*54925bf6Swillf krb5_kdb_encode_int32(entry->fail_auth_count, nextloc);
167*54925bf6Swillf nextloc += 4;
168*54925bf6Swillf
169*54925bf6Swillf /* # tl_data strutures */
170*54925bf6Swillf krb5_kdb_encode_int16(entry->n_tl_data, nextloc);
171*54925bf6Swillf nextloc += 2;
172*54925bf6Swillf
173*54925bf6Swillf /* # key_data strutures */
174*54925bf6Swillf krb5_kdb_encode_int16(entry->n_key_data, nextloc);
175*54925bf6Swillf nextloc += 2;
176*54925bf6Swillf
177*54925bf6Swillf /* Put extended fields here */
178*54925bf6Swillf if (entry->len != KRB5_KDB_V1_BASE_LENGTH)
179*54925bf6Swillf abort();
180*54925bf6Swillf
181*54925bf6Swillf /* Any extra data that this version doesn't understand. */
182*54925bf6Swillf if (entry->e_length) {
183*54925bf6Swillf memcpy(nextloc, entry->e_data, entry->e_length);
184*54925bf6Swillf nextloc += entry->e_length;
185*54925bf6Swillf }
186*54925bf6Swillf
187*54925bf6Swillf /*
188*54925bf6Swillf * Now we get to the principal.
189*54925bf6Swillf * To squeze a few extra bytes out it is always assumed to come
190*54925bf6Swillf * after the base type.
191*54925bf6Swillf */
192*54925bf6Swillf psize16 = (krb5_int16) unparse_princ_size;
193*54925bf6Swillf krb5_kdb_encode_int16(psize16, nextloc);
194*54925bf6Swillf nextloc += 2;
195*54925bf6Swillf (void) memcpy(nextloc, unparse_princ, unparse_princ_size);
196*54925bf6Swillf nextloc += unparse_princ_size;
197*54925bf6Swillf
198*54925bf6Swillf /* tl_data is a linked list, of type, legth, contents */
199*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
200*54925bf6Swillf krb5_kdb_encode_int16(tl_data->tl_data_type, nextloc);
201*54925bf6Swillf nextloc += 2;
202*54925bf6Swillf krb5_kdb_encode_int16(tl_data->tl_data_length, nextloc);
203*54925bf6Swillf nextloc += 2;
204*54925bf6Swillf
205*54925bf6Swillf memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length);
206*54925bf6Swillf nextloc += tl_data->tl_data_length;
207*54925bf6Swillf }
208*54925bf6Swillf
209*54925bf6Swillf /* key_data is an array */
210*54925bf6Swillf for (i = 0; i < entry->n_key_data; i++) {
211*54925bf6Swillf krb5_kdb_encode_int16(entry->key_data[i].key_data_ver, nextloc);
212*54925bf6Swillf nextloc += 2;
213*54925bf6Swillf krb5_kdb_encode_int16(entry->key_data[i].key_data_kvno, nextloc);
214*54925bf6Swillf nextloc += 2;
215*54925bf6Swillf
216*54925bf6Swillf for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
217*54925bf6Swillf krb5_int16 type = entry->key_data[i].key_data_type[j];
218*54925bf6Swillf krb5_ui_2 length = entry->key_data[i].key_data_length[j];
219*54925bf6Swillf
220*54925bf6Swillf krb5_kdb_encode_int16(type, nextloc);
221*54925bf6Swillf nextloc += 2;
222*54925bf6Swillf krb5_kdb_encode_int16(length, nextloc);
223*54925bf6Swillf nextloc += 2;
224*54925bf6Swillf
225*54925bf6Swillf if (length) {
226*54925bf6Swillf memcpy(nextloc, entry->key_data[i].key_data_contents[j],length);
227*54925bf6Swillf nextloc += length;
228*54925bf6Swillf }
229*54925bf6Swillf }
230*54925bf6Swillf }
231*54925bf6Swillf
232*54925bf6Swillf epc_error:;
233*54925bf6Swillf free(unparse_princ);
234*54925bf6Swillf return retval;
235*54925bf6Swillf }
236*54925bf6Swillf
237*54925bf6Swillf void
krb5_free_princ_contents(context,contents)238*54925bf6Swillf krb5_free_princ_contents(context, contents)
239*54925bf6Swillf krb5_context context;
240*54925bf6Swillf krb5_data *contents;
241*54925bf6Swillf {
242*54925bf6Swillf krb5_free_data_contents(context, contents);
243*54925bf6Swillf return;
244*54925bf6Swillf }
245*54925bf6Swillf
246*54925bf6Swillf krb5_error_code
krb5_decode_princ_contents(context,content,entry)247*54925bf6Swillf krb5_decode_princ_contents(context, content, entry)
248*54925bf6Swillf krb5_context context;
249*54925bf6Swillf krb5_data * content;
250*54925bf6Swillf krb5_db_entry * entry;
251*54925bf6Swillf {
252*54925bf6Swillf int sizeleft, i;
253*54925bf6Swillf char * nextloc;
254*54925bf6Swillf krb5_tl_data ** tl_data;
255*54925bf6Swillf krb5_int16 i16;
256*54925bf6Swillf
257*54925bf6Swillf krb5_error_code retval;
258*54925bf6Swillf
259*54925bf6Swillf /* Zero out entry and NULL pointers */
260*54925bf6Swillf memset(entry, 0, sizeof(krb5_db_entry));
261*54925bf6Swillf
262*54925bf6Swillf /*
263*54925bf6Swillf * undo the effects of encode_princ_contents.
264*54925bf6Swillf *
265*54925bf6Swillf * The first part is decoding the base type. If the base type is
266*54925bf6Swillf * bigger than the original base type then the additional fields
267*54925bf6Swillf * need to be filled in. If the base type is larger than any
268*54925bf6Swillf * known base type the additional data goes in e_data.
269*54925bf6Swillf */
270*54925bf6Swillf
271*54925bf6Swillf /* First do the easy stuff */
272*54925bf6Swillf nextloc = content->data;
273*54925bf6Swillf sizeleft = content->length;
274*54925bf6Swillf if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0)
275*54925bf6Swillf return KRB5_KDB_TRUNCATED_RECORD;
276*54925bf6Swillf
277*54925bf6Swillf /* Base Length */
278*54925bf6Swillf krb5_kdb_decode_int16(nextloc, entry->len);
279*54925bf6Swillf nextloc += 2;
280*54925bf6Swillf
281*54925bf6Swillf /* Attributes */
282*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->attributes);
283*54925bf6Swillf nextloc += 4;
284*54925bf6Swillf
285*54925bf6Swillf /* Max Life */
286*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->max_life);
287*54925bf6Swillf nextloc += 4;
288*54925bf6Swillf
289*54925bf6Swillf /* Max Renewable Life */
290*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->max_renewable_life);
291*54925bf6Swillf nextloc += 4;
292*54925bf6Swillf
293*54925bf6Swillf /* When the client expires */
294*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->expiration);
295*54925bf6Swillf nextloc += 4;
296*54925bf6Swillf
297*54925bf6Swillf /* When its passwd expires */
298*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->pw_expiration);
299*54925bf6Swillf nextloc += 4;
300*54925bf6Swillf
301*54925bf6Swillf /* Last successful passwd */
302*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->last_success);
303*54925bf6Swillf nextloc += 4;
304*54925bf6Swillf
305*54925bf6Swillf /* Last failed passwd attempt */
306*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->last_failed);
307*54925bf6Swillf nextloc += 4;
308*54925bf6Swillf
309*54925bf6Swillf /* # of failed passwd attempt */
310*54925bf6Swillf krb5_kdb_decode_int32(nextloc, entry->fail_auth_count);
311*54925bf6Swillf nextloc += 4;
312*54925bf6Swillf
313*54925bf6Swillf /* # tl_data strutures */
314*54925bf6Swillf krb5_kdb_decode_int16(nextloc, entry->n_tl_data);
315*54925bf6Swillf nextloc += 2;
316*54925bf6Swillf
317*54925bf6Swillf if (entry->n_tl_data < 0)
318*54925bf6Swillf return KRB5_KDB_TRUNCATED_RECORD;
319*54925bf6Swillf
320*54925bf6Swillf /* # key_data strutures */
321*54925bf6Swillf krb5_kdb_decode_int16(nextloc, entry->n_key_data);
322*54925bf6Swillf nextloc += 2;
323*54925bf6Swillf
324*54925bf6Swillf if (entry->n_key_data < 0)
325*54925bf6Swillf return KRB5_KDB_TRUNCATED_RECORD;
326*54925bf6Swillf
327*54925bf6Swillf /* Check for extra data */
328*54925bf6Swillf if (entry->len > KRB5_KDB_V1_BASE_LENGTH) {
329*54925bf6Swillf entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH;
330*54925bf6Swillf if ((entry->e_data = (krb5_octet *)malloc(entry->e_length))) {
331*54925bf6Swillf memcpy(entry->e_data, nextloc, entry->e_length);
332*54925bf6Swillf nextloc += entry->e_length;
333*54925bf6Swillf } else {
334*54925bf6Swillf return ENOMEM;
335*54925bf6Swillf }
336*54925bf6Swillf }
337*54925bf6Swillf
338*54925bf6Swillf /*
339*54925bf6Swillf * Get the principal name for the entry
340*54925bf6Swillf * (stored as a string which gets unparsed.)
341*54925bf6Swillf */
342*54925bf6Swillf if ((sizeleft -= 2) < 0) {
343*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
344*54925bf6Swillf goto error_out;
345*54925bf6Swillf }
346*54925bf6Swillf
347*54925bf6Swillf i = 0;
348*54925bf6Swillf krb5_kdb_decode_int16(nextloc, i16);
349*54925bf6Swillf i = (int) i16;
350*54925bf6Swillf nextloc += 2;
351*54925bf6Swillf
352*54925bf6Swillf if ((retval = krb5_parse_name(context, nextloc, &(entry->princ))))
353*54925bf6Swillf goto error_out;
354*54925bf6Swillf if (((size_t) i != (strlen(nextloc) + 1)) || (sizeleft < i)) {
355*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
356*54925bf6Swillf goto error_out;
357*54925bf6Swillf }
358*54925bf6Swillf sizeleft -= i;
359*54925bf6Swillf nextloc += i;
360*54925bf6Swillf
361*54925bf6Swillf /* tl_data is a linked list */
362*54925bf6Swillf tl_data = &entry->tl_data;
363*54925bf6Swillf for (i = 0; i < entry->n_tl_data; i++) {
364*54925bf6Swillf if ((sizeleft -= 4) < 0) {
365*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
366*54925bf6Swillf goto error_out;
367*54925bf6Swillf }
368*54925bf6Swillf if ((*tl_data = (krb5_tl_data *)
369*54925bf6Swillf malloc(sizeof(krb5_tl_data))) == NULL) {
370*54925bf6Swillf retval = ENOMEM;
371*54925bf6Swillf goto error_out;
372*54925bf6Swillf }
373*54925bf6Swillf (*tl_data)->tl_data_next = NULL;
374*54925bf6Swillf (*tl_data)->tl_data_contents = NULL;
375*54925bf6Swillf krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_type);
376*54925bf6Swillf nextloc += 2;
377*54925bf6Swillf krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_length);
378*54925bf6Swillf nextloc += 2;
379*54925bf6Swillf
380*54925bf6Swillf if ((sizeleft -= (*tl_data)->tl_data_length) < 0) {
381*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
382*54925bf6Swillf goto error_out;
383*54925bf6Swillf }
384*54925bf6Swillf if (((*tl_data)->tl_data_contents = (krb5_octet *)
385*54925bf6Swillf malloc((*tl_data)->tl_data_length)) == NULL) {
386*54925bf6Swillf retval = ENOMEM;
387*54925bf6Swillf goto error_out;
388*54925bf6Swillf }
389*54925bf6Swillf memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length);
390*54925bf6Swillf nextloc += (*tl_data)->tl_data_length;
391*54925bf6Swillf tl_data = &((*tl_data)->tl_data_next);
392*54925bf6Swillf }
393*54925bf6Swillf
394*54925bf6Swillf /* key_data is an array */
395*54925bf6Swillf if (entry->n_key_data && ((entry->key_data = (krb5_key_data *)
396*54925bf6Swillf malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL)) {
397*54925bf6Swillf retval = ENOMEM;
398*54925bf6Swillf goto error_out;
399*54925bf6Swillf }
400*54925bf6Swillf for (i = 0; i < entry->n_key_data; i++) {
401*54925bf6Swillf krb5_key_data * key_data;
402*54925bf6Swillf int j;
403*54925bf6Swillf
404*54925bf6Swillf if ((sizeleft -= 4) < 0) {
405*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
406*54925bf6Swillf goto error_out;
407*54925bf6Swillf }
408*54925bf6Swillf key_data = entry->key_data + i;
409*54925bf6Swillf memset(key_data, 0, sizeof(krb5_key_data));
410*54925bf6Swillf krb5_kdb_decode_int16(nextloc, key_data->key_data_ver);
411*54925bf6Swillf nextloc += 2;
412*54925bf6Swillf krb5_kdb_decode_int16(nextloc, key_data->key_data_kvno);
413*54925bf6Swillf nextloc += 2;
414*54925bf6Swillf
415*54925bf6Swillf /* key_data_ver determins number of elements and how to unparse them. */
416*54925bf6Swillf if (key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) {
417*54925bf6Swillf for (j = 0; j < key_data->key_data_ver; j++) {
418*54925bf6Swillf if ((sizeleft -= 4) < 0) {
419*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
420*54925bf6Swillf goto error_out;
421*54925bf6Swillf }
422*54925bf6Swillf krb5_kdb_decode_int16(nextloc, key_data->key_data_type[j]);
423*54925bf6Swillf nextloc += 2;
424*54925bf6Swillf krb5_kdb_decode_int16(nextloc, key_data->key_data_length[j]);
425*54925bf6Swillf nextloc += 2;
426*54925bf6Swillf
427*54925bf6Swillf if ((sizeleft -= key_data->key_data_length[j]) < 0) {
428*54925bf6Swillf retval = KRB5_KDB_TRUNCATED_RECORD;
429*54925bf6Swillf goto error_out;
430*54925bf6Swillf }
431*54925bf6Swillf if (key_data->key_data_length[j]) {
432*54925bf6Swillf if ((key_data->key_data_contents[j] = (krb5_octet *)
433*54925bf6Swillf malloc(key_data->key_data_length[j])) == NULL) {
434*54925bf6Swillf retval = ENOMEM;
435*54925bf6Swillf goto error_out;
436*54925bf6Swillf }
437*54925bf6Swillf memcpy(key_data->key_data_contents[j], nextloc,
438*54925bf6Swillf key_data->key_data_length[j]);
439*54925bf6Swillf nextloc += key_data->key_data_length[j];
440*54925bf6Swillf }
441*54925bf6Swillf }
442*54925bf6Swillf } else {
443*54925bf6Swillf /* This isn't right. I'll fix it later */
444*54925bf6Swillf abort();
445*54925bf6Swillf }
446*54925bf6Swillf }
447*54925bf6Swillf return 0;
448*54925bf6Swillf
449*54925bf6Swillf error_out:;
450*54925bf6Swillf krb5_dbe_free_contents(context, entry);
451*54925bf6Swillf return retval;
452*54925bf6Swillf }
453*54925bf6Swillf
454*54925bf6Swillf void
krb5_dbe_free_contents(context,entry)455*54925bf6Swillf krb5_dbe_free_contents(context, entry)
456*54925bf6Swillf krb5_context context;
457*54925bf6Swillf krb5_db_entry * entry;
458*54925bf6Swillf {
459*54925bf6Swillf krb5_tl_data * tl_data_next;
460*54925bf6Swillf krb5_tl_data * tl_data;
461*54925bf6Swillf int i, j;
462*54925bf6Swillf
463*54925bf6Swillf if (entry->e_data)
464*54925bf6Swillf free(entry->e_data);
465*54925bf6Swillf if (entry->princ)
466*54925bf6Swillf krb5_free_principal(context, entry->princ);
467*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
468*54925bf6Swillf tl_data_next = tl_data->tl_data_next;
469*54925bf6Swillf if (tl_data->tl_data_contents)
470*54925bf6Swillf free(tl_data->tl_data_contents);
471*54925bf6Swillf free(tl_data);
472*54925bf6Swillf }
473*54925bf6Swillf if (entry->key_data) {
474*54925bf6Swillf for (i = 0; i < entry->n_key_data; i++) {
475*54925bf6Swillf for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
476*54925bf6Swillf if (entry->key_data[i].key_data_length[j]) {
477*54925bf6Swillf if (entry->key_data[i].key_data_contents[j]) {
478*54925bf6Swillf memset(entry->key_data[i].key_data_contents[j],
479*54925bf6Swillf 0,
480*54925bf6Swillf (unsigned) entry->key_data[i].key_data_length[j]);
481*54925bf6Swillf free (entry->key_data[i].key_data_contents[j]);
482*54925bf6Swillf }
483*54925bf6Swillf }
484*54925bf6Swillf entry->key_data[i].key_data_contents[j] = NULL;
485*54925bf6Swillf entry->key_data[i].key_data_length[j] = 0;
486*54925bf6Swillf entry->key_data[i].key_data_type[j] = 0;
487*54925bf6Swillf }
488*54925bf6Swillf }
489*54925bf6Swillf free(entry->key_data);
490*54925bf6Swillf }
491*54925bf6Swillf memset(entry, 0, sizeof(*entry));
492*54925bf6Swillf return;
493*54925bf6Swillf }
494