Nalin Dahyabhai 037ab92
(Had to drop the changes to src/tests/t_keytab.py, which didn't exist in 1.10.)
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
commit d1da158f47ea604bed4d5db5e98a976a9e54ccd0
Nalin Dahyabhai 037ab92
Author: Greg Hudson <ghudson@mit.edu>
Nalin Dahyabhai 037ab92
Date:   Thu Apr 19 17:55:10 2012 +0000
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
    Unify krb5_get_init_creds_keytab code paths
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    Use krb5_init_creds_set_keytab in krb5_get_init_creds_keytab, so that
Nalin Dahyabhai 037ab92
    processing added to the former will be used by the latter.  This is
Nalin Dahyabhai 037ab92
    slightly awkward because of the way we do the use_master fallback, in
Nalin Dahyabhai 037ab92
    that we have to duplicate some of krb5int_get_init_creds.
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    Based on a patch from Stef Walter.
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25817 dc483132-0cff-0310-8789-dd5450dbe970
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
diff --git a/src/lib/krb5/krb/deps b/src/lib/krb5/krb/deps
Nalin Dahyabhai 037ab92
index fe2d54c..8c4db77 100644
Nalin Dahyabhai 037ab92
--- a/src/lib/krb5/krb/deps
Nalin Dahyabhai 037ab92
+++ b/src/lib/krb5/krb/deps
Nalin Dahyabhai 037ab92
@@ -473,7 +473,8 @@ gic_keytab.so gic_keytab.po $(OUTPRE)gic_keytab.$(OBJEXT): \
Nalin Dahyabhai 037ab92
   $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
Nalin Dahyabhai 037ab92
   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
Nalin Dahyabhai 037ab92
   $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
Nalin Dahyabhai 037ab92
-  $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h
Nalin Dahyabhai 037ab92
+  $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h \
Nalin Dahyabhai 037ab92
+  int-proto.h
Nalin Dahyabhai 037ab92
 gic_opt.so gic_opt.po $(OUTPRE)gic_opt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
Nalin Dahyabhai 037ab92
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
Nalin Dahyabhai 037ab92
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
Nalin Dahyabhai 037ab92
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
Nalin Dahyabhai 037ab92
index aaabc4e..681b648 100644
Nalin Dahyabhai 037ab92
--- a/src/lib/krb5/krb/get_in_tkt.c
Nalin Dahyabhai 037ab92
+++ b/src/lib/krb5/krb/get_in_tkt.c
Nalin Dahyabhai 037ab92
@@ -542,10 +542,9 @@ krb5_init_creds_free(krb5_context context,
Nalin Dahyabhai 037ab92
     free(ctx);
Nalin Dahyabhai 037ab92
 }
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
-static krb5_error_code
Nalin Dahyabhai 037ab92
-init_creds_get(krb5_context context,
Nalin Dahyabhai 037ab92
-               krb5_init_creds_context ctx,
Nalin Dahyabhai 037ab92
-               int *use_master)
Nalin Dahyabhai 037ab92
+krb5_error_code
Nalin Dahyabhai 037ab92
+k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
Nalin Dahyabhai 037ab92
+                  int *use_master)
Nalin Dahyabhai 037ab92
 {
Nalin Dahyabhai 037ab92
     krb5_error_code code;
Nalin Dahyabhai 037ab92
     krb5_data request;
Nalin Dahyabhai 037ab92
@@ -599,7 +598,7 @@ krb5_init_creds_get(krb5_context context,
Nalin Dahyabhai 037ab92
 {
Nalin Dahyabhai 037ab92
     int use_master = 0;
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
-    return init_creds_get(context, ctx, &use_master);
Nalin Dahyabhai 037ab92
+    return k5_init_creds_get(context, ctx, &use_master);
Nalin Dahyabhai 037ab92
 }
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
 krb5_error_code KRB5_CALLCONV
Nalin Dahyabhai 037ab92
@@ -1664,7 +1663,7 @@ krb5int_get_init_creds(krb5_context context,
Nalin Dahyabhai 037ab92
             goto cleanup;
Nalin Dahyabhai 037ab92
     }
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
-    code = init_creds_get(context, ctx, use_master);
Nalin Dahyabhai 037ab92
+    code = k5_init_creds_get(context, ctx, use_master);
Nalin Dahyabhai 037ab92
     if (code != 0)
Nalin Dahyabhai 037ab92
         goto cleanup;
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
index 88de6a8..e59177f 100644
Nalin Dahyabhai 037ab92
--- a/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
+++ b/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
@@ -26,6 +26,7 @@
Nalin Dahyabhai 037ab92
 #ifndef LEAN_CLIENT
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
 #include "k5-int.h"
Nalin Dahyabhai 037ab92
+#include "int-proto.h"
Nalin Dahyabhai 037ab92
 #include "init_creds_ctx.h"
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
 static krb5_error_code
Nalin Dahyabhai 037ab92
@@ -87,6 +88,44 @@ krb5_init_creds_set_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
     return 0;
Nalin Dahyabhai 037ab92
 }
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
+static krb5_error_code
Nalin Dahyabhai 037ab92
+get_init_creds_keytab(krb5_context context, krb5_creds *creds,
Nalin Dahyabhai 037ab92
+                      krb5_principal client, krb5_keytab keytab,
Nalin Dahyabhai 037ab92
+                      krb5_deltat start_time, char *in_tkt_service,
Nalin Dahyabhai 037ab92
+                      krb5_get_init_creds_opt *options, int *use_master)
Nalin Dahyabhai 037ab92
+{
Nalin Dahyabhai 037ab92
+    krb5_error_code ret;
Nalin Dahyabhai 037ab92
+    krb5_init_creds_context ctx = NULL;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    ret = krb5_init_creds_init(context, client, NULL, NULL, start_time,
Nalin Dahyabhai 037ab92
+                               options, &ctx;;
Nalin Dahyabhai 037ab92
+    if (ret != 0)
Nalin Dahyabhai 037ab92
+        goto cleanup;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    if (in_tkt_service) {
Nalin Dahyabhai 037ab92
+        ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
Nalin Dahyabhai 037ab92
+        if (ret != 0)
Nalin Dahyabhai 037ab92
+            goto cleanup;
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    ret = krb5_init_creds_set_keytab(context, ctx, keytab);
Nalin Dahyabhai 037ab92
+    if (ret != 0)
Nalin Dahyabhai 037ab92
+        goto cleanup;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    ret = k5_init_creds_get(context, ctx, use_master);
Nalin Dahyabhai 037ab92
+    if (ret != 0)
Nalin Dahyabhai 037ab92
+        goto cleanup;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    ret = krb5_init_creds_get_creds(context, ctx, creds);
Nalin Dahyabhai 037ab92
+    if (ret != 0)
Nalin Dahyabhai 037ab92
+        goto cleanup;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+cleanup:
Nalin Dahyabhai 037ab92
+    krb5_init_creds_free(context, ctx);
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    return ret;
Nalin Dahyabhai 037ab92
+}
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
 krb5_error_code KRB5_CALLCONV
Nalin Dahyabhai 037ab92
 krb5_get_init_creds_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
                            krb5_creds *creds,
Nalin Dahyabhai 037ab92
@@ -111,10 +150,8 @@ krb5_get_init_creds_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
     /* first try: get the requested tkt from any kdc */
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
-    ret = krb5int_get_init_creds(context, creds, client, NULL, NULL,
Nalin Dahyabhai 037ab92
-                                 start_time, in_tkt_service, options,
Nalin Dahyabhai 037ab92
-                                 get_as_key_keytab, (void *) keytab,
Nalin Dahyabhai 037ab92
-                                 &use_master,NULL);
Nalin Dahyabhai 037ab92
+    ret = get_init_creds_keytab(context, creds, client, keytab, start_time,
Nalin Dahyabhai 037ab92
+                                in_tkt_service, options, &use_master);
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
     /* check for success */
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
@@ -132,10 +169,9 @@ krb5_get_init_creds_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
     if (!use_master) {
Nalin Dahyabhai 037ab92
         use_master = 1;
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
-        ret2 = krb5int_get_init_creds(context, creds, client, NULL, NULL,
Nalin Dahyabhai 037ab92
-                                      start_time, in_tkt_service, options,
Nalin Dahyabhai 037ab92
-                                      get_as_key_keytab, (void *) keytab,
Nalin Dahyabhai 037ab92
-                                      &use_master, NULL);
Nalin Dahyabhai 037ab92
+        ret2 = get_init_creds_keytab(context, creds, client, keytab,
Nalin Dahyabhai 037ab92
+                                     start_time, in_tkt_service, options,
Nalin Dahyabhai 037ab92
+                                     &use_master);
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
         if (ret2 == 0) {
Nalin Dahyabhai 037ab92
             ret = 0;
Nalin Dahyabhai 037ab92
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
Nalin Dahyabhai 037ab92
index 6b16095..899579f 100644
Nalin Dahyabhai 037ab92
--- a/src/lib/krb5/krb/int-proto.h
Nalin Dahyabhai 037ab92
+++ b/src/lib/krb5/krb/int-proto.h
Nalin Dahyabhai 037ab92
@@ -196,4 +196,8 @@ krb5int_mk_setpw_req(krb5_context context, krb5_auth_context auth_context,
Nalin Dahyabhai 037ab92
 void
Nalin Dahyabhai 037ab92
 k5_ccselect_free_context(krb5_context context);
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
+krb5_error_code
Nalin Dahyabhai 037ab92
+k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
Nalin Dahyabhai 037ab92
+                  int *use_master);
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
 #endif /* KRB5_INT_FUNC_PROTO__ */
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
commit 8230c4b7b7323cdef2a6c877deb710a15380f40f
Nalin Dahyabhai 037ab92
Author: Greg Hudson <ghudson@mit.edu>
Nalin Dahyabhai 037ab92
Date:   Thu Apr 19 17:55:14 2012 +0000
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
    Use etypes from keytab in krb5_gic_keytab
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    When getting initial credentials with a keytab, filter the list of
Nalin Dahyabhai 037ab92
    request enctypes based on the keys in the keytab.
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    Based on a patch from Stef Walter.
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    ticket: 2131
Nalin Dahyabhai 037ab92
    
Nalin Dahyabhai 037ab92
    git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25818 dc483132-0cff-0310-8789-dd5450dbe970
Nalin Dahyabhai 037ab92
Nalin Dahyabhai 037ab92
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
Nalin Dahyabhai 037ab92
index 3749cf9..36eb23b 100644
Nalin Dahyabhai 037ab92
--- a/src/include/k5-trace.h
Nalin Dahyabhai 037ab92
+++ b/src/include/k5-trace.h
Nalin Dahyabhai 037ab92
@@ -187,6 +187,10 @@
Nalin Dahyabhai 037ab92
 #define TRACE_INIT_CREDS_GAK(c, salt, s2kparams)                        \
Nalin Dahyabhai 037ab92
     TRACE(c, (c, "Getting AS key, salt \"{data}\", params \"{data}\"",  \
Nalin Dahyabhai 037ab92
               salt, s2kparams))
Nalin Dahyabhai 037ab92
+#define TRACE_INIT_CREDS_KEYTAB_LOOKUP(c, etypes)                       \
Nalin Dahyabhai 037ab92
+    TRACE(c, (c, "Looked up etypes in keytab: {etypes}", etypes))
Nalin Dahyabhai 037ab92
+#define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code)                  \
Nalin Dahyabhai 037ab92
+    TRACE(c, (c, "Couldn't lookup etypes in keytab: {kerr}", code))
Nalin Dahyabhai 037ab92
 #define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code)                  \
Nalin Dahyabhai 037ab92
     TRACE(c, (c, "Decrypt with preauth AS key failed: {kerr}", code))
Nalin Dahyabhai 037ab92
 #define TRACE_INIT_CREDS_RESTART_FAST(c)                \
Nalin Dahyabhai 037ab92
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
index e59177f..3554b25 100644
Nalin Dahyabhai 037ab92
--- a/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
+++ b/src/lib/krb5/krb/gic_keytab.c
Nalin Dahyabhai 037ab92
@@ -77,14 +77,132 @@ get_as_key_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
     return(ret);
Nalin Dahyabhai 037ab92
 }
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
+/* Return the list of etypes available for client in keytab. */
Nalin Dahyabhai 037ab92
+static krb5_error_code
Nalin Dahyabhai 037ab92
+lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab,
Nalin Dahyabhai 037ab92
+                         krb5_principal client, krb5_enctype **etypes_out)
Nalin Dahyabhai 037ab92
+{
Nalin Dahyabhai 037ab92
+    krb5_kt_cursor cursor;
Nalin Dahyabhai 037ab92
+    krb5_keytab_entry entry;
Nalin Dahyabhai 037ab92
+    krb5_enctype *p, *etypes = NULL;
Nalin Dahyabhai 037ab92
+    krb5_kvno max_kvno = 0;
Nalin Dahyabhai 037ab92
+    krb5_error_code ret;
Nalin Dahyabhai 037ab92
+    size_t count = 0;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    *etypes_out = NULL;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    if (keytab->ops->start_seq_get == NULL)
Nalin Dahyabhai 037ab92
+        return EINVAL;
Nalin Dahyabhai 037ab92
+    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
Nalin Dahyabhai 037ab92
+    if (ret != 0)
Nalin Dahyabhai 037ab92
+        return ret;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    for (;;) {
Nalin Dahyabhai 037ab92
+        ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
Nalin Dahyabhai 037ab92
+        if (ret == KRB5_KT_END)
Nalin Dahyabhai 037ab92
+            break;
Nalin Dahyabhai 037ab92
+        if (ret)
Nalin Dahyabhai 037ab92
+            goto cleanup;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+        if (!krb5_c_valid_enctype(entry.key.enctype))
Nalin Dahyabhai 037ab92
+            continue;
Nalin Dahyabhai 037ab92
+        if (!krb5_principal_compare(context, entry.principal, client))
Nalin Dahyabhai 037ab92
+            continue;
Nalin Dahyabhai 037ab92
+        /* Make sure our list is for the highest kvno found for client. */
Nalin Dahyabhai 037ab92
+        if (entry.vno > max_kvno) {
Nalin Dahyabhai 037ab92
+            free(etypes);
Nalin Dahyabhai 037ab92
+            etypes = NULL;
Nalin Dahyabhai 037ab92
+            count = 0;
Nalin Dahyabhai 037ab92
+            max_kvno = entry.vno;
Nalin Dahyabhai 037ab92
+        } else if (entry.vno != max_kvno)
Nalin Dahyabhai 037ab92
+            continue;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+        /* Leave room for the terminator and possibly a second entry. */
Nalin Dahyabhai 037ab92
+        p = realloc(etypes, (count + 3) * sizeof(*etypes));
Nalin Dahyabhai 037ab92
+        if (p == NULL) {
Nalin Dahyabhai 037ab92
+            ret = ENOMEM;
Nalin Dahyabhai 037ab92
+            goto cleanup;
Nalin Dahyabhai 037ab92
+        }
Nalin Dahyabhai 037ab92
+        etypes = p;
Nalin Dahyabhai 037ab92
+        etypes[count++] = entry.key.enctype;
Nalin Dahyabhai 037ab92
+        /* All DES key types work with des-cbc-crc, which is more likely to be
Nalin Dahyabhai 037ab92
+         * accepted by the KDC (since MIT KDCs refuse des-cbc-md5). */
Nalin Dahyabhai 037ab92
+        if (entry.key.enctype == ENCTYPE_DES_CBC_MD5 ||
Nalin Dahyabhai 037ab92
+            entry.key.enctype == ENCTYPE_DES_CBC_MD4)
Nalin Dahyabhai 037ab92
+            etypes[count++] = ENCTYPE_DES_CBC_CRC;
Nalin Dahyabhai 037ab92
+        etypes[count] = 0;
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    ret = 0;
Nalin Dahyabhai 037ab92
+    *etypes_out = etypes;
Nalin Dahyabhai 037ab92
+    etypes = NULL;
Nalin Dahyabhai 037ab92
+cleanup:
Nalin Dahyabhai 037ab92
+    krb5_kt_end_seq_get(context, keytab, &cursor);
Nalin Dahyabhai 037ab92
+    free(etypes);
Nalin Dahyabhai 037ab92
+    return ret;
Nalin Dahyabhai 037ab92
+}
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+/* Return true if search_for is in etype_list. */
Nalin Dahyabhai 037ab92
+static krb5_boolean
Nalin Dahyabhai 037ab92
+check_etypes_have(krb5_enctype *etype_list, krb5_enctype search_for)
Nalin Dahyabhai 037ab92
+{
Nalin Dahyabhai 037ab92
+    int i;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    if (!etype_list)
Nalin Dahyabhai 037ab92
+        return FALSE;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    for (i = 0; etype_list[i] != 0; i++) {
Nalin Dahyabhai 037ab92
+        if (etype_list[i] == search_for)
Nalin Dahyabhai 037ab92
+            return TRUE;
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    return FALSE;
Nalin Dahyabhai 037ab92
+}
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
 krb5_error_code KRB5_CALLCONV
Nalin Dahyabhai 037ab92
 krb5_init_creds_set_keytab(krb5_context context,
Nalin Dahyabhai 037ab92
                            krb5_init_creds_context ctx,
Nalin Dahyabhai 037ab92
                            krb5_keytab keytab)
Nalin Dahyabhai 037ab92
 {
Nalin Dahyabhai 037ab92
+    krb5_enctype *etype_list;
Nalin Dahyabhai 037ab92
+    krb5_error_code ret;
Nalin Dahyabhai 037ab92
+    int i, j;
Nalin Dahyabhai 037ab92
+    char *name;
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
     ctx->gak_fct = get_as_key_keytab;
Nalin Dahyabhai 037ab92
     ctx->gak_data = keytab;
Nalin Dahyabhai 037ab92
 
Nalin Dahyabhai 037ab92
+    ret = lookup_etypes_for_keytab(context, keytab, ctx->request->client,
Nalin Dahyabhai 037ab92
+                                   &etype_list);
Nalin Dahyabhai 037ab92
+    if (ret) {
Nalin Dahyabhai 037ab92
+        TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(context, ret);
Nalin Dahyabhai 037ab92
+        return 0;
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    TRACE_INIT_CREDS_KEYTAB_LOOKUP(context, etype_list);
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    /* Filter the ktypes list based on what's in the keytab */
Nalin Dahyabhai 037ab92
+    for (i = 0, j = 0; i < ctx->request->nktypes; i++) {
Nalin Dahyabhai 037ab92
+        if (check_etypes_have(etype_list, ctx->request->ktype[i])) {
Nalin Dahyabhai 037ab92
+            ctx->request->ktype[j] = ctx->request->ktype[i];
Nalin Dahyabhai 037ab92
+            j++;
Nalin Dahyabhai 037ab92
+        }
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+    ctx->request->nktypes = j;
Nalin Dahyabhai 037ab92
+    free(etype_list);
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
+    /* Error out now if there's no overlap. */
Nalin Dahyabhai 037ab92
+    if (ctx->request->nktypes == 0) {
Nalin Dahyabhai 037ab92
+        ret = krb5_unparse_name(context, ctx->request->client, &name);
Nalin Dahyabhai 037ab92
+        if (ret == 0) {
Nalin Dahyabhai 037ab92
+            krb5_set_error_message(context, KRB5_KT_NOTFOUND,
Nalin Dahyabhai 037ab92
+                                   _("Keytab contains no suitable keys for "
Nalin Dahyabhai 037ab92
+                                     "%s"), name);
Nalin Dahyabhai 037ab92
+        }
Nalin Dahyabhai 037ab92
+        krb5_free_unparsed_name(context, name);
Nalin Dahyabhai 037ab92
+        return KRB5_KT_NOTFOUND;
Nalin Dahyabhai 037ab92
+    }
Nalin Dahyabhai 037ab92
+
Nalin Dahyabhai 037ab92
     return 0;
Nalin Dahyabhai 037ab92
 }
Nalin Dahyabhai 037ab92