From 92f2d10e2fc83bb84a9a5168664e2ad8f74527b9 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 30 Sep 1998 04:03:35 +0000 Subject: [PATCH] Add support for changing the master key for a database as part of creating a dump of the database. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10952 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin/dbutil/ChangeLog | 5 + src/kadmin/dbutil/dump.c | 188 +++++++++++++++++++++++++++++++----- 2 files changed, 167 insertions(+), 26 deletions(-) diff --git a/src/kadmin/dbutil/ChangeLog b/src/kadmin/dbutil/ChangeLog index 3ab92e90e..e6ab156f9 100644 --- a/src/kadmin/dbutil/ChangeLog +++ b/src/kadmin/dbutil/ChangeLog @@ -1,3 +1,8 @@ +Wed Sep 30 00:02:01 1998 Theodore Y. Ts'o + + * dump.c: Add support for changing the master key for a database + as part of creating a dump of the database. + 1998-05-06 Theodore Ts'o * kdb5_stash.c (argv): diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c index 194c6abad..cf7dfef5a 100644 --- a/src/kadmin/dbutil/dump.c +++ b/src/kadmin/dbutil/dump.c @@ -34,6 +34,18 @@ #include #endif /* HAVE_REGEX_H */ +/* + * Needed for master key conversion. + */ +extern krb5_keyblock master_keyblock; +extern krb5_principal master_princ; +extern krb5_encrypt_block master_encblock; +extern int valid_master_key; +extern void usage(); +static int mkey_convert; +static krb5_keyblock new_master_keyblock; +static krb5_encrypt_block new_master_encblock; + /* * Use compile(3) if no regcomp present. */ @@ -193,6 +205,7 @@ static const char standard_fmt_name[] = "Kerberos version 5 format"; static const char no_name_mem_fmt[] = "%s: cannot get memory for temporary name\n"; static const char ctx_err_fmt[] = "%s: cannot initialize Kerberos context\n"; static const char stdin_name[] = "standard input"; +static const char remaster_err_fmt[] = "while re-encoding keys for principal %s with new master key"; static const char restfail_fmt[] = "%s: %s restore failed\n"; static const char close_err_fmt[] = "%s: cannot close database (%s)\n"; static const char dbinit_err_fmt[] = "%s: cannot initialize database (%s)\n"; @@ -212,6 +225,51 @@ static const char hashoption[] = "-hash"; static const char ovoption[] = "-ov"; static const char dump_tmptrail[] = "~"; +/* + * Re-encrypt the key_data with the new master key... + */ +krb5_error_code master_key_convert(context, db_entry) + krb5_context context; + krb5_db_entry * db_entry; +{ + krb5_error_code retval; + krb5_keyblock v5plainkey, *key_ptr; + krb5_keysalt keysalt; + int i; + krb5_key_data new_key_data, *key_data; + krb5_boolean is_mkey; + + is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ); + + if (is_mkey && db_entry->n_key_data != 1) + fprintf(stderr, + "Master key db entry has %d keys, expecting only 1!\n", + db_entry->n_key_data); + for (i=0; i < db_entry->n_key_data; i++) { + key_data = &db_entry->key_data[i]; + if (key_data->key_data_length == 0) + continue; + retval = krb5_dbekd_decrypt_key_data(context, &master_encblock, + key_data, &v5plainkey, + &keysalt); + if (retval) + return retval; + + memset(&new_key_data, 0, sizeof(new_key_data)); + key_ptr = is_mkey ? &new_master_keyblock : &v5plainkey; + retval = krb5_dbekd_encrypt_key_data(context, &new_master_encblock, + key_ptr, &keysalt, + key_data->key_data_kvno, + &new_key_data); + if (retval) + return retval; + krb5_free_keyblock_contents(context, &v5plainkey); + free(key_data->key_data_contents); + *key_data = new_key_data; + } + return 0; +} + /* * Update the "ok" file. */ @@ -368,7 +426,7 @@ find_enctype(dbentp, enctype, salttype, kentp) maxkvno = -1; datap = (krb5_key_data *) NULL; for (i=0; in_key_data; i++) { - if ((dbentp->key_data[i].key_data_type[0] == enctype) && + if (( (krb5_enctype)dbentp->key_data[i].key_data_type[0] == enctype) && ((dbentp->key_data[i].key_data_type[1] == salttype) || (salttype < 0))) { maxkvno = dbentp->key_data[i].key_data_kvno; @@ -409,7 +467,6 @@ dump_k5beta_iterator(ptr, entry) struct dump_args *arg; char *name, *mod_name; krb5_principal mod_princ; - krb5_tl_data *pwchg; krb5_key_data *pkey, *akey, nullkey; krb5_timestamp mod_date, last_pwd_change; int i; @@ -430,6 +487,18 @@ dump_k5beta_iterator(ptr, entry) arg->programname, error_message(retval)); return(retval); } + + /* + * Re-encode the keys in the new master key, if necessary. + */ + if (mkey_convert) { + retval = master_key_convert(arg->kcontext, entry); + if (retval) { + com_err(arg->programname, retval, remaster_err_fmt, name); + return retval; + } + } + /* * If we don't have any match strings, or if our name matches, then * proceed with the dump, otherwise, just forget about it. @@ -464,9 +533,9 @@ dump_k5beta_iterator(ptr, entry) /* * Find the last password change record and set it straight. */ - if (retval = - krb5_dbe_lookup_last_pwd_change(arg->kcontext, entry, - &last_pwd_change)) { + if ((retval = + krb5_dbe_lookup_last_pwd_change(arg->kcontext, entry, + &last_pwd_change))) { fprintf(stderr, nokeys_err, arg->programname, name); krb5_xfree(mod_name); krb5_xfree(name); @@ -585,6 +654,18 @@ dump_k5beta6_iterator(ptr, entry) arg->programname, error_message(retval)); return(retval); } + + /* + * Re-encode the keys in the new master key, if necessary. + */ + if (mkey_convert) { + retval = master_key_convert(arg->kcontext, entry); + if (retval) { + com_err(arg->programname, retval, remaster_err_fmt, name); + return retval; + } + } + /* * If we don't have any match strings, or if our name matches, then * proceed with the dump, otherwise, just forget about it. @@ -883,11 +964,12 @@ dump_db(argc, argv) int error; char *programname; char *ofile; - krb5_error_code kret; + krb5_error_code kret, retval; dump_version *dump; int aindex; krb5_boolean locked; extern osa_adb_policy_t policy_db; + char *new_mkey_file = 0; /* * Parse the arguments. @@ -899,6 +981,8 @@ dump_db(argc, argv) error = 0; dump = &beta7_version; arglist.verbose = 0; + new_mkey_file = 0; + mkey_convert = 0; /* * Parse the qualifiers. @@ -912,7 +996,12 @@ dump_db(argc, argv) dump = &ov_version; else if (!strcmp(argv[aindex], verboseoption)) arglist.verbose++; - else + else if (!strcmp(argv[aindex], "-mkey_convert")) + mkey_convert = 1; + else if (!strcmp(argv[aindex], "-new_mkey_file")) { + new_mkey_file = argv[++aindex]; + mkey_convert = 1; + } else break; } @@ -937,6 +1026,52 @@ dump_db(argc, argv) return; } + /* + * If we're doing a master key conversion, set up for it. + */ + if (mkey_convert) { + if (!valid_master_key) { + /* TRUE here means read the keyboard, but only once */ + if ((retval = krb5_db_fetch_mkey(util_context, + master_princ, &master_encblock, TRUE, FALSE, + (char *) NULL, 0, &master_keyblock))) { + com_err(argv[0], retval, "while reading master key"); + exit(1); + } + if ((retval = krb5_db_verify_master_key(util_context, + master_princ, &master_keyblock,&master_encblock))) { + com_err(argv[0], retval, "while verifying master key"); + exit(1); + } + if ((retval = krb5_process_key(util_context, + &master_encblock, &master_keyblock))) { + com_err(argv[0], retval, "while processing master key"); + exit(1); + } + } + new_master_keyblock.enctype = global_params.enctype; + if (new_master_keyblock.enctype == ENCTYPE_UNKNOWN) + new_master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; + krb5_use_enctype(util_context, &new_master_encblock, + new_master_keyblock.enctype); + if (!new_mkey_file) + printf("Please enter new master key....\n"); + if ((retval = krb5_db_fetch_mkey(util_context, master_princ, + &new_master_encblock, + !new_mkey_file, TRUE, + new_mkey_file, 0, + &new_master_keyblock))) { + com_err(argv[0], retval, "while reading old master key"); + exit(1); + } + if ((retval = krb5_process_key(util_context, &new_master_encblock, + &new_master_keyblock))) { + com_err(argv[0], retval, + "while processing old master key"); + exit(1); + } + } + kret = 0; locked = 0; if (ofile && strcmp(ofile, "-")) { @@ -1749,9 +1884,9 @@ int process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db) return 1; } - if (ret = osa_adb_create_policy(pol_db, &rec)) { + if ((ret = osa_adb_create_policy(pol_db, &rec))) { if (ret == OSA_ADB_DUP && - (ret = osa_adb_put_policy(pol_db, &rec))) { + ((ret = osa_adb_put_policy(pol_db, &rec)))) { fprintf(stderr, "cannot create policy on line %d: %s\n", *linenop, error_message(ret)); return 1; @@ -1967,7 +2102,8 @@ load_db(argc, argv) exit_status++; return; } - if (kret = krb5_lock_file(kcontext, fileno(f), KRB5_LOCKMODE_SHARED)) { + if ((kret = krb5_lock_file(kcontext, fileno(f), + KRB5_LOCKMODE_SHARED))) { fprintf(stderr, "%s: Cannot lock %s: %s\n", programname, dumpfile, error_message(errno)); exit_status++; @@ -2023,8 +2159,8 @@ load_db(argc, argv) newparams.mask |= KADM5_CONFIG_DBNAME; newparams.dbname = dbname_tmp; - if (kret = kadm5_get_config_params(kcontext, NULL, NULL, - &newparams, &newparams)) { + if ((kret = kadm5_get_config_params(kcontext, NULL, NULL, + &newparams, &newparams))) { com_err(argv[0], kret, "while retreiving new configuration parameters"); exit_status++; @@ -2038,7 +2174,7 @@ load_db(argc, argv) * with policy info, because they may be loading an old dump * intending to use it with the new kadm5 system. */ - if (!update && (kret = krb5_db_create(kcontext, dbname_tmp, crflags))) { + if (!update && ((kret = krb5_db_create(kcontext, dbname_tmp, crflags)))) { fprintf(stderr, dbcreaterr_fmt, programname, dbname_tmp, error_message(kret)); exit_status++; @@ -2058,15 +2194,15 @@ load_db(argc, argv) /* * Point ourselves at the new databases. */ - if (kret = krb5_db_set_name(kcontext, - (update) ? dbname : dbname_tmp)) { + if ((kret = krb5_db_set_name(kcontext, + (update) ? dbname : dbname_tmp))) { fprintf(stderr, dbname_err_fmt, programname, (update) ? dbname : dbname_tmp, error_message(kret)); exit_status++; goto error; } - if (kret = osa_adb_open_policy(&tmppol_db, &newparams)) { + if ((kret = osa_adb_open_policy(&tmppol_db, &newparams))) { fprintf(stderr, "%s: %s while opening policy database\n", programname, error_message(kret)); exit_status++; @@ -2077,7 +2213,7 @@ load_db(argc, argv) * the update fails. */ if (update) { - if (kret = osa_adb_get_lock(tmppol_db, OSA_ADB_PERMANENT)) { + if ((kret = osa_adb_get_lock(tmppol_db, OSA_ADB_PERMANENT))) { fprintf(stderr, "%s: %s while permanently locking database\n", programname, error_message(kret)); exit_status++; @@ -2088,7 +2224,7 @@ load_db(argc, argv) /* * Initialize the database. */ - if (kret = krb5_db_init(kcontext)) { + if ((kret = krb5_db_init(kcontext))) { fprintf(stderr, dbinit_err_fmt, programname, error_message(kret)); exit_status++; @@ -2120,14 +2256,14 @@ load_db(argc, argv) programname, dbname_tmp, error_message(kret)); exit_status++; } - if (kret = krb5_db_fini(kcontext)) { + if ((kret = krb5_db_fini(kcontext))) { fprintf(stderr, close_err_fmt, programname, error_message(kret)); exit_status++; } if (!update && load->create_kadm5 && - (kret = kadm5_create_magic_princs(&newparams, kcontext))) { + ((kret = kadm5_create_magic_princs(&newparams, kcontext)))) { /* error message printed by create_magic_princs */ exit_status++; } @@ -2148,7 +2284,7 @@ error: programname, dbname_tmp, error_message(kret)); exit_status++; } - if (kret = osa_adb_destroy_policy_db(&newparams)) { + if ((kret = osa_adb_destroy_policy_db(&newparams))) { fprintf(stderr, "%s: %s while destroying policy database\n", programname, error_message(kret)); exit_status++; @@ -2164,14 +2300,14 @@ error: exit_status++; } - if (kret = osa_adb_close_policy(tmppol_db)) { + if ((kret = osa_adb_close_policy(tmppol_db))) { fprintf(stderr, close_err_fmt, programname, error_message(kret)); exit_status++; } - if (kret = osa_adb_rename_policy_db(&newparams, - &global_params)) { + if ((kret = osa_adb_rename_policy_db(&newparams, + &global_params))) { fprintf(stderr, "%s: %s while renaming policy db %s to %s\n", programname, error_message(kret), @@ -2181,13 +2317,13 @@ error: } } } else /* update */ { - if (! exit_status && (kret = osa_adb_release_lock(tmppol_db))) { + if (! exit_status && ((kret = osa_adb_release_lock(tmppol_db)))) { fprintf(stderr, "%s: %s while releasing permanent lock\n", programname, error_message(kret)); exit_status++; } - if(tmppol_db && (kret = osa_adb_close_policy(tmppol_db))) { + if (tmppol_db && ((kret = osa_adb_close_policy(tmppol_db)))) { fprintf(stderr, close_err_fmt, programname, error_message(kret)); exit_status++; -- 2.26.2