Petr Spacek notes that when we walk the keytab in lookup_etypes_for_keytab(), we don't free entries when we're finished examining them. Ensure that when krb5_kt_next_entry() succeeds, we make sure to free the entry storage before we exit the current loop iteration. (RT#7586) --- a/src/lib/krb5/krb/gic_keytab.c +++ b/src/lib/krb5/krb/gic_keytab.c @@ -110,9 +110,9 @@ lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab, goto cleanup; if (!krb5_c_valid_enctype(entry.key.enctype)) - continue; + goto next_entry; if (!krb5_principal_compare(context, entry.principal, client)) - continue; + goto next_entry; /* Make sure our list is for the highest kvno found for client. */ if (entry.vno > max_kvno) { free(etypes); @@ -120,11 +120,12 @@ lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab, count = 0; max_kvno = entry.vno; } else if (entry.vno != max_kvno) - continue; + goto next_entry; /* Leave room for the terminator and possibly a second entry. */ p = realloc(etypes, (count + 3) * sizeof(*etypes)); if (p == NULL) { + krb5_free_keytab_entry_contents(context, &entry); ret = ENOMEM; goto cleanup; } @@ -136,6 +137,8 @@ lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab, entry.key.enctype == ENCTYPE_DES_CBC_MD4) etypes[count++] = ENCTYPE_DES_CBC_CRC; etypes[count] = 0; +next_entry: + krb5_free_keytab_entry_contents(context, &entry); } ret = 0;