auth/kerberos: Use talloc_stackframe to avoid memory and FD leak of event context
[kai/samba-autobuild/.git] / source4 / auth / kerberos / srv_keytab.c
index 318c642c73d31caf37ad7d7c66ae6e00483a827a..3baba1427e8ccc186a87546c41af7c4f9fa15597 100644 (file)
@@ -80,7 +80,7 @@ static krb5_error_code principals_from_list(TALLOC_CTX *parent_ctx,
        }
 
        if (samAccountName) {
-               ret = krb5_make_principal(context, &principals[i],
+               ret = smb_krb5_make_principal(context, &principals[i],
                                          upper_realm, samAccountName,
                                          NULL);
                if (ret) {
@@ -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);
@@ -176,7 +176,7 @@ static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx,
                return ENOMEM;
        }
 
-       ret = krb5_make_principal(context, salt_princ, upper_realm,
+       ret = smb_krb5_make_principal(context, salt_princ, upper_realm,
                                                "host", salt_body, NULL);
        if (ret) {
                *error_string = smb_get_krb5_error_message(context,
@@ -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_MD5;
-       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,9 +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,
-                                               &entry.keyblock, 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;
                }
@@ -283,14 +241,14 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
                                free(unparsed);
                                talloc_free(k5_error_string);
                                krb5_free_keyblock_contents(context,
-                                                           &entry.keyblock);
+                                                           KRB5_KT_KEY(&entry));
                                return ret;
                        }
 
                        DEBUG(5, ("Added key (kvno %d) to keytab (enctype %d)\n",
                                  kvno, (int)enctypes[i]));
                }
-               krb5_free_keyblock_contents(context, &entry.keyblock);
+               krb5_free_keyblock_contents(context, KRB5_KT_KEY(&entry));
        }
        return 0;
 }
@@ -321,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;
        }
 
@@ -348,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;
        }
 
@@ -355,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:
@@ -397,7 +360,9 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
        switch (ret) {
        case 0:
                break;
+#ifdef HEIM_ERR_OPNOTSUPP
        case HEIM_ERR_OPNOTSUPP:
+#endif
        case ENOENT:
        case KRB5_KT_END:
                /* no point enumerating if there isn't anything here */
@@ -421,8 +386,8 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
                }
                for (i = 0; principals[i]; i++) {
                        /* if it matches our principal */
-                       if (krb5_kt_compare(context, &entry,
-                                           principals[i], 0, 0)) {
+                       if (smb_krb5_kt_compare(context, &entry,
+                                               principals[i], 0, 0)) {
                                matched = true;
                                break;
                        }