[PR PATCH] [Updated] samba-tool domain trust: fix trust compatibility to Windows Server 1709 and FreeIPA

Alexander Bokovoy ab at samba.org
Thu Mar 1 21:48:30 UTC 2018


On to, 01 maalis 2018, Alexander Bokovoy via samba-technical wrote:
> On to, 01 maalis 2018, Stefan Metzmacher via samba-technical wrote:
> > Am 01.03.2018 um 10:41 schrieb Alexander Bokovoy:
> > > On to, 01 maalis 2018, Stefan Metzmacher via samba-technical wrote:
> > >> Am 01.03.2018 um 08:54 schrieb Alexander Bokovoy via samba-technical:
> > >>> On to, 01 maalis 2018, Stefan Metzmacher via samba-technical wrote:
> > >>>> Hi Alexander,
> > >>>>
> > >>>>>> As we only use remote_netlogon_info.dc_unc can we
> > >>>>>> add get_netlogon_dc_unc() that falls back to netr_GetDcName()
> > >>>>>> against the remote dc.
> > >>>>>>
> > >>>>>> That would also help if we try to implement trusts against
> > >>>>>> an NT4 style domain.
> > >>>>> Makes sense. Updated patches attached.
> > >>>>
> > >>>> Thanks much better:-)!
> > >>>> Is that tested against FreeIPA?
> > >>> Not yet, in my plans for today as I'm trying to figure out what else we
> > >>> are missing in TDO salt principals.
> > >>
> > >> The salt principal for the BLA$ user object is wrong.
> > >>
> > >> dn: CN=bla.base,CN=System,DC=w4edom-l4,DC=base
> > >> securityIdentifier: S-1-5-21-4053568372-2049667917-3384589010
> > >> trustDirection: 3
> > >> trustPartner: bla.base
> > >> trustPosixOffset: -2147483648
> > >> trustType: 2
> > >> trustAttributes: 8
> > >> flatName: BLA
> > >>
> > >> dn: CN=BLA$,CN=Users,DC=w4edom-l4,DC=base
> > >> userAccountControl: 2080
> > >> primaryGroupID: 513
> > >> objectSid: S-1-5-21-278041429-3399921908-1452754838-1597
> > >> accountExpires: 9223372036854775807
> > >> sAMAccountName: BLA$
> > >> sAMAccountType: 805306370
> > >> pwdLastSet: 131485652467995000
> > >>
> > >> The salt stored by Windows in the package_PrimaryKerberosBlob
> > >> (within supplementalCredentials) seems to be
> > >> 'W4EDOM-L4.BASEkrbtgtBLA' for the above trust
> > >> and Samba stores 'W4EDOM-L4.BASEBLA$'.
> > > Yes, exactly. It doesn't affect Samba AD DC trying to contact Windows AD
> > > DC because KDC advertises salt and Samba always generates the key on the
> > > fly. However, it does affect SSSD on FreeIPA masters because in IPA case
> > > KDC has all keys pregenerated at the time Kerberos principals are
> > > created when trust is added and SSSD uses a keytab to authenticate as
> > > TDO.
> > > 
> > > I have a patch that passes userAccountControl to
> > > smb_krb5_salt_principal() and it should fix the problem. The patch is
> > > against 4.7.
> > 
> > That looks good, can you prepare this for master and
> > add a test to demonstrate the SSSD behavior, so we don't
> > regress on this in future. I guess it's just using
> > BLA$@W4EDOM-L4.BASE as client and/or server principal?
> It does use BLA$@W4EDOM-L4.BASE as an initiator to talk to LDAP (i.e.
> ldap/dc.w4edom-l4.base) but the salt to obtain TGT is negotiated with
> KDC.
> 
> I'll look at making a test.
Full patchset is attached. It includes all patches discussed plus a test
for retrieving a keytab for TDO and using kinit from keytab.

Below is a sample output from a test run when I enabled explicit logging
of KRB5 tracing. As you can see, the salt is now a correct one.

