krb5_error_code krb5_dbe_update_last_pwd_change(krb5_context context, krb5_db_entry *entry, krb5_timestamp stamp) { krb5_tl_data tl_data; krb5_octet buf[4]; /* this is the encoded size of an int32 */ tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; tl_data.tl_data_length = sizeof(buf); krb5_kdb_encode_int32((krb5_int32) stamp, buf); tl_data.tl_data_contents = buf; return(krb5_dbe_update_tl_data(context, entry, &tl_data)); }
krb5_error_code krb5_dbe_update_mod_princ_data(krb5_context context, krb5_db_entry *entry, krb5_timestamp mod_date, krb5_const_principal mod_princ) { krb5_tl_data tl_data; krb5_error_code retval = 0; krb5_octet * nextloc = 0; char * unparse_mod_princ = 0; unsigned int unparse_mod_princ_size; if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ))) return(retval); unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) == NULL) { free(unparse_mod_princ); return(ENOMEM); } tl_data.tl_data_type = KRB5_TL_MOD_PRINC; tl_data.tl_data_length = unparse_mod_princ_size + 4; tl_data.tl_data_contents = nextloc; /* Mod Date */ krb5_kdb_encode_int32(mod_date, nextloc); /* Mod Princ */ memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); retval = krb5_dbe_update_tl_data(context, entry, &tl_data); free(unparse_mod_princ); free(nextloc); return(retval); }
krb5_error_code krb5_encode_princ_entry(krb5_context context, krb5_data *content, krb5_db_entry *entry) { int i, j; unsigned int unparse_princ_size; char * unparse_princ; unsigned char * nextloc; krb5_tl_data * tl_data; krb5_error_code retval; krb5_int16 psize16; /* * Generate one lump of data from the krb5_db_entry. * This data must be independent of byte order of the machine, * compact and extensible. */ /* * First allocate enough space for all the data. * Need 2 bytes for the length of the base structure * then 36 [ 8 * 4 + 2 * 2] bytes for the base information * [ attributes, max_life, max_renewable_life, expiration, * pw_expiration, last_success, last_failed, fail_auth_count ] * [ n_key_data, n_tl_data ] * then XX bytes [ e_length ] for the extra data [ e_data ] * then XX bytes [ 2 for length + length for string ] for the principal, * then (4 [type + length] + tl_data_length) bytes per tl_data * then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data */ content->length = entry->len + entry->e_length; if ((retval = krb5_unparse_name(context, entry->princ, &unparse_princ))) return(retval); unparse_princ_size = strlen(unparse_princ) + 1; content->length += unparse_princ_size; content->length += 2; i = 0; /* tl_data is a linked list */ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { content->length += tl_data->tl_data_length; content->length += 4; /* type, length */ i++; } if (i != entry->n_tl_data) { retval = KRB5_KDB_TRUNCATED_RECORD; goto epc_error; } /* key_data is an array */ for (i = 0; i < entry->n_key_data; i++) { content->length += 4; /* Version, KVNO */ for (j = 0; j < entry->key_data[i].key_data_ver; j++) { content->length += entry->key_data[i].key_data_length[j]; content->length += 4; /* type + length */ } } if ((content->data = malloc(content->length)) == NULL) { retval = ENOMEM; goto epc_error; } /* * Now we go through entry again, this time copying data * These first entries are always saved regardless of version */ nextloc = (unsigned char *)content->data; /* Base Length */ krb5_kdb_encode_int16(entry->len, nextloc); nextloc += 2; /* Attributes */ krb5_kdb_encode_int32(entry->attributes, nextloc); nextloc += 4; /* Max Life */ krb5_kdb_encode_int32(entry->max_life, nextloc); nextloc += 4; /* Max Renewable Life */ krb5_kdb_encode_int32(entry->max_renewable_life, nextloc); nextloc += 4; /* When the client expires */ krb5_kdb_encode_int32(entry->expiration, nextloc); nextloc += 4; /* When its passwd expires */ krb5_kdb_encode_int32(entry->pw_expiration, nextloc); nextloc += 4; /* Last successful passwd */ krb5_kdb_encode_int32(entry->last_success, nextloc); nextloc += 4; /* Last failed passwd attempt */ krb5_kdb_encode_int32(entry->last_failed, nextloc); nextloc += 4; /* # of failed passwd attempt */ krb5_kdb_encode_int32(entry->fail_auth_count, nextloc); nextloc += 4; /* # tl_data strutures */ krb5_kdb_encode_int16(entry->n_tl_data, nextloc); nextloc += 2; /* # key_data strutures */ krb5_kdb_encode_int16(entry->n_key_data, nextloc); nextloc += 2; /* Put extended fields here */ if (entry->len != KRB5_KDB_V1_BASE_LENGTH) abort(); /* Any extra data that this version doesn't understand. */ if (entry->e_length) { memcpy(nextloc, entry->e_data, entry->e_length); nextloc += entry->e_length; } /* * Now we get to the principal. * To squeze a few extra bytes out it is always assumed to come * after the base type. */ psize16 = (krb5_int16) unparse_princ_size; krb5_kdb_encode_int16(psize16, nextloc); nextloc += 2; (void) memcpy(nextloc, unparse_princ, unparse_princ_size); nextloc += unparse_princ_size; /* tl_data is a linked list, of type, legth, contents */ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { krb5_kdb_encode_int16(tl_data->tl_data_type, nextloc); nextloc += 2; krb5_kdb_encode_int16(tl_data->tl_data_length, nextloc); nextloc += 2; memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length); nextloc += tl_data->tl_data_length; } /* key_data is an array */ for (i = 0; i < entry->n_key_data; i++) { krb5_kdb_encode_int16(entry->key_data[i].key_data_ver, nextloc); nextloc += 2; krb5_kdb_encode_int16(entry->key_data[i].key_data_kvno, nextloc); nextloc += 2; for (j = 0; j < entry->key_data[i].key_data_ver; j++) { krb5_int16 type = entry->key_data[i].key_data_type[j]; krb5_ui_2 length = entry->key_data[i].key_data_length[j]; krb5_kdb_encode_int16(type, nextloc); nextloc += 2; krb5_kdb_encode_int16(length, nextloc); nextloc += 2; if (length) { memcpy(nextloc, entry->key_data[i].key_data_contents[j],length); nextloc += length; } } } epc_error: ; free(unparse_princ); return retval; }