kadm5_ret_t _kadm5_set_keys2(kadm5_server_context *context, hdb_entry *ent, int16_t n_key_data, krb5_key_data *key_data) { krb5_error_code ret; int i; unsigned len; Key *keys; len = n_key_data; keys = malloc (len * sizeof(*keys)); if (keys == NULL) return ENOMEM; _kadm5_init_keys (keys, len); for(i = 0; i < n_key_data; i++) { keys[i].mkvno = NULL; keys[i].key.keytype = key_data[i].key_data_type[0]; ret = krb5_data_copy(&keys[i].key.keyvalue, key_data[i].key_data_contents[0], key_data[i].key_data_length[0]); if(ret) goto out; if(key_data[i].key_data_ver == 2) { Salt *salt; salt = calloc(1, sizeof(*salt)); if(salt == NULL) { ret = ENOMEM; goto out; } keys[i].salt = salt; salt->type = key_data[i].key_data_type[1]; krb5_data_copy(&salt->salt, 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; hdb_entry_set_pw_change_time(context->context, ent, 0); hdb_entry_clear_password(context->context, ent); return 0; out: _kadm5_free_keys (context->context, len, keys); return ret; }
kadm5_ret_t _kadm5_set_keys(kadm5_server_context *context, hdb_entry *ent, const char *password) { Key *keys; size_t num_keys; kadm5_ret_t ret; ret = hdb_generate_key_set_password(context->context, ent->principal, password, &keys, &num_keys); if (ret) return ret; _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.val = keys; ent->keys.len = num_keys; hdb_entry_set_pw_change_time(context->context, ent, 0); if (krb5_config_get_bool_default(context->context, NULL, FALSE, "kadmin", "save-password", NULL)) { ret = hdb_entry_set_password(context->context, context->db, ent, password); if (ret) return ret; } return 0; }
kadm5_ret_t _kadm5_set_keys3(kadm5_server_context *context, hdb_entry *ent, int n_keys, krb5_keyblock *keyblocks) { krb5_error_code ret; int i; unsigned len; Key *keys; len = n_keys; keys = malloc (len * sizeof(*keys)); if (keys == NULL) return ENOMEM; _kadm5_init_keys (keys, len); for(i = 0; i < n_keys; i++) { keys[i].mkvno = NULL; ret = krb5_copy_keyblock_contents (context->context, &keyblocks[i], &keys[i].key); if(ret) goto out; keys[i].salt = NULL; } _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.len = len; ent->keys.val = keys; hdb_entry_set_pw_change_time(context->context, ent, 0); hdb_entry_clear_password(context->context, ent); return 0; out: _kadm5_free_keys (context->context, len, keys); return ret; }
static void parse_file(krb5_context context, krb5_principal principal, int no_salt) { krb5_error_code ret; size_t nkeys; Key *keys; ret = hdb_generate_key_set(context, principal, &keys, &nkeys, no_salt); if (ret) krb5_err(context, 1, ret, "hdb_generate_key_set"); print_keys(context, keys, nkeys); _kadm5_free_keys(context, nkeys, keys); }
kadm5_ret_t _kadm5_set_keys_randomly (kadm5_server_context *context, hdb_entry *ent, krb5_keyblock **new_keys, int *n_keys) { krb5_keyblock *kblock = NULL; kadm5_ret_t ret = 0; int i, des_keyblock; size_t num_keys; Key *keys; ret = hdb_generate_key_set(context->context, ent->principal, &keys, &num_keys, 1); if (ret) return ret; kblock = malloc(num_keys * sizeof(kblock[0])); if (kblock == NULL) { ret = ENOMEM; _kadm5_free_keys (context->context, num_keys, keys); return ret; } memset(kblock, 0, num_keys * sizeof(kblock[0])); des_keyblock = -1; for (i = 0; i < num_keys; i++) { /* * To make sure all des keys are the the same we generate only * the first one and then copy key to all other des keys. */ if (des_keyblock != -1 && is_des_key_p(keys[i].key.keytype)) { ret = krb5_copy_keyblock_contents (context->context, &kblock[des_keyblock], &kblock[i]); if (ret) goto out; kblock[i].keytype = keys[i].key.keytype; } else { ret = krb5_generate_random_keyblock (context->context, keys[i].key.keytype, &kblock[i]); if (ret) goto out; if (is_des_key_p(keys[i].key.keytype)) des_keyblock = i; } ret = krb5_copy_keyblock_contents (context->context, &kblock[i], &keys[i].key); if (ret) goto out; } out: if(ret) { for (i = 0; i < num_keys; ++i) krb5_free_keyblock_contents (context->context, &kblock[i]); free(kblock); _kadm5_free_keys (context->context, num_keys, keys); return ret; } _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.val = keys; ent->keys.len = num_keys; *new_keys = kblock; *n_keys = num_keys; hdb_entry_set_pw_change_time(context->context, ent, 0); hdb_entry_clear_password(context->context, ent); return 0; }
static kadm5_ret_t change(void *server_handle, krb5_principal princ, int keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, const char *password, int cond) { kadm5_server_context *context = server_handle; hdb_entry_ex ent; kadm5_ret_t ret; Key *keys; size_t num_keys; int existsp = 0; memset(&ent, 0, sizeof(ent)); if (!context->keep_open) { ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; } ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); if(ret) goto out; if (keepold || cond) { /* * We save these for now so we can handle password history checking; * we handle keepold further below. */ ret = hdb_add_current_keys_to_history(context->context, &ent.entry); if (ret) goto out; } if (context->db->hdb_capability_flags & HDB_CAP_F_HANDLE_PASSWORDS) { ret = context->db->hdb_password(context->context, context->db, &ent, password, cond); if (ret) goto out2; } else { num_keys = ent.entry.keys.len; keys = ent.entry.keys.val; ent.entry.keys.len = 0; ent.entry.keys.val = NULL; ret = _kadm5_set_keys(context, &ent.entry, n_ks_tuple, ks_tuple, password); if(ret) { _kadm5_free_keys(context->context, num_keys, keys); goto out2; } _kadm5_free_keys(context->context, num_keys, keys); if (cond) { HDB_extension *ext; ext = hdb_find_extension(&ent.entry, choice_HDB_extension_data_hist_keys); if (ext != NULL) existsp = _kadm5_exists_keys_hist(ent.entry.keys.val, ent.entry.keys.len, &ext->data.u.hist_keys); } if (existsp) { ret = KADM5_PASS_REUSE; krb5_set_error_message(context->context, ret, "Password reuse forbidden"); goto out2; } } ent.entry.kvno++; ent.entry.flags.require_pwchange = 0; if (keepold) { ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) goto out2; } else { HDB_extension ext; memset(&ext, 0, sizeof (ext)); ext.data.element = choice_HDB_extension_data_hist_keys; ext.data.u.hist_keys.len = 0; ext.data.u.hist_keys.val = NULL; ret = hdb_replace_extension(context->context, &ent.entry, &ext); if (ret) goto out2; } ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; ret = _kadm5_bump_pw_expire(context, &ent.entry); if (ret) goto out2; ret = context->db->hdb_store(context->context, context->db, HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, &ent.entry, KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | KADM5_TL_DATA); out2: hdb_free_entry(context->context, &ent); out: if (!context->keep_open) context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); }
static kadm5_ret_t change(void *server_handle, krb5_principal princ, const char *password, int cond) { kadm5_server_context *context = server_handle; hdb_entry_ex ent; kadm5_ret_t ret; Key *keys; size_t num_keys; int existsp = 0; memset(&ent, 0, sizeof(ent)); ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); if(ret) goto out; if (context->db->hdb_capability_flags & HDB_CAP_F_HANDLE_PASSWORDS) { ret = context->db->hdb_password(context->context, context->db, &ent, password, cond); if (ret) goto out2; } else { num_keys = ent.entry.keys.len; keys = ent.entry.keys.val; ent.entry.keys.len = 0; ent.entry.keys.val = NULL; ret = _kadm5_set_keys(context, &ent.entry, password); if(ret) { _kadm5_free_keys (context->context, num_keys, keys); goto out2; } if (cond) existsp = _kadm5_exists_keys (ent.entry.keys.val, ent.entry.keys.len, keys, num_keys); _kadm5_free_keys (context->context, num_keys, keys); if (existsp) { ret = KADM5_PASS_REUSE; krb5_set_error_message(context->context, ret, "Password reuse forbidden"); goto out2; } ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) goto out2; } ent.entry.kvno++; ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; ret = _kadm5_bump_pw_expire(context, &ent.entry); if (ret) goto out2; ret = context->db->hdb_store(context->context, context->db, HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, &ent.entry, KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | KADM5_TL_DATA); out2: hdb_free_entry(context->context, &ent); out: context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); }