testsuite: samba4.blackbox.kinit_trust_tdo(fl2008r2dc:local)(fl2008r2dc:local)
progress: push
time: 2018-03-01 22:12:18.000000Z
time: 2018-03-01 20:12:18.318658Z
test: samba4.blackbox.kinit_trust_tdo(fl2008r2dc:local).retrieve keytab for TDO of ADDOM.SAMBA.EXAMPLE.COM(fl2008r2dc:local)
time: 2018-03-01 20:12:18.704795Z
successful: samba4.blackbox.kinit_trust_tdo(fl2008r2dc:local).retrieve keytab for TDO of ADDOM.SAMBA.EXAMPLE.COM(fl2008r2dc:local)
[7022] 1519935138.717384: Getting initial credentials for ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM
[7022] 1519935138.717385: Looked up etypes in keytab: aes256-cts, aes128-cts, rc4-hmac, des, des-cbc-crc, des-cbc-crc
[7022] 1519935138.717387: Sending request (208 bytes) to SAMBA2008R2.EXAMPLE.COM
[7022] 1519935138.717388: Resolving hostname 127.0.0.27
[7022] 1519935138.717389: Sending initial UDP request to dgram 127.0.0.27:88
[7022] 1519935138.717390: Received answer (315 bytes) from dgram 127.0.0.27:88
[7022] 1519935138.717391: Response was not from master KDC
[7022] 1519935138.717392: Received error from KDC: -1765328359/Additional pre-authentication required
[7022] 1519935138.717395: Processing preauth types: 136, 19, 2, 133
[7022] 1519935138.717396: Selected etype info: etype aes256-cts, salt "SAMBA2008R2.EXAMPLE.COMkrbtgtADDOMAIN", params ""
[7022] 1519935138.717397: Received cookie: MIT
[7022] 1519935138.717398: Retrieving ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM from FILE:./st/tmptdo.keytab (vno 0, enctype aes256-cts) with result: 0/Success
[7022] 1519935138.717399: AS key obtained for encrypted timestamp: aes256-cts/3F1D
[7022] 1519935138.717401: Encrypted timestamp (for 1519935138.717400): plain 301AA011180F32303138303330313230313231385AA10502030AF258, encrypted 948B5770763917B06BB95618EA53AE295A6F32FEA40D8DD64D614D844AD9546523A666EC5A3845D620A19E54060CBB08217898EFC00FFEA1
[7022] 1519935138.717402: Preauth module encrypted_timestamp (2) (real) returned: 0/Success
[7022] 1519935138.717403: Produced preauth for next request: 133, 2
[7022] 1519935138.717404: Sending request (303 bytes) to SAMBA2008R2.EXAMPLE.COM
[7022] 1519935138.717405: Resolving hostname 127.0.0.27
[7022] 1519935138.717406: Sending initial UDP request to dgram 127.0.0.27:88
[7022] 1519935138.717407: Received answer (1542 bytes) from dgram 127.0.0.27:88
[7022] 1519935138.717408: Response was not from master KDC
[7022] 1519935138.717409: Processing preauth types: 19
[7022] 1519935138.717410: Selected etype info: etype aes256-cts, salt "SAMBA2008R2.EXAMPLE.COMkrbtgtADDOMAIN", params ""
[7022] 1519935138.717411: Produced preauth for next request: (empty)
[7022] 1519935138.717412: AS key determined by preauth: aes256-cts/3F1D
[7022] 1519935138.717413: Decrypted AS reply; session key is: aes256-cts/779C
[7022] 1519935138.717414: FAST negotiation: available
[7022] 1519935138.717415: Initializing FILE:./st/tmpccache with default princ ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM
[7022] 1519935138.717416: Storing ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM -> krbtgt/SAMBA2008R2.EXAMPLE.COM at SAMBA2008R2.EXAMPLE.COM in FILE:./st/tmpccache
[7022] 1519935138.717417: Storing config in FILE:./st/tmpccache for krbtgt/SAMBA2008R2.EXAMPLE.COM at SAMBA2008R2.EXAMPLE.COM: fast_avail: yes
[7022] 1519935138.717418: Storing ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM -> krb5_ccache_conf_data/fast_avail/krbtgt\/SAMBA2008R2.EXAMPLE.COM\@SAMBA2008R2.EXAMPLE.COM at X-CACHECONF: in FILE:./st/tmpccache
[7022] 1519935138.717419: Storing config in FILE:./st/tmpccache for krbtgt/SAMBA2008R2.EXAMPLE.COM at SAMBA2008R2.EXAMPLE.COM: pa_type: 2
[7022] 1519935138.717420: Storing ADDOMAIN$@SAMBA2008R2.EXAMPLE.COM -> krb5_ccache_conf_data/pa_type/krbtgt\/SAMBA2008R2.EXAMPLE.COM\@SAMBA2008R2.EXAMPLE.COM at X-CACHECONF: in FILE:./st/tmpccache

