Re-write _kadm5_set_keys2() to handle key history.

This commit is contained in:
Nicolas Williams
2011-07-20 17:45:14 -05:00
parent 1eb56edd86
commit c818890dd7

View File

@@ -72,6 +72,23 @@ _kadm5_set_keys(kadm5_server_context *context,
return 0; return 0;
} }
static void
setup_Key(Key *k, Salt *s, krb5_key_data *kd, size_t kd_offset)
{
memset(k, 0, sizeof (*k)); /* sets mkvno and salt */
k->key.keytype = kd[kd_offset].key_data_type[0];
k->key.keyvalue.length = kd[kd_offset].key_data_length[0];
k->key.keyvalue.data = kd[kd_offset].key_data_contents[0];
if(kd[kd_offset].key_data_ver == 2) {
memset(s, 0, sizeof (*s));
s->type = kd[kd_offset].key_data_type[1];
s->salt.length = kd[kd_offset].key_data_length[1];
s->salt.data = kd[kd_offset].key_data_contents[1];
k->salt = s;
}
}
/* /*
* Set the keys of `ent' to (`n_key_data', `key_data') * Set the keys of `ent' to (`n_key_data', `key_data')
*/ */
@@ -83,51 +100,78 @@ _kadm5_set_keys2(kadm5_server_context *context,
krb5_key_data *key_data) krb5_key_data *key_data)
{ {
krb5_error_code ret; krb5_error_code ret;
int i; size_t i, k;
unsigned len; HDB_extension ext;
Key *keys; HDB_Ext_KeySet *hist_keys = &ext.data.u.hist_keys;
Key key;
Salt salt;
Keys keys;
hdb_keyset hkset;
len = n_key_data; memset(&keys, 0, sizeof (keys));
keys = malloc (len * sizeof(*keys)); memset(&hkset, 0, sizeof (hkset)); /* set set_time */
if (keys == NULL && len != 0) ext.data.element = choice_HDB_extension_data_hist_keys;
return ENOMEM; memset(hist_keys, 0, sizeof (*hist_keys));
_kadm5_init_keys (keys, len);
for(i = 0; i < n_key_data; i++) { for(i = 0; i < n_key_data; i++) {
keys[i].mkvno = NULL; if (key_data[i].key_data_kvno == ent->kvno) {
keys[i].key.keytype = key_data[i].key_data_type[0]; /* A current key; add to current key set */
ret = krb5_data_copy(&keys[i].key.keyvalue, setup_Key(&key, &salt, key_data, i);
key_data[i].key_data_contents[0], ret = add_Keys(&keys, &key);
key_data[i].key_data_length[0]); continue;
if(ret) }
goto out;
if(key_data[i].key_data_ver == 2) {
Salt *salt;
salt = calloc(1, sizeof(*salt)); /*
if(salt == NULL) { * This kvno is historical. Build an hdb_keyset for keys of
ret = ENOMEM; * this enctype and add them to the new key history.
*/
for (k = 0; k < hist_keys->len; k++) {
if (hist_keys->val[k].kvno == key_data[i].key_data_kvno)
break;
}
if (hist_keys->len > k &&
hist_keys->val[k].kvno == key_data[i].key_data_kvno)
/* We've added all keys of this kvno already (see below) */
continue;
memset(&hkset, 0, sizeof (hkset)); /* set set_time */
hkset.kvno = key_data[i].key_data_kvno;
for (k = 0; k < n_key_data; k++) {
/* Find all keys of this kvno and add them to the new keyset */
if (key_data[k].key_data_kvno != hkset.kvno)
continue;
setup_Key(&key, &salt, key_data, k);
ret = add_Keys(&hkset.keys, &key);
if (ret)
goto out; goto out;
} }
keys[i].salt = salt; ret = add_HDB_Ext_KeySet(hist_keys, &hkset);
salt->type = key_data[i].key_data_type[1]; if (ret)
krb5_data_copy(&salt->salt, goto out;
key_data[i].key_data_contents[1],
key_data[i].key_data_length[1]);
} else
keys[i].salt = NULL;
} }
_kadm5_free_keys (context->context, ent->keys.len, ent->keys.val);
ent->keys.len = len; /*
ent->keys.val = keys; * A structure copy is more efficient here than this would be:
*
* copy_Keys(&keys, &ent->keys);
* free_Keys(&keys);
*/
free_Keys(&ent->keys);
ent->keys = keys;
/* XXX We should try to keep the set_time values from the old hist keys */
hdb_replace_extension(context->context, ent, &ext);
hdb_entry_set_pw_change_time(context->context, ent, 0); hdb_entry_set_pw_change_time(context->context, ent, 0);
hdb_entry_clear_password(context->context, ent); hdb_entry_clear_password(context->context, ent);
return 0; return 0;
out:
_kadm5_free_keys (context->context, len, keys); out:
free_Keys(&keys);
free_hdb_keyset(&hkset);
free_HDB_extension(&ext);
return ret; return ret;
} }