diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c index ff89a90d5..0c2f5cf53 100644 --- a/lib/krb5/init_creds_pw.c +++ b/lib/krb5/init_creds_pw.c @@ -398,6 +398,9 @@ get_init_creds_common(krb5_context context, } } if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { + if (ctx->etypes) + free(ctx->etypes); + etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); if (etypes == NULL) { @@ -1417,10 +1420,17 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_keytab keytab) { krb5_keytab_key_proc_args *a; + krb5_keytab_entry entry; + krb5_kt_cursor cursor; + krb5_enctype *etypes = NULL; + krb5_error_code ret; + size_t netypes = 0; + int kvno = 0; a = malloc(sizeof(*a)); if (a == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + krb5_set_error_message(context, ENOMEM, + N_("malloc: out of memory", "")); return ENOMEM; } @@ -1431,6 +1441,58 @@ krb5_init_creds_set_keytab(krb5_context context, ctx->keyseed = (void *)a; ctx->keyproc = keytab_key_proc; + /* + * We need to the KDC what enctypes we support for this keytab, + * esp if the keytab is really a password based entry, then the + * KDC might have more enctypes in the database then what we have + * in the keytab. + */ + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if(ret) + goto out; + + while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0){ + void *ptr; + + if (!krb5_principal_compare(context, entry.principal, ctx->cred.client)) + goto next; + + /* check if we ahve this kvno already */ + if (entry.vno > kvno) { + /* remove old list of etype */ + if (etypes) + free(etypes); + netypes = 0; + kvno = entry.vno; + } else if (entry.vno != kvno) + goto next; + + /* check if enctype is supported */ + if (krb5_enctype_valid(context, entry.keyblock.keytype) != 0) + goto next; + + /* add enctype to supported list */ + ptr = realloc(etypes, sizeof(etypes[0]) * (netypes + 1)); + if (ptr == NULL) + goto next; + + etypes = ptr; + etypes[netypes] = entry.keyblock.keytype; + etypes[netypes + 1] = 0; + netypes++; + next: + krb5_kt_free_entry(context, &entry); + } + krb5_kt_end_seq_get(context, keytab, &cursor); + + if (etypes) { + if (ctx->etypes) + free(ctx->etypes); + ctx->etypes = etypes; + } + + out: return 0; } diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in index 237e099f5..ead3dde66 100644 --- a/tests/kdc/check-kdc.in +++ b/tests/kdc/check-kdc.in @@ -113,6 +113,7 @@ ${kadmin} add -p bar --use-defaults bar@${R} || exit 1 ${kadmin} add -p foo --use-defaults remove@${R} || exit 1 ${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1 ${kadmin} add -p kaka --use-defaults ${server}-des3@${R} || exit 1 +${kadmin} add -p kaka --use-defaults kt-des3@${R} || exit 1 ${kadmin} add -p foo --use-defaults ${ps} || exit 1 ${kadmin} modify --attributes=+trusted-for-delegation ${ps} || exit 1 ${kadmin} modify --constrained-delegation=${server} ${ps} || exit 1 @@ -157,6 +158,12 @@ enctypes=`grep Keytypes: tempfile | sed 's/(pw-salt)//g' | sed 's/,//g' | sed 's enctype_sans_aes=`echo $enctypes | sed 's/aes[^ ]*//g'` enctype_sans_des3=`echo $enctypes | sed 's/des3-cbc-sha1//g'` +echo "deleting all but des enctypes on kt-des3 in keytab" +${kadmin} ext -k ${keytab} kt-des3@${R} || exit 1 +for a in ${enctype_sans_des3} ; do + ${ktutil} -k ${keytab} remove -p kt-des3@${R} -e $a +done + echo foo > ${objdir}/foopassword echo Starting kdc @@ -274,6 +281,12 @@ ${klist} | grep "Principal: ${server}" > /dev/null || \ { ec=1 ; eval "${testfailed}"; } ${kdestroy} +echo "Getting key for key that are a subset in keytab compared to kdb" +${kinit} --keytab=${keytab} kt-des3@${R} +${klist} | grep "Principal: kt-des3" > /dev/null || \ + { ec=1 ; eval "${testfailed}"; } +${kdestroy} + echo "initial tickets for deleted user test case"; > messages.log ${kinit} --password-file=${objdir}/foopassword remove@$R || \ { ec=1 ; eval "${testfailed}"; }