-- 
/ Alexander Bokovoy
-------------- next part --------------
>From 1e880949617bad22bcb31c1e453bd618bf6d32f0 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Sat, 24 Feb 2018 13:12:20 +0200
Subject: [PATCH 1/3] samba-tool domain trust: allow using smb2 by default

Windows Server 1709 defaults to SMB2 and does not have SMB1 enabled.
When establishing trust, samba-tool does not specify SMB protocol
version and fail by default.

We have two ways to handle this situation:
 - switch 'client ipc min protocol' to 'SMB2' or later
 - explicitly specify 'smb2' to binding options and retry

Using first approach would be better in a longer term but right now Samba
defaults to 'CORE' in 'client min protocol' and changing it would deny
connecting to older SMB servers.

Another way is to explicitly specify a protocol in a binding string and
fall back to a default if connection fails. A similar approach is used
by the FreeIPA trust code for several years.

Signed-off-by: Alexander Bokovoy <ab at samba.org>
---
 python/samba/netcmd/domain.py | 40 ++++++++++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index d3b9b0ccf6f..e14cbec9444 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -1666,6 +1666,7 @@ class DomainTrustCommand(Command):
         self.remote_server = None
         self.remote_binding_string = None
         self.remote_creds = None
+        self.protocol_options = ['smb2', '']
 
     def _uint32(self, v):
         return ctypes.c_uint32(v).value
@@ -1730,16 +1731,39 @@ class DomainTrustCommand(Command):
         self.local_lp = lp
 
         self.local_server = local_server
-        self.local_binding_string = "%s:%s[%s]" % (local_transport, local_server, local_binding_options)
+        self.local_bindings = ["%s:%s[%s%s]" % (local_transport, local_server,
+                                                protocol, local_binding_options)
+                               for protocol in self.protocol_options]
         self.local_ldap_url = local_ldap_url
         self.local_creds = local_creds
         return self.local_server
 
+    def _get_connection(self, connect_func, lp, creds, bindings):
+        """ _get_connection: try to generate a valid connection
+                             using multiple bindings to allow
+                             protocol fallbacks
+        """
+        bnd = None
+        last_exc = None
+        for binding in bindings:
+            try:
+                bnd = connect_func(binding, lp, creds)
+                if bnd is not None:
+                    break
+            except NTSTATUSError as error:
+                last_exc = error
+                continue
+        if bnd is None:
+            raise last_exc
+        return bnd
+
     def new_local_lsa_connection(self):
-        return lsa.lsarpc(self.local_binding_string, self.local_lp, self.local_creds)
+        return self._get_connection(lsa.lsarpc, self.local_lp,
+                                    self.local_creds, self.local_bindings)
 
     def new_local_netlogon_connection(self):
-        return netlogon.netlogon(self.local_binding_string, self.local_lp, self.local_creds)
+        return self._get_connection(netlogon.netlogon, self.local_lp,
+                                    self.local_creds, self.local_bindings)
 
     def new_local_ldap_connection(self):
         return SamDB(url=self.local_ldap_url,
@@ -1807,15 +1831,19 @@ class DomainTrustCommand(Command):
                         server_type_string))
 
         self.remote_server = remote_info.pdc_dns_name
-        self.remote_binding_string="ncacn_np:%s[%s]" % (self.remote_server, remote_binding_options)
+        self.remote_bindings = ["ncacn_np:%s[%s%s]" % (self.remote_server, protocol,
+                                                       remote_binding_options)
+                                for protocol in self.protocol_options]
         self.remote_creds = remote_creds
         return self.remote_server
 
     def new_remote_lsa_connection(self):
