From: Will Fiveash Date: Thu, 19 Jun 2008 22:27:47 +0000 (+0000) Subject: second commit to backup files, tweaked some logic to better support kdb5_util dump... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81e92ce6aaa344f0bf968d368baf9b0cb3901b6a;p=thirdparty%2Fkrb5.git second commit to backup files, tweaked some logic to better support kdb5_util dump -mkey_convert git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mkey_keytab@20430 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/kdb.h b/src/include/kdb.h index b510404d31..cc5951d464 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -286,11 +286,12 @@ krb5_error_code krb5_db_fetch_mkey ( krb5_context context, krb5_boolean fromkeyboard, krb5_boolean twice, char *db_args, + krb5_kvno *kvno, krb5_data *salt, krb5_keyblock *key); krb5_error_code krb5_db_verify_master_key ( krb5_context kcontext, krb5_principal mprinc, - krb5_kvno *kvno, + krb5_kvno kvno, krb5_keyblock *mkey ); krb5_error_code krb5_dbe_find_enctype( krb5_context kcontext, @@ -447,9 +448,9 @@ krb5_db_def_fetch_mkey( krb5_context context, char *db_args); krb5_error_code -krb5_def_verify_master_key( krb5_context context, +krb5_def_verify_master_key( krb5_context context, krb5_principal mprinc, - krb5_kvno *kvno, + krb5_kvno kvno, krb5_keyblock *mkey); krb5_error_code kdb_def_set_mkey ( krb5_context kcontext, diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c index 66fedf0aa6..9698d2c190 100644 --- a/src/kadmin/dbutil/dump.c +++ b/src/kadmin/dbutil/dump.c @@ -256,6 +256,7 @@ static krb5_error_code master_key_convert(context, db_entry) int i, j; krb5_key_data new_key_data, *key_data; krb5_boolean is_mkey; + krb5_kvno kvno; is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ); @@ -274,10 +275,22 @@ static krb5_error_code master_key_convert(context, db_entry) return retval; memset(&new_key_data, 0, sizeof(new_key_data)); - key_ptr = is_mkey ? &new_master_keyblock : &v5plainkey; + + if (is_mkey) { + key_ptr = &new_master_keyblock; + /* override mkey princ's kvno */ + if (global_params.mask & KADM5_CONFIG_KVNO) + kvno = global_params.kvno; + else + kvno = (krb5_kvno) key_data->key_data_kvno; + } else { + key_ptr = &v5plainkey; + kvno = (krb5_kvno) key_data->key_data_kvno; + } + retval = krb5_dbekd_encrypt_key_data(context, &new_master_keyblock, key_ptr, &keysalt, - key_data->key_data_kvno, + (int) kvno, &new_key_data); if (retval) return retval; @@ -1092,12 +1105,14 @@ dump_db(argc, argv) */ if (mkey_convert) { if (!valid_master_key) { + krb5_kvno mkvno = IGNORE_VNO; /* TRUE here means read the keyboard, but only once */ retval = krb5_db_fetch_mkey(util_context, master_princ, master_keyblock.enctype, TRUE, FALSE, - (char *) NULL, 0, + (char *) NULL, + NULL, NULL, &master_keyblock); if (retval) { com_err(argv[0], retval, @@ -1106,7 +1121,7 @@ dump_db(argc, argv) } retval = krb5_db_verify_master_key(util_context, master_princ, - NULL, + IGNORE_VNO, &master_keyblock); if (retval) { com_err(argv[0], retval, @@ -1117,18 +1132,38 @@ dump_db(argc, argv) new_master_keyblock.enctype = global_params.enctype; if (new_master_keyblock.enctype == ENCTYPE_UNKNOWN) new_master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; - if (!new_mkey_file) - printf("Please enter new master key....\n"); - if ((retval = krb5_db_fetch_mkey(util_context, master_princ, - new_master_keyblock.enctype, - (new_mkey_file == 0) ? - (krb5_boolean) 1 : 0, - TRUE, - new_mkey_file, 0, - &new_master_keyblock))) { - com_err(argv[0], retval, "while reading new master key"); - exit(1); - } + + if (new_mkey_file) { + krb5_kvno kt_kvno; + + if (global_params.mask & KADM5_CONFIG_KVNO) + kt_kvno = global_params.kvno; + else + kt_kvno = IGNORE_VNO; + + if ((retval = krb5_db_fetch_mkey(util_context, master_princ, + new_master_keyblock.enctype, + FALSE, + FALSE, + new_mkey_file, + &kt_kvno, + NULL, + &new_master_keyblock))) { + com_err(argv[0], retval, "while reading new master key"); + exit(1); + } + } else { + printf("Please enter new master key....\n"); + if ((retval = krb5_db_fetch_mkey(util_context, master_princ, + new_master_keyblock.enctype, + TRUE, + TRUE, + NULL, NULL, NULL, + &new_master_keyblock))) { + com_err(argv[0], retval, "while reading new master key"); + exit(1); + } + } } kret = 0; diff --git a/src/kadmin/dbutil/kdb5_stash.c b/src/kadmin/dbutil/kdb5_stash.c index 5ae482a050..18c35c011d 100644 --- a/src/kadmin/dbutil/kdb5_stash.c +++ b/src/kadmin/dbutil/kdb5_stash.c @@ -143,25 +143,27 @@ kdb5_stash(argc, argv) exit_status++; return; } + if (global_params.mask & KADM5_CONFIG_KVNO) + mkey_kvno = global_params.kvno; /* user specified */ + else + mkey_kvno = IGNORE_VNO; /* use whatever krb5_db_fetch_mkey finds */ + /* TRUE here means read the keyboard, but only once */ retval = krb5_db_fetch_mkey(context, master_princ, master_keyblock.enctype, TRUE, FALSE, (char *) NULL, - 0, &master_keyblock); + &mkey_kvno, + NULL, &master_keyblock); if (retval) { com_err(argv[0], retval, "while reading master key"); (void) krb5_db_fini(context); exit_status++; return; } - if (global_params.mask & KADM5_CONFIG_KVNO) - mkey_kvno = global_params.kvno; /* user specified */ - else - mkey_kvno = IGNORE_VNO; /* use whatever krb5_db_verify_master_key finds */ /* verify will set mkey_kvno to mkey princ's kvno mkey_kvno if it's IGNORE_VNO */ retval = krb5_db_verify_master_key(context, master_princ, - &mkey_kvno, + mkey_kvno, &master_keyblock); if (retval) { com_err(argv[0], retval, "while verifying master key"); diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c index c986405942..f684fdb9b6 100644 --- a/src/kadmin/dbutil/kdb5_util.c +++ b/src/kadmin/dbutil/kdb5_util.c @@ -381,6 +381,7 @@ static int open_db_and_mkey() int nentries; krb5_boolean more; krb5_data scratch, pwd, seed; + krb5_kvno mprinc_kvno, kvno; dbactive = FALSE; valid_master_key = 0; @@ -422,6 +423,9 @@ static int open_db_and_mkey() return(1); } + /* may be used later */ + mprinc_kvno = (krb5_kvno) master_entry.key_data->key_data_kvno; + krb5_db_free_principal(util_context, &master_entry, nentries); /* the databases are now open, and the master principal exists */ @@ -437,13 +441,12 @@ static int open_db_and_mkey() } /* If no encryption type is set, use the default */ - if (master_keyblock.enctype == ENCTYPE_UNKNOWN) { + if (master_keyblock.enctype == ENCTYPE_UNKNOWN) master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; - if (!krb5_c_valid_enctype(master_keyblock.enctype)) - com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, - "while setting up enctype %d", - master_keyblock.enctype); - } + if (!krb5_c_valid_enctype(master_keyblock.enctype)) + com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, + "while setting up enctype %d", + master_keyblock.enctype); retval = krb5_c_string_to_key(util_context, master_keyblock.enctype, &pwd, &scratch, &master_keyblock); @@ -454,10 +457,16 @@ static int open_db_and_mkey() } free(scratch.data); mkey_password = 0; + + if (global_params.mask & KADM5_CONFIG_KVNO) + kvno = global_params.kvno; /* user specified */ + else + kvno = mprinc_kvno; } else if ((retval = krb5_db_fetch_mkey(util_context, master_princ, master_keyblock.enctype, manual_mkey, FALSE, global_params.stash_file, + &kvno, 0, &master_keyblock))) { com_err(progname, retval, "while reading master key"); com_err(progname, 0, "Warning: proceeding without master key"); @@ -465,7 +474,7 @@ static int open_db_and_mkey() return(0); } if ((retval = krb5_db_verify_master_key(util_context, master_princ, - NULL, &master_keyblock))) { + kvno, &master_keyblock))) { com_err(progname, retval, "while verifying master key"); exit_status++; krb5_free_keyblock_contents(util_context, &master_keyblock); diff --git a/src/kdc/main.c b/src/kdc/main.c index 1827649e4d..d25a80c1be 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -267,7 +267,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, - 0, &rdp->realm_mkey))) { + NULL, NULL, &rdp->realm_mkey))) { com_err(progname, kret, "while fetching master key %s for realm %s", rdp->realm_mpname, realm); @@ -277,7 +277,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm, /* Verify the master key */ if ((kret = krb5_db_verify_master_key(rdp->realm_context, rdp->realm_mprinc, - NULL, + IGNORE_VNO, &rdp->realm_mkey))) { com_err(progname, kret, "while verifying master key for realm %s", realm); diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index a08a2a5354..048934b59a 100644 --- a/src/lib/kadm5/srv/server_kdb.c +++ b/src/lib/kadm5/srv/server_kdb.c @@ -54,6 +54,7 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, master_keyblock.enctype, from_kbd, FALSE /* only prompt once */, handle->params.stash_file, + NULL /* don't care about kvno */, NULL /* I'm not sure about this, but it's what the kdc does --marc */, &master_keyblock); @@ -61,7 +62,7 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, goto done; if ((ret = krb5_db_verify_master_key(handle->context, master_princ, - NULL, &master_keyblock))) { + IGNORE_VNO, &master_keyblock))) { krb5_db_fini(handle->context); return ret; } diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index 37f1cdb2bd..bbca07175d 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -1251,16 +1251,18 @@ char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; krb5_error_code krb5_db_fetch_mkey(krb5_context context, krb5_principal mname, - krb5_enctype etype, - krb5_boolean fromkeyboard, - krb5_boolean twice, - char *db_args, krb5_data * salt, krb5_keyblock * key) + krb5_enctype etype, + krb5_boolean fromkeyboard, + krb5_boolean twice, + char * db_args, + krb5_kvno * kvno, + krb5_data * salt, + krb5_keyblock * key) { krb5_error_code retval; char password[BUFSIZ]; krb5_data pwd; unsigned int size = sizeof(password); - int kvno = IGNORE_VNO; krb5_keyblock tmp_key; memset(&tmp_key, 0, sizeof(tmp_key)); @@ -1284,6 +1286,30 @@ krb5_db_fetch_mkey(krb5_context context, retval = krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch, key); + /* + * If a kvno pointer was passed in and it dereferences the IGNORE_VNO + * value then it should be assigned the value of the kvno associated + * with the current mkey princ key if that princ entry is available + * otherwise assign 1 which is the default kvno value for the mkey + * princ. + */ + if (kvno != NULL && *kvno == IGNORE_VNO) { + int nentries = 1; + krb5_boolean more; + krb5_error_code rc; + krb5_db_entry master_entry; + + rc = krb5_db_get_principal(context, mname, + &master_entry, &nentries, &more); + + if (rc == 0 && nentries == 1 && more == FALSE) + *kvno = (krb5_kvno) master_entry.key_data->key_data_kvno; + else + *kvno = 1; + + if (rc == 0 && nentries) + krb5_db_free_principal(context, &master_entry, nentries); + } if (!salt) krb5_xfree(scratch.data); @@ -1309,7 +1335,7 @@ krb5_db_fetch_mkey(krb5_context context, retval = dal_handle->lib_handle->vftabl.fetch_master_key(context, mname, &tmp_key, - &kvno, + kvno, db_args); get_errmsg(context, retval); kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); @@ -1341,7 +1367,7 @@ krb5_db_fetch_mkey(krb5_context context, krb5_error_code krb5_db_verify_master_key(krb5_context kcontext, krb5_principal mprinc, - krb5_kvno *kvno, + krb5_kvno kvno, krb5_keyblock *mkey) { krb5_error_code status = 0; diff --git a/src/lib/kdb/kdb5.h b/src/lib/kdb/kdb5.h index 3893ba6398..09fe909d48 100644 --- a/src/lib/kdb/kdb5.h +++ b/src/lib/kdb/kdb5.h @@ -146,12 +146,12 @@ typedef struct _kdb_vftabl{ krb5_error_code (*fetch_master_key) (krb5_context kcontext, krb5_principal mname, krb5_keyblock *key, - int *kvno, + krb5_kvno *kvno, char *db_args); krb5_error_code (*verify_master_key) (krb5_context kcontext, krb5_principal mprinc, - krb5_kvno *kvno, + krb5_kvno kvno, krb5_keyblock *mkey); krb5_error_code (*dbe_search_enctype) (krb5_context kcontext, diff --git a/src/lib/kdb/kdb_default.c b/src/lib/kdb/kdb_default.c index 5b34632f79..4a35838108 100644 --- a/src/lib/kdb/kdb_default.c +++ b/src/lib/kdb/kdb_default.c @@ -284,11 +284,11 @@ krb5_db_def_fetch_mkey_stash( krb5_context context, retval = 0; /* - * Note, the old stash format did not store the kvno so it was always hard - * coded to be 0. + * Note, the old stash format did not store the kvno and at this point it + * can be assumed to be 1 as is the case for the mkey princ. */ if (kvno) - *kvno = 0; + *kvno = 1; errout: (void) fclose(kf); @@ -341,10 +341,10 @@ krb5_db_def_fetch_mkey_keytab( krb5_context context, if (kvno != NULL) { /* - * if a kvno pointer was passed in and it dereferences to - * IGNORE_VNO then it should be assigned the value of the - * kvno found in the keytab otherwise the KNVO specified - * should be the same as the one returned from the keytab. + * If a kvno pointer was passed in and it dereferences the + * IGNORE_VNO value then it should be assigned the value of the kvno + * found in the keytab otherwise the KNVO specified should be the + * same as the one returned from the keytab. */ if (*kvno == IGNORE_VNO) { *kvno = kt_ent.vno; @@ -419,7 +419,7 @@ krb5_db_def_fetch_mkey( krb5_context context, krb5_error_code krb5_def_verify_master_key( krb5_context context, krb5_principal mprinc, - krb5_kvno *kvno, + krb5_kvno kvno, krb5_keyblock *mkey) { krb5_error_code retval; @@ -455,16 +455,12 @@ krb5_def_verify_master_key( krb5_context context, retval = KRB5_KDB_BADMASTERKEY; } - if (kvno != NULL) { - if (*kvno == IGNORE_VNO) { - /* return value of mkey princs kvno */ - *kvno = master_entry.key_data->key_data_kvno; - } else if (*kvno != (krb5_kvno) master_entry.key_data->key_data_kvno) { - retval = KRB5_KDB_BADMASTERKEY; - krb5_set_error_message (context, retval, - "User specified mkeyVNO (%u) does not match master key princ's KVNO (%u)", - *kvno, master_entry.key_data->key_data_kvno); - } + if (kvno != IGNORE_VNO && + kvno != (krb5_kvno) master_entry.key_data->key_data_kvno) { + retval = KRB5_KDB_BADMASTERKEY; + krb5_set_error_message (context, retval, + "User specified mkeyVNO (%u) does not match master key princ's KVNO (%u)", + kvno, master_entry.key_data->key_data_kvno); } memset((char *)tempkey.contents, 0, tempkey.length); diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c index 2af219b999..3abef65dba 100644 --- a/src/tests/create/kdb5_mkdums.c +++ b/src/tests/create/kdb5_mkdums.c @@ -360,7 +360,8 @@ char *dbname; } else { if ((retval = krb5_db_fetch_mkey(test_context, master_princ, master_keyblock.enctype, manual_mkey, - FALSE, 0, NULL, &master_keyblock))) { + FALSE, 0, NULL, NULL, + &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } @@ -389,7 +390,7 @@ char *dbname; free(args[0]); if ((retval = krb5_db_verify_master_key(test_context, master_princ, - NULL, &master_keyblock))){ + IGNORE_VNO, &master_keyblock))){ com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(test_context); return(1); diff --git a/src/tests/verify/kdb5_verify.c b/src/tests/verify/kdb5_verify.c index 2fb0ac2fd6..b6d7b23325 100644 --- a/src/tests/verify/kdb5_verify.c +++ b/src/tests/verify/kdb5_verify.c @@ -389,8 +389,9 @@ set_dbname_help(context, pname, dbname) } else { if ((retval = krb5_db_fetch_mkey(context, master_princ, master_keyblock.enctype, - manual_mkey, FALSE, (char *) NULL, 0, - &master_keyblock))) { + manual_mkey, FALSE, (char *) NULL, + NULL, NULL, + &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } @@ -416,7 +417,7 @@ set_dbname_help(context, pname, dbname) return(1); } if ((retval = krb5_db_verify_master_key(context, master_princ, - NULL, &master_keyblock))) { + IGNORE_VNO, &master_keyblock))) { com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(context); return(1);