diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /python/samba/tests/auth_log_netlogon_bad_creds.py | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'python/samba/tests/auth_log_netlogon_bad_creds.py')
-rw-r--r-- | python/samba/tests/auth_log_netlogon_bad_creds.py | 190 |
1 files changed, 190 insertions, 0 deletions
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..e97ca85 --- /dev/null +++ b/python/samba/tests/auth_log_netlogon_bad_creds.py @@ -0,0 +1,190 @@ +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Bartlett <abartlet@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 +from samba.common import get_string +from samba.dcerpc.windows_event_ids import ( + EVT_ID_UNSUCCESSFUL_LOGON, + EVT_LOGON_NETWORK +) + + +class AuthLogTestsNetLogonBadCreds(samba.tests.auth_log_base.AuthLogTestBase): + + def setUp(self): + super().setUp() + self.lp = samba.tests.env_loadparm() + self.session = system_session() + self.ldb = SamDB( + session_info=self.session, + 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 = get_string('"' + self.machinepass + '"').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().tearDown() + delete_force(self.ldb, self.dn) + + def _test_netlogon(self, name, pwd, status, checkFunction, event_id): + + def isLastExpectedMessage(msg): + return ( + msg["type"] == "Authentication" and + msg["Authentication"]["serviceDescription"] == "NETLOGON" and + msg["Authentication"]["authDescription"] == + "ServerAuthenticate" and + msg["Authentication"]["status"] == status and + msg["Authentication"]["eventId"] == event_id and + msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK) + + 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.assertEqual(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.assertEqual("Authorization", msg["type"]) + self.assertEqual("DCE/RPC", + msg["Authorization"]["serviceDescription"]) + self.assertEqual("ncalrpc", msg["Authorization"]["authType"]) + self.assertEqual("NONE", msg["Authorization"]["transportProtection"]) + self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"])) + + def test_netlogon_bad_machine_name(self): + self._test_netlogon("bad_name", + self.machinepass, + "NT_STATUS_NO_TRUST_SAM_ACCOUNT", + self.netlogon_check, + EVT_ID_UNSUCCESSFUL_LOGON) + + def test_netlogon_bad_password(self): + self._test_netlogon(self.netbios_name, + "badpass", + "NT_STATUS_ACCESS_DENIED", + self.netlogon_check, + EVT_ID_UNSUCCESSFUL_LOGON) + + 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" and + (msg["Authentication"]["eventId"] == + EVT_ID_UNSUCCESSFUL_LOGON) and + msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK) + + 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 + msg["Authentication"]["passwordType"] == "HMAC-MD5" and + (msg["Authentication"]["eventId"] == + EVT_ID_UNSUCCESSFUL_LOGON) and + msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK) + + 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, + NETLOGON_NEG_STRONG_KEYS) + except NTSTATUSError: + pass + self.waitForMessages(isLastExpectedMessage) |