krb5-samba: interdomain trust uses different salt principal
[vlendec/samba-autobuild/.git] / lib / krb5_wrap / krb5_samba.c
index 7c461e5c2860b6f3bb5d8af4adacd8f4ba319cff..73e89ea9525b047264972be5acb6b0673dac04bf 100644 (file)
@@ -24,6 +24,7 @@
 #include "system/filesys.h"
 #include "krb5_samba.h"
 #include "lib/crypto/crypto.h"
+#include "../libds/common/flags.h"
 
 #ifdef HAVE_COM_ERR_H
 #include <com_err.h>
@@ -445,8 +446,7 @@ int smb_krb5_get_pw_salt(krb5_context context,
  * @param[in]  userPrincipalName  The userPrincipalName attribute of the object
  *                                or NULL is not available.
  *
- * @param[in]  is_computer        The indication of the object includes
- *                                objectClass=computer.
+ * @param[in]  uac_flags          UF_ACCOUNT_TYPE_MASKed userAccountControl field
  *
  * @param[in]  mem_ctx            The TALLOC_CTX to allocate _salt_principal.
  *
@@ -459,7 +459,7 @@ int smb_krb5_get_pw_salt(krb5_context context,
 int smb_krb5_salt_principal(const char *realm,
                            const char *sAMAccountName,
                            const char *userPrincipalName,
-                           bool is_computer,
+                           uint32_t uac_flags,
                            TALLOC_CTX *mem_ctx,
                            char **_salt_principal)
 {
@@ -480,6 +480,23 @@ int smb_krb5_salt_principal(const char *realm,
                return EINVAL;
        }
 
+       if (uac_flags & ~UF_ACCOUNT_TYPE_MASK) {
+               /*
+                * catch callers which still
+                * pass 'true'.
+                */
+               TALLOC_FREE(frame);
+               return EINVAL;
+       }
+       if (uac_flags == 0) {
+               /*
+                * catch callers which still
+                * pass 'false'.
+                */
+               TALLOC_FREE(frame);
+               return EINVAL;
+       }
+
        upper_realm = strupper_talloc(frame, realm);
        if (upper_realm == NULL) {
                TALLOC_FREE(frame);
@@ -493,7 +510,7 @@ int smb_krb5_salt_principal(const char *realm,
        /*
         * Determine a salting principal
         */
-       if (is_computer) {
+       if (uac_flags & UF_TRUST_ACCOUNT_MASK) {
                int computer_len = 0;
                char *tmp = NULL;
 
@@ -502,20 +519,32 @@ int smb_krb5_salt_principal(const char *realm,
                        computer_len -= 1;
                }
 
-               tmp = talloc_asprintf(frame, "host/%*.*s.%s",
-                                     computer_len, computer_len,
-                                     sAMAccountName, realm);
-               if (tmp == NULL) {
-                       TALLOC_FREE(frame);
-                       return ENOMEM;
-               }
+               if (uac_flags & UF_INTERDOMAIN_TRUST_ACCOUNT) {
+                       principal = talloc_asprintf(frame, "krbtgt/%*.*s",
+                                                   computer_len, computer_len,
+                                                   sAMAccountName);
+                       if (principal == NULL) {
+                               TALLOC_FREE(frame);
+                               return ENOMEM;
+                       }
+               } else {
 
-               principal = strlower_talloc(frame, tmp);
-               TALLOC_FREE(tmp);
-               if (principal == NULL) {
-                       TALLOC_FREE(frame);
-                       return ENOMEM;
+                       tmp = talloc_asprintf(frame, "host/%*.*s.%s",
+                                             computer_len, computer_len,
+                                             sAMAccountName, realm);
+                       if (tmp == NULL) {
+                               TALLOC_FREE(frame);
+                               return ENOMEM;
+                       }
+
+                       principal = strlower_talloc(frame, tmp);
+                       TALLOC_FREE(tmp);
+                       if (principal == NULL) {
+                               TALLOC_FREE(frame);
+                               return ENOMEM;
+                       }
                }
+
                principal_len = strlen(principal);
 
        } else if (userPrincipalName != NULL) {
@@ -1549,7 +1578,7 @@ krb5_error_code smb_krb5_kt_seek_and_delete_old_entries(krb5_context context,
                }
 
                if (!flush &&
-                   (kt_entry.vno == kvno) &&
+                   ((kt_entry.vno & 0xff) == (kvno & 0xff)) &&
                    (kt_entry_enctype != enctype))
                {
                        DEBUG(5, (__location__ ": Saving entry with kvno [%d] "