#include <errno.h>
#include "kdb_xdr.h"
-#define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n)))
-
-krb5_error_code
-krb5_dbe_create_key_data(context, entry)
- krb5_context context;
- krb5_db_entry * entry;
-{
- if ((entry->key_data =
- (krb5_key_data *) safe_realloc(entry->key_data,
- (sizeof(krb5_key_data)*
- (entry->n_key_data + 1)))) == NULL)
- return(ENOMEM);
-
-
- memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
- entry->n_key_data++;
-
- return 0;
-}
-
-krb5_error_code
-krb5_dbe_update_tl_data(context, entry, new_tl_data)
- krb5_context context;
- krb5_db_entry * entry;
- krb5_tl_data * new_tl_data;
-{
- krb5_tl_data * tl_data;
- krb5_octet * tmp;
-
- /* copy the new data first, so we can fail cleanly if malloc()
- fails */
-
- if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL)
- return(ENOMEM);
-
- /* Find an existing entry of the specified type and point at
- it, or NULL if not found */
-
- for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next)
- if (tl_data->tl_data_type == new_tl_data->tl_data_type)
- break;
-
- /* if necessary, chain a new record in the beginning and point at it */
-
- if (!tl_data) {
- if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data)))
- == NULL) {
- free(tmp);
- return(ENOMEM);
- }
- tl_data->tl_data_next = entry->tl_data;
- entry->tl_data = tl_data;
- entry->n_tl_data++;
- }
-
- /* fill in the record */
-
- if (tl_data->tl_data_contents)
- free(tl_data->tl_data_contents);
-
- tl_data->tl_data_type = new_tl_data->tl_data_type;
- tl_data->tl_data_length = new_tl_data->tl_data_length;
- tl_data->tl_data_contents = tmp;
- memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
-
- return(0);
-}
-
-krb5_error_code
-krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
- krb5_context context;
- krb5_db_entry * entry;
- krb5_tl_data * ret_tl_data;
-{
- krb5_tl_data *tl_data;
-
- for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
- if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
- *ret_tl_data = *tl_data;
- return(0);
- }
- }
-
- /* if the requested record isn't found, return zero bytes.
- if it ever means something to have a zero-length tl_data,
- this code and its callers will have to be changed */
-
- ret_tl_data->tl_data_length = 0;
- ret_tl_data->tl_data_contents = NULL;
- return(0);
-}
-
-krb5_error_code
-krb5_dbe_update_last_pwd_change(context, entry, stamp)
- 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_lookup_last_pwd_change(context, entry, stamp)
- krb5_context context;
- krb5_db_entry * entry;
- krb5_timestamp * stamp;
-{
- krb5_tl_data tl_data;
- krb5_error_code code;
- krb5_int32 tmp;
-
- tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
-
- if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
- return(code);
-
- if (tl_data.tl_data_length != 4) {
- *stamp = 0;
- return(0);
- }
-
- krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
-
- *stamp = (krb5_timestamp) tmp;
-
- return(0);
-}
-
-/* it seems odd that there's no function to remove a tl_data, but if
- I need one, I'll add one */
-
-krb5_error_code
-krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
- 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_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
- krb5_context context;
- krb5_db_entry * entry;
- krb5_timestamp * mod_time;
- krb5_principal * mod_princ;
-{
- krb5_tl_data tl_data;
- krb5_error_code code;
-
- tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
-
- if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
- return(code);
-
- if ((tl_data.tl_data_length < 5) ||
- (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0'))
- return(KRB5_KDB_TRUNCATED_RECORD);
-
- /* Mod Date */
- krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
-
- /* Mod Princ */
- if ((code = krb5_parse_name(context,
- (const char *) (tl_data.tl_data_contents+4),
- mod_princ)))
- return(code);
-
- return(0);
-}
-
krb5_error_code
krb5_encode_princ_dbkey(context, key, principal)
krb5_context context;
memset(entry, 0, sizeof(*entry));
return;
}
-
-/*
- * Given a particular enctype and optional salttype and kvno, find the
- * most appropriate krb5_key_data entry of the database entry.
- *
- * If stype or kvno is negative, it is ignored.
- * If kvno is 0 get the key which is maxkvno for the princ and matches
- * the other attributes.
- */
-krb5_error_code
-krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_int32 *start;
- krb5_int32 ktype;
- krb5_int32 stype;
- krb5_int32 kvno;
- krb5_key_data **kdatap;
-{
- int i, idx;
- int maxkvno;
- krb5_key_data *datap;
- krb5_error_code ret;
-
- ret = 0;
- if (kvno == -1 && stype == -1 && ktype == -1)
- kvno = 0;
-
- if (kvno == 0) {
- /* Get the max key version */
- for (i = 0; i < dbentp->n_key_data; i++) {
- if (kvno < dbentp->key_data[i].key_data_kvno) {
- kvno = dbentp->key_data[i].key_data_kvno;
- }
- }
- }
-
- maxkvno = -1;
- datap = (krb5_key_data *) NULL;
- for (i = *start; i < dbentp->n_key_data; i++) {
- krb5_boolean similar;
- krb5_int32 db_stype;
-
- ret = 0;
- if (dbentp->key_data[i].key_data_ver > 1) {
- db_stype = dbentp->key_data[i].key_data_type[1];
- } else {
- db_stype = KRB5_KDB_SALTTYPE_NORMAL;
- }
-
- /*
- * Filter out non-permitted enctypes.
- */
- if (!krb5_is_permitted_enctype(kcontext,
- dbentp->key_data[i].key_data_type[0])) {
- ret = KRB5_KDB_NO_PERMITTED_KEY;
- continue;
- }
-
-
- if (ktype > 0) {
- if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype,
- dbentp->key_data[i].key_data_type[0],
- &similar)))
-
- return(ret);
- }
-
- if (((ktype <= 0) || similar) &&
- ((db_stype == stype) || (stype < 0))) {
- if (kvno >= 0) {
- if (kvno == dbentp->key_data[i].key_data_kvno) {
- datap = &dbentp->key_data[i];
- idx = i;
- maxkvno = kvno;
- break;
- }
- } else {
- if (dbentp->key_data[i].key_data_kvno > maxkvno) {
- maxkvno = dbentp->key_data[i].key_data_kvno;
- datap = &dbentp->key_data[i];
- idx = i;
- }
- }
- }
- }
- if (maxkvno < 0)
- return ret ? ret : KRB5_KDB_NO_MATCHING_KEY;
- *kdatap = datap;
- *start = idx+1;
- return 0;
-}
-
-krb5_error_code
-krb5_dbe_find_enctype(kcontext, dbentp, ktype, stype, kvno, kdatap)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_int32 ktype;
- krb5_int32 stype;
- krb5_int32 kvno;
- krb5_key_data **kdatap;
-{
- krb5_int32 start = 0;
-
- return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype,
- kvno, kdatap);
-}
-
-