auth log: Add windows event codes
[vlendec/samba-autobuild/.git] / python / samba / tests / auth_log_netlogon_bad_creds.py
1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
3 # Copyright (C) Catalyst IT Ltd. 2017
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18
19 """
20     Tests that exercise auth logging for unsuccessful netlogon attempts.
21
22     NOTE: netlogon is only done once per session, so this file should only
23           test failed logons.  Adding a successful case will potentially break
24           the other tests, depending on the order of execution.
25 """
26
27 import samba.tests
28 import os
29 from samba import NTSTATUSError
30 from samba.samdb import SamDB
31 import samba.tests.auth_log_base
32 from samba.credentials import Credentials
33 from samba.dcerpc import netlogon
34 from samba.dcerpc.dcerpc import AS_SYSTEM_MAGIC_PATH_TOKEN
35 from samba.auth import system_session
36 from samba.tests import delete_force
37 from samba.dsdb import UF_WORKSTATION_TRUST_ACCOUNT, UF_PASSWD_NOTREQD
38 from samba.dcerpc.misc import SEC_CHAN_WKSTA
39 from samba.dcerpc.netlogon import NETLOGON_NEG_STRONG_KEYS
40 from samba.compat import get_string
41 from samba.dcerpc.windows_event_ids import EVT_ID_UNSUCCESSFUL_LOGON
42
43
44 class AuthLogTestsNetLogonBadCreds(samba.tests.auth_log_base.AuthLogTestBase):
45
46     def setUp(self):
47         super(AuthLogTestsNetLogonBadCreds, self).setUp()
48         self.lp      = samba.tests.env_loadparm()
49         self.creds   = Credentials()
50
51         self.session = system_session()
52         self.ldb = SamDB(
53             session_info=self.session,
54             credentials=self.creds,
55             lp=self.lp)
56
57         self.domain        = os.environ["DOMAIN"]
58         self.netbios_name  = "NetLogonBad"
59         self.machinepass   = "abcdefghij"
60         self.remoteAddress = AS_SYSTEM_MAGIC_PATH_TOKEN
61         self.base_dn       = self.ldb.domain_dn()
62         self.dn            = ("cn=%s,cn=users,%s" %
63                               (self.netbios_name, self.base_dn))
64
65         utf16pw = get_string('"' + self.machinepass + '"').encode('utf-16-le')
66         self.ldb.add({
67             "dn": self.dn,
68             "objectclass": "computer",
69             "sAMAccountName": "%s$" % self.netbios_name,
70             "userAccountControl":
71                 str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
72             "unicodePwd": utf16pw})
73
74     def tearDown(self):
75         super(AuthLogTestsNetLogonBadCreds, self).tearDown()
76         delete_force(self.ldb, self.dn)
77
78     def _test_netlogon(self, name, pwd, status, checkFunction, event_id):
79
80         def isLastExpectedMessage(msg):
81             return (
82                 msg["type"] == "Authentication" and
83                 msg["Authentication"]["serviceDescription"] == "NETLOGON" and
84                 msg["Authentication"]["authDescription"] ==
85                 "ServerAuthenticate" and
86                 msg["Authentication"]["status"] == status and
87                 msg["Authentication"]["eventId"] == event_id)
88
89         machine_creds = Credentials()
90         machine_creds.guess(self.get_loadparm())
91         machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
92         machine_creds.set_password(pwd)
93         machine_creds.set_username(name + "$")
94
95         try:
96             netlogon.netlogon("ncalrpc:[schannel]",
97                               self.get_loadparm(),
98                               machine_creds)
99             self.fail("NTSTATUSError not raised")
100         except NTSTATUSError:
101             pass
102
103         messages = self.waitForMessages(isLastExpectedMessage)
104         checkFunction(messages)
105
106     def netlogon_check(self, messages):
107
108         expected_messages = 4
109         self.assertEquals(expected_messages,
110                           len(messages),
111                           "Did not receive the expected number of messages")
112
113         # Check the first message it should be an Authorization
114         msg = messages[0]
115         self.assertEquals("Authorization", msg["type"])
116         self.assertEquals("DCE/RPC",
117                           msg["Authorization"]["serviceDescription"])
118         self.assertEquals("ncalrpc", msg["Authorization"]["authType"])
119         self.assertEquals("NONE", msg["Authorization"]["transportProtection"])
120         self.assertTrue(self.is_guid(msg["Authorization"]["sessionId"]))
121
122     def test_netlogon_bad_machine_name(self):
123         self._test_netlogon("bad_name",
124                             self.machinepass,
125                             "NT_STATUS_NO_TRUST_SAM_ACCOUNT",
126                             self.netlogon_check,
127                             EVT_ID_UNSUCCESSFUL_LOGON)
128
129     def test_netlogon_bad_password(self):
130         self._test_netlogon(self.netbios_name,
131                             "badpass",
132                             "NT_STATUS_ACCESS_DENIED",
133                             self.netlogon_check,
134                             EVT_ID_UNSUCCESSFUL_LOGON)
135
136     def test_netlogon_password_DES(self):
137         """Logon failure that exercises the "DES" passwordType path.
138         """
139         def isLastExpectedMessage(msg):
140             return (
141                 msg["type"] == "Authentication" and
142                 msg["Authentication"]["serviceDescription"] == "NETLOGON" and
143                 msg["Authentication"]["authDescription"] ==
144                 "ServerAuthenticate" and
145                 msg["Authentication"]["passwordType"] == "DES" and
146                 msg["Authentication"]["eventId"] == EVT_ID_UNSUCCESSFUL_LOGON)
147
148         c = netlogon.netlogon("ncalrpc:[schannel]", self.get_loadparm())
149         creds = netlogon.netr_Credential()
150         c.netr_ServerReqChallenge(self.server, self.netbios_name, creds)
151         try:
152             c.netr_ServerAuthenticate3(self.server,
153                                        self.netbios_name,
154                                        SEC_CHAN_WKSTA,
155                                        self.netbios_name,
156                                        creds,
157                                        0)
158         except NTSTATUSError:
159             pass
160         self.waitForMessages(isLastExpectedMessage)
161
162     def test_netlogon_password_HMAC_MD5(self):
163         """Logon failure that exercises the "HMAC-MD5" passwordType path.
164         """
165         def isLastExpectedMessage(msg):
166             return (
167                 msg["type"] == "Authentication" and
168                 msg["Authentication"]["serviceDescription"] == "NETLOGON" and
169                 msg["Authentication"]["authDescription"] ==
170                 "ServerAuthenticate" and
171                 msg["Authentication"]["passwordType"] == "HMAC-MD5" and
172                 msg["Authentication"]["eventId"] == EVT_ID_UNSUCCESSFUL_LOGON)
173
174         c = netlogon.netlogon("ncalrpc:[schannel]", self.get_loadparm())
175         creds = netlogon.netr_Credential()
176         c.netr_ServerReqChallenge(self.server, self.netbios_name, creds)
177         try:
178             c.netr_ServerAuthenticate3(self.server,
179                                        self.netbios_name,
180                                        SEC_CHAN_WKSTA,
181                                        self.netbios_name,
182                                        creds,
183                                        NETLOGON_NEG_STRONG_KEYS)
184         except NTSTATUSError:
185             pass
186         self.waitForMessages(isLastExpectedMessage)