diff --git a/lib/krb5/keytab.c b/lib/krb5/keytab.c index 4242e6f48..8ea0775b8 100644 --- a/lib/krb5/keytab.c +++ b/lib/krb5/keytab.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -262,6 +262,7 @@ krb5_kt_compare(krb5_context context, /* * Retrieve the keytab entry for `principal, kvno, enctype' into `entry' * from the keytab `id'. + * kvno == 0 is a wildcard and gives the keytab with the highest vno. * Return 0 or an error. */ @@ -287,7 +288,10 @@ krb5_kt_get_entry(krb5_context context, entry->vno = 0; while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) { if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) { - if (kvno == tmp.vno) { + /* the file keytab might only store the lower 8 bits of + the kvno, so only compare those bits */ + if (kvno == tmp.vno + || (tmp.vno < 256 && kvno % 256 == tmp.vno)) { krb5_kt_copy_entry_contents (context, &tmp, entry); krb5_kt_free_entry (context, &tmp); krb5_kt_end_seq_get(context, id, &cursor); @@ -310,16 +314,19 @@ krb5_kt_get_entry(krb5_context context, krb5_kt_get_name (context, id, kt_name, sizeof(kt_name)); krb5_set_error_string (context, - "failed to find %s in keytab %s", - princ, kt_name); + "failed to find %s%s%d%s in keytab %s", + princ, + kvno ? "(" : "", + kvno, + kvno ? ")" : "", + kt_name); return KRB5_KT_NOTFOUND; } } /* * Copy the contents of `in' into `out'. - * Return 0 or an error. - */ + * Return 0 or an error. */ krb5_error_code krb5_kt_copy_entry_contents(krb5_context context, diff --git a/lib/krb5/keytab_file.c b/lib/krb5/keytab_file.c index 46df3f031..e9800b762 100644 --- a/lib/krb5/keytab_file.c +++ b/lib/krb5/keytab_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -376,6 +376,13 @@ loop: ret = krb5_kt_ret_keyblock (context, cursor->sp, &entry->keyblock); if (ret) goto out; + /* there might be a 32 bit kvno here + * if it's zero, assume that the 8bit one was right, + * otherwise trust the new value */ + ret = krb5_ret_int32(cursor->sp, &tmp32); + if (ret == 0 && tmp32 != 0) { + entry->vno = tmp32; + } if(start) *start = pos; if(end) *end = *start + 4 + len; out: @@ -482,7 +489,7 @@ fkt_add_entry(krb5_context context, krb5_storage_free(emem); goto out; } - ret = krb5_store_int8 (emem, entry->vno); + ret = krb5_store_int8 (emem, entry->vno % 256); if(ret) { krb5_storage_free(emem); goto out; @@ -492,6 +499,12 @@ fkt_add_entry(krb5_context context, krb5_storage_free(emem); goto out; } + ret = krb5_store_int32 (emem, entry->vno); + if (ret) { + krb5_storage_free(emem); + goto out; + } + ret = krb5_storage_to_data(emem, &keytab); krb5_storage_free(emem); if(ret)