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