-        return lsa.lsarpc(self.remote_binding_string, self.local_lp, self.remote_creds)
+        return self._get_connection(lsa.lsarpc, self.local_lp,
+                                    self.remote_creds, self.remote_bindings)
 
     def new_remote_netlogon_connection(self):
-        return netlogon.netlogon(self.remote_binding_string, self.local_lp, self.remote_creds)
+        return self._get_connection(netlogon.netlogon, self.local_lp,
+                                    self.remote_creds, self.remote_bindings)
 
     def get_lsa_info(self, conn, policy_access):
         objectAttr = lsa.ObjectAttribute()
-- 
2.14.3


>From 59d7161a5abeec2019ef9ebd490e8dc4b949e161 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Sat, 24 Feb 2018 14:34:44 +0200
Subject: [PATCH 2/3] samba-tool trust: support discovery via netr_GetDcName

In case a remote DC does not support netr_DsRGetDCNameEx2(),
use netr_GetDcName() instead.

This should help with FreeIPA where embedded smbd runs as a domain
controller but does not implement full Active Directory compatibility.

Signed-off-by: Alexander Bokovoy <ab at samba.org>
---
 python/samba/netcmd/domain.py | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index e14cbec9444..b4da0b69afa 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -1856,6 +1856,15 @@ class DomainTrustCommand(Command):
 
         return (policy, info)
 
+    def get_netlogon_dc_unc(self, conn, server, domain):
+        try:
+            info = conn.netr_DsRGetDCNameEx2(server,
+                                             None, 0, None, None, None,
+                                             netlogon.DS_RETURN_DNS_NAME)
+            return info.dc_unc
+        except RuntimeError:
+            return conn.netr_GetDcName(server, domain)
+
     def get_netlogon_dc_info(self, conn, server):
         info = conn.netr_DsRGetDCNameEx2(server,
                                          None, 0, None, None, None,
@@ -2490,7 +2499,8 @@ class cmd_domain_trust_create(DomainTrustCommand):
                 raise self.RemoteRuntimeError(self, error, "failed to connect netlogon server")
 
             try:
-                remote_netlogon_info = self.get_netlogon_dc_info(remote_netlogon, remote_server)
+                remote_netlogon_dc_unc = self.get_netlogon_dc_unc(remote_netlogon,
+                                                                  remote_server, domain)
             except RuntimeError as error:
                 raise self.RemoteRuntimeError(self, error, "failed to get netlogon dc info")
 
@@ -2640,9 +2650,9 @@ class cmd_domain_trust_create(DomainTrustCommand):
                         # this triggers netr_GetForestTrustInformation to our domain.
                         # and lsaRSetForestTrustInformation() remotely, but new top level
                         # names are disabled by default.
-                        remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_info.dc_unc,
-                                                                      local_lsa_info.dns_domain.string,
-                                                                      netlogon.DS_GFTI_UPDATE_TDO)
+                        remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_dc_unc,
+                                                                                               local_lsa_info.dns_domain.string,
+                                                                                               netlogon.DS_GFTI_UPDATE_TDO)
                     except RuntimeError as error:
                         raise self.RemoteRuntimeError(self, error, "netr_DsRGetForestTrustInformation() failed")
 
@@ -2693,10 +2703,10 @@ class cmd_domain_trust_create(DomainTrustCommand):
                 if remote_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_OUTBOUND:
                     self.outf.write("Validating incoming trust...\n")
                     try:
-                        remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_info.dc_unc,
-                                                                      netlogon.NETLOGON_CONTROL_TC_VERIFY,
-                                                                      2,
-                                                                      local_lsa_info.dns_domain.string)
+                        remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_dc_unc,
+                                                                                   netlogon.NETLOGON_CONTROL_TC_VERIFY,
+                                                                                   2,
+                                                                                   local_lsa_info.dns_domain.string)
                     except RuntimeError as error:
                         raise self.RemoteRuntimeError(self, error, "NETLOGON_CONTROL_TC_VERIFY failed")
 
-- 
2.14.3


>From ab68a70164fff02a13997f6ce102da6c2e3482bd Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab at samba.org>
Date: Fri, 16 Feb 2018 18:15:28 +0200
Subject: [PATCH 3/3] krb5-samba: interdomain trust uses different salt
 principal

