/* * Fetch the current history key(s), creating the history principal if * necessary. Database created since krb5 1.3 will have only one key, but * databases created before that may have multiple keys (of the same kvno) * and we need to try them all. History keys will be returned in a list * terminated by an entry with enctype 0. */ krb5_error_code kdb_get_hist_key(kadm5_server_handle_t handle, krb5_keyblock **keyblocks_out, krb5_kvno *kvno_out) { krb5_error_code ret; krb5_db_entry *kdb; krb5_keyblock *mkey, *kblist = NULL; krb5_int16 i; /* Fetch the history principal, creating it if necessary. */ ret = kdb_get_entry(handle, hist_princ, &kdb, NULL); if (ret == KADM5_UNK_PRINC) { ret = create_hist(handle); if (ret) return ret; ret = kdb_get_entry(handle, hist_princ, &kdb, NULL); } if (ret) return ret; if (kdb->n_key_data <= 0) { ret = KRB5_KDB_NO_MATCHING_KEY; k5_setmsg(handle->context, ret, _("History entry contains no key data")); goto done; } ret = krb5_dbe_find_mkey(handle->context, kdb, &mkey); if (ret) goto done; kblist = k5calloc(kdb->n_key_data + 1, sizeof(*kblist), &ret); if (kblist == NULL) goto done; for (i = 0; i < kdb->n_key_data; i++) { ret = krb5_dbe_decrypt_key_data(handle->context, mkey, &kdb->key_data[i], &kblist[i], NULL); if (ret) goto done; } *keyblocks_out = kblist; kblist = NULL; *kvno_out = kdb->key_data[0].key_data_kvno; done: kdb_free_entry(handle, kdb, NULL); kdb_free_keyblocks(handle, kblist); return ret; }
/* Write a principal's metadata. */ static krb5_error_code princ_meta(struct rec_args *args, const char *name, krb5_db_entry *dbe) { int got_adb = 0; char *modby; krb5_kvno mkvno; const char *policy; krb5_principal mod_princ = NULL; krb5_timestamp mod_time, last_pwd; krb5_error_code ret; osa_princ_ent_rec adb; struct rechandle *h = args->rh; memset(&adb, 0, sizeof(adb)); if (startrec(h) < 0) return errno; if (writefield(h, "%s", name) < 0) return errno; ret = krb5_dbe_lookup_last_pwd_change(util_context, dbe, &last_pwd); if (ret) return ret; ret = krb5_dbe_get_mkvno(util_context, dbe, &mkvno); if (ret) return ret; ret = krb5_dbe_lookup_mod_princ_data(util_context, dbe, &mod_time, &mod_princ); if (ret) return ret; ret = krb5_unparse_name(util_context, mod_princ, &modby); krb5_free_principal(util_context, mod_princ); if (ret) return ret; ret = writefield(h, "%s", modby); krb5_free_unparsed_name(util_context, modby); if (ret < 0) return errno; if (write_date(args, mod_time) < 0) return errno; if (write_date(args, last_pwd) < 0) return errno; got_adb = get_adb(dbe, &adb); if (got_adb && adb.policy != NULL) policy = adb.policy; else policy = ""; ret = writefield(h, "%s", policy); if (ret < 0) { ret = errno; goto cleanup; } if (writefield(h, "%d", mkvno) < 0) { ret = errno; goto cleanup; } if (writefield(h, "%d", adb.admin_history_kvno) < 0) { ret = errno; goto cleanup; } if (endrec(h) < 0) ret = errno; else ret = 0; cleanup: kdb_free_entry(NULL, NULL, &adb); return ret; }