heimdal: import heimdal's trunk svn rev 23697 + lorikeet-heimdal patches
[amitay/samba.git] / source4 / heimdal / kdc / misc.c
index a61c647f719fc956be7b6b7ae75f9f19cc5f26c6..0c64dd568eb9ffa69fcb94678f277ea89a1cba54 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: misc.c,v 1.29 2006/04/27 11:33:21 lha Exp $");
+RCSID("$Id$");
 
 struct timeval _kdc_now;
 
@@ -42,15 +42,18 @@ _kdc_db_fetch(krb5_context context,
              krb5_kdc_configuration *config,
              krb5_const_principal principal,
              unsigned flags,
+             HDB **db,
              hdb_entry_ex **h)
 {
     hdb_entry_ex *ent;
-    krb5_error_code ret = HDB_ERR_NOENTRY;
+    krb5_error_code ret;
     int i;
 
     ent = calloc (1, sizeof (*ent));
-    if (ent == NULL)
+    if (ent == NULL) {
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
+    }
 
     for(i = 0; i < config->num_db; i++) {
        ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0);
@@ -66,12 +69,15 @@ _kdc_db_fetch(krb5_context context,
                                       ent);
        config->db[i]->hdb_close(context, config->db[i]);
        if(ret == 0) {
+           if (db)
+               *db = config->db[i];
            *h = ent;
            return 0;
        }
     }
     free(ent);
-    return ret;
+    krb5_set_error_message(context, HDB_ERR_NOENTRY, "no such entry found in hdb");
+    return HDB_ERR_NOENTRY;
 }
 
 void
@@ -81,3 +87,37 @@ _kdc_free_ent(krb5_context context, hdb_entry_ex *ent)
     free (ent);
 }
 
+/*
+ * Use the order list of preferred encryption types and sort the
+ * available keys and return the most preferred key.
+ */
+
+krb5_error_code
+_kdc_get_preferred_key(krb5_context context,
+                      krb5_kdc_configuration *config,
+                      hdb_entry_ex *h,
+                      const char *name,
+                      krb5_enctype *enctype,
+                      Key **key)
+{
+    const krb5_enctype *p;
+    krb5_error_code ret;
+    int i;
+
+    p = krb5_kerberos_enctypes(context);
+
+    for (i = 0; p[i] != ETYPE_NULL; i++) {
+       if (krb5_enctype_valid(context, p[i]) != 0)
+           continue;
+       ret = hdb_enctype2key(context, &h->entry, p[i], key);
+       if (ret == 0) {
+           *enctype = p[i];
+           return 0;
+       }
+    }
+
+    krb5_set_error_message(context, EINVAL, 
+                          "No valid kerberos key found for %s", name);
+    return EINVAL;
+}
+