heimdal: import heimdal's trunk svn rev 23697 + lorikeet-heimdal patches
[metze/samba/wip.git] / source / heimdal / lib / hdb / keys.c
index c5a2efd7583b845e24ff680540f872e4052e01f0..e649f445e0ad1a9ea66ddf8b8bb5eff2915c1954 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: keys.c,v 1.3 2005/03/17 00:42:05 lha Exp $");
+RCSID("$Id$");
 
 /*
  * free all the memory used by (len, keys)
@@ -68,11 +68,13 @@ hdb_free_keys (krb5_context context, int len, Key *keys)
  *     afs or afs3 == des:afs3-salt
  */
 
-/* the 3 DES types must be first */
-static const krb5_enctype all_etypes[] = { 
+static const krb5_enctype des_etypes[] = { 
     ETYPE_DES_CBC_MD5,
     ETYPE_DES_CBC_MD4,
-    ETYPE_DES_CBC_CRC,
+    ETYPE_DES_CBC_CRC
+};
+
+static const krb5_enctype all_etypes[] = { 
     ETYPE_AES256_CTS_HMAC_SHA1_96,
     ETYPE_ARCFOUR_HMAC_MD5,
     ETYPE_DES3_CBC_SHA1
@@ -105,29 +107,27 @@ parse_key_set(krb5_context context, const char *key,
     salt->saltvalue.length = 0;
 
     for(i = 0; i < num_buf; i++) {
-       if(enctypes == NULL) {
+       if(enctypes == NULL && num_buf > 1) {
            /* this might be a etype specifier */
            /* XXX there should be a string_to_etypes handling
               special cases like `des' and `all' */
            if(strcmp(buf[i], "des") == 0) {
-               enctypes = all_etypes;
-               num_enctypes = 3;
-               continue;
+               enctypes = des_etypes;
+               num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]);
            } else if(strcmp(buf[i], "des3") == 0) {
                e = ETYPE_DES3_CBC_SHA1;
                enctypes = &e;
                num_enctypes = 1;
-               continue;
            } else {
                ret = krb5_string_to_enctype(context, buf[i], &e);
                if (ret == 0) {
                    enctypes = &e;
                    num_enctypes = 1;
-                   continue;
-               }
+               } else
+                   return ret;
            }
+           continue;
        }
-
        if(salt->salttype == 0) {
            /* interpret string as a salt specifier, if no etype
               is set, this sets default values */
@@ -141,18 +141,21 @@ parse_key_set(krb5_context context, const char *key,
                salt->salttype = KRB5_PW_SALT;
            } else if(strcmp(buf[i], "afs3-salt") == 0) {
                if(enctypes == NULL) {
-                   enctypes = all_etypes;
-                   num_enctypes = 3;
+                   enctypes = des_etypes;
+                   num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]);
                }
                salt->salttype = KRB5_AFS3_SALT;
            }
-       } else {
+           continue;
+       }
+
+       {
            /* if there is a final string, use it as the string to
               salt with, this is mostly useful with null salt for
               v4 compat, and a cell name for afs compat */
            salt->saltvalue.data = strdup(buf[i]);
            if (salt->saltvalue.data == NULL) {
-               krb5_set_error_string(context, "malloc out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            salt->saltvalue.length = strlen(buf[i]);
@@ -160,7 +163,7 @@ parse_key_set(krb5_context context, const char *key,
     }
     
     if(enctypes == NULL || salt->salttype == 0) {
-       krb5_set_error_string(context, "bad value for default_keys `%s'", key);
+       krb5_set_error_message(context, EINVAL, "bad value for default_keys `%s'", key);
        return EINVAL;
     }
     
@@ -172,8 +175,9 @@ parse_key_set(krb5_context context, const char *key,
            krb5_realm *realm = krb5_princ_realm(context, principal);
            salt->saltvalue.data = strdup(*realm);
            if(salt->saltvalue.data == NULL) {
-               krb5_set_error_string(context, "out of memory while "
-                                     "parsing salt specifiers");
+               krb5_set_error_message(context, ENOMEM,
+                                      "out of memory while "
+                                      "parsing salt specifiers");
                return ENOMEM;
            }
            strlwr(salt->saltvalue.data);
@@ -184,7 +188,7 @@ parse_key_set(krb5_context context, const char *key,
     *ret_enctypes = malloc(sizeof(enctypes[0]) * num_enctypes);
     if (*ret_enctypes == NULL) {
        krb5_free_salt(context, *salt);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes);
@@ -243,7 +247,7 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
 /*
  * Generate the `key_set' from the [kadmin]default_keys statement. If
  * `no_salt' is set, salt is not important (and will not be set) since
- * its random keys that is going to be created.
+ * it's random keys that is going to be created.
  */
 
 krb5_error_code
@@ -297,7 +301,8 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
        ret = parse_key_set(context, p,
                            &enctypes, &num_enctypes, &salt, principal);
        if (ret) {
-           krb5_warnx(context, "bad value for default_keys `%s'", *kp);
+           krb5_warn(context, ret, "bad value for default_keys `%s'", *kp);
+           ret = 0;
            continue;
        }
 
@@ -334,7 +339,12 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
        krb5_free_salt(context, salt);
     }
     
+    *ret_key_set = key_set;
+
  out:
+    if (ktypes != default_keytypes)
+       krb5_config_free_strings(ktypes);
+
     if (ret) {
        krb5_warn(context, ret, 
                  "failed to parse the [kadmin]default_keys values");
@@ -348,8 +358,6 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
        ret = EINVAL; /* XXX */
     }
 
-    *ret_key_set = key_set;
-
     return ret;
 }