#include <regex.h>
#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.
*/
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";
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.
*/
maxkvno = -1;
datap = (krb5_key_data *) NULL;
for (i=0; i<dbentp->n_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;
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;
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.
/*
* 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);
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.
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.
error = 0;
dump = &beta7_version;
arglist.verbose = 0;
+ new_mkey_file = 0;
+ mkey_convert = 0;
/*
* Parse the qualifiers.
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;
}
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, "-")) {
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;
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++;
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++;
* 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++;
/*
* 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++;
* 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++;
/*
* 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++;
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++;
}
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++;
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),
}
}
} 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++;