commit 56890d866fc431a7e8f2e2c06edac70f034ef177 Author: tlyu tlyu@dc483132-0cff-0310-8789-dd5450dbe970 Date: Mon Feb 8 20:55:27 2010 +0000
ticket: 6651 version_fixed: 1.8 status: resolved
pull up r23676, r23679 from trunk
------------------------------------------------------------------------ r23679 | ghudson | 2010-01-31 16:04:48 -0500 (Sun, 31 Jan 2010) | 4 lines
ticket: 6650
Fix minor error-handling bug in r23676.
------------------------------------------------------------------------ r23676 | ghudson | 2010-01-28 16:39:31 -0500 (Thu, 28 Jan 2010) | 17 lines
ticket: 6650 subject: Handle migration from pre-1.7 databases with master key kvno != 1 target_version: 1.7.1 tags: pullup
krb5_dbe_lookup_mkvno assumes an mkvno of 1 for entries with no explicit tl_data. We've seen at least one pre-1.7 KDB with a master kvno of 0, violating this assumption. Fix this as follows:
* krb5_dbe_lookup_mkvno outputs 0 instead of 1 if no tl_data exists. * A new function krb5_dbe_get_mkvno translates this 0 value to the minimum version number in the mkey_list. (krb5_dbe_lookup_mkvno cannot do this as it doesn't take the mkey_list as a parameter.) * Call sites to krb5_dbe_lookup_mkvno are converted to krb5_dbe_get_mkvno, except for an LDAP case where it is acceptable to store 0 if the mkvno is unknown.
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-8@23703 dc483132-0cff-0310-8789-dd5450dbe970
src/include/kdb.h | 8 ++++++++ src/kadmin/dbutil/kdb5_mkey.c | 10 ++++++++-- src/lib/kadm5/srv/svr_principal.c | 3 ++- src/lib/kdb/kdb5.c | 36 ++++++++++++++++++++++++++++++++++-- src/lib/kdb/libkdb5.exports | 1 + 5 files changed, 53 insertions(+), 5 deletions(-) --- diff --git a/src/include/kdb.h b/src/include/kdb.h index fe0166b..be73939 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -556,11 +556,19 @@ krb5_dbe_find_mkey( krb5_context context, krb5_db_entry * entry, krb5_keyblock ** mkey);
+/* Set *mkvno to mkvno in entry tl_data, or 0 if not present. */ krb5_error_code krb5_dbe_lookup_mkvno( krb5_context context, krb5_db_entry * entry, krb5_kvno * mkvno);
+/* Set *mkvno to mkvno in entry tl_data, or minimum value from mkey_list. */ +krb5_error_code +krb5_dbe_get_mkvno( krb5_context context, + krb5_db_entry * entry, + krb5_keylist_node * mkey_list, + krb5_kvno * mkvno); + krb5_error_code krb5_dbe_lookup_mod_princ_data( krb5_context context, krb5_db_entry * entry, diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c index 9ea7e5e..83a23ef 100644 --- a/src/kadmin/dbutil/kdb5_mkey.c +++ b/src/kadmin/dbutil/kdb5_mkey.c @@ -866,7 +866,7 @@ update_princ_encryption_1(void *cb, krb5_db_entry *ent) goto skip; } p->re_match_count++; - retval = krb5_dbe_lookup_mkvno(util_context, ent, &old_mkvno); + retval = krb5_dbe_get_mkvno(util_context, ent, master_keylist, &old_mkvno); if (retval) { com_err(progname, retval, "determining master key used for principal '%s'", @@ -1137,7 +1137,7 @@ find_mkvnos_in_use(krb5_pointer ptr,
args = (struct purge_args *) ptr;
- retval = krb5_dbe_lookup_mkvno(args->kcontext, entry, &mkvno); + retval = krb5_dbe_get_mkvno(args->kcontext, entry, master_keylist, &mkvno); if (retval) return (retval);
@@ -1193,6 +1193,12 @@ kdb5_purge_mkeys(int argc, char *argv[]) } }
+ if (master_keylist == NULL) { + com_err(progname, 0, "master keylist not initialized"); + exit_status++; + return; + } + /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(util_context, global_params.mkey_name, diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 2f2faaa..a01f072 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -874,7 +874,8 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, if (kdb.key_data[i].key_data_kvno > entry->kvno) entry->kvno = kdb.key_data[i].key_data_kvno;
- ret = krb5_dbe_lookup_mkvno(handle->context, &kdb, &entry->mkvno); + ret = krb5_dbe_get_mkvno(handle->context, &kdb, master_keylist, + &entry->mkvno); if (ret) goto done;
diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index cd9f716..83dde51 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -1591,7 +1591,7 @@ krb5_dbe_find_mkey(krb5_context context, krb5_error_code retval; krb5_keylist_node *cur_keyblock = mkey_list;
- retval = krb5_dbe_lookup_mkvno(context, entry, &mkvno); + retval = krb5_dbe_get_mkvno(context, entry, mkey_list, &mkvno); if (retval) return (retval);
@@ -1852,7 +1852,7 @@ krb5_dbe_lookup_mkvno(krb5_context context, return (code);
if (tl_data.tl_data_length == 0) { - *mkvno = 1; /* default for princs that lack the KRB5_TL_MKVNO data */ + *mkvno = 0; /* Indicates KRB5_TL_MKVNO data not present */ return (0); } else if (tl_data.tl_data_length != 2) { return (KRB5_KDB_TRUNCATED_RECORD); @@ -1864,6 +1864,38 @@ krb5_dbe_lookup_mkvno(krb5_context context, }
krb5_error_code +krb5_dbe_get_mkvno(krb5_context context, + krb5_db_entry * entry, + krb5_keylist_node * mkey_list, + krb5_kvno * mkvno) +{ + krb5_error_code code; + krb5_kvno kvno; + + if (mkey_list == NULL) + return EINVAL; + + /* Output the value from entry tl_data if present. */ + code = krb5_dbe_lookup_mkvno(context, entry, &kvno); + if (code != 0) + return code; + if (kvno != 0) { + *mkvno = kvno; + return 0; + } + + /* Determine the minimum kvno in mkey_list and output that. */ + kvno = (krb5_kvno) -1; + while (mkey_list != NULL) { + if (mkey_list->kvno < kvno) + kvno = mkey_list->kvno; + mkey_list = mkey_list->next; + } + *mkvno = kvno; + return 0; +} + +krb5_error_code krb5_dbe_update_mkvno(krb5_context context, krb5_db_entry * entry, krb5_kvno mkvno) diff --git a/src/lib/kdb/libkdb5.exports b/src/lib/kdb/libkdb5.exports index b493df0..8f0644b 100644 --- a/src/lib/kdb/libkdb5.exports +++ b/src/lib/kdb/libkdb5.exports @@ -43,6 +43,7 @@ krb5_dbe_free_actkvno_list krb5_dbe_free_key_data_contents krb5_dbe_free_mkey_aux_list krb5_dbe_free_key_list +krb5_dbe_get_mkvno krb5_dbe_lookup_last_pwd_change krb5_dbe_lookup_actkvno krb5_dbe_lookup_mkey_aux