[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Jul 25 01:22:03 UTC 2017


The branch, master has been updated
       via  a420b1b selftest: Use NETLOGON_NEG_STRONG_KEYS constant in AuthLogTestsNetLogonBadCreds
       via  427a11b s4-netlogon: Use log_escape to protect against un-validated strings
       via  abd821b s4-netlogon: Extend ServerAuthenticate3 logging to split up username forms
       via  efc335a source4 netlogon: Add authentication logging for ServerAuthenticate3
       via  f3d3e6d tests auth_log: Add new tests for NETLOGON
       via  5c27c5b tests auth_log: Modify existing tests to handle NETLOGON messages
       via  ddfe8aa auth_log: use symbolic constant to replace /root/ncalrpc_as_system
       via  1898096 rpc: use symbolic constant to replace /root/ncalrpc_as_system
       via  6ab9f78 dcerpc.idl Add symbolic constant for /root/ncalrpc_as_system
      from  9b64b11 mit-kdb: Fix NULL pointer check after malloc

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a420b1bdccbba72faf1108f7fae8b8202075db97
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jul 18 09:03:17 2017 +1200

    selftest: Use NETLOGON_NEG_STRONG_KEYS constant in AuthLogTestsNetLogonBadCreds
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Jul 25 03:21:19 CEST 2017 on sn-devel-144

commit 427a11b812d1872879658c998ef0328dd7c2a53a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jul 18 08:57:03 2017 +1200

    s4-netlogon: Use log_escape to protect against un-validated strings
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit abd821b76b27eb8d9bc2f8acfcf9d98caf015f5f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jul 18 08:46:08 2017 +1200

    s4-netlogon: Extend ServerAuthenticate3 logging to split up username forms
    
    This splits out the username into the input, mapped and obtained
    just as we do elsewhere.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit efc335a03062740f51a6edd09d765a8b77e239c5
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 10 07:48:08 2017 +1200

    source4 netlogon: Add authentication logging for ServerAuthenticate3
    
    Log NETLOGON authentication activity by instrumenting the
    netr_ServerAuthenticate3 processing.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12865
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit f3d3e6da5a42833b8de86e9b7c0aa1c56e1c4e80
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 10 07:46:26 2017 +1200

    tests auth_log: Add new tests for NETLOGON
    
    Tests for the logging of NETLOGON authentications in the
    netr_ServerAuthenticate3 message processing
    
    Test code based on the existing auth_log tests.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12865
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 5c27c5b6efb4226aa8bdaf4e5cbb770f8b3ef22f
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 10 07:45:16 2017 +1200

    tests auth_log: Modify existing tests to handle NETLOGON messages
    
    Modify the existing tests to ignore auth logging for NETLOGON messages.
    NETLOGON authentication is logged once per session, and is tested
    separately.  Ignoring it in these tests avoids order dependencies.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12865
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit ddfe8aa9cccd78426456b6397bc7b352d9705648
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 24 10:59:18 2017 +1200

    auth_log: use symbolic constant to replace /root/ncalrpc_as_system
    
    Modified to use constant AS_SYSTEM_MAGIC_PATH_TOKEN instead of
    string literal "/root/ncalrpc_as_system"
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 1898096c7ecef4c323b14b7cf30db4283386f913
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 24 11:00:45 2017 +1200

    rpc: use symbolic constant to replace /root/ncalrpc_as_system
    
    Modified to use constant AS_SYSTEM_MAGIC_PATH_TOKEN instead of string literal
    "/root/ncalrpc_as_system"
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12865
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 6ab9f789ff6e6328cf222fdb1a39457af7ed58b4
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jul 24 10:55:48 2017 +1200

    dcerpc.idl Add symbolic constant for /root/ncalrpc_as_system
    
    This is string is used several places in the code and tests, so it
    should be a constant.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12865
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 auth/auth_log.c                                   |  12 ++
 auth/gensec/ncalrpc.c                             |   2 +-
 librpc/idl/dcerpc.idl                             |   1 +
 python/samba/tests/auth_log.py                    |  11 ++
 python/samba/tests/auth_log_base.py               |  17 +++
 python/samba/tests/auth_log_ncalrpc.py            |   3 +-
 python/samba/tests/auth_log_netlogon.py           | 131 ++++++++++++++++
 python/samba/tests/auth_log_netlogon_bad_creds.py | 178 ++++++++++++++++++++++
 python/samba/tests/auth_log_samlogon.py           |   4 +-
 source3/rpc_server/rpc_server.c                   |   2 +-
 source4/rpc_server/dcerpc_server.c                |   2 +-
 source4/rpc_server/netlogon/dcerpc_netlogon.c     | 134 ++++++++++------
 source4/selftest/tests.py                         |  18 +++
 13 files changed, 467 insertions(+), 48 deletions(-)
 create mode 100644 python/samba/tests/auth_log_netlogon.py
 create mode 100644 python/samba/tests/auth_log_netlogon_bad_creds.py


Changeset truncated at 500 lines:

diff --git a/auth/auth_log.c b/auth/auth_log.c
index 9dbf8f2..d4c6c44 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -639,6 +639,18 @@ static const char* get_password_type(const struct auth_usersupplied_info *ui)
 
 	if (ui->password_type != NULL) {
 		password_type = ui->password_type;
+	} else if (ui->auth_description != NULL &&
+		   strncmp("ServerAuthenticate", ui->auth_description, 18) == 0)
+	{
+		if (ui->netlogon_trust_account.negotiate_flags
+		    & NETLOGON_NEG_SUPPORTS_AES) {
+			password_type = "HMAC-SHA256";
+		} else if (ui->netlogon_trust_account.negotiate_flags
+		           & NETLOGON_NEG_STRONG_KEYS) {
+			password_type = "HMAC-MD5";
+		} else {
+			password_type = "DES";
+		}
 	} else if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
 		   (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
 		   ui->password.response.nt.length == 24) {
diff --git a/auth/gensec/ncalrpc.c b/auth/gensec/ncalrpc.c
index f28a1c4..70b3bb5 100644
--- a/auth/gensec/ncalrpc.c
+++ b/auth/gensec/ncalrpc.c
@@ -203,7 +203,7 @@ static NTSTATUS gensec_ncalrpc_update_internal(
 			return NT_STATUS_LOGON_FAILURE;
 		}
 
-		cmp = strcmp(unix_path, "/root/ncalrpc_as_system");
+		cmp = strcmp(unix_path, AS_SYSTEM_MAGIC_PATH_TOKEN);
 		TALLOC_FREE(unix_path);
 		if (cmp != 0) {
 			state->step = GENSEC_NCALRPC_ERROR;
diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
index 1e06bc1..bbb17f0 100644
--- a/librpc/idl/dcerpc.idl
+++ b/librpc/idl/dcerpc.idl
@@ -247,6 +247,7 @@ interface dcerpc
 		DCERPC_AUTH_TYPE_MSMQ     = 100,
 		DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM = 200
 	} dcerpc_AuthType;
+	const char *AS_SYSTEM_MAGIC_PATH_TOKEN = "/root/ncalrpc_as_system";
 
 	typedef [enum8bit] enum {
 		DCERPC_AUTH_LEVEL_NONE      = 1,
diff --git a/python/samba/tests/auth_log.py b/python/samba/tests/auth_log.py
index 65800c9..6b032a8 100644
--- a/python/samba/tests/auth_log.py
+++ b/python/samba/tests/auth_log.py
@@ -991,6 +991,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1020,6 +1021,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1049,6 +1051,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1077,6 +1080,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1106,6 +1110,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1135,6 +1140,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1164,6 +1170,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1194,6 +1201,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1224,6 +1232,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1252,6 +1261,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
@@ -1290,6 +1300,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         call(["bin/rpcclient", "-c", samlogon, "-U%", server])
 
         messages = self.waitForMessages( isLastExpectedMessage)
+        messages = self.remove_netlogon_messages(messages)
         received = len(messages)
         self.assertIs(True,
                       (received == 5 or received == 6),
diff --git a/python/samba/tests/auth_log_base.py b/python/samba/tests/auth_log_base.py
index e9ae464..aefd57e 100644
--- a/python/samba/tests/auth_log_base.py
+++ b/python/samba/tests/auth_log_base.py
@@ -62,6 +62,10 @@ class AuthLogTestBase(samba.tests.TestCase):
 
 
     def waitForMessages(self, isLastExpectedMessage, connection=None):
+        """Wait for all the expected messages to arrive
+        The connection is passed through to keep the connection alive
+        until all the logging messages have been received.
+        """
 
         def completed( messages):
             for message in messages:
@@ -102,3 +106,16 @@ class AuthLogTestBase(samba.tests.TestCase):
         while len( self.context["messages"]):
             self.msg_ctx.loop_once(0.001)
         self.context["messages"] = []
+
+    # Remove any NETLOGON authentication messages
+    # NETLOGON is only performed once per session, so to avoid ordering
+    # dependencies within the tests it's best to strip out NETLOGON messages.
+    #
+    def remove_netlogon_messages(self, messages):
+        def is_not_netlogon(msg):
+            if "Authentication" not in msg:
+                return True
+            sd = msg["Authentication"]["serviceDescription"]
+            return sd != "NETLOGON"
+
+        return list(filter(is_not_netlogon, messages))
diff --git a/python/samba/tests/auth_log_ncalrpc.py b/python/samba/tests/auth_log_ncalrpc.py
index 2538c61..be7f6b2 100644
--- a/python/samba/tests/auth_log_ncalrpc.py
+++ b/python/samba/tests/auth_log_ncalrpc.py
@@ -22,6 +22,7 @@ from samba import auth
 import samba.tests
 from samba.messaging import Messaging
 from samba.dcerpc.messaging import MSG_AUTH_LOG, AUTH_EVENT_NAME
+from samba.dcerpc.dcerpc import AS_SYSTEM_MAGIC_PATH_TOKEN
 from samba.dcerpc import samr
 import time
 import json
@@ -35,7 +36,7 @@ class AuthLogTestsNcalrpc(samba.tests.auth_log_base.AuthLogTestBase):
 
     def setUp(self):
         super(AuthLogTestsNcalrpc, self).setUp()
-        self.remoteAddress = "/root/ncalrpc_as_system"
+        self.remoteAddress = AS_SYSTEM_MAGIC_PATH_TOKEN
 
     def tearDown(self):
         super(AuthLogTestsNcalrpc , self).tearDown()
diff --git a/python/samba/tests/auth_log_netlogon.py b/python/samba/tests/auth_log_netlogon.py
new file mode 100644
index 0000000..228fbe9
--- /dev/null
+++ b/python/samba/tests/auth_log_netlogon.py
@@ -0,0 +1,131 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2017
+# Copyright (C) Catalyst IT Ltd. 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+    Tests that exercise the auth logging for a successful netlogon attempt
+
+    NOTE: As the netlogon authentication is performed once per session,
+          there is only one test in this routine.  If another test is added
+          only the test executed first will generate the netlogon auth message
+"""
+
+import samba.tests
+import os
+from samba.samdb import SamDB
+import samba.tests.auth_log_base
+from samba.credentials import Credentials
+from samba.dcerpc import netlogon
+from samba.dcerpc.dcerpc import AS_SYSTEM_MAGIC_PATH_TOKEN
+from samba.auth import system_session
+from samba.tests import delete_force
+from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_PASSWD_NOTREQD
+from samba.dcerpc.misc import SEC_CHAN_WKSTA
+
+
+class AuthLogTestsNetLogon(samba.tests.auth_log_base.AuthLogTestBase):
+
+    def setUp(self):
+        super(AuthLogTestsNetLogon, self).setUp()
+        self.lp      = samba.tests.env_loadparm()
+        self.creds   = Credentials()
+
+        self.session = system_session()
+        self.ldb = SamDB(
+            session_info=self.session,
+            credentials=self.creds,
+            lp=self.lp)
+
+        self.domain        = os.environ["DOMAIN"]
+        self.netbios_name  = "NetLogonGood"
+        self.machinepass   = "abcdefghij"
+        self.remoteAddress = AS_SYSTEM_MAGIC_PATH_TOKEN
+        self.base_dn       = self.ldb.domain_dn()
+        self.dn            = ("cn=%s,cn=users,%s" %
+                              (self.netbios_name, self.base_dn))
+
+        utf16pw = unicode(
+            '"' + self.machinepass.encode('utf-8') + '"', 'utf-8'
+        ).encode('utf-16-le')
+        self.ldb.add({
+            "dn": self.dn,
+            "objectclass": "computer",
+            "sAMAccountName": "%s$" % self.netbios_name,
+            "userAccountControl":
+                str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
+            "unicodePwd": utf16pw})
+
+    def tearDown(self):
+        super(AuthLogTestsNetLogon, self).tearDown()
+        delete_force(self.ldb, self.dn)
+
+    def _test_netlogon(self, binding, checkFunction):
+
+        def isLastExpectedMessage(msg):
+            return (
+                msg["type"] == "Authorization" and
+                msg["Authorization"]["serviceDescription"]  == "DCE/RPC" and
+                msg["Authorization"]["authType"]            == "schannel" and
+                msg["Authorization"]["transportProtection"] == "SEAL")
+
+        if binding:
+            binding = "[schannel,%s]" % binding
+        else:
+            binding = "[schannel]"
+
+        machine_creds = Credentials()
+        machine_creds.guess(self.get_loadparm())
+        machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
+        machine_creds.set_password(self.machinepass)
+        machine_creds.set_username(self.netbios_name + "$")
+
+        netlogon_conn = netlogon.netlogon("ncalrpc:%s" % binding,
+                                          self.get_loadparm(),
+                                          machine_creds)
+
+        messages = self.waitForMessages(isLastExpectedMessage, netlogon_conn)
+        checkFunction(messages)
+
+    def netlogon_check(self, messages):
+
+        expected_messages = 5
+        self.assertEquals(expected_messages,
+                          len(messages),
+                          "Did not receive the expected number of messages")
+
+        # Check the first message it should be an Authorization
+        msg = messages[0]
+        self.assertEquals("Authorization", msg["type"])
+        self.assertEquals("DCE/RPC",
+                          msg["Authorization"]["serviceDescription"])
+        self.assertEquals("ncalrpc", msg["Authorization"]["authType"])
+        self.assertEquals("NONE", msg["Authorization"]["transportProtection"])
+
+        # Check the fourth message it should be a NETLOGON Authentication
+        msg = messages[3]
+        self.assertEquals("Authentication", msg["type"])
+        self.assertEquals("NETLOGON",
+                          msg["Authentication"]["serviceDescription"])
+        self.assertEquals("ServerAuthenticate",
+                          msg["Authentication"]["authDescription"])
+        self.assertEquals("NT_STATUS_OK",
+                          msg["Authentication"]["status"])
+        self.assertEquals("HMAC-SHA256",
+                          msg["Authentication"]["passwordType"])
+
+    def test_netlogon(self):
+        self._test_netlogon("SEAL", self.netlogon_check)
diff --git a/python/samba/tests/auth_log_netlogon_bad_creds.py b/python/samba/tests/auth_log_netlogon_bad_creds.py
new file mode 100644
index 0000000..2bae02e
--- /dev/null
+++ b/python/samba/tests/auth_log_netlogon_bad_creds.py
@@ -0,0 +1,178 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2017
+# Copyright (C) Catalyst IT Ltd. 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+    Tests that exercise auth logging for unsuccessful netlogon attempts.
+
+    NOTE: netlogon is only done once per session, so this file should only
+          test failed logons.  Adding a successful case will potentially break
+          the other tests, depending on the order of execution.
+"""
+
+import samba.tests
+import os
+from samba import NTSTATUSError
+from samba.samdb import SamDB
+import samba.tests.auth_log_base
+from samba.credentials import Credentials
+from samba.dcerpc import netlogon
+from samba.dcerpc.dcerpc import AS_SYSTEM_MAGIC_PATH_TOKEN
+from samba.auth import system_session
+from samba.tests import delete_force
+from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_PASSWD_NOTREQD
+from samba.dcerpc.misc import SEC_CHAN_WKSTA
+from samba.dcerpc.netlogon import NETLOGON_NEG_STRONG_KEYS
+
+class AuthLogTestsNetLogonBadCreds(samba.tests.auth_log_base.AuthLogTestBase):
+
+    def setUp(self):
+        super(AuthLogTestsNetLogonBadCreds, self).setUp()
+        self.lp      = samba.tests.env_loadparm()
+        self.creds   = Credentials()
+
+        self.session = system_session()
+        self.ldb = SamDB(
+            session_info=self.session,
+            credentials=self.creds,
+            lp=self.lp)
+
+        self.domain        = os.environ["DOMAIN"]
+        self.netbios_name  = "NetLogonBad"
+        self.machinepass   = "abcdefghij"
+        self.remoteAddress = AS_SYSTEM_MAGIC_PATH_TOKEN
+        self.base_dn       = self.ldb.domain_dn()
+        self.dn            = ("cn=%s,cn=users,%s" %
+                              (self.netbios_name, self.base_dn))
+
+        utf16pw = unicode(
+            '"' + self.machinepass.encode('utf-8') + '"', 'utf-8'
+        ).encode('utf-16-le')
+        self.ldb.add({
+            "dn": self.dn,
+            "objectclass": "computer",
+            "sAMAccountName": "%s$" % self.netbios_name,
+            "userAccountControl":
+                str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
+            "unicodePwd": utf16pw})
+
+    def tearDown(self):
+        super(AuthLogTestsNetLogonBadCreds, self).tearDown()
+        delete_force(self.ldb, self.dn)
+
+    def _test_netlogon(self, name, pwd, status, checkFunction):
+
+        def isLastExpectedMessage(msg):
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "NETLOGON" and
+                msg["Authentication"]["authDescription"] ==
+                "ServerAuthenticate" and
+                msg["Authentication"]["status"] == status)
+
+        machine_creds = Credentials()
+        machine_creds.guess(self.get_loadparm())
+        machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
+        machine_creds.set_password(pwd)
+        machine_creds.set_username(name + "$")
+
+        try:
+            netlogon.netlogon("ncalrpc:[schannel]",
+                              self.get_loadparm(),
+                              machine_creds)
+            self.fail("NTSTATUSError not raised")
+        except NTSTATUSError:
+            pass
+
+        messages = self.waitForMessages(isLastExpectedMessage)
+        checkFunction(messages)
+
+    def netlogon_check(self, messages):
+
+        expected_messages = 4
+        self.assertEquals(expected_messages,
+                          len(messages),
+                          "Did not receive the expected number of messages")
+
+        # Check the first message it should be an Authorization
+        msg = messages[0]
+        self.assertEquals("Authorization", msg["type"])
+        self.assertEquals("DCE/RPC",
+                          msg["Authorization"]["serviceDescription"])
+        self.assertEquals("ncalrpc", msg["Authorization"]["authType"])
+        self.assertEquals("NONE", msg["Authorization"]["transportProtection"])
+
+    def test_netlogon_bad_machine_name(self):
+        self._test_netlogon("bad_name",
+                            self.machinepass,
+                            "NT_STATUS_NO_TRUST_SAM_ACCOUNT",
+                            self.netlogon_check)
+
+    def test_netlogon_bad_password(self):
+        self._test_netlogon(self.netbios_name,
+                            "badpass",
+                            "NT_STATUS_ACCESS_DENIED",
+                            self.netlogon_check)
+
+    def test_netlogon_password_DES(self):
+        """Logon failure that exercises the "DES" passwordType path.
+        """
+        def isLastExpectedMessage(msg):
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "NETLOGON" and
+                msg["Authentication"]["authDescription"] ==
+                "ServerAuthenticate" and
+                msg["Authentication"]["passwordType"] == "DES")
+
+        c = netlogon.netlogon("ncalrpc:[schannel]", self.get_loadparm())
+        creds = netlogon.netr_Credential()
+        c.netr_ServerReqChallenge(self.server, self.netbios_name, creds)
+        try:
+            c.netr_ServerAuthenticate3(self.server,
+                                       self.netbios_name,
+                                       SEC_CHAN_WKSTA,
+                                       self.netbios_name,
+                                       creds,
+                                       0)
+        except NTSTATUSError:
+            pass
+        self.waitForMessages(isLastExpectedMessage)
+
+    def test_netlogon_password_HMAC_MD5(self):
+        """Logon failure that exercises the "HMAC-MD5" passwordType path.
+        """
+        def isLastExpectedMessage(msg):
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "NETLOGON" and
+                msg["Authentication"]["authDescription"] ==
+                "ServerAuthenticate" and


-- 
Samba Shared Repository



More information about the samba-cvs mailing list