lib/krb5_wrap: use krb5_const_principal in smb_krb5_create_key_from_string.
[kai/samba-autobuild/.git] / source4 / auth / kerberos / srv_keytab.c
index ca2d3853da200f33e16b7e5952bbfcbb1376e337..754f2c2c2c9c0cd97fb7627a2bc577e333cf2690 100644 (file)
@@ -54,8 +54,7 @@ static krb5_error_code principals_from_list(TALLOC_CTX *parent_ctx,
        }
 
        if (!realm) {
-               *error_string = "Cannot have a kerberos secret in "
-                               "secrets.ldb without a realm";
+               *error_string = "Cannot make principal without a realm";
                ret = EINVAL;
                goto done;
        }
@@ -81,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) {
@@ -134,8 +133,7 @@ static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx,
        }
 
        if (!realm) {
-               *error_string = "Cannot have a kerberos secret in "
-                               "secrets.ldb without a realm";
+               *error_string = "Cannot make principal without a realm";
                return EINVAL;
        }
 
@@ -145,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);
@@ -178,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,
@@ -189,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,
@@ -249,7 +202,7 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
        krb5_data password;
        char *unparsed;
 
-       password.data = discard_const_p(char *, password_s);
+       password.data = discard_const_p(char, password_s);
        password.length = strlen(password_s);
 
        for (i = 0; enctypes[i]; i++) {
@@ -257,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;
                }
@@ -285,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;
 }
@@ -323,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;
        }
 
@@ -350,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;
        }
 
@@ -357,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:
@@ -399,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 */
@@ -417,14 +380,15 @@ 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;
                }
                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;
                        }
@@ -434,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;
                }
 
@@ -451,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)));
@@ -474,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);