krb5_wrap: fix keep_old_entries logic in smb_krb5_kt_seek_and_delete_old_entries()
authorRalph Boehme <slow@samba.org>
Thu, 21 Apr 2016 18:55:36 +0000 (20:55 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 25 Apr 2016 08:35:14 +0000 (10:35 +0200)
This fixes an regression introduced in 5c5d586d3ebd40 at a higher level
in the caller smb_krb5_kt_add_entry(): calling smb_krb5_kt_add_entry
with keep_old_entries=false resulted in only one enctype per principal
remaining in the exported keytab.

The function smb_krb5_kt_seek_and_delete_old_entries() is called from
smb_krb5_kt_add_entry() when adding keys to a keytab. When the keytab
contains keys with the same kvno as the key to be added and
keep_old_entries is false, the key is deleted without checking the
encryption type of the key. This means that when adding keys for a
principal only the last enctype will be in the exported keytab.

Fix this by checking the encryption type and only treat a key as "old"
if keytab_key_kvno <= new_key_kvno and keytab_key_enctype ==
new_key_enctype.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
lib/krb5_wrap/krb5_samba.c

index ea1f2d18b5c30f36093feffebb28bb18a2ad47cb..d1e60eb23cdc5534f72c79c1897a9d0ad7733b1f 100644 (file)
@@ -1519,6 +1519,8 @@ krb5_error_code smb_krb5_kt_seek_and_delete_old_entries(krb5_context context,
        DEBUG(3, (__location__ ": Will try to delete old keytab entries\n"));
        while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
                bool name_ok = false;
+               krb5_enctype kt_entry_enctype =
+                       smb_get_enctype_from_kt_entry(&kt_entry);
 
                if (!flush && (princ_s != NULL)) {
                        ret = smb_krb5_unparse_name(tmp_ctx, context,
@@ -1588,6 +1590,16 @@ krb5_error_code smb_krb5_kt_seek_and_delete_old_entries(krb5_context context,
                        continue;
                }
 
+               if (!flush &&
+                   (kt_entry.vno == kvno) &&
+                   (kt_entry_enctype != enctype))
+               {
+                       DEBUG(5, (__location__ ": Saving entry with kvno [%d] "
+                                 "enctype [%d] for principal: %s.\n",
+                                 kvno, kt_entry_enctype, princ_s));
+                       continue;
+               }
+
                DEBUG(5, (__location__ ": Found old entry for principal: %s "
                          "(kvno %d) - trying to remove it.\n",
                          princ_s, kt_entry.vno));