From c438b327af4cf5ba96ed3f7e02b6327b9d06c1ae Mon Sep 17 00:00:00 2001 From: Will Fiveash Date: Fri, 15 Aug 2008 00:38:41 +0000 Subject: [PATCH] a stash file is not a keytab Note, this is the commit for the associated Krb Consortium project: Projects/Masterkey Keytab Stash ticket: 194 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20661 dc483132-0cff-0310-8789-dd5450dbe970 --- src/configure.in | 2 +- src/include/k5-int.h | 5 + src/include/kdb.h | 15 +- src/kadmin/dbutil/dump.c | 61 +++- src/kadmin/dbutil/kdb5_create.c | 19 +- src/kadmin/dbutil/kdb5_stash.c | 12 +- src/kadmin/dbutil/kdb5_util.M | 5 + src/kadmin/dbutil/kdb5_util.c | 39 ++- src/kdc/main.c | 3 +- src/lib/kadm5/admin.h | 3 +- src/lib/kadm5/alt_prof.c | 5 + src/lib/kadm5/srv/server_kdb.c | 3 +- src/lib/kadm5/unit-test/api.2/init-v2.exp | 2 +- src/lib/kdb/kdb5.c | 58 +++- src/lib/kdb/kdb5.h | 4 +- src/lib/kdb/kdb_default.c | 311 +++++++++++++----- src/lib/krb5/keytab/kt_file.c | 2 - src/lib/krb5/keytab/kt_memory.c | 2 - src/lib/krb5/keytab/kt_srvtab.c | 2 - .../kdb/ldap/ldap_util/kdb5_ldap_realm.c | 11 + .../kdb/ldap/ldap_util/kdb5_ldap_util.M | 6 +- .../kdb/ldap/ldap_util/kdb5_ldap_util.c | 18 +- src/tests/Makefile.in | 2 +- src/tests/create/kdb5_mkdums.c | 5 +- src/tests/mkeystash_compat/Makefile.in | 49 +++ src/tests/mkeystash_compat/bigendian.c | 17 + src/tests/mkeystash_compat/old_stash_bendian | Bin 0 -> 67 bytes src/tests/mkeystash_compat/old_stash_lendian | Bin 0 -> 30 bytes src/tests/verify/kdb5_verify.c | 7 +- 29 files changed, 513 insertions(+), 155 deletions(-) create mode 100644 src/tests/mkeystash_compat/Makefile.in create mode 100644 src/tests/mkeystash_compat/bigendian.c create mode 100644 src/tests/mkeystash_compat/old_stash_bendian create mode 100644 src/tests/mkeystash_compat/old_stash_lendian diff --git a/src/configure.in b/src/configure.in index ffec8b0af..0e9bd3ab5 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1141,6 +1141,6 @@ V5_AC_OUTPUT_MAKEFILE(. tests tests/resolve tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi tests/dejagnu tests/threads tests/shlib - tests/gss-threads tests/misc + tests/gss-threads tests/misc tests/mkeystash_compat util/collected-client-lib ) diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 4b0a0937e..b9abd8a34 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1803,6 +1803,11 @@ krb5int_make_srv_query_realm(const krb5_data *realm, void krb5int_free_srv_dns_data(struct srv_dns_entry *); #endif +/* value to use when requesting a keytab entry and KVNO doesn't matter */ +#define IGNORE_VNO 0 +/* value to use when requesting a keytab entry and enctype doesn't matter */ +#define IGNORE_ENCTYPE 0 + /* * Convenience function for structure magic number */ diff --git a/src/include/kdb.h b/src/include/kdb.h index 66e8d0698..cc5951d46 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -275,8 +275,9 @@ krb5_error_code krb5_db_get_mkey ( krb5_context kcontext, krb5_error_code krb5_db_free_master_key ( krb5_context kcontext, krb5_keyblock *key ); krb5_error_code krb5_db_store_master_key ( krb5_context kcontext, - char *db_arg, + char *keyfile, krb5_principal mname, + krb5_kvno kvno, krb5_keyblock *key, char *master_pwd); krb5_error_code krb5_db_fetch_mkey ( krb5_context context, @@ -285,11 +286,13 @@ 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_error_code krb5_db_verify_master_key ( krb5_context kcontext, krb5_principal mprinc, - krb5_keyblock *mkey ); + krb5_kvno kvno, + krb5_keyblock *mkey ); krb5_error_code krb5_dbe_find_enctype( krb5_context kcontext, krb5_db_entry *dbentp, @@ -432,6 +435,7 @@ krb5_error_code krb5_def_store_mkey( krb5_context context, char *keyfile, krb5_principal mname, + krb5_kvno kvno, krb5_keyblock *key, char *master_pwd); @@ -440,12 +444,13 @@ krb5_error_code krb5_db_def_fetch_mkey( krb5_context context, krb5_principal mname, krb5_keyblock *key, - int *kvno, + krb5_kvno *kvno, 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_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 0cc227d30..fbb8fd21e 100644 --- a/src/kadmin/dbutil/dump.c +++ b/src/kadmin/dbutil/dump.c @@ -270,6 +270,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); @@ -288,10 +289,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; @@ -1126,7 +1139,8 @@ dump_db(argc, argv) master_princ, master_keyblock.enctype, TRUE, FALSE, - (char *) NULL, 0, + (char *) NULL, + NULL, NULL, &master_keyblock); if (retval) { com_err(progname, retval, @@ -1135,6 +1149,7 @@ dump_db(argc, argv) } retval = krb5_db_verify_master_key(util_context, master_princ, + IGNORE_VNO, &master_keyblock); if (retval) { com_err(progname, retval, @@ -1145,17 +1160,37 @@ 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) + + 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(progname, 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, - (new_mkey_file == 0) ? - (krb5_boolean) 1 : 0, - TRUE, - new_mkey_file, 0, - &new_master_keyblock))) { - com_err(progname, retval, "while reading new master key"); - exit(1); + if ((retval = krb5_db_fetch_mkey(util_context, master_princ, + new_master_keyblock.enctype, + TRUE, + TRUE, + NULL, NULL, NULL, + &new_master_keyblock))) { + com_err(progname, retval, "while reading new master key"); + exit(1); + } } } diff --git a/src/kadmin/dbutil/kdb5_create.c b/src/kadmin/dbutil/kdb5_create.c index eaeade163..c996dad25 100644 --- a/src/kadmin/dbutil/kdb5_create.c +++ b/src/kadmin/dbutil/kdb5_create.c @@ -166,6 +166,7 @@ void kdb5_create(argc, argv) int do_stash = 0; krb5_data pwd, seed; kdb_log_context *log_ctx; + krb5_kvno mkey_kvno; while ((optchar = getopt(argc, argv, "s")) != -1) { switch(optchar) { @@ -319,9 +320,20 @@ master key name '%s'\n", * it; delete the file below if it was not requested. DO NOT EXIT * BEFORE DELETING THE KEYFILE if do_stash is not set. */ + + /* + * Determine the kvno to use, it must be that used to create the master key + * princ. + */ + if (global_params.mask & KADM5_CONFIG_KVNO) + mkey_kvno = global_params.kvno; /* user specified */ + else + mkey_kvno = 1; /* Default */ + retval = krb5_db_store_master_key(util_context, global_params.stash_file, master_princ, + mkey_kvno, &master_keyblock, mkey_password); if (retval) { @@ -401,6 +413,7 @@ add_principal(context, princ, op, pblock) { krb5_error_code retval; krb5_db_entry entry; + krb5_kvno mkey_kvno; krb5_timestamp now; struct iterate_args iargs; @@ -433,10 +446,14 @@ add_principal(context, princ, op, pblock) memset((char *) entry.key_data, 0, sizeof(krb5_key_data)); entry.n_key_data = 1; + if (global_params.mask & KADM5_CONFIG_KVNO) + mkey_kvno = global_params.kvno; /* user specified */ + else + mkey_kvno = 1; /* Default */ entry.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; if ((retval = krb5_dbekd_encrypt_key_data(context, pblock->key, &master_keyblock, NULL, - 1, entry.key_data))) + mkey_kvno, entry.key_data))) return retval; break; case TGT_KEY: diff --git a/src/kadmin/dbutil/kdb5_stash.c b/src/kadmin/dbutil/kdb5_stash.c index a34aa132a..3583a3285 100644 --- a/src/kadmin/dbutil/kdb5_stash.c +++ b/src/kadmin/dbutil/kdb5_stash.c @@ -81,6 +81,7 @@ kdb5_stash(argc, argv) char *mkey_fullname; char *keyfile = 0; krb5_context context; + krb5_kvno mkey_kvno; retval = kadm5_init_krb5_context(&context); if( retval ) @@ -139,11 +140,17 @@ 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(progname, retval, "while reading master key"); (void) krb5_db_fini(context); @@ -151,6 +158,7 @@ kdb5_stash(argc, argv) } retval = krb5_db_verify_master_key(context, master_princ, + mkey_kvno, &master_keyblock); if (retval) { com_err(progname, retval, "while verifying master key"); @@ -159,7 +167,7 @@ kdb5_stash(argc, argv) } retval = krb5_db_store_master_key(context, keyfile, master_princ, - &master_keyblock, NULL); + mkey_kvno, &master_keyblock, NULL); if (retval) { com_err(progname, errno, "while storing key"); memset((char *)master_keyblock.contents, 0, master_keyblock.length); diff --git a/src/kadmin/dbutil/kdb5_util.M b/src/kadmin/dbutil/kdb5_util.M index 11ef7ca18..d58c972af 100644 --- a/src/kadmin/dbutil/kdb5_util.M +++ b/src/kadmin/dbutil/kdb5_util.M @@ -5,6 +5,7 @@ kdb5_util \- Kerberos database maintainance utility .B kdb5_util [\fB\-r\fP\ \fIrealm\fP] [\fB\-d\fP\ \fIdbname\fP] [\fB\-k\fP\ \fImkeytype\fP] [\fB\-M\fP\ \fImkeyname\fP] +[\fB\-kv\fP\ \fImkeyVNO\fP] [\fB\-sf\fP\ \fIstashfilename\fP] [\fB\-m\fP] .I command @@ -58,6 +59,10 @@ specifies the key type of the master key in the database; the default is that given in .IR kdc.conf . .TP +\fB\-kv\fP\ \fImkeyVNO\fP +Specifies the version number of the master key in the database; the default is +1. Note that 0 is not allowed. +.TP \fB\-M\fP\ \fImkeyname\fP principal name for the master key in the database; the default is that given in diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c index cfc3d0821..ff6bcc995 100644 --- a/src/kadmin/dbutil/kdb5_util.c +++ b/src/kadmin/dbutil/kdb5_util.c @@ -81,7 +81,7 @@ void usage() { fprintf(stderr, "Usage: " "kdb5_util [-x db_args]* [-r realm] [-d dbname] [-k mkeytype] [-M mkeyname]\n" - "\t [-sf stashfilename] [-m] cmd [cmd_options]\n" + "\t [-kv mkeyVNO] [-sf stashfilename] [-m] cmd [cmd_options]\n" "\tcreate [-s]\n" "\tdestroy [-f]\n" "\tstash [-f keyfile]\n" @@ -205,7 +205,7 @@ int main(argc, argv) } memset(cmd_argv, 0, sizeof(char *)*argc); cmd_argc = 1; - + argv++; argc--; while (*argv) { if (strcmp(*argv, "-P") == 0 && ARG_VAL) { @@ -246,10 +246,18 @@ int main(argc, argv) exit(1); } } else if (strcmp(*argv, "-k") == 0 && ARG_VAL) { - if (krb5_string_to_enctype(koptarg, &global_params.enctype)) - com_err(progname, 0, "%s is an invalid enctype", koptarg); - else + if (krb5_string_to_enctype(koptarg, &global_params.enctype)) { + com_err(progname, EINVAL, ": %s is an invalid enctype", koptarg); + exit(1); + } else global_params.mask |= KADM5_CONFIG_ENCTYPE; + } else if (strcmp(*argv, "-kv") == 0 && ARG_VAL) { + global_params.kvno = (krb5_kvno) atoi(koptarg); + if (global_params.kvno == IGNORE_VNO) { + com_err(progname, EINVAL, ": %s is an invalid mkeyVNO", koptarg); + exit(1); + } else + global_params.mask |= KADM5_CONFIG_KVNO; } else if (strcmp(*argv, "-M") == 0 && ARG_VAL) { global_params.mkey_name = koptarg; global_params.mask |= KADM5_CONFIG_MKEY_NAME; @@ -380,6 +388,7 @@ static int open_db_and_mkey() int nentries; krb5_boolean more; krb5_data scratch, pwd, seed; + krb5_kvno kvno; dbactive = FALSE; valid_master_key = 0; @@ -421,6 +430,11 @@ static int open_db_and_mkey() return(1); } + if (global_params.mask & KADM5_CONFIG_KVNO) + kvno = global_params.kvno; /* user specified */ + else + 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 +451,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); @@ -455,10 +468,12 @@ static int open_db_and_mkey() } free(scratch.data); mkey_password = 0; + } 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"); @@ -466,7 +481,7 @@ static int open_db_and_mkey() return(0); } if ((retval = krb5_db_verify_master_key(util_context, master_princ, - &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 ff675dcae..ff47c0088 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,6 +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, + IGNORE_VNO, &rdp->realm_mkey))) { com_err(progname, kret, "while verifying master key for realm %s", realm); diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h index 9013305b6..281719561 100644 --- a/src/lib/kadm5/admin.h +++ b/src/lib/kadm5/admin.h @@ -139,6 +139,7 @@ typedef long kadm5_ret_t; #define KADM5_CONFIG_POLL_TIME 0x04000000 #define KADM5_CONFIG_IPROP_LOGFILE 0x08000000 #define KADM5_CONFIG_IPROP_PORT 0x10000000 +#define KADM5_CONFIG_KVNO 0x20000000 /* * permission bits */ @@ -256,7 +257,7 @@ typedef struct _kadm5_config_params { krb5_flags flags; krb5_key_salt_tuple *keysalts; krb5_int32 num_keysalts; - + krb5_kvno kvno; bool_t iprop_enabled; uint32_t iprop_ulogsize; krb5_deltat iprop_poll_time; diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index c8bc6b052..cfcbd79aa 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -501,6 +501,11 @@ krb5_error_code kadm5_get_config_params(context, use_kdc_config, params.realm = lrealm; params.mask |= KADM5_CONFIG_REALM; } + + if (params_in->mask & KADM5_CONFIG_KVNO) { + params.kvno = params_in->kvno; + params.mask |= KADM5_CONFIG_KVNO; + } /* * XXX These defaults should to work on both client and * server. kadm5_get_config_params can be implemented as a diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index 700b53a66..836cd00b7 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, - &master_keyblock))) { + IGNORE_VNO, &master_keyblock))) { krb5_db_fini(handle->context); return ret; } diff --git a/src/lib/kadm5/unit-test/api.2/init-v2.exp b/src/lib/kadm5/unit-test/api.2/init-v2.exp index 21f6260a4..24bfb09b0 100644 --- a/src/lib/kadm5/unit-test/api.2/init-v2.exp +++ b/src/lib/kadm5/unit-test/api.2/init-v2.exp @@ -147,7 +147,7 @@ proc test108 {} { [config_params {KADM5_CONFIG_MKEY_NAME} does/not/exist] \ $KADM5_STRUCT_VERSION $KADM5_API_VERSION_2 \ server_handle - } "KDB_NOMASTERKEY" + } "KRB5_KDB_CANTREAD_STORED" } if {! $RPC} test108 diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index f25864dc7..67ceacb99 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -1390,8 +1390,9 @@ krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key) krb5_error_code krb5_db_store_master_key(krb5_context kcontext, - char *db_arg, + char *keyfile, krb5_principal mname, + krb5_kvno kvno, krb5_keyblock * key, char *master_pwd) { krb5_error_code status = 0; @@ -1411,8 +1412,9 @@ krb5_db_store_master_key(krb5_context kcontext, } status = dal_handle->lib_handle->vftabl.store_master_key(kcontext, - db_arg, + keyfile, mname, + kvno, key, master_pwd); get_errmsg(kcontext, status); kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); @@ -1425,18 +1427,20 @@ char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1; 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_db_fetch_mkey(krb5_context context, + krb5_principal mname, + 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; krb5_keyblock tmp_key; memset(&tmp_key, 0, sizeof(tmp_key)); @@ -1460,6 +1464,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); @@ -1485,7 +1513,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); @@ -1515,8 +1543,10 @@ krb5_db_fetch_mkey(krb5_context context, } krb5_error_code -krb5_db_verify_master_key(krb5_context kcontext, - krb5_principal mprinc, krb5_keyblock * mkey) +krb5_db_verify_master_key(krb5_context kcontext, + krb5_principal mprinc, + krb5_kvno kvno, + krb5_keyblock * mkey) { krb5_error_code status = 0; kdb5_dal_handle *dal_handle; @@ -1535,7 +1565,9 @@ krb5_db_verify_master_key(krb5_context kcontext, } status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext, - mprinc, mkey); + mprinc, + kvno, + mkey); get_errmsg(kcontext, status); kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); diff --git a/src/lib/kdb/kdb5.h b/src/lib/kdb/kdb5.h index 328ce2519..f9f449442 100644 --- a/src/lib/kdb/kdb5.h +++ b/src/lib/kdb/kdb5.h @@ -139,17 +139,19 @@ typedef struct _kdb_vftabl{ krb5_error_code (*store_master_key) (krb5_context kcontext, char *db_arg, krb5_principal mname, + krb5_kvno kvno, krb5_keyblock *key, char *master_pwd); 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_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 22d3af242..bf4ba3584 100644 --- a/src/lib/kdb/kdb_default.c +++ b/src/lib/kdb/kdb_default.c @@ -133,102 +133,117 @@ krb5_dbe_def_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) #endif krb5_error_code -krb5_def_store_mkey(context, keyfile, mname, key, master_pwd) - krb5_context context; - char *keyfile; - krb5_principal mname; - krb5_keyblock *key; - char *master_pwd; +krb5_def_store_mkey(krb5_context context, + char *keyfile, + krb5_principal mname, + krb5_kvno kvno, + krb5_keyblock *key, + char *master_pwd) { - FILE *kf; krb5_error_code retval = 0; - krb5_ui_2 enctype; - krb5_ui_4 keylength; char defkeyfile[MAXPATHLEN+1]; + char *tmp_ktname = NULL, *tmp_ktpath; krb5_data *realm = krb5_princ_realm(context, mname); -#if HAVE_UMASK - mode_t oumask; -#endif + krb5_keytab kt; + krb5_keytab_entry new_entry; + struct stat stb; + int statrc; if (!keyfile) { - (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); - (void) strncat(defkeyfile, realm->data, - min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, - realm->length)); - defkeyfile[sizeof(defkeyfile) - 1] = '\0'; - keyfile = defkeyfile; + (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); + (void) strncat(defkeyfile, realm->data, + min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, + realm->length)); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; + keyfile = defkeyfile; } -#if HAVE_UMASK - oumask = umask(077); -#endif -#ifdef ANSI_STDIO - if (!(kf = fopen(keyfile, "wb"))) -#else - if (!(kf = fopen(keyfile, "w"))) -#endif - { - int e = errno; -#if HAVE_UMASK - (void) umask(oumask); -#endif - krb5_set_error_message (context, e, - "%s accessing file '%s'", - error_message (e), keyfile); - return e; + /* + * XXX making the assumption that the keyfile is in a dir that requires root + * privilege to write to thus making timing attacks unlikely. + */ + if ((statrc = stat(keyfile, &stb)) >= 0) { + /* if keyfile exists it better be a regular file */ + if (!S_ISREG(stb.st_mode)) { + retval = EINVAL; + krb5_set_error_message (context, retval, + "keyfile (%s) is not a regular file: %s", + keyfile, error_message(retval)); + goto out; + } } - set_cloexec_file(kf); -#if BIG_ENDIAN_MASTER_KEY - enctype = htons((uint16_t) key->enctype); - keylength = htonl((uint32_t) key->length); -#else - enctype = key->enctype; - keylength = key->length; -#endif - if ((fwrite((krb5_pointer) &enctype, - 2, 1, kf) != 1) || - (fwrite((krb5_pointer) &keylength, - sizeof(keylength), 1, kf) != 1) || - (fwrite((krb5_pointer) key->contents, - sizeof(key->contents[0]), (unsigned) key->length, - kf) != key->length)) { - retval = errno; - (void) fclose(kf); - } else if (fclose(kf) == EOF) - retval = errno; -#if HAVE_UMASK - (void) umask(oumask); -#endif + + /* Use temp keytab file name in case creation of keytab fails */ + + /* create temp file template for use by mktemp() */ + if ((retval = asprintf(&tmp_ktname, "WRFILE:%s_XXXXXX", keyfile)) < 0) { + krb5_set_error_message (context, retval, + "Could not create temp keytab file name."); + goto out; + } + + if (mktemp(tmp_ktname) == NULL) { + retval = errno; + krb5_set_error_message (context, retval, + "Could not create temp stash file: %s", + error_message(errno)); + goto out; + } + + /* create new stash keytab using temp file name */ + retval = krb5_kt_resolve(context, tmp_ktname, &kt); + if (retval != 0) + goto out; + + memset((char *) &new_entry, 0, sizeof(new_entry)); + new_entry.principal = mname; + new_entry.key = *key; + new_entry.vno = kvno; + + /* + * Set tmp_ktpath to point to the keyfile path (skip WRFILE:). Subtracting + * 1 to account for NULL terminator in sizeof calculation of a string + * constant. Used further down. + */ + tmp_ktpath = tmp_ktname + (sizeof("WRFILE:") - 1); + + retval = krb5_kt_add_entry(context, kt, &new_entry); + if (retval != 0) { + /* delete tmp keyfile if it exists and an error occurrs */ + if (stat(keyfile, &stb) >= 0) + (void) unlink(tmp_ktpath); + } else { + /* rename original keyfile to original filename */ + if (rename(tmp_ktpath, keyfile) < 0) { + retval = errno; + krb5_set_error_message (context, retval, + "rename of temporary keyfile (%s) to (%s) failed: %s", + tmp_ktpath, keyfile, error_message(errno)); + } + } + +out: + if (tmp_ktname != NULL) + free(tmp_ktname); + return retval; } - -krb5_error_code -krb5_db_def_fetch_mkey( krb5_context context, - krb5_principal mname, - krb5_keyblock *key, - int *kvno, - char *db_args) +static krb5_error_code +krb5_db_def_fetch_mkey_stash(krb5_context context, + const char *keyfile, + krb5_keyblock *key, + krb5_kvno *kvno) { - krb5_error_code retval; + krb5_error_code retval = 0; krb5_ui_2 enctype; krb5_ui_4 keylength; - char defkeyfile[MAXPATHLEN+1]; - krb5_data *realm = krb5_princ_realm(context, mname); FILE *kf = NULL; - retval = 0; - key->magic = KV5M_KEYBLOCK; - (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); - (void) strncat(defkeyfile, realm->data, - min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, - realm->length)); - defkeyfile[sizeof(defkeyfile) - 1] = '\0'; - #ifdef ANSI_STDIO - if (!(kf = fopen((db_args) ? db_args : defkeyfile, "rb"))) + if (!(kf = fopen(keyfile, "rb"))) #else - if (!(kf = fopen((db_args) ? db_args : defkeyfile, "r"))) + if (!(kf = fopen(keyfile, "r"))) #endif return KRB5_KDB_CANTREAD_STORED; set_cloexec_file(kf); @@ -260,7 +275,7 @@ krb5_db_def_fetch_mkey( krb5_context context, #else key->length = keylength; #endif - + if (!key->length || ((int) key->length) < 0) { retval = KRB5_KDB_BADSTORED_MKEY; goto errout; @@ -271,9 +286,8 @@ krb5_db_def_fetch_mkey( krb5_context context, goto errout; } - if (fread((krb5_pointer) key->contents, - sizeof(key->contents[0]), key->length, kf) - != key->length) { + if (fread((krb5_pointer) key->contents, sizeof(key->contents[0]), + key->length, kf) != key->length) { retval = KRB5_KDB_CANTREAD_STORED; memset(key->contents, 0, key->length); free(key->contents); @@ -281,20 +295,137 @@ krb5_db_def_fetch_mkey( krb5_context context, } else retval = 0; - *kvno = 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 the kvno is + * passed in and isn't ignore_vno just leave it alone as this could cause + * verifcation trouble if the mkey princ is using a kvno other than 1. + */ + if (kvno && *kvno == IGNORE_VNO) + *kvno = 1; errout: (void) fclose(kf); return retval; +} +static krb5_error_code +krb5_db_def_fetch_mkey_keytab(krb5_context context, + const char *keyfile, + krb5_principal mname, + krb5_keyblock *key, + krb5_kvno *kvno) +{ + krb5_error_code retval = 0; + krb5_keytab kt; + krb5_keytab_entry kt_ent; + krb5_enctype enctype = IGNORE_ENCTYPE; + + if ((retval = krb5_kt_resolve(context, keyfile, &kt)) != 0) + goto errout; + + /* override default */ + if (key->enctype != ENCTYPE_UNKNOWN) + enctype = key->enctype; + + if ((retval = krb5_kt_get_entry(context, kt, mname, + kvno ? *kvno : IGNORE_VNO, + enctype, + &kt_ent)) == 0) { + + if (key->enctype == ENCTYPE_UNKNOWN) + key->enctype = kt_ent.key.enctype; + + if (((int) kt_ent.key.length) < 0) { + retval = KRB5_KDB_BADSTORED_MKEY; + krb5_kt_free_entry(context, &kt_ent); + goto errout; + } + + key->length = kt_ent.key.length; + + /* + * 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 != NULL && *kvno == IGNORE_VNO) + *kvno = kt_ent.vno; + + /* + * kt_ent will be free'd so need to allocate and copy key contents for + * output to caller. + */ + if (!(key->contents = (krb5_octet *)malloc(key->length))) { + retval = ENOMEM; + krb5_kt_free_entry(context, &kt_ent); + goto errout; + } + memcpy(key->contents, kt_ent.key.contents, kt_ent.key.length); + krb5_kt_free_entry(context, &kt_ent); + } + +errout: + return retval; } +krb5_error_code +krb5_db_def_fetch_mkey(krb5_context context, + krb5_principal mname, + krb5_keyblock *key, + krb5_kvno *kvno, + char *db_args) +{ + krb5_error_code retval_ofs = 0, retval_kt = 0; + char keyfile[MAXPATHLEN+1]; + krb5_data *realm = krb5_princ_realm(context, mname); + + key->magic = KV5M_KEYBLOCK; + + if (db_args != NULL) { + (void) strncpy(keyfile, db_args, sizeof(keyfile)); + } else { + (void) strcpy(keyfile, DEFAULT_KEYFILE_STUB); + (void) strncat(keyfile, realm->data, + min(sizeof(keyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, + realm->length)); + } + /* null terminate no matter what */ + keyfile[sizeof(keyfile) - 1] = '\0'; + + /* assume the master key is in a keytab */ + retval_kt = krb5_db_def_fetch_mkey_keytab(context, keyfile, mname, key, kvno); + if (retval_kt != 0) { + /* + * If it's not in a keytab, fall back and try getting the mkey from the + * older stash file format. + */ + retval_ofs = krb5_db_def_fetch_mkey_stash(context, keyfile, key, kvno); + } + + if (retval_kt != 0 && retval_ofs != 0) { + /* + * Error, not able to get mkey from either file format. Note, in order + * to try to return a more correct error, the logic below is assuming + * that if either of the stash reading functions returned + * KRB5_KDB_BADSTORED_MKEY then this is probably the real error. + */ + krb5_set_error_message (context, KRB5_KDB_CANTREAD_STORED, + "Can not fetch master key either from keytab (error: %s) or old " + "format (error %s).", error_message(retval_kt), + error_message(retval_ofs)); + return KRB5_KDB_CANTREAD_STORED; + } else { + return 0; + } +} krb5_error_code -krb5_def_verify_master_key(context, mprinc, mkey) - krb5_context context; - krb5_principal mprinc; - krb5_keyblock *mkey; +krb5_def_verify_master_key(krb5_context context, + krb5_principal mprinc, + krb5_kvno kvno, + krb5_keyblock *mkey) { krb5_error_code retval; krb5_db_entry master_entry; @@ -329,6 +460,14 @@ krb5_def_verify_master_key(context, mprinc, mkey) retval = KRB5_KDB_BADMASTERKEY; } + 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); krb5_xfree(tempkey.contents); krb5_db_free_principal(context, &master_entry, nprinc); diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c index cc254dd4b..357bb1246 100644 --- a/src/lib/krb5/keytab/kt_file.c +++ b/src/lib/krb5/keytab/kt_file.c @@ -37,8 +37,6 @@ /* * Constants */ -#define IGNORE_VNO 0 -#define IGNORE_ENCTYPE 0 #define KRB5_KT_VNO_1 0x0501 /* krb v5, keytab version 1 (DCE compat) */ #define KRB5_KT_VNO 0x0502 /* krb v5, keytab version 2 (standard) */ diff --git a/src/lib/krb5/keytab/kt_memory.c b/src/lib/krb5/keytab/kt_memory.c index db392e6d5..bf9634e53 100644 --- a/src/lib/krb5/keytab/kt_memory.c +++ b/src/lib/krb5/keytab/kt_memory.c @@ -39,8 +39,6 @@ /* * Constants */ -#define IGNORE_VNO 0 -#define IGNORE_ENCTYPE 0 /* * Types diff --git a/src/lib/krb5/keytab/kt_srvtab.c b/src/lib/krb5/keytab/kt_srvtab.c index e3dd00926..77546446e 100644 --- a/src/lib/krb5/keytab/kt_srvtab.c +++ b/src/lib/krb5/keytab/kt_srvtab.c @@ -30,8 +30,6 @@ /* * Constants */ -#define IGNORE_VNO 0 -#define IGNORE_ENCTYPE 0 #define KRB5_KT_VNO_1 0x0501 /* krb v5, keytab version 1 (DCE compat) */ #define KRB5_KT_VNO 0x0502 /* krb v5, keytab version 2 (standard) */ diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c index eb20a28ed..288a5a0c6 100644 --- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c +++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c @@ -845,9 +845,20 @@ void kdb5_ldap_create(argc, argv) /* Stash the master key only if '-s' option is specified */ if (do_stash || global_params.mask & KADM5_CONFIG_STASH_FILE) { + krb5_kvno mkey_kvno; + /* + * Determine the kvno to use, it must be that used to create the master + * key princ. + */ + if (global_params.mask & KADM5_CONFIG_KVNO) + mkey_kvno = global_params.kvno; /* user specified */ + else + mkey_kvno = 1; /* Default */ + retval = krb5_def_store_mkey(util_context, global_params.stash_file, master_princ, + mkey_kvno, &master_keyblock, NULL); if (retval) { com_err(progname, errno, "while storing key"); diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.M b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.M index 08463b7f8..484c4ce88 100644 --- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.M +++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.M @@ -25,7 +25,7 @@ This option is not recommended. Specifies the URI of the LDAP server. .SH COMMANDS .TP -\fBcreate\fP [\fB\-subtrees\fP\ \fIsubtree_dn_list\fP] [\fB\-sscope\fP\ \fIsearch_scope\fP] [\fB\-containerref\fP\ \fIcontainer_reference_dn\fP] [\fB\-k\fP\ \fImkeytype\fP] [\fB\-m\fP|\fB\-P\fP\ \fIpassword\fP|\fB\-sf\fP\ \fIstashfilename\fP] [\fB\-s\fP] [\fB\-r\fP\ \fIrealm\fP] [\fB\-kdcdn\fP\ \fIkdc_service_list\fP] [\fB\-admindn\fP\ \fIadmin_service_list\fP] [\fB\-maxtktlife\fP\ \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP\ \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] +\fBcreate\fP [\fB\-subtrees\fP\ \fIsubtree_dn_list\fP] [\fB\-sscope\fP\ \fIsearch_scope\fP] [\fB\-containerref\fP\ \fIcontainer_reference_dn\fP] [\fB\-k\fP\ \fImkeytype\fP] [\fB\-kv\fP\ \fImkeyVNO\fP] [\fB\-m\fP|\fB\-P\fP\ \fIpassword\fP|\fB\-sf\fP\ \fIstashfilename\fP] [\fB\-s\fP] [\fB\-r\fP\ \fIrealm\fP] [\fB\-kdcdn\fP\ \fIkdc_service_list\fP] [\fB\-admindn\fP\ \fIadmin_service_list\fP] [\fB\-maxtktlife\fP\ \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP\ \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] Creates realm in directory. Options: .RS .TP @@ -47,6 +47,10 @@ Specifies the key type of the master key in the database; the default is that given in .IR kdc.conf . .TP +\fB\-kv\fP\ \fImkeyVNO\fP +Specifies the version number of the master key in the database; the default is +1. Note that 0 is not allowed. +.TP \fB\-m\fP Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk. diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c index 704bb163e..1f900e67a 100644 --- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c +++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c @@ -116,7 +116,7 @@ void usage() "\t\t[-kdcdn kdc_service_list] [-admindn admin_service_list]\n" "\t\t[-pwddn passwd_service_list]\n" #endif -"\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-s]\n" +"\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-kv mkeyVNO] [-s]\n" "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n" "\t\t[ticket_flags] [-r realm]\n" @@ -346,10 +346,20 @@ int main(argc, argv) goto cleanup; } } else if (strcmp(*argv, "-k") == 0 && ARG_VAL) { - if (krb5_string_to_enctype(koptarg, &global_params.enctype)) - com_err(progname, 0, "%s is an invalid enctype", koptarg); - else + if (krb5_string_to_enctype(koptarg, &global_params.enctype)) { + com_err(progname, EINVAL, ": %s is an invalid enctype", koptarg); + exit_status++; + goto cleanup; + } else global_params.mask |= KADM5_CONFIG_ENCTYPE; + } else if (strcmp(*argv, "-kv") == 0 && ARG_VAL) { + global_params.kvno = (krb5_kvno) atoi(koptarg); + if (global_params.kvno == IGNORE_VNO) { + com_err(progname, EINVAL, ": %s is an invalid mkeyVNO", koptarg); + exit_status++; + goto cleanup; + } else + global_params.mask |= KADM5_CONFIG_KVNO; } else if (strcmp(*argv, "-M") == 0 && ARG_VAL) { global_params.mkey_name = koptarg; global_params.mask |= KADM5_CONFIG_MKEY_NAME; diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index 1329e8063..09bc04424 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -3,7 +3,7 @@ mydir=tests myfulldir=tests BUILDTOP=$(REL).. SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \ - gss-threads misc + gss-threads misc mkeystash_compat RUN_SETUP = @KRB5_RUN_ENV@ KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf KRB5_RUN_ENV= @KRB5_RUN_ENV@ diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c index 79112e7c2..3abef65db 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, - &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/mkeystash_compat/Makefile.in b/src/tests/mkeystash_compat/Makefile.in new file mode 100644 index 000000000..7b8956e43 --- /dev/null +++ b/src/tests/mkeystash_compat/Makefile.in @@ -0,0 +1,49 @@ +thisconfigdir=../.. +mydir=tests/mkeystash_compat +myfulldir=tests/mkeystash_compat +BUILDTOP=$(REL)..$(S).. + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf +KRB5_RUN_ENV= @KRB5_RUN_ENV@ +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +OBJS = bigendian.o +SRCS = $(srcdir)/bigendian.c + +TEST_DB = ./testdb +TEST_REALM = FOO.TEST.REALM +TEST_MKEY = footes + +KADMIN_OPTS= -d $(TEST_DB) -r $(TEST_REALM) +KDB_OPTS= $(KADMIN_OPTS) -P $(TEST_MKEY) + +check-unix:: mkeystash_check + +bigendian: $(OUTPRE)bigendian.$(OBJEXT) $(SUPPORT_DEPLIB) + $(CC_LINK) $(ALL_CFLAGS) -o bigendian $(OUTPRE)bigendian.$(OBJEXT) + +kdc.conf: Makefile + rm -rf kdc.conf + @echo "[realms]" > kdc.conf + @echo "$(TEST_REALM) = {" >> kdc.conf + @echo " key_stash_file = `pwd`/stash_file" >> kdc.conf + @echo "}" >> kdc.conf + +krb5.conf: Makefile + cat $(SRCTOP)/config-files/krb5.conf > krb5.new + +# Verify that the mkey stash code is backward compat with old/non-keytab stashfile format +mkeystash_check: kdc.conf krb5.conf bigendian + $(RM) $(TEST_DB)* stash_file + $(RUN_SETUP) $(VALGRIND) ../../kadmin/dbutil/kdb5_util $(KDB_OPTS) create -s + # overwrite keytab stash file with old format stash, depends on endianness of current test system + ./bigendian && cp $(srcdir)/old_stash_bendian stash_file || cp $(srcdir)/old_stash_lendian stash_file + # getprinc will fail if old stash file can not be read + $(RUN_SETUP) $(VALGRIND) ../../kadmin/cli/kadmin.local $(KADMIN_OPTS) -q 'getprinc K/M' + $(RUN_SETUP) $(VALGRIND) ../../kadmin/dbutil/kdb5_util $(KDB_OPTS) destroy -f + $(RM) $(TEST_DB)* stash_file + +clean:: + $(RM) kdc.conf + diff --git a/src/tests/mkeystash_compat/bigendian.c b/src/tests/mkeystash_compat/bigendian.c new file mode 100644 index 000000000..bcdeeb573 --- /dev/null +++ b/src/tests/mkeystash_compat/bigendian.c @@ -0,0 +1,17 @@ +#include + +/* + * Test to see if system is bigendian + * Returns 0 if it is big endian + * 1 if it is little endian + */ +int main() +{ + int int_var = 1; + unsigned char *char_array = (unsigned char*)&int_var; + + if (char_array[0] == 0) + return 0; /* big endian */ + else + return 1; /* little endian */ +} diff --git a/src/tests/mkeystash_compat/old_stash_bendian b/src/tests/mkeystash_compat/old_stash_bendian new file mode 100644 index 0000000000000000000000000000000000000000..7d3761fb7c903a3aa30b5a3812411d3a8acc8460 GIT binary patch literal 67 zcmZQ&VqjpfWng09bMyDt3vmq&(F<~Q^zmh2^k!i61nOo_H4tiP#PM?zd>=OW=U<|(i literal 0 HcmV?d00001 diff --git a/src/tests/verify/kdb5_verify.c b/src/tests/verify/kdb5_verify.c index 2dd19ba44..b6d7b2332 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, - &master_keyblock))) { + IGNORE_VNO, &master_keyblock))) { com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(context); return(1); -- 2.26.2