Salt principal for the interdomain trust is krbtgt/DOMAIN at REALM where
DOMAIN is the sAMAccountName without the dollar sign ($)

To test it, add a blackbox test that ensures we pass a keytab-based
authentication with a TDO account from a trusted domain.

Signed-off-by: Alexander Bokovoy <ab at samba.org>
---
 auth/credentials/credentials_krb5.c            |  9 ++++--
 lib/krb5_wrap/krb5_samba.c                     | 31 +++++++++++-------
 lib/krb5_wrap/krb5_samba.h                     |  2 +-
 source3/passdb/machine_account_secrets.c       |  3 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c |  5 ++-
 source4/selftest/tests.py                      |  1 +
 testprogs/blackbox/test_tdo.sh                 | 44 ++++++++++++++++++++++++++
 7 files changed, 77 insertions(+), 18 deletions(-)
 create mode 100755 testprogs/blackbox/test_tdo.sh

diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 9da1aa09250..ddbca8d5755 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -34,6 +34,7 @@
 #include "auth/kerberos/kerberos_util.h"
 #include "auth/kerberos/pac_utils.h"
 #include "param/param.h"
+#include "../libds/common/flags.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -974,7 +975,7 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 	const char *upn = NULL;
 	const char *realm = cli_credentials_get_realm(cred);
 	char *salt_principal = NULL;
