pull up r23676 from trunk
authorTom Yu <tlyu@mit.edu>
Tue, 23 Mar 2010 01:31:30 +0000 (01:31 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 23 Mar 2010 01:31:30 +0000 (01:31 +0000)
 ------------------------------------------------------------------------
 r23676 | ghudson | 2010-01-28 13:39:31 -0800 (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.

ticket: 6650

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-7@23822 dc483132-0cff-0310-8789-dd5450dbe970

src/include/kdb.h
src/kadmin/dbutil/kdb5_mkey.c
src/lib/kadm5/srv/svr_principal.c
src/lib/kdb/kdb5.c
src/lib/kdb/libkdb5.exports

index ea81cfeef156cefe934b814445b0e38e0983d117..936598516dbb9f21c952be9ad8235440e124aba6 100644 (file)
@@ -421,11 +421,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,
index 4916de2cbd658df389f898fdd0517e60075bd96d..d236c8964814327203b22c2bca1f55e2bf213c2f 100644 (file)
@@ -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, retval, "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,
index f0fe849bbc92b72d6f62bb58fdd443f4d1d151d4..5b19af8a11add968b34d4f6a471e3d7d67406db2 100644 (file)
@@ -868,7 +868,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;
 
index ed85d89a6215638d2aa9099858015f6115ea6afb..c2708f8b8bf513bc5d3c3e08395cdc5c1de48996 100644 (file)
@@ -2007,7 +2007,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);
 
@@ -2304,8 +2304,8 @@ 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 */
-       return (0);
+       *mkvno = 0; /* Indicates KRB5_TL_MKVNO data not present */
+        return (0);
     } else if (tl_data.tl_data_length != 2) {
        return (KRB5_KDB_TRUNCATED_RECORD);
     }
@@ -2315,6 +2315,38 @@ krb5_dbe_lookup_mkvno(krb5_context       context,
     return (0);
 }
 
+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,
index a1fd4d5e83487e3b1e0f2c86407287edd395b754..343ae9899232d641663d8e9a2f635a566128d388 100644 (file)
@@ -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