Make kadmin ext work when lacking get-keys priv
When we added the get-keys privilege we lost the ability to setup keytabs with the kadmin ext command. The fix is to note that we got bogus key data and randkey (as we used to).
This commit is contained in:
28
kadmin/ext.c
28
kadmin/ext.c
@@ -46,15 +46,16 @@ do_ext_keytab(krb5_principal principal, void *data)
|
||||
struct ext_keytab_data *e = data;
|
||||
krb5_keytab_entry *keys = NULL;
|
||||
krb5_keyblock *k = NULL;
|
||||
int i, n_k;
|
||||
int i;
|
||||
int n_k = 0;
|
||||
|
||||
ret = kadm5_get_principal(kadm_handle, principal, &princ,
|
||||
KADM5_PRINCIPAL|KADM5_KVNO|KADM5_KEY_DATA);
|
||||
if(ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (princ.n_key_data) {
|
||||
keys = malloc(sizeof(*keys) * princ.n_key_data);
|
||||
keys = calloc(sizeof(*keys), princ.n_key_data);
|
||||
if (keys == NULL) {
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
krb5_clear_error_message(context);
|
||||
@@ -63,22 +64,33 @@ do_ext_keytab(krb5_principal principal, void *data)
|
||||
for (i = 0; i < princ.n_key_data; i++) {
|
||||
krb5_key_data *kd = &princ.key_data[i];
|
||||
|
||||
/*
|
||||
* If the kadm5 client princ lacks get-keys then it may get
|
||||
* bogus keys four bytes long.
|
||||
*/
|
||||
if (kd->key_data_length[0] == sizeof (KADM5_BOGUS_KEY_DATA) - 1 &&
|
||||
memcmp(kd->key_data_contents[0], KADM5_BOGUS_KEY_DATA,
|
||||
kd->key_data_length[0]) == 0)
|
||||
continue;
|
||||
|
||||
keys[i].principal = princ.principal;
|
||||
keys[i].vno = kd->key_data_kvno;
|
||||
keys[i].keyblock.keytype = kd->key_data_type[0];
|
||||
keys[i].keyblock.keyvalue.length = kd->key_data_length[0];
|
||||
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
|
||||
keys[i].timestamp = time(NULL);
|
||||
n_k++;
|
||||
}
|
||||
}
|
||||
|
||||
n_k = princ.n_key_data;
|
||||
} else {
|
||||
if (n_k == 0) {
|
||||
/* Probably lack get-keys privilege, but we may be able to set keys */
|
||||
ret = kadm5_randkey_principal(kadm_handle, principal, &k, &n_k);
|
||||
if (ret) {
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
return ret;
|
||||
}
|
||||
keys = malloc(sizeof(*keys) * n_k);
|
||||
keys = calloc(sizeof(*keys), n_k);
|
||||
if (keys == NULL) {
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
krb5_clear_error_message(context);
|
||||
@@ -92,9 +104,9 @@ do_ext_keytab(krb5_principal principal, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < n_k; i++) {
|
||||
for (i = 0; i < n_k; i++) {
|
||||
ret = krb5_kt_add_entry(context, e->keytab, &keys[i]);
|
||||
if(ret)
|
||||
if (ret)
|
||||
krb5_warn(context, ret, "krb5_kt_add_entry(%d)", i);
|
||||
}
|
||||
|
||||
|
@@ -201,8 +201,12 @@ typedef struct _kadm5_policy_ent_t {
|
||||
#define KADM5_PRIV_LIST (1 << 4)
|
||||
#define KADM5_PRIV_CPW (1 << 5)
|
||||
#define KADM5_PRIV_GET_KEYS (1 << 6)
|
||||
|
||||
/* Note: KADM5_PRIV_GET_KEYS not included */
|
||||
#define KADM5_PRIV_ALL (KADM5_PRIV_GET | KADM5_PRIV_ADD | KADM5_PRIV_MODIFY | KADM5_PRIV_DELETE | KADM5_PRIV_LIST | KADM5_PRIV_CPW)
|
||||
|
||||
#define KADM5_BOGUS_KEY_DATA "\xe5\xe5\xe5\xe5"
|
||||
|
||||
typedef struct _kadm5_config_params {
|
||||
uint32_t mask;
|
||||
|
||||
|
@@ -57,7 +57,6 @@ kadm5_ret_t
|
||||
kadm5_store_fake_key_data(krb5_storage *sp,
|
||||
krb5_key_data *key)
|
||||
{
|
||||
char buf[4] = {0};
|
||||
krb5_data c;
|
||||
|
||||
krb5_store_int32(sp, key->key_data_ver);
|
||||
@@ -72,9 +71,8 @@ kadm5_store_fake_key_data(krb5_storage *sp,
|
||||
* did want keys will either fail or they'll, say, create bogus
|
||||
* keytab entries that will subsequently fail to be useful.
|
||||
*/
|
||||
c.length = sizeof (buf);
|
||||
c.data = buf;
|
||||
memset(buf, 0xdeadcee5, sizeof (buf)); /* bad bad hexspeak for deadkeys */
|
||||
c.length = sizeof (KADM5_BOGUS_KEY_DATA) - 1;
|
||||
c.data = KADM5_BOGUS_KEY_DATA;
|
||||
krb5_store_data(sp, c);
|
||||
|
||||
/* This is the salt -- no need to send garbage */
|
||||
|
Reference in New Issue
Block a user