-	bool is_computer = false;
+	uint32_t uac_flags = 0;
 
 	if (cred->keytab_obtained >= (MAX(cred->principal_obtained, 
 					  cred->username_obtained))) {
@@ -1001,8 +1002,10 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 	case SEC_CHAN_WKSTA:
 	case SEC_CHAN_BDC:
 	case SEC_CHAN_RODC:
-		is_computer = true;
+		uac_flags = UF_WORKSTATION_TRUST_ACCOUNT;
 		break;
+	case SEC_CHAN_DNS_DOMAIN:
+		uac_flags = UF_INTERDOMAIN_TRUST_ACCOUNT;
 	default:
 		upn = cli_credentials_get_principal(cred, mem_ctx);
 		if (upn == NULL) {
@@ -1015,7 +1018,7 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 	ret = smb_krb5_salt_principal(realm,
 				      username, /* sAMAccountName */
 				      upn, /* userPrincipalName */
-				      is_computer,
+				      uac_flags,
 				      mem_ctx,
 				      &salt_principal);
 	if (ret) {
diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index 7c461e5c286..285f4ad9abd 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -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)
 {
@@ -493,7 +493,7 @@ int smb_krb5_salt_principal(const char *realm,
 	/*
 	 * Determine a salting principal
 	 */
-	if (is_computer) {
+	if (uac_flags & UF_MACHINE_ACCOUNT_MASK) {
 		int computer_len = 0;
 		char *tmp = NULL;
 
@@ -502,16 +502,23 @@ 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);
+		} else {
+			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);
 		}
 
-		principal = strlower_talloc(frame, tmp);
-		TALLOC_FREE(tmp);
 		if (principal == NULL) {
 			TALLOC_FREE(frame);
 			return ENOMEM;
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 315d3c3492e..8305c1f77af 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -353,7 +353,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);
 int smb_krb5_salt_principal2data(krb5_context context,
diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
index 40511f96a8b..35b4bbd17e6 100644
--- a/source3/passdb/machine_account_secrets.c
+++ b/source3/passdb/machine_account_secrets.c
@@ -36,6 +36,7 @@
 #include "lib/crypto/crypto.h"
 #include "lib/krb5_wrap/krb5_samba.h"
 #include "lib/util/time_basic.h"
+#include "../libds/common/flags.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_PASSDB
@@ -1601,7 +1602,7 @@ NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
 		ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string,
 					      info->account_name,
 					      NULL /* userPrincipalName */,
-					      true /* is_computer */,
+					      UF_WORKSTATION_TRUST_ACCOUNT /* uac_flags */,
 					      info, &p);
 		if (ret != 0) {
 			status = krb5_to_nt_status(ret);
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 2e6464f0dd1..cb7f09735d9 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -47,6 +47,7 @@
 #include "lib/krb5_wrap/krb5_samba.h"
 #include "auth/common_auth.h"
 #include "lib/messaging/messaging.h"
+#include "../libds/common/flags.h"
 
 #ifdef ENABLE_GPGME
 #undef class
@@ -676,15 +677,17 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io)
 	krb5_data salt;
 	krb5_keyblock key;
 	krb5_data cleartext_data;
+	uint32_t uac_flags = 0;
 
 	ldb = ldb_module_get_ctx(io->ac->module);
 	cleartext_data.data = (char *)io->n.cleartext_utf8->data;
 	cleartext_data.length = io->n.cleartext_utf8->length;
 
+	uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK;
 	krb5_ret = smb_krb5_salt_principal(io->ac->status->domain_data.realm,
 					   io->u.sAMAccountName,
 					   io->u.user_principal_name,
-					   io->u.is_computer,
+					   uac_flags,
 					   io->ac,
 					   &salt_principal);
 	if (krb5_ret) {
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 4e397a8f134..1d7b83b2ee7 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -415,6 +415,7 @@ plantestsuite("samba4.blackbox.trust_utils(fl2008r2dc:local)", "fl2008r2dc:local
 plantestsuite("samba4.blackbox.trust_utils(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
 plantestsuite("samba4.blackbox.ktpass(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(bbdir, "test_ktpass.sh"), '$PREFIX/ad_dc_ntvfs'])
 plantestsuite("samba4.blackbox.password_settings(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_password_settings.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"])
+plantestsuite("samba4.blackbox.kinit_trust_tdo(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_tdo.sh"), '$PREFIX', '$REALM', '$DOMAIN', '$TRUST_REALM', '$TRUST_DOMAIN'])
 plantestsuite("samba4.blackbox.cifsdd(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "client/tests/test_cifsdd.sh"), '$SERVER', '$USERNAME', '$PASSWORD', "$DOMAIN"])
 plantestsuite("samba4.blackbox.nmblookup(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "utils/tests/test_nmblookup.sh"), '$NETBIOSNAME', '$NETBIOSALIAS', '$SERVER', '$SERVER_IP', nmblookup4])
 plantestsuite("samba4.blackbox.locktest(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(samba4srcdir, "torture/tests/test_locktest.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$DOMAIN', '$PREFIX'])
diff --git a/testprogs/blackbox/test_tdo.sh b/testprogs/blackbox/test_tdo.sh
new file mode 100755
index 00000000000..bcbdbdfdada
--- /dev/null
+++ b/testprogs/blackbox/test_tdo.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF
+Usage: test_tdo.sh PREFIX OUR_REALM OUR_FLAT REMOTE_REALM REMOTE_FLAT
+EOF
+exit 1;
+fi
+
+PREFIX="$1"
+OUR_REALM="$2"
+OUR_FLAT="$3"
+REMOTE_REALM="$4"
+REMOTE_FLAT="$5"
+shift 5
+
+. `dirname $0`/subunit.sh
+
+
+samba_tool="$BINDIR/samba-tool"
+samba4bindir="$BINDIR"
+samba4srcdir="$SRCDIR/source4"
+samba4kinit="kinit -k"
+if test -x $BINDIR/samba4kinit; then
+	samba4kinit="$BINDIR/samba4kinit --use-keytab"
+fi
+
+KEYTAB="$PREFIX/tmptdo.keytab"
+
+KRB5_TRACE=/dev/stderr
+export KRB5_TRACE
+
+testit "retrieve keytab for TDO of $REMOTE_REALM" $samba_tool domain exportkeytab $KEYTAB $CONFIGURATION --principal "$REMOTE_FLAT\$@$OUR_REALM" || failed=`expr $failed + 1`
+
+KRB5CCNAME="$PREFIX/tmptdo.ccache"
+export KRB5CCNAME
+
+rm -f $KRB5CCNAME
+
+testit "kinit with keytab for TDO of $REMOTE_REALM" $samba4kinit -t $KEYTAB "$REMOTE_FLAT\$@$OUR_REALM" || failed=`expr $failed + 1`
+
+rm -f $KRB5CCNAME $KEYTAB
+
+exit $failed
-- 
2.14.3



More information about the samba-technical mailing list