Handle migration from pre-1.7 databases with master key kvno != 1
[krb5.git] / src / lib / kdb / kdb5.c
index cd9f7169747b7b8a007ae2476b081ba36fc80761..83dde5137dde5a393376dff2793d73e6f56f5857 100644 (file)
@@ -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);
@@ -1863,6 +1863,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,