s4-auth: avoid double free of krb5 kt_entries when compiling with MIT kerberos library.
[kai/samba-autobuild/.git] / source4 / auth / kerberos / srv_keytab.c
index c3c96163e021bae6d93951750ca32a3a48ef976f..1ffd1e3f33de070a7fc37e1cee278a6430f83e9e 100644 (file)
@@ -143,7 +143,7 @@ static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx,
                return ENOMEM;
        }
 
-       machine_username = talloc_strdup(tmp_ctx, samAccountName);
+       machine_username = strlower_talloc(tmp_ctx, samAccountName);
        if (!machine_username) {
                *error_string = "Cannot duplicate samAccountName";
                talloc_free(tmp_ctx);
@@ -187,51 +187,6 @@ static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx,
        return ret;
 }
 
-/* Translate between the Microsoft msDS-SupportedEncryptionTypes values
- * and the IETF encryption type values */
-static krb5_enctype ms_suptype_to_ietf_enctype(uint32_t enctype_bitmap)
-{
-       switch (enctype_bitmap) {
-       case ENC_CRC32:
-               return ENCTYPE_DES_CBC_CRC;
-       case ENC_RSA_MD5:
-               return ENCTYPE_DES_CBC_MD5;
-       case ENC_RC4_HMAC_MD5:
-               return ENCTYPE_ARCFOUR_HMAC;
-       case ENC_HMAC_SHA1_96_AES128:
-               return ENCTYPE_AES128_CTS_HMAC_SHA1_96;
-       case ENC_HMAC_SHA1_96_AES256:
-               return ENCTYPE_AES256_CTS_HMAC_SHA1_96;
-       default:
-               return 0;
-       }
-}
-
-/* Return an array of krb5_enctype values */
-static krb5_error_code ms_suptypes_to_ietf_enctypes(TALLOC_CTX *mem_ctx,
-                                               uint32_t enctype_bitmap,
-                                               krb5_enctype **enctypes)
-{
-       unsigned int i, j = 0;
-       *enctypes = talloc_zero_array(mem_ctx, krb5_enctype,
-                                       (8 * sizeof(enctype_bitmap)) + 1);
-       if (!*enctypes) {
-               return ENOMEM;
-       }
-       for (i = 0; i < (8 * sizeof(enctype_bitmap)); i++) {
-               uint32_t bit_value = (1 << i) & enctype_bitmap;
-               if (bit_value & enctype_bitmap) {
-                       (*enctypes)[j] = ms_suptype_to_ietf_enctype(bit_value);
-                       if (!(*enctypes)[j]) {
-                               continue;
-                       }
-                       j++;
-               }
-       }
-       (*enctypes)[j] = 0;
-       return 0;
-}
-
 static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
                                       krb5_principal *principals,
                                       krb5_principal salt_princ,
@@ -255,10 +210,12 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
 
                ZERO_STRUCT(entry);
 
-               ret = create_kerberos_key_from_string_direct(context,
-                                               salt_princ, &password,
-                                               KRB5_KT_KEY(&entry),
-                                               enctypes[i]);
+               ret = smb_krb5_create_key_from_string(context,
+                                                     &salt_princ,
+                                                     NULL,
+                                                     &password,
+                                                     enctypes[i],
+                                                     KRB5_KT_KEY(&entry));
                if (ret != 0) {
                        return ret;
                }
@@ -322,7 +279,8 @@ static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,
 
        mem_ctx = talloc_new(parent_ctx);
        if (!mem_ctx) {
-               *error_string = "unable to allocate tmp_ctx for create_keytab";
+               *error_string = talloc_strdup(parent_ctx,
+                       "unable to allocate tmp_ctx for create_keytab");
                return ENOMEM;
        }
 
@@ -349,6 +307,7 @@ static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,
                              salt_princ, kvno, new_secret,
                              context, enctypes, keytab, error_string);
        if (ret) {
+               talloc_steal(parent_ctx, *error_string);
                goto done;
        }
 
@@ -356,6 +315,9 @@ static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,
                ret = keytab_add_keys(mem_ctx, principals,
                                      salt_princ, kvno - 1, old_secret,
                                      context, enctypes, keytab, error_string);
+               if (ret) {
+                       talloc_steal(parent_ctx, *error_string);
+               }
        }
 
 done:
@@ -418,6 +380,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
                unsigned int i;
                bool matched = false;
                krb5_keytab_entry entry;
+
                ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
                if (ret) {
                        break;
@@ -435,6 +398,8 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
                        /* Free the entry,
                         * it wasn't the one we were looking for anyway */
                        krb5_kt_free_entry(context, &entry);
+                       /* Make sure we do not double free */
+                       ZERO_STRUCT(entry);
                        continue;
                }
 
@@ -452,11 +417,15 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
 
                        ret = krb5_kt_remove_entry(context, keytab, &entry);
                        krb5_kt_free_entry(context, &entry);
+                       /* Make sure we do not double free */
+                       ZERO_STRUCT(entry);
 
                        /* Deleted: Restart from the top */
                        ret2 = krb5_kt_start_seq_get(context, keytab, &cursor);
                        if (ret2) {
                                krb5_kt_free_entry(context, &entry);
+                               /* Make sure we do not double free */
+                               ZERO_STRUCT(entry);
                                DEBUG(1, ("failed to restart enumeration of keytab: %s\n",
                                          smb_get_krb5_error_message(context,
                                                                ret, mem_ctx)));
@@ -475,6 +444,8 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
 
                /* Free the entry, we don't need it any more */
                krb5_kt_free_entry(context, &entry);
+               /* Make sure we do not double free */
+               ZERO_STRUCT(entry);
        }
        krb5_kt_end_seq_get(context, keytab, &cursor);