samba-tool tests: add tests for userPassword
[Samba.git] / python / samba / tests / password_hash_fl2003.py
blob0ac38b05f48251857913c08886bf29614632e23a
1 # Tests for Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
3 # Copyright (C) Catalyst IT Ltd. 2017
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.
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.
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/>.
19 """
20 Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
22 These tests need to be run in an environment in which
23 io->ac->gpg_key_ids == NULL, so that the gpg supplemental credentials
24 are not generated. And also need to be in an environment with a
25 functional level less than 2008 to ensure the kerberos newer keys are not
26 generated
27 """
29 from samba.tests.password_hash import (
30 PassWordHashTests,
31 get_package,
32 USER_PASS
34 from samba.ndr import ndr_unpack
35 from samba.dcerpc import drsblobs
36 import binascii
40 class PassWordHashFl2003Tests(PassWordHashTests):
42 def setUp(self):
43 super(PassWordHashFl2003Tests, self).setUp()
45 def test_default_supplementalCredentials(self):
46 self.add_user(options=[("password hash userPassword schemes", "")])
48 sc = self.get_supplemental_creds()
50 # Check that we got all the expected supplemental credentials
51 # And they are in the expected order.
52 size = len(sc.sub.packages)
53 self.assertEquals(3, size)
55 (pos, package) = get_package(sc, "Primary:Kerberos")
56 self.assertEquals(1, pos)
57 self.assertEquals("Primary:Kerberos", package.name)
59 (pos, package) = get_package(sc, "Packages")
60 self.assertEquals(2, pos)
61 self.assertEquals("Packages", package.name)
63 (pos, package) = get_package(sc, "Primary:WDigest")
64 self.assertEquals(3, pos)
65 self.assertEquals("Primary:WDigest", package.name)
67 # Check that the WDigest values are correct.
69 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
70 binascii.a2b_hex(package.data))
71 self.check_wdigests(digests)
73 def test_userPassword_sha256(self):
74 self.add_user(options=[("password hash userPassword schemes",
75 "CryptSHA256")])
77 sc = self.get_supplemental_creds()
79 # Check that we got all the expected supplemental credentials
80 # And they are in the expected order.
81 size = len(sc.sub.packages)
82 self.assertEquals(4, size)
84 (pos, package) = get_package(sc, "Primary:Kerberos")
85 self.assertEquals(1, pos)
86 self.assertEquals("Primary:Kerberos", package.name)
88 (pos, wd_package) = get_package(sc, "Primary:WDigest")
89 self.assertEquals(2, pos)
90 self.assertEquals("Primary:WDigest", wd_package.name)
92 (pos, package) = get_package(sc, "Packages")
93 self.assertEquals(3, pos)
94 self.assertEquals("Packages", package.name)
96 (pos, up_package) = get_package(sc, "Primary:userPassword")
97 self.assertEquals(4, pos)
98 self.assertEquals("Primary:userPassword", up_package.name)
100 # Check that the WDigest values are correct.
102 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
103 binascii.a2b_hex(wd_package.data))
104 self.check_wdigests(digests)
106 # Check that the userPassword hashes are computed correctly
108 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
109 binascii.a2b_hex(up_package.data))
111 self.checkUserPassword(up, [("{CRYPT}", "5", None)])
112 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
114 def test_supplementalCredentials_cleartext(self):
115 self.add_user(clear_text=True,
116 options=[("password hash userPassword schemes", "")])
118 sc = self.get_supplemental_creds()
120 # Check that we got all the expected supplemental credentials
121 # And they are in the expected order.
122 size = len(sc.sub.packages)
123 self.assertEquals(4, size)
125 (pos, package) = get_package(sc, "Primary:Kerberos")
126 self.assertEquals(1, pos)
127 self.assertEquals("Primary:Kerberos", package.name)
129 (pos, wd_package) = get_package(sc, "Primary:WDigest")
130 self.assertEquals(2, pos)
131 self.assertEquals("Primary:WDigest", wd_package.name)
133 (pos, package) = get_package(sc, "Packages")
134 self.assertEquals(3, pos)
135 self.assertEquals("Packages", package.name)
137 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
138 self.assertEquals(4, pos)
139 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
142 # Check that the WDigest values are correct.
144 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
145 binascii.a2b_hex(wd_package.data))
146 self.check_wdigests(digests)
148 # Check the clear text value is correct.
149 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
150 binascii.a2b_hex(ct_package.data))
151 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
153 def test_userPassword_cleartext_sha512(self):
154 self.add_user(clear_text=True,
155 options=[("password hash userPassword schemes",
156 "CryptSHA512:rounds=10000")])
158 sc = self.get_supplemental_creds()
160 # Check that we got all the expected supplemental credentials
161 # And they are in the expected order.
162 size = len(sc.sub.packages)
163 self.assertEquals(5, size)
165 (pos, package) = get_package(sc, "Primary:Kerberos")
166 self.assertEquals(1, pos)
167 self.assertEquals("Primary:Kerberos", package.name)
169 (pos, wd_package) = get_package(sc, "Primary:WDigest")
170 self.assertEquals(2, pos)
171 self.assertEquals("Primary:WDigest", wd_package.name)
173 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
174 self.assertEquals(3, pos)
175 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
177 (pos, package) = get_package(sc, "Packages")
178 self.assertEquals(4, pos)
179 self.assertEquals("Packages", package.name)
181 (pos, up_package) = get_package(sc, "Primary:userPassword")
182 self.assertEquals(5, pos)
183 self.assertEquals("Primary:userPassword", up_package.name)
185 # Check that the WDigest values are correct.
187 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
188 binascii.a2b_hex(wd_package.data))
189 self.check_wdigests(digests)
191 # Check the clear text value is correct.
192 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
193 binascii.a2b_hex(ct_package.data))
194 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
196 # Check that the userPassword hashes are computed correctly
198 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
199 binascii.a2b_hex(up_package.data))
200 self.checkUserPassword(up, [("{CRYPT}", "6",10000 )])
201 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)