1 #pragma ident "%Z%%M% %I% %E% SMI"
6 * Copyright 1995 by the Massachusetts Institute of Technology.
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.
37 krb5_encode_princ_dbkey(context
, key
, principal
)
40 krb5_const_principal principal
;
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
;
54 krb5_free_princ_dbkey(context
, key
)
58 (void) krb5_free_data_contents(context
, key
);
62 krb5_encode_princ_contents(context
, content
, entry
)
65 krb5_db_entry
* entry
;
68 unsigned int unparse_princ_size
;
71 krb5_tl_data
* tl_data
;
72 krb5_error_code retval
;
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.
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
)))
98 unparse_princ_size
= strlen(unparse_princ
) + 1;
99 content
->length
+= unparse_princ_size
;
100 content
->length
+= 2;
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 */
110 if (i
!= entry
->n_tl_data
) {
111 retval
= KRB5_KDB_TRUNCATED_RECORD
;
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
) {
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
;
136 krb5_kdb_encode_int16(entry
->len
, nextloc
);
140 krb5_kdb_encode_int32(entry
->attributes
, nextloc
);
144 krb5_kdb_encode_int32(entry
->max_life
, nextloc
);
147 /* Max Renewable Life */
148 krb5_kdb_encode_int32(entry
->max_renewable_life
, nextloc
);
151 /* When the client expires */
152 krb5_kdb_encode_int32(entry
->expiration
, nextloc
);
155 /* When its passwd expires */
156 krb5_kdb_encode_int32(entry
->pw_expiration
, nextloc
);
159 /* Last successful passwd */
160 krb5_kdb_encode_int32(entry
->last_success
, nextloc
);
163 /* Last failed passwd attempt */
164 krb5_kdb_encode_int32(entry
->last_failed
, nextloc
);
167 /* # of failed passwd attempt */
168 krb5_kdb_encode_int32(entry
->fail_auth_count
, nextloc
);
171 /* # tl_data strutures */
172 krb5_kdb_encode_int16(entry
->n_tl_data
, nextloc
);
175 /* # key_data strutures */
176 krb5_kdb_encode_int16(entry
->n_key_data
, nextloc
);
179 /* Put extended fields here */
180 if (entry
->len
!= KRB5_KDB_V1_BASE_LENGTH
)
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
);
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
);
204 krb5_kdb_encode_int16(tl_data
->tl_data_length
, nextloc
);
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
);
215 krb5_kdb_encode_int16(entry
->key_data
[i
].key_data_kvno
, nextloc
);
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
);
224 krb5_kdb_encode_int16(length
, nextloc
);
228 memcpy(nextloc
, entry
->key_data
[i
].key_data_contents
[j
],length
);
240 krb5_free_princ_contents(context
, contents
)
241 krb5_context context
;
244 krb5_free_data_contents(context
, contents
);
249 krb5_decode_princ_contents(context
, content
, entry
)
250 krb5_context context
;
252 krb5_db_entry
* entry
;
256 krb5_tl_data
** tl_data
;
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
;
280 krb5_kdb_decode_int16(nextloc
, entry
->len
);
284 krb5_kdb_decode_int32(nextloc
, entry
->attributes
);
288 krb5_kdb_decode_int32(nextloc
, entry
->max_life
);
291 /* Max Renewable Life */
292 krb5_kdb_decode_int32(nextloc
, entry
->max_renewable_life
);
295 /* When the client expires */
296 krb5_kdb_decode_int32(nextloc
, entry
->expiration
);
299 /* When its passwd expires */
300 krb5_kdb_decode_int32(nextloc
, entry
->pw_expiration
);
303 /* Last successful passwd */
304 krb5_kdb_decode_int32(nextloc
, entry
->last_success
);
307 /* Last failed passwd attempt */
308 krb5_kdb_decode_int32(nextloc
, entry
->last_failed
);
311 /* # of failed passwd attempt */
312 krb5_kdb_decode_int32(nextloc
, entry
->fail_auth_count
);
315 /* # tl_data strutures */
316 krb5_kdb_decode_int16(nextloc
, entry
->n_tl_data
);
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
);
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
;
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
;
350 krb5_kdb_decode_int16(nextloc
, i16
);
354 if ((retval
= krb5_parse_name(context
, nextloc
, &(entry
->princ
))))
356 if (((size_t) i
!= (strlen(nextloc
) + 1)) || (sizeleft
< i
)) {
357 retval
= KRB5_KDB_TRUNCATED_RECORD
;
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
;
370 if ((*tl_data
= (krb5_tl_data
*)
371 malloc(sizeof(krb5_tl_data
))) == NULL
) {
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
);
379 krb5_kdb_decode_int16(nextloc
, (*tl_data
)->tl_data_length
);
382 if ((sizeleft
-= (*tl_data
)->tl_data_length
) < 0) {
383 retval
= KRB5_KDB_TRUNCATED_RECORD
;
386 if (((*tl_data
)->tl_data_contents
= (krb5_octet
*)
387 malloc((*tl_data
)->tl_data_length
)) == NULL
) {
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
)) {
402 for (i
= 0; i
< entry
->n_key_data
; i
++) {
403 krb5_key_data
* key_data
;
406 if ((sizeleft
-= 4) < 0) {
407 retval
= KRB5_KDB_TRUNCATED_RECORD
;
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
);
414 krb5_kdb_decode_int16(nextloc
, key_data
->key_data_kvno
);
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
;
424 krb5_kdb_decode_int16(nextloc
, key_data
->key_data_type
[j
]);
426 krb5_kdb_decode_int16(nextloc
, key_data
->key_data_length
[j
]);
429 if ((sizeleft
-= key_data
->key_data_length
[j
]) < 0) {
430 retval
= KRB5_KDB_TRUNCATED_RECORD
;
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
) {
439 memcpy(key_data
->key_data_contents
[j
], nextloc
,
440 key_data
->key_data_length
[j
]);
441 nextloc
+= key_data
->key_data_length
[j
];
445 /* This isn't right. I'll fix it later */
452 krb5_dbe_free_contents(context
, entry
);
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
;
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
);
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
));