From 95a3d7a16fcd0a43ee705fcfd9f5677206d2b240 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Thu, 19 Apr 2018 17:05:21 +1200 Subject: [PATCH 01/17] Fix a few typo for response reponse --> response Signed-off-by: Joe Guo --- auth/credentials/pycredentials.c | 2 +- auth/ntlmssp/ntlmssp_client.c | 2 +- examples/pcap2nbench/readandxresponse.hpp | 2 +- source4/torture/krb5/kdc-canon-heimdal.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 638ae8de2ed..68bb3060a99 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -130,7 +130,7 @@ static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyOb ret = Py_BuildValue("{sis" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "}", "flags", flags, - "lm_reponse", + "lm_response", (const char *)lm_response.data, lm_response.length, "nt_response", (const char *)nt_response.data, nt_response.length, diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index db2003f0d6b..c511290d36b 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -777,7 +777,7 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true); - ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); + ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_response", true); ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx); diff --git a/examples/pcap2nbench/readandxresponse.hpp b/examples/pcap2nbench/readandxresponse.hpp index 0a302cb6575..8ecb3a35c0c 100644 --- a/examples/pcap2nbench/readandxresponse.hpp +++ b/examples/pcap2nbench/readandxresponse.hpp @@ -22,7 +22,7 @@ #define _READ_AND_X_RESPONSE_HPP class ReadAndXResponse { - ReadAndXReponse(const uint8_t *data, size_t size); + ReadAndXResponse(const uint8_t *data, size_t size); uint8_t word_count; uint8_t and_x_command; diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c index 7f806e73e66..5b782a23fc4 100644 --- a/source4/torture/krb5/kdc-canon-heimdal.c +++ b/source4/torture/krb5/kdc-canon-heimdal.c @@ -515,7 +515,7 @@ static bool torture_krb5_post_recv_tgs_req_krbtgt_canon_test(struct torture_krb5 torture_assert_str_equal(test_context->tctx, test_context->tgs_rep.ticket.sname.name_string.val[0], "krbtgt", - "Mismatch in name between reponse and expected response, expected krbtgt"); + "Mismatch in name between response and expected response, expected krbtgt"); torture_assert_str_equal(test_context->tctx, test_context->tgs_rep.ticket.sname.name_string.val[1], test_context->test_data->real_realm, "Mismatch in realm part of krbtgt/ in expected response, expected krbtgt/REALM@REALM"); From ed4bec2211e8176f98756d215f31d97a33c03490 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 2 May 2018 04:41:04 +0000 Subject: [PATCH 02/17] samdb: fix wrong computer container dn for newcomputer CN=Users --> CN=Computers Signed-off-by: Joe Guo --- python/samba/samdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/samdb.py b/python/samba/samdb.py index b66afb7431c..424a648446b 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -508,7 +508,7 @@ def newcomputer(self, computername, computerou=None, description=None, raise Exception('Illegal computername "%s"' % computername) samaccountname = "%s$" % cn - computercontainer_dn = "CN=Users,%s" % self.domain_dn() + computercontainer_dn = "CN=Computers,%s" % self.domain_dn() if computerou: computercontainer_dn = self.normalize_dn_in_domain(computerou) From ec81eae9db23982f7d8bf42e4d57ae330b4b3e0c Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 18 Apr 2018 15:31:12 +1200 Subject: [PATCH 03/17] traffic_replay: set gensec features to encrypt credentials While running traffic_replay script against windows dc, it will fail with a `LDAP_UNWILLING_TO_PERFORM` error for adding user. Windows requires the credentials to be encrypted before sending. `set_gensec_features` will fix it. Signed-off-by: Joe Guo --- script/traffic_replay | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/traffic_replay b/script/traffic_replay index 0e97d0a64af..df86115a48f 100755 --- a/script/traffic_replay +++ b/script/traffic_replay @@ -25,6 +25,7 @@ import shutil sys.path.insert(0, "bin/python") +from samba import gensec from samba.emulate import traffic import samba.getopt as options @@ -134,6 +135,7 @@ def main(): print_err("Removing user and machine accounts") lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) + creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) ldb = traffic.openLdb(host, creds, lp) traffic.clean_up_accounts(ldb, opts.instance_id) exit(0) @@ -155,6 +157,7 @@ def main(): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) + creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) domain = opts.workgroup if domain: From af05138f7b65d4e4c040cf49a56bc8dcedcd319b Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 18 Apr 2018 15:36:02 +1200 Subject: [PATCH 04/17] traffic: add paged_results control for ldb search While there are more then 1000 records in the search result, a `LDAP_SIZE_LIMIT_EXCEEDED` error will be returned. Add paged_results control to fix. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index 9d95e3a14d5..a99cf9163a5 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -343,6 +343,7 @@ def generate_ldap_search_tables(self): res = db.search(db.domain_dn(), scope=ldb.SCOPE_SUBTREE, + controls=["paged_results:1:1000"], attrs=['dn']) # find a list of dns for each pattern From 7069acf52bbd065060a561eab8035cfaf76291d8 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 18 Apr 2018 15:40:18 +1200 Subject: [PATCH 05/17] traffic_replay: fix typo in message string Signed-off-by: Joe Guo --- script/traffic_replay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/traffic_replay b/script/traffic_replay index df86115a48f..a56ea25d5c9 100755 --- a/script/traffic_replay +++ b/script/traffic_replay @@ -37,7 +37,7 @@ def print_err(*args, **kwargs): def main(): desc = ("Generates network traffic 'conversations' based on " - " (which should the output file produced by either traffic_learner" + " (which should be the output file produced by either traffic_learner" " or traffic_summary.pl). This traffic is sent to ," " which is the full DNS hostname of the DC being tested.") From c9b6b8348f43c8f87af90980e762024998eae78e Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 18 Apr 2018 15:45:10 +1200 Subject: [PATCH 06/17] traffic_packets: support NT_STATUS_NO_SUCH_DOMAIN in packet_lsarpc_39 For packet_lsarpc_39, samba will return NT_STATUS_OBJECT_NAME_NOT_FOUND, however, windows will return NT_STATUS_NO_SUCH_DOMAIN. Allow both status for now to keep compatiable with both samba and windows DC. Signed-off-by: Joe Guo --- python/samba/emulate/traffic_packets.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 688c935cdc0..89f97b41f8b 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -31,7 +31,10 @@ DONT_USE_KERBEROS ) from samba import NTSTATUSError -from samba.ntstatus import NT_STATUS_OBJECT_NAME_NOT_FOUND +from samba.ntstatus import ( + NT_STATUS_OBJECT_NAME_NOT_FOUND, + NT_STATUS_NO_SUCH_DOMAIN +) from samba.dcerpc.misc import SEC_CHAN_WKSTA import samba samba.ensure_third_party_module("dns", "dnspython") @@ -429,9 +432,11 @@ def packet_lsarpc_39(packet, conversation, context): try: c.QueryTrustedDomainInfoBySid(pol_handle, domsid, level) except NTSTATUSError as error: - # Object Not found is the expected result, anything else is a - # failure. - if not check_runtime_error(error, NT_STATUS_OBJECT_NAME_NOT_FOUND): + # Object Not found is the expected result from samba, + # while No Such Domain is the expected result from windows, + # anything else is a failure. + if not check_runtime_error(error, NT_STATUS_OBJECT_NAME_NOT_FOUND) \ + and not check_runtime_error(error, NT_STATUS_NO_SUCH_DOMAIN): raise return True From b4dbbc78dca6f3fdc06bb812c5dfd1a9de478faf Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Thu, 26 Apr 2018 12:15:10 +1200 Subject: [PATCH 07/17] traffic: add credentials to samr lp and creds are missing in SamrContext and samr connection. While run traffic_replay against windows, this will cause `Access Denied` error. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index a99cf9163a5..8fa3dab3edb 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -670,7 +670,8 @@ def sasl_bind(creds): def get_samr_context(self, new=False): if not self.samr_contexts or new: - self.samr_contexts.append(SamrContext(self.server)) + self.samr_contexts.append( + SamrContext(self.server, lp=self.lp, creds=self.creds)) return self.samr_contexts[-1] def get_netlogon_connection(self): @@ -707,7 +708,7 @@ def get_authenticator(self): class SamrContext(object): """State/Context associated with a samr connection. """ - def __init__(self, server): + def __init__(self, server, lp=None, creds=None): self.connection = None self.handle = None self.domain_handle = None @@ -716,10 +717,16 @@ def __init__(self, server): self.user_handle = None self.rids = None self.server = server + self.lp = lp + self.creds = creds def get_connection(self): if not self.connection: - self.connection = samr.samr("ncacn_ip_tcp:%s" % (self.server)) + self.connection = samr.samr( + "ncacn_ip_tcp:%s[seal]" % (self.server), + lp_ctx=self.lp, + credentials=self.creds) + return self.connection def get_handle(self): From 94d0a04583fdf2c452d393082ebf3a9ef1205a49 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Fri, 27 Apr 2018 11:27:59 +1200 Subject: [PATCH 08/17] traffic_packets: replace level 102 to 101 for packet_srvsvc_21 Level 102 will cause WERR_ACCESS_DENIED error against Windows, because: > If the level is 102 or 502, the Windows implementation checks whether > the caller is a member of one of the groups previously mentioned or > is a member of the Power Users local group. It passed against Samba since this check is not implemented by Samba yet. refer to: https://msdn.microsoft.com/en-us/library/cc247297.aspx#Appendix_A_80 Signed-off-by: Joe Guo --- python/samba/emulate/traffic_packets.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 89f97b41f8b..9b81e07edbd 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -932,9 +932,25 @@ def packet_srvsvc_16(packet, conversation, context): def packet_srvsvc_21(packet, conversation, context): - # NetSrvGetInfo + """NetSrvGetInfo + + FIXME: Level changed from 102 to 101 here, to bypass Windows error. + + Level 102 will cause WERR_ACCESS_DENIED error against Windows, because: + + > If the level is 102 or 502, the Windows implementation checks whether + > the caller is a member of one of the groups previously mentioned or + > is a member of the Power Users local group. + + It passed against Samba since this check is not implemented by Samba yet. + + refer to: + + https://msdn.microsoft.com/en-us/library/cc247297.aspx#Appendix_A_80 + + """ srvsvc = context.get_srvsvc_connection() server_unc = "\\\\" + context.server - level = 102 + level = 101 srvsvc.NetSrvGetInfo(server_unc, level) return True From ff32da3ffc7dd05eb1a5ba2f805949f43d8d244a Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Fri, 27 Apr 2018 12:07:16 +1200 Subject: [PATCH 09/17] traffic_packets: replace share_name from netlogon to IPC$ for packet_srvsvc_16 Sharename list for Windows: Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC For Samba: Sharename Type Comment --------- ---- ------- netlogon Disk sysvol Disk IPC$ IPC IPC Service While test packet_srvsvc_16 with share_name `netlogon`, it passed Samba, and got a WERR_NERR_NETNAMENOTFOUND error for Windows. Change share name to `IPC$` so Samba and Windows have it in common. Signed-off-by: Joe Guo --- python/samba/emulate/traffic_packets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 9b81e07edbd..5785586f835 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -925,7 +925,7 @@ def packet_srvsvc_16(packet, conversation, context): # NetShareGetInfo s = context.get_srvsvc_connection() server_unc = "\\\\" + context.server - share_name = "netlogon" + share_name = "IPC$" level = 1 s.NetShareGetInfo(server_unc, share_name, level) return True From 8f235f19e924d38b24bc471b1da2dfa13446fb88 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Fri, 27 Apr 2018 14:51:11 +1200 Subject: [PATCH 10/17] traffic_packets: add windows instructions for ldap 0 simple bind To run packet_ldap_0 simple bind test against Windows, we need to install CA on Windows with following PowerShell commands: Install-windowsfeature ADCS-Cert-Authority Install-AdcsCertificationAuthority -CAType EnterpriseRootCA Restart-Computer Otherwise we will get `NT_STATUS_CONNECTION_RESET` error. Didn't change any code, just add above instructions in comment. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index 8fa3dab3edb..8275218114d 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -644,6 +644,15 @@ def get_ldap_connection(self, new=False, simple=False): return self.ldap_connections[-1] def simple_bind(creds): + """ + To run simple bind against Windows, we need to run + following commands in PowerShell: + + Install-windowsfeature ADCS-Cert-Authority + Install-AdcsCertificationAuthority -CAType EnterpriseRootCA + Restart-Computer + + """ return SamDB('ldaps://%s' % self.server, credentials=creds, lp=self.lp) From 82dbfa51306532f37b81a167f4071616c20405ea Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Tue, 1 May 2018 17:15:09 +1200 Subject: [PATCH 11/17] traffic_packets: add trailing $ to fix packet_rpc_netlogon_30 For `NetrServerPasswordSet2`, the 2nd arg `account_name` must end with a $, otherwise windows will return an `Access Denied` error. Use `creds.get_username()` instead of `creds.get_workstation()` to include the trailing $. Signed-off-by: Joe Guo --- python/samba/emulate/traffic_packets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 5785586f835..b46c7bc50ff 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -561,7 +561,9 @@ def packet_rpc_netlogon_30(packet, conversation, context): pwd.data = filler + [ord(x) for x in newpass] context.machine_creds.encrypt_netr_crypt_password(pwd) c.netr_ServerPasswordSet2(context.server, - context.machine_creds.get_workstation(), + # must ends with $, so use get_username instead + # of get_workstation here + context.machine_creds.get_username(), SEC_CHAN_WKSTA, context.netbios_name, auth, From ebf0404c09ce8524ab4ab69de4dd2fc6e28dc45d Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Tue, 1 May 2018 12:44:43 +1200 Subject: [PATCH 12/17] cmd_drsuapi: add dswriteaccountspn command The dswriteaccountspn command is missing in drsuapi, add it so we can use it in rpcclient. Signed-off-by: Joe Guo --- source3/rpcclient/cmd_drsuapi.c | 91 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/source3/rpcclient/cmd_drsuapi.c b/source3/rpcclient/cmd_drsuapi.c index b2221a713dd..852e2e91479 100644 --- a/source3/rpcclient/cmd_drsuapi.c +++ b/source3/rpcclient/cmd_drsuapi.c @@ -304,6 +304,96 @@ static WERROR cmd_drsuapi_getdcinfo(struct rpc_pipe_client *cli, return werr; } +static WERROR cmd_drsuapi_writeaccountspn(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + + struct GUID bind_guid; + struct policy_handle bind_handle; + struct dcerpc_binding_handle *b = cli->binding_handle; + struct drsuapi_DsNameString *spn_names = NULL; + + int i = 0; + uint32_t level_out; + union drsuapi_DsWriteAccountSpnRequest req; + union drsuapi_DsWriteAccountSpnResult result; + + if (argc < 4) { + printf("usage: %s [add|replace|delete] dn [spn_names]+\n", argv[0]); + return WERR_OK; + } + + req.req1.unknown1 = 0; /* Unused, must be 0 */ + req.req1.object_dn = argv[2]; + req.req1.count = argc - 3; + + if (strcmp(argv[1], "add") == 0) { + req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD; + } else if (strcmp(argv[1], "replace") == 0) { + req.req1.operation = DRSUAPI_DS_SPN_OPERATION_REPLACE; + } else if (strcmp(argv[1], "delete") == 0) { + req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE; + } else { + printf("usage: %s [add|replace|delete] dn [spn_names]+\n", argv[0]); + return WERR_OK; + } + + spn_names = talloc_zero_array(mem_ctx, + struct drsuapi_DsNameString, + req.req1.count); + W_ERROR_HAVE_NO_MEMORY(spn_names); + + for (i=0; i Date: Tue, 1 May 2018 16:58:01 +1200 Subject: [PATCH 13/17] traffic_packets: provision request data for packet_drsuapi_13 The `drsuapi.DsWriteAccountSpnRequest1` struct in this packet was empty before. Samba lets it go but Windows will report an invalid parameter error. Provision the request with proper data, and give user permission to write account SPN. Signed-off-by: Joe Guo --- python/samba/emulate/traffic_packets.py | 8 +++++++- python/samba/tests/emulate/traffic_packet.py | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index b46c7bc50ff..7db2282b2b8 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -242,7 +242,13 @@ def packet_drsuapi_12(packet, conversation, context): def packet_drsuapi_13(packet, conversation, context): # DsWriteAccountSpn req = drsuapi.DsWriteAccountSpnRequest1() - req.operation = drsuapi.DRSUAPI_DS_SPN_OPERATION_ADD + req.operation = drsuapi.DRSUAPI_DS_SPN_OPERATION_REPLACE + req.unknown1 = 0 # Unused, must be 0 + req.object_dn = context.user_dn + req.count = 1 # only 1 name + spn_name = drsuapi.DsNameString() + spn_name.str = 'foo/{}'.format(context.username) + req.spn_names = [spn_name] (drs, handle) = context.get_drsuapi_connection_pair() (level, res) = drs.DsWriteAccountSpn(handle, 1, req) return True diff --git a/python/samba/tests/emulate/traffic_packet.py b/python/samba/tests/emulate/traffic_packet.py index 8aa6ca03247..61fd9008964 100644 --- a/python/samba/tests/emulate/traffic_packet.py +++ b/python/samba/tests/emulate/traffic_packet.py @@ -28,6 +28,7 @@ from samba.samdb import SamDB import samba.tests +from samba import sd_utils class TrafficEmulatorPacketTests(samba.tests.TestCase): @@ -79,6 +80,11 @@ def setUp(self): self.context.generate_process_local_config(account, self.conversation) + # grant user write permission to do things like write account SPN + sdutils = sd_utils.SDUtils(self.ldb) + mod = "(A;;WP;;;PS)" + sdutils.dacl_add_ace(self.context.user_dn, mod) + def tearDown(self): super(TrafficEmulatorPacketTests, self).tearDown() traffic.clean_up_accounts(self.ldb, 1) From 1605f14526b0282a0845337e01b9759c99af14d4 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 2 May 2018 05:04:03 +0000 Subject: [PATCH 14/17] traffic: set domain on user_creds and machine_creds The domain is missing in traffic user and machine credential, this will cause some packet tests fail against windows. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index 8275218114d..64b40fbece0 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -456,6 +456,7 @@ def generate_user_creds(self): self.user_creds.set_workstation(self.netbios_name) self.user_creds.set_password(self.userpass) self.user_creds.set_username(self.username) + self.user_creds.set_domain(self.domain) if self.prefer_kerberos: self.user_creds.set_kerberos_state(MUST_USE_KERBEROS) else: @@ -513,6 +514,7 @@ def generate_machine_creds(self): self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) self.machine_creds.set_password(self.machinepass) self.machine_creds.set_username(self.netbios_name + "$") + self.machine_creds.set_domain(self.domain) if self.prefer_kerberos: self.machine_creds.set_kerberos_state(MUST_USE_KERBEROS) else: From 9c45e6c166a9b1ca14cb877b5196842b01d0d942 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 2 May 2018 21:40:39 +0000 Subject: [PATCH 15/17] pycredentials: add py_creds_get_secure_channel_type We have only set, need get. Signed-off-by: Joe Guo --- auth/credentials/pycredentials.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 68bb3060a99..c626e3fa8a0 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -680,6 +680,16 @@ static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args Py_RETURN_NONE; } +static PyObject *py_creds_get_secure_channel_type(PyObject *self, PyObject *args) +{ + enum netr_SchannelType channel_type = SEC_CHAN_NULL; + + channel_type = cli_credentials_get_secure_channel_type( + PyCredentials_AsCliCredentials(self)); + + return PyInt_FromLong(channel_type); +} + static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self, PyObject *args) { @@ -815,6 +825,8 @@ static PyMethodDef py_creds_methods[] = { "Get a new client NETLOGON_AUTHENTICATOR"}, { "set_secure_channel_type", py_creds_set_secure_channel_type, METH_VARARGS, NULL }, + { "get_secure_channel_type", py_creds_get_secure_channel_type, + METH_VARARGS }, { "encrypt_netr_crypt_password", py_creds_encrypt_netr_crypt_password, METH_VARARGS, From fcde3d457e325849541b37380f767e99b9a4031d Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 2 May 2018 22:12:51 +0000 Subject: [PATCH 16/17] traffic: change machine creds secure channel type SEC_CHAN_WKSTA --> SEC_CHAN_BDC This will fix netlogon failure against windows. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 6 +++--- python/samba/emulate/traffic_packets.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index 64b40fbece0..b50689ce77a 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -44,7 +44,7 @@ from samba.auth import system_session from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_PASSWD_NOTREQD from samba.dsdb import UF_NORMAL_ACCOUNT -from samba.dcerpc.misc import SEC_CHAN_WKSTA +from samba.dcerpc.misc import SEC_CHAN_BDC from samba import gensec SLEEP_OVERHEAD = 3e-4 @@ -511,7 +511,7 @@ def generate_machine_creds(self): self.machine_creds = Credentials() self.machine_creds.guess(self.lp) self.machine_creds.set_workstation(self.netbios_name) - self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) + self.machine_creds.set_secure_channel_type(SEC_CHAN_BDC) self.machine_creds.set_password(self.machinepass) self.machine_creds.set_username(self.netbios_name + "$") self.machine_creds.set_domain(self.domain) @@ -523,7 +523,7 @@ def generate_machine_creds(self): self.machine_creds_bad = Credentials() self.machine_creds_bad.guess(self.lp) self.machine_creds_bad.set_workstation(self.netbios_name) - self.machine_creds_bad.set_secure_channel_type(SEC_CHAN_WKSTA) + self.machine_creds_bad.set_secure_channel_type(SEC_CHAN_BDC) self.machine_creds_bad.set_password(self.machinepass[:-4]) self.machine_creds_bad.set_username(self.netbios_name + "$") if self.prefer_kerberos: diff --git a/python/samba/emulate/traffic_packets.py b/python/samba/emulate/traffic_packets.py index 7db2282b2b8..306cd613579 100644 --- a/python/samba/emulate/traffic_packets.py +++ b/python/samba/emulate/traffic_packets.py @@ -35,7 +35,6 @@ NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_NO_SUCH_DOMAIN ) -from samba.dcerpc.misc import SEC_CHAN_WKSTA import samba samba.ensure_third_party_module("dns", "dnspython") import dns.resolver @@ -570,7 +569,7 @@ def packet_rpc_netlogon_30(packet, conversation, context): # must ends with $, so use get_username instead # of get_workstation here context.machine_creds.get_username(), - SEC_CHAN_WKSTA, + context.machine_creds.get_secure_channel_type(), context.netbios_name, auth, pwd) From be316970a104d64c786ae5d8dd81c2b18b11f849 Mon Sep 17 00:00:00 2001 From: Joe Guo Date: Wed, 2 May 2018 22:22:52 +0000 Subject: [PATCH 17/17] traffic: fix userAccountControl for machine account change userAccountControl from UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD to UF_TRUSTED_FOR_DELEGATION | UF_SERVER_TRUST_ACCOUNT This will fix NetrServerPasswordSet2 failure in packet_rpc_netlogon_30 while testing against windows. Signed-off-by: Joe Guo --- python/samba/emulate/traffic.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/samba/emulate/traffic.py b/python/samba/emulate/traffic.py index b50689ce77a..1720afa61c8 100644 --- a/python/samba/emulate/traffic.py +++ b/python/samba/emulate/traffic.py @@ -42,8 +42,11 @@ import traceback from samba.credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS from samba.auth import system_session -from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_PASSWD_NOTREQD -from samba.dsdb import UF_NORMAL_ACCOUNT +from samba.dsdb import ( + UF_NORMAL_ACCOUNT, + UF_SERVER_TRUST_ACCOUNT, + UF_TRUSTED_FOR_DELEGATION +) from samba.dcerpc.misc import SEC_CHAN_BDC from samba import gensec @@ -1667,7 +1670,7 @@ def create_machine_account(ldb, instance_id, netbios_name, machinepass): "objectclass": "computer", "sAMAccountName": "%s$" % netbios_name, "userAccountControl": - str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), + str(UF_TRUSTED_FOR_DELEGATION | UF_SERVER_TRUST_ACCOUNT), "unicodePwd": utf16pw}) end = time.time() duration = end - start