4
* Copyright 1995 by the Massachusetts Institute of Technology.
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
35
krb5_encode_princ_dbkey(context, key, principal)
38
krb5_const_principal principal;
41
krb5_error_code retval;
43
if (!(retval = krb5_unparse_name(context, principal, &princ_name))) {
44
/* need to store the NULL for decoding */
45
key->length = strlen(princ_name)+1;
46
key->data = princ_name;
52
krb5_free_princ_dbkey(context, key)
56
(void) krb5_free_data_contents(context, key);
60
krb5_encode_princ_contents(context, content, entry)
63
krb5_db_entry * entry;
66
unsigned int unparse_princ_size;
68
unsigned char * nextloc;
69
krb5_tl_data * tl_data;
70
krb5_error_code retval;
74
* Generate one lump of data from the krb5_db_entry.
75
* This data must be independent of byte order of the machine,
76
* compact and extensible.
80
* First allocate enough space for all the data.
81
* Need 2 bytes for the length of the base structure
82
* then 36 [ 8 * 4 + 2 * 2] bytes for the base information
83
* [ attributes, max_life, max_renewable_life, expiration,
84
* pw_expiration, last_success, last_failed, fail_auth_count ]
85
* [ n_key_data, n_tl_data ]
86
* then XX bytes [ e_length ] for the extra data [ e_data ]
87
* then XX bytes [ 2 for length + length for string ] for the principal,
88
* then (4 [type + length] + tl_data_length) bytes per tl_data
89
* then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data
91
content->length = entry->len + entry->e_length;
93
if ((retval = krb5_unparse_name(context, entry->princ, &unparse_princ)))
96
unparse_princ_size = strlen(unparse_princ) + 1;
97
content->length += unparse_princ_size;
101
/* tl_data is a linked list */
102
for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
103
content->length += tl_data->tl_data_length;
104
content->length += 4; /* type, length */
108
if (i != entry->n_tl_data) {
109
retval = KRB5_KDB_TRUNCATED_RECORD;
113
/* key_data is an array */
114
for (i = 0; i < entry->n_key_data; i++) {
115
content->length += 4; /* Version, KVNO */
116
for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
117
content->length += entry->key_data[i].key_data_length[j];
118
content->length += 4; /* type + length */
122
if ((content->data = malloc(content->length)) == NULL) {
128
* Now we go through entry again, this time copying data
129
* These first entries are always saved regardless of version
131
nextloc = (unsigned char *)content->data;
134
krb5_kdb_encode_int16(entry->len, nextloc);
138
krb5_kdb_encode_int32(entry->attributes, nextloc);
142
krb5_kdb_encode_int32(entry->max_life, nextloc);
145
/* Max Renewable Life */
146
krb5_kdb_encode_int32(entry->max_renewable_life, nextloc);
149
/* When the client expires */
150
krb5_kdb_encode_int32(entry->expiration, nextloc);
153
/* When its passwd expires */
154
krb5_kdb_encode_int32(entry->pw_expiration, nextloc);
157
/* Last successful passwd */
158
krb5_kdb_encode_int32(entry->last_success, nextloc);
161
/* Last failed passwd attempt */
162
krb5_kdb_encode_int32(entry->last_failed, nextloc);
165
/* # of failed passwd attempt */
166
krb5_kdb_encode_int32(entry->fail_auth_count, nextloc);
169
/* # tl_data strutures */
170
krb5_kdb_encode_int16(entry->n_tl_data, nextloc);
173
/* # key_data strutures */
174
krb5_kdb_encode_int16(entry->n_key_data, nextloc);
177
/* Put extended fields here */
178
if (entry->len != KRB5_KDB_V1_BASE_LENGTH)
181
/* Any extra data that this version doesn't understand. */
182
if (entry->e_length) {
183
memcpy(nextloc, entry->e_data, entry->e_length);
184
nextloc += entry->e_length;
188
* Now we get to the principal.
189
* To squeze a few extra bytes out it is always assumed to come
190
* after the base type.
192
psize16 = (krb5_int16) unparse_princ_size;
193
krb5_kdb_encode_int16(psize16, nextloc);
195
(void) memcpy(nextloc, unparse_princ, unparse_princ_size);
196
nextloc += unparse_princ_size;
198
/* tl_data is a linked list, of type, legth, contents */
199
for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
200
krb5_kdb_encode_int16(tl_data->tl_data_type, nextloc);
202
krb5_kdb_encode_int16(tl_data->tl_data_length, nextloc);
205
memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length);
206
nextloc += tl_data->tl_data_length;
209
/* key_data is an array */
210
for (i = 0; i < entry->n_key_data; i++) {
211
krb5_kdb_encode_int16(entry->key_data[i].key_data_ver, nextloc);
213
krb5_kdb_encode_int16(entry->key_data[i].key_data_kvno, nextloc);
216
for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
217
krb5_int16 type = entry->key_data[i].key_data_type[j];
218
krb5_ui_2 length = entry->key_data[i].key_data_length[j];
220
krb5_kdb_encode_int16(type, nextloc);
222
krb5_kdb_encode_int16(length, nextloc);
226
memcpy(nextloc, entry->key_data[i].key_data_contents[j],length);
238
krb5_free_princ_contents(context, contents)
239
krb5_context context;
242
krb5_free_data_contents(context, contents);
247
krb5_decode_princ_contents(context, content, entry)
248
krb5_context context;
250
krb5_db_entry * entry;
253
unsigned char * nextloc;
254
krb5_tl_data ** tl_data;
257
krb5_error_code retval;
259
/* Zero out entry and NULL pointers */
260
memset(entry, 0, sizeof(krb5_db_entry));
263
* undo the effects of encode_princ_contents.
265
* The first part is decoding the base type. If the base type is
266
* bigger than the original base type then the additional fields
267
* need to be filled in. If the base type is larger than any
268
* known base type the additional data goes in e_data.
271
/* First do the easy stuff */
272
nextloc = (unsigned char *)content->data;
273
sizeleft = content->length;
274
if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0)
275
return KRB5_KDB_TRUNCATED_RECORD;
278
krb5_kdb_decode_int16(nextloc, entry->len);
282
krb5_kdb_decode_int32(nextloc, entry->attributes);
286
krb5_kdb_decode_int32(nextloc, entry->max_life);
289
/* Max Renewable Life */
290
krb5_kdb_decode_int32(nextloc, entry->max_renewable_life);
293
/* When the client expires */
294
krb5_kdb_decode_int32(nextloc, entry->expiration);
297
/* When its passwd expires */
298
krb5_kdb_decode_int32(nextloc, entry->pw_expiration);
301
/* Last successful passwd */
302
krb5_kdb_decode_int32(nextloc, entry->last_success);
305
/* Last failed passwd attempt */
306
krb5_kdb_decode_int32(nextloc, entry->last_failed);
309
/* # of failed passwd attempt */
310
krb5_kdb_decode_int32(nextloc, entry->fail_auth_count);
313
/* # tl_data strutures */
314
krb5_kdb_decode_int16(nextloc, entry->n_tl_data);
317
if (entry->n_tl_data < 0)
318
return KRB5_KDB_TRUNCATED_RECORD;
320
/* # key_data strutures */
321
krb5_kdb_decode_int16(nextloc, entry->n_key_data);
324
if (entry->n_key_data < 0)
325
return KRB5_KDB_TRUNCATED_RECORD;
327
/* Check for extra data */
328
if (entry->len > KRB5_KDB_V1_BASE_LENGTH) {
329
entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH;
330
if ((entry->e_data = (krb5_octet *)malloc(entry->e_length))) {
331
memcpy(entry->e_data, nextloc, entry->e_length);
332
nextloc += entry->e_length;
339
* Get the principal name for the entry
340
* (stored as a string which gets unparsed.)
342
if ((sizeleft -= 2) < 0) {
343
retval = KRB5_KDB_TRUNCATED_RECORD;
348
krb5_kdb_decode_int16(nextloc, i16);
352
if ((retval = krb5_parse_name(context, (char *)nextloc, &(entry->princ))))
354
if (((size_t) i != (strlen((char *)nextloc) + 1)) || (sizeleft < i)) {
355
retval = KRB5_KDB_TRUNCATED_RECORD;
361
/* tl_data is a linked list */
362
tl_data = &entry->tl_data;
363
for (i = 0; i < entry->n_tl_data; i++) {
364
if ((sizeleft -= 4) < 0) {
365
retval = KRB5_KDB_TRUNCATED_RECORD;
368
if ((*tl_data = (krb5_tl_data *)
369
malloc(sizeof(krb5_tl_data))) == NULL) {
373
(*tl_data)->tl_data_next = NULL;
374
(*tl_data)->tl_data_contents = NULL;
375
krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_type);
377
krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_length);
380
if ((sizeleft -= (*tl_data)->tl_data_length) < 0) {
381
retval = KRB5_KDB_TRUNCATED_RECORD;
384
if (((*tl_data)->tl_data_contents = (krb5_octet *)
385
malloc((*tl_data)->tl_data_length)) == NULL) {
389
memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length);
390
nextloc += (*tl_data)->tl_data_length;
391
tl_data = &((*tl_data)->tl_data_next);
394
/* key_data is an array */
395
if (entry->n_key_data && ((entry->key_data = (krb5_key_data *)
396
malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL)) {
400
for (i = 0; i < entry->n_key_data; i++) {
401
krb5_key_data * key_data;
404
if ((sizeleft -= 4) < 0) {
405
retval = KRB5_KDB_TRUNCATED_RECORD;
408
key_data = entry->key_data + i;
409
memset(key_data, 0, sizeof(krb5_key_data));
410
krb5_kdb_decode_int16(nextloc, key_data->key_data_ver);
412
krb5_kdb_decode_int16(nextloc, key_data->key_data_kvno);
415
/* key_data_ver determins number of elements and how to unparse them. */
416
if (key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) {
417
for (j = 0; j < key_data->key_data_ver; j++) {
418
if ((sizeleft -= 4) < 0) {
419
retval = KRB5_KDB_TRUNCATED_RECORD;
422
krb5_kdb_decode_int16(nextloc, key_data->key_data_type[j]);
424
krb5_kdb_decode_int16(nextloc, key_data->key_data_length[j]);
427
if ((sizeleft -= key_data->key_data_length[j]) < 0) {
428
retval = KRB5_KDB_TRUNCATED_RECORD;
431
if (key_data->key_data_length[j]) {
432
if ((key_data->key_data_contents[j] = (krb5_octet *)
433
malloc(key_data->key_data_length[j])) == NULL) {
437
memcpy(key_data->key_data_contents[j], nextloc,
438
key_data->key_data_length[j]);
439
nextloc += key_data->key_data_length[j];
443
/* This isn't right. I'll fix it later */
450
krb5_dbe_free_contents(context, entry);
455
krb5_dbe_free_contents(context, entry)
456
krb5_context context;
457
krb5_db_entry * entry;
459
krb5_tl_data * tl_data_next;
460
krb5_tl_data * tl_data;
466
krb5_free_principal(context, entry->princ);
467
for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
468
tl_data_next = tl_data->tl_data_next;
469
if (tl_data->tl_data_contents)
470
free(tl_data->tl_data_contents);
473
if (entry->key_data) {
474
for (i = 0; i < entry->n_key_data; i++) {
475
for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
476
if (entry->key_data[i].key_data_length[j]) {
477
if (entry->key_data[i].key_data_contents[j]) {
478
memset(entry->key_data[i].key_data_contents[j],
480
(unsigned) entry->key_data[i].key_data_length[j]);
481
free (entry->key_data[i].key_data_contents[j]);
484
entry->key_data[i].key_data_contents[j] = NULL;
485
entry->key_data[i].key_data_length[j] = 0;
486
entry->key_data[i].key_data_type[j] = 0;
489
free(entry->key_data);
491
memset(entry, 0, sizeof(*entry));