ctdb-scripts: Improve update and listing code
[samba4-gss.git] / python / samba / tests / samba_tool / user_wdigest.py
blob349cb490d5461a9f633ec67e9674f7551976185b
1 # Tests for the samba-tool user sub command reading Primary:WDigest
3 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import os
21 import samba
22 from samba.tests.samba_tool.base import SambaToolCmdTest
23 from hashlib import md5
26 USER_NAME = "WdigestTestUser"
28 # Calculate the MD5 password digest from the supplied user, realm and password
32 def calc_digest(user, realm, password):
33 data = "%s:%s:%s" % (user, realm, password)
34 if isinstance(data, str):
35 data = data.encode('utf8')
37 return "%s:%s:%s" % (user, realm, md5(data).hexdigest())
40 class UserCmdWdigestTestCase(SambaToolCmdTest):
41 """Tests for samba-tool user subcommands extraction of the wdigest values
42 Test results validated against Windows Server 2012 R2.
43 NOTE: That as at 22-05-2017 the values Documented at
44 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
45 are incorrect.
46 """
47 users = []
48 samdb = None
50 def setUp(self):
51 super().setUp()
52 self.lp = samba.tests.env_loadparm()
53 self.samdb = self.getSamDB(
54 "-H", "ldap://%s" % os.environ["DC_SERVER"],
55 "-U%s%%%s" % (os.environ["DC_USERNAME"],
56 os.environ["DC_PASSWORD"]))
57 self.dns_domain = self.samdb.domain_dns_name()
58 res = self.samdb.search(
59 base=self.samdb.get_config_basedn(),
60 expression="ncName=%s" % self.samdb.get_default_basedn(),
61 attrs=["nETBIOSName"])
62 self.netbios_domain = str(res[0]["nETBIOSName"][0])
63 self.password = self.random_password()
64 result, out, err = self.runsubcmd("user",
65 "create",
66 USER_NAME,
67 self.password)
68 self.assertCmdSuccess(result,
69 out,
70 err,
71 "Ensure user is created")
73 def tearDown(self):
74 super().tearDown()
75 result, out, err = self.runsubcmd("user", "delete", USER_NAME)
76 self.assertCmdSuccess(result,
77 out,
78 err,
79 "Ensure user is deleted")
81 def _testWDigest(self, attribute, expected, missing=False):
83 (result, out, err) = self.runsubcmd("user",
84 "getpassword",
85 USER_NAME,
86 "--attributes",
87 attribute)
88 self.assertCmdSuccess(result,
89 out,
90 err,
91 "Ensure getpassword runs")
92 self.assertEqual(err, "Any available password returned OK\n", "getpassword")
94 if missing:
95 self.assertTrue(attribute not in out)
96 else:
97 self.assertMatch(out.replace('\n ', ''),
98 "%s: %s" % (attribute, expected))
100 def test_Wdigest_no_suffix(self):
101 attribute = "virtualWDigest"
102 self._testWDigest(attribute, None, True)
104 def test_Wdigest_non_numeric_suffix(self):
105 attribute = "virtualWDigestss"
106 self._testWDigest(attribute, None, True)
108 def test_Wdigest00(self):
109 attribute = "virtualWDigest00"
110 self._testWDigest(attribute, None, True)
112 # Hash01 MD5(sAMAccountName,
113 # NETBIOSDomainName,
114 # password)
116 def test_Wdigest01(self):
117 attribute = "virtualWDigest01"
118 expected = calc_digest(USER_NAME,
119 self.netbios_domain,
120 self.password)
121 self._testWDigest(attribute, expected)
123 # Hash02 MD5(LOWER(sAMAccountName),
124 # LOWER(NETBIOSDomainName),
125 # password)
127 def test_Wdigest02(self):
128 attribute = "virtualWDigest02"
129 expected = calc_digest(USER_NAME.lower(),
130 self.netbios_domain.lower(),
131 self.password)
132 self._testWDigest(attribute, expected)
134 # Hash03 MD5(UPPER(sAMAccountName),
135 # UPPER(NETBIOSDomainName),
136 # password)
138 def test_Wdigest03(self):
139 attribute = "virtualWDigest03"
140 expected = calc_digest(USER_NAME.upper(),
141 self.netbios_domain.upper(),
142 self.password)
143 self._testWDigest(attribute, expected)
145 # Hash04 MD5(sAMAccountName,
146 # UPPER(NETBIOSDomainName),
147 # password)
149 def test_Wdigest04(self):
150 attribute = "virtualWDigest04"
151 expected = calc_digest(USER_NAME,
152 self.netbios_domain.upper(),
153 self.password)
154 self._testWDigest(attribute, expected)
156 # Hash05 MD5(sAMAccountName,
157 # LOWER(NETBIOSDomainName),
158 # password)
160 def test_Wdigest05(self):
161 attribute = "virtualWDigest05"
162 expected = calc_digest(USER_NAME,
163 self.netbios_domain.lower(),
164 self.password)
165 self._testWDigest(attribute, expected)
167 # Hash06 MD5(UPPER(sAMAccountName),
168 # LOWER(NETBIOSDomainName),
169 # password)
171 def test_Wdigest06(self):
172 attribute = "virtualWDigest06"
173 expected = calc_digest(USER_NAME.upper(),
174 self.netbios_domain.lower(),
175 self.password)
176 self._testWDigest(attribute, expected)
178 # Hash07 MD5(LOWER(sAMAccountName),
179 # UPPER(NETBIOSDomainName),
180 # password)
182 def test_Wdigest07(self):
183 attribute = "virtualWDigest07"
184 expected = calc_digest(USER_NAME.lower(),
185 self.netbios_domain.upper(),
186 self.password)
187 self._testWDigest(attribute, expected)
189 # Hash08 MD5(sAMAccountName,
190 # DNSDomainName,
191 # password)
193 # Note: Samba lowercases the DNSDomainName at provision time,
194 # Windows preserves the case. This means that the WDigest08 values
195 # calculated byt Samba and Windows differ.
197 def test_Wdigest08(self):
198 attribute = "virtualWDigest08"
199 expected = calc_digest(USER_NAME,
200 self.dns_domain,
201 self.password)
202 self._testWDigest(attribute, expected)
204 # Hash09 MD5(LOWER(sAMAccountName),
205 # LOWER(DNSDomainName),
206 # password)
208 def test_Wdigest09(self):
209 attribute = "virtualWDigest09"
210 expected = calc_digest(USER_NAME.lower(),
211 self.dns_domain.lower(),
212 self.password)
213 self._testWDigest(attribute, expected)
215 # Hash10 MD5(UPPER(sAMAccountName),
216 # UPPER(DNSDomainName),
217 # password)
219 def test_Wdigest10(self):
220 attribute = "virtualWDigest10"
221 expected = calc_digest(USER_NAME.upper(),
222 self.dns_domain.upper(),
223 self.password)
224 self._testWDigest(attribute, expected)
226 # Hash11 MD5(sAMAccountName,
227 # UPPER(DNSDomainName),
228 # password)
230 def test_Wdigest11(self):
231 attribute = "virtualWDigest11"
232 expected = calc_digest(USER_NAME,
233 self.dns_domain.upper(),
234 self.password)
235 self._testWDigest(attribute, expected)
237 # Hash12 MD5(sAMAccountName,
238 # LOWER(DNSDomainName),
239 # password)
241 def test_Wdigest12(self):
242 attribute = "virtualWDigest12"
243 expected = calc_digest(USER_NAME,
244 self.dns_domain.lower(),
245 self.password)
246 self._testWDigest(attribute, expected)
248 # Hash13 MD5(UPPER(sAMAccountName),
249 # LOWER(DNSDomainName),
250 # password)
252 def test_Wdigest13(self):
253 attribute = "virtualWDigest13"
254 expected = calc_digest(USER_NAME.upper(),
255 self.dns_domain.lower(),
256 self.password)
257 self._testWDigest(attribute, expected)
259 # Hash14 MD5(LOWER(sAMAccountName),
260 # UPPER(DNSDomainName),
261 # password)
264 def test_Wdigest14(self):
265 attribute = "virtualWDigest14"
266 expected = calc_digest(USER_NAME.lower(),
267 self.dns_domain.upper(),
268 self.password)
269 self._testWDigest(attribute, expected)
271 # Hash15 MD5(userPrincipalName,
272 # password)
274 def test_Wdigest15(self):
275 attribute = "virtualWDigest15"
276 name = "%s@%s" % (USER_NAME, self.dns_domain)
277 expected = calc_digest(name,
279 self.password)
280 self._testWDigest(attribute, expected)
282 # Hash16 MD5(LOWER(userPrincipalName),
283 # password)
285 def test_Wdigest16(self):
286 attribute = "virtualWDigest16"
287 name = "%s@%s" % (USER_NAME.lower(), self.dns_domain.lower())
288 expected = calc_digest(name,
290 self.password)
291 self._testWDigest(attribute, expected)
293 # Hash17 MD5(UPPER(userPrincipalName),
294 # password)
296 def test_Wdigest17(self):
297 attribute = "virtualWDigest17"
298 name = "%s@%s" % (USER_NAME.upper(), self.dns_domain.upper())
299 expected = calc_digest(name,
301 self.password)
302 self._testWDigest(attribute, expected)
304 # Hash18 MD5(NETBIOSDomainName\sAMAccountName,
305 # password)
307 def test_Wdigest18(self):
308 attribute = "virtualWDigest18"
309 name = "%s\\%s" % (self.netbios_domain, USER_NAME)
310 expected = calc_digest(name,
312 self.password)
313 self._testWDigest(attribute, expected)
315 # Hash19 MD5(LOWER(NETBIOSDomainName\sAMAccountName),
316 # password)
318 def test_Wdigest19(self):
319 attribute = "virtualWDigest19"
320 name = "%s\\%s" % (self.netbios_domain, USER_NAME)
321 expected = calc_digest(name.lower(),
323 self.password)
324 self._testWDigest(attribute, expected)
326 # Hash20 MD5(UPPER(NETBIOSDomainName\sAMAccountName),
327 # password)
329 def test_Wdigest20(self):
330 attribute = "virtualWDigest20"
331 name = "%s\\%s" % (self.netbios_domain, USER_NAME)
332 expected = calc_digest(name.upper(),
334 self.password)
335 self._testWDigest(attribute, expected)
337 # Hash21 MD5(sAMAccountName,
338 # "Digest",
339 # password)
341 def test_Wdigest21(self):
342 attribute = "virtualWDigest21"
343 expected = calc_digest(USER_NAME,
344 "Digest",
345 self.password)
346 self._testWDigest(attribute, expected)
348 # Hash22 MD5(LOWER(sAMAccountName),
349 # "Digest",
350 # password)
352 def test_Wdigest22(self):
353 attribute = "virtualWDigest22"
354 expected = calc_digest(USER_NAME.lower(),
355 "Digest",
356 self.password)
357 self._testWDigest(attribute, expected)
359 # Hash23 MD5(UPPER(sAMAccountName),
360 # "Digest",
361 # password)
363 def test_Wdigest23(self):
364 attribute = "virtualWDigest23"
365 expected = calc_digest(USER_NAME.upper(),
366 "Digest",
367 self.password)
368 self._testWDigest(attribute, expected)
370 # Hash24 MD5(userPrincipalName),
371 # "Digest",
372 # password)
374 def test_Wdigest24(self):
375 attribute = "virtualWDigest24"
376 name = "%s@%s" % (USER_NAME, self.dns_domain)
377 expected = calc_digest(name,
378 "Digest",
379 self.password)
380 self._testWDigest(attribute, expected)
382 # Hash25 MD5(LOWER(userPrincipalName),
383 # "Digest",
384 # password)
386 def test_Wdigest25(self):
387 attribute = "virtualWDigest25"
388 name = "%s@%s" % (USER_NAME, self.dns_domain.lower())
389 expected = calc_digest(name.lower(),
390 "Digest",
391 self.password)
392 self._testWDigest(attribute, expected)
394 # Hash26 MD5(UPPER(userPrincipalName),
395 # "Digest",
396 # password)
398 def test_Wdigest26(self):
399 attribute = "virtualWDigest26"
400 name = "%s@%s" % (USER_NAME, self.dns_domain.lower())
401 expected = calc_digest(name.upper(),
402 "Digest",
403 self.password)
404 self._testWDigest(attribute, expected)
405 # Hash27 MD5(NETBIOSDomainName\sAMAccountName,
406 # "Digest",
407 # password)
410 def test_Wdigest27(self):
411 attribute = "virtualWDigest27"
412 name = "%s\\%s" % (self.netbios_domain, USER_NAME)
413 expected = calc_digest(name,
414 "Digest",
415 self.password)
416 self._testWDigest(attribute, expected)
418 # Hash28 MD5(LOWER(NETBIOSDomainName\sAMAccountName),
419 # "Digest",
420 # password)
422 def test_Wdigest28(self):
423 attribute = "virtualWDigest28"
424 name = "%s\\%s" % (self.netbios_domain.lower(), USER_NAME.lower())
425 expected = calc_digest(name,
426 "Digest",
427 self.password)
428 self._testWDigest(attribute, expected)
430 # Hash29 MD5(UPPER(NETBIOSDomainName\sAMAccountName),
431 # "Digest",
432 # password)
434 def test_Wdigest29(self):
435 attribute = "virtualWDigest29"
436 name = "%s\\%s" % (self.netbios_domain.upper(), USER_NAME.upper())
437 expected = calc_digest(name,
438 "Digest",
439 self.password)
440 self._testWDigest(attribute, expected)
442 def test_Wdigest30(self):
443 attribute = "virtualWDigest30"
444 self._testWDigest(attribute, None, True)
446 # Check digest calculation against an known htdigest value
447 def test_calc_digest(self):
448 htdigest = "gary:fred:2204fcc247cb47ded249ef2fe0013255"
449 digest = calc_digest("gary", "fred", "password")
450 self.assertEqual(htdigest, digest)