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