1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Catalyst.NET Ltd 2022
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from hashlib
import blake2b
26 from samba
import param
28 from samba
.auth
import system_session
29 from samba
.credentials
import Credentials
30 from samba
.dcerpc
import security
31 from samba
.ndr
import ndr_unpack
32 from samba
.samdb
import SamDB
33 from samba
.tests
import (
40 sys
.path
.insert(0, 'bin/python')
41 os
.environ
['PYTHONUNBUFFERED'] = '1'
44 late_ERR_CONSTRAINT_VIOLATION
= b
"a hack to allow Windows to sometimes fail late"
47 class SidStringBase(TestCase
):
49 def setUpDynamicTestCases(cls
):
50 if not hasattr(cls
, 'skip_local'):
51 cls
.skip_local
= env_get_var_value('SAMBA_SID_STRINGS_SKIP_LOCAL',
54 if env_get_var_value('CHECK_ALL_COMBINATIONS',
56 for x
in string
.ascii_uppercase
:
57 for y
in string
.ascii_uppercase
:
59 if code
not in cls
.cases
:
60 cls
.cases
[code
] = None
62 for code
, expected_sid
in cls
.cases
.items():
65 cls
.generate_dynamic_test('test_sid_string', name
,
67 if not cls
.skip_local
:
68 cls
.generate_dynamic_test('test_sid_string_internal', name
,
75 server
= os
.environ
['DC_SERVER']
76 host
= f
'ldap://{server}'
79 lp
.load(os
.environ
['SMB_CONF_PATH'])
83 creds
.set_username(env_get_var_value('DC_USERNAME'))
84 creds
.set_password(env_get_var_value('DC_PASSWORD'))
86 cls
.ldb
= SamDB(host
, credentials
=creds
,
87 session_info
=system_session(lp
), lp
=lp
)
88 cls
.base_dn
= cls
.ldb
.domain_dn()
89 cls
.schema_dn
= cls
.ldb
.get_schema_basedn().get_linearized()
90 cls
.timestamp
= str(int(time
.time()))
91 cls
.domain_sid
= cls
.ldb
.get_domain_sid()
93 def _test_sid_string_with_args(self
, code
, expected_sid
):
94 suffix
= int(blake2b(code
.encode(), digest_size
=3).hexdigest(), 16)
96 class_name
= f
'my-Sid-String-Class-{self.timestamp}-{suffix}'
97 class_ldap_display_name
= class_name
.replace('-', '')
99 class_dn
= f
'CN={class_name},{self.schema_dn}'
101 governs_id
= f
'1.3.6.1.4.1.7165.4.6.2.9.1{self.timestamp[-7:]}.{suffix}'
103 # expected_sid can be a SID string, an error code, None, or a
104 # special value indicating a deferred error, as follows:
106 # * a number represents the expected error code at the *first*
107 # hurdle, creating the classSchema object.
109 # * late_ERR_CONSTRAINT_VIOLATION means an error when
110 # creating an object based on the class schema.
112 # * None means a somewhat unspecified error or failure to set
113 # the object owner sid.
115 # * a string is the expected owner sid. The rid is borrowed
116 # * and tacked onto the governs-id.
118 if expected_sid
is None:
119 expected_err
= ldb
.ERR_UNWILLING_TO_PERFORM
120 elif isinstance(expected_sid
, int):
121 expected_err
= expected_sid
122 elif expected_sid
is late_ERR_CONSTRAINT_VIOLATION
:
126 # Append the RID to our OID to ensure more uniqueness.
127 rid
= expected_sid
.rsplit('-', 1)[1]
128 governs_id
+= f
'.{rid}'
132 objectClass: classSchema
134 governsId: {governs_id}
136 possSuperiors: domainDNS
137 defaultSecurityDescriptor: O:{code}
140 self
.ldb
.add_ldif(ldif
)
141 except ldb
.LdbError
as err
:
143 self
.assertEqual(num
, expected_err
)
146 if isinstance(expected_sid
, int):
147 self
.fail("should have failed")
149 # Search for created objectclass
150 res
= self
.ldb
.search(class_dn
, scope
=ldb
.SCOPE_BASE
,
151 attrs
=['defaultSecurityDescriptor'])
152 self
.assertEqual(1, len(res
))
153 self
.assertEqual(res
[0].get('defaultSecurityDescriptor', idx
=0),
154 f
'O:{code}'.encode('utf-8'))
162 self
.ldb
.modify_ldif(ldif
)
164 object_name
= f
'sddl_{self.timestamp}_{suffix}'
165 object_dn
= f
'CN={object_name},{self.base_dn}'
169 objectClass: {class_ldap_display_name}
172 if expected_sid
is late_ERR_CONSTRAINT_VIOLATION
:
173 expected_err
= ldb
.ERR_CONSTRAINT_VIOLATION
176 self
.ldb
.add_ldif(ldif
)
177 except ldb
.LdbError
as err
:
179 self
.assertEqual(num
, expected_err
)
182 if expected_sid
is not None:
183 self
.assertIsNone(expected_err
)
185 # Search for created object
186 res
= self
.ldb
.search(object_dn
, scope
=ldb
.SCOPE_BASE
,
187 attrs
=['nTSecurityDescriptor'])
188 self
.assertEqual(1, len(res
))
191 delete_force(self
.ldb
, object_dn
)
193 data
= res
[0].get('nTSecurityDescriptor', idx
=0)
194 descriptor
= ndr_unpack(security
.descriptor
, data
)
196 expected_sid
= self
.format_expected_sid(expected_sid
)
197 owner_sid
= str(descriptor
.owner_sid
)
198 self
.assertEqual(expected_sid
, owner_sid
)
200 def format_expected_sid(self
, expected_sid
):
201 if expected_sid
is None:
202 return f
'{self.domain_sid}-{security.DOMAIN_RID_ADMINS}'
204 if not isinstance(expected_sid
, str):
205 # never going to match, should have failed already
208 return expected_sid
.format(domain_sid
=self
.domain_sid
)
210 def _test_sid_string_internal_with_args(self
, code
, expected_sid
):
211 """We just want to test the SIDs, which Samba can't really do because
212 it doesn't parse them until creating an object using the
213 schema class, at which time it doesn't distinguish between a
214 missing value and a nonsense value.
216 So let's also run the test using libcli/security/sddl.c and
217 see what we *would* have done.
220 domsid
= security
.dom_sid(self
.domain_sid
)
223 sd
= security
.descriptor
.from_sddl(sddl
, domsid
)
224 except (ValueError, security
.SDDLValueError
):
225 # we don't have detail as to what went wrong
226 self
.assertNotIsInstance(expected_sid
, str)
228 expected_sid
= self
.format_expected_sid(expected_sid
)
229 self
.assertEqual(expected_sid
, str(sd
.owner_sid
))
233 class SidStringTests(SidStringBase
):
234 """Testing two letter aliases."""
236 'AA': 'S-1-5-32-579',
239 'AO': 'S-1-5-32-548',
240 'AP': '{domain_sid}-525',
243 'BA': 'S-1-5-32-544',
244 'BG': 'S-1-5-32-546',
245 'BO': 'S-1-5-32-551',
246 'BU': 'S-1-5-32-545',
247 'CA': '{domain_sid}-517',
248 'CD': 'S-1-5-32-574',
250 'CN': '{domain_sid}-522',
252 'CY': 'S-1-5-32-569',
253 'DC': '{domain_sid}-515',
254 'DD': '{domain_sid}-516',
255 'DG': '{domain_sid}-514',
256 'DU': '{domain_sid}-513',
257 'EA': '{domain_sid}-519',
259 'EK': '{domain_sid}-527',
260 'ER': 'S-1-5-32-573',
261 'ES': 'S-1-5-32-576',
262 'HA': 'S-1-5-32-578',
263 'HI': 'S-1-16-12288',
264 'IS': 'S-1-5-32-568',
266 'KA': '{domain_sid}-526',
267 'LA': '{domain_sid}-500',
268 'LG': '{domain_sid}-501',
270 'LU': 'S-1-5-32-559',
274 'MS': 'S-1-5-32-577',
275 'MU': 'S-1-5-32-558',
276 'NO': 'S-1-5-32-556',
280 'PA': '{domain_sid}-520',
281 'PO': 'S-1-5-32-550',
283 'PU': 'S-1-5-32-547',
284 'RA': 'S-1-5-32-575',
286 'RD': 'S-1-5-32-555',
287 'RE': 'S-1-5-32-552',
288 'RM': 'S-1-5-32-580',
289 'RO': '{domain_sid}-498',
290 'RS': '{domain_sid}-553',
291 'RU': 'S-1-5-32-554',
292 'SA': '{domain_sid}-518',
293 'SI': 'S-1-16-16384',
294 'SO': 'S-1-5-32-549',
298 # Not tested, as it always gives us an OPERATIONS_ERROR with Windows.
299 # 'UD': 'S-1-5-84-0-0-0-0-0',
302 'aa': 'S-1-5-32-579',
303 'Aa': 'S-1-5-32-579',
304 'aA': 'S-1-5-32-579',
312 class SidStringsThatStartWithS(SidStringBase
):
313 """Testing normal or normal-adjacent SIDs"""
315 # testing explicit string to string round trips.
316 'S-1-5-32-579': 'S-1-5-32-579',
317 'S-1-5-0x20-579': 'S-1-5-32-579', # hex
318 'S-1-0x05-32-579': 'S-1-5-32-579',
319 'S-1-5-040-579': 'S-1-5-40-579', # no octal
320 'S-1-0x50000000-32-579': 'S-1-1342177280-32-579',
321 'S-1-0x500000000-32-579': 'S-1-0x500000000-32-579',
322 'S-1-21474836480-32-579': 'S-1-0x500000000-32-579', # >32 bit is hex
323 f
'S-1-5-{(1 << 32) - 1}-579': 'S-1-5-4294967295-579',
324 f
'S-1-{(1 << 48) - 1}-579': 'S-1-0xffffffffffff-579',
325 f
'S-1-{(1 << 48)}-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
326 'S-1-99999999999999999999999999999999999999-32-11111111111': ldb
.ERR_UNWILLING_TO_PERFORM
,
327 'S-1-5-0-579': 'S-1-5-0-579',
328 'S-1-0-0-579': 'S-1-0-0-579',
329 'S-1-0x5-0x20-0x243': 'S-1-5-32-579',
330 'S-1-5-32--579': ldb
.ERR_UNWILLING_TO_PERFORM
,
331 'S-1-5-32- 579': ldb
.ERR_UNWILLING_TO_PERFORM
,
332 'S-1-5-32 -579': ldb
.ERR_UNWILLING_TO_PERFORM
,
333 'S-1-5-3 2-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
334 ' S-1-1-1-1-1-1-1': ldb
.ERR_UNWILLING_TO_PERFORM
,
335 # go to lower case in hex.
336 'S-1-0xABcDef123-0xABCDef-579': 'S-1-0xabcdef123-11259375-579',
337 'S-1-1-1-1-1-1-1': 'S-1-1-1-1-1-1-1',
338 's-1-5-32-579': 'S-1-5-32-579',
339 'S-01-5-32-579': 'S-1-5-32-579',
340 'S-000000001-5-32-579': 'S-1-5-32-579',
341 # some strings from https://bugzilla.samba.org/show_bug.cgi?id=14213
342 'S-1-0': ldb
.ERR_UNWILLING_TO_PERFORM
,
343 'S-1-22': ldb
.ERR_UNWILLING_TO_PERFORM
,
344 'S-1-22-1': 'S-1-22-1',
345 'S-1-22-1-0': 'S-1-22-1-0',
346 'S-1-3-0': 'S-1-3-0',
347 'S-1-3-99': 'S-1-3-99',
348 'S-01-05-020-0243': 'S-1-5-20-243',
349 'S-000000000001-5-20-243': 'S-1-5-20-243',
350 'S-1-000000000000000005-20-243': 'S-1-5-20-243',
351 'S-1-5-20-00000000000243': 'S-1-5-20-243',
356 class SidStringBehavioursThatWindowsAllows(SidStringBase
):
357 """Windows interpretations that we probably don't want to follow"""
359 # saturating sub-auth values at 32 bits
360 'S-1-5-9999999999-579': 'S-1-5-4294967295-579',
361 'S-1-0x500000000-0x500000000-579': 'S-1-0x500000000-4294967295-579',
362 'S-1-5-11111111111111111111111111111111111-579': 'S-1-5-4294967295-579',
363 f
'S-1-5-{(1 << 64) - 1}-579': 'S-1-5-4294967295-579',
364 f
'S-1-5-{1 << 64}-579': 'S-1-5-4294967295-579',
365 # S-0x1- ?! on Windows this makes everything else a hex number.
366 'S-0x1-5-40-579': 'S-1-5-64-1401',
367 'S-0x1-0-0-579': 'S-1-0-0-1401',
368 'S-0x1-500000000-20-243': 'S-1-0x500000000-32-579',
369 'S-0x1-5-20-243': 'S-1-5-32-579',
370 'S-0x1-0x5-020-0243': 'S-1-5-32-579',
371 'S-1-0xABcDef123-0xABCDef123-579': 'S-1-0xabcdef123-4294967295-579',
373 'S-0-5-32-579': late_ERR_CONSTRAINT_VIOLATION
,
374 'S-2-5-32-579': late_ERR_CONSTRAINT_VIOLATION
,
375 'S-10-5-32-579': late_ERR_CONSTRAINT_VIOLATION
,
380 class SidStringBehavioursThatSambaPrefers(SidStringBase
):
381 """Aspirational alternative answers to the
382 SidStringBehavioursThatWindowsAllows cases."""
384 'S-1-5-9999999999-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
385 'S-1-0x500000000-0x500000000-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
386 'S-1-5-11111111111111111111111111111111111-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
387 f
'S-1-5-{(1 << 64) - 1}-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
388 f
'S-1-5-{1 << 64}-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
389 'S-0x1-5-40-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
390 'S-0x1-0-0-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
391 'S-0x1-500000000-20-243': ldb
.ERR_UNWILLING_TO_PERFORM
,
392 'S-0x1-5-20-243': ldb
.ERR_UNWILLING_TO_PERFORM
,
393 'S-0x1-0x5-020-0243': ldb
.ERR_UNWILLING_TO_PERFORM
,
394 'S-1-0xABcDef123-0xABCDef123-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
396 'S-0-5-32-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
397 'S-2-5-32-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
398 'S-10-5-32-579': ldb
.ERR_UNWILLING_TO_PERFORM
,
403 class SidStringsAsDnInSearchBase(SidStringBase
):
404 """How does a bad <SID=x> dn work as a search base, if at all?
406 This suggests that Windows does the SID parsing
407 (INVALID_DN_SYNTAX) before starting the search (NO_SUCH_OBJECT).
409 Currently Samba does not.
412 cases
= {' S-1-1-1-1-1-1-1': ldb
.ERR_INVALID_DN_SYNTAX
,
413 'S-0-5-32-545': ldb
.ERR_INVALID_DN_SYNTAX
,
414 'S-000000000001-5-20-243': ldb
.ERR_INVALID_DN_SYNTAX
,
415 'S-000000001-5-32-545': ldb
.ERR_INVALID_DN_SYNTAX
,
416 'S-01-05-020-0243': ldb
.ERR_NO_SUCH_OBJECT
,
417 'S-01-5-32-11579': ldb
.ERR_NO_SUCH_OBJECT
,
418 'S-0x1-0-0-579': ldb
.ERR_INVALID_DN_SYNTAX
,
419 'S-0x1-0x5-020-0243': ldb
.ERR_INVALID_DN_SYNTAX
,
420 'S-0x1-5-20-243': ldb
.ERR_INVALID_DN_SYNTAX
,
421 'S-0x1-5-40-579': ldb
.ERR_INVALID_DN_SYNTAX
,
422 'S-0x1-500000000-20-243': ldb
.ERR_INVALID_DN_SYNTAX
,
423 'S-1-0': ldb
.ERR_NO_SUCH_OBJECT
,
424 'S-1-0-0-579': ldb
.ERR_NO_SUCH_OBJECT
,
425 'S-1-0x05-32-11579': ldb
.ERR_NO_SUCH_OBJECT
,
426 'S-1-0x5-0x20-0x221': None,
427 'S-1-0x50000000-32-579': ldb
.ERR_NO_SUCH_OBJECT
,
428 'S-1-0x500000000-0x500000000-579': ldb
.ERR_INVALID_DN_SYNTAX
,
429 'S-1-0x500000000-32-579': ldb
.ERR_NO_SUCH_OBJECT
,
430 'S-1-0xABcDef123-0xABCDef123-579': ldb
.ERR_INVALID_DN_SYNTAX
,
431 'S-1-1-1-1-1-1-1': ldb
.ERR_NO_SUCH_OBJECT
,
432 'S-1-21474836480-32-579': ldb
.ERR_NO_SUCH_OBJECT
,
433 'S-1-22': ldb
.ERR_NO_SUCH_OBJECT
,
434 'S-1-22-1': ldb
.ERR_NO_SUCH_OBJECT
,
435 'S-1-22-1-0': ldb
.ERR_NO_SUCH_OBJECT
,
436 'S-1-281474976710655-579': ldb
.ERR_NO_SUCH_OBJECT
,
437 'S-1-281474976710656-579': ldb
.ERR_INVALID_DN_SYNTAX
,
438 'S-1-3-0': ldb
.ERR_NO_SUCH_OBJECT
,
439 'S-1-3-99': ldb
.ERR_NO_SUCH_OBJECT
,
440 'S-1-5-0-579': ldb
.ERR_NO_SUCH_OBJECT
,
441 'S-1-5-040-579': ldb
.ERR_NO_SUCH_OBJECT
,
442 'S-1-5-0x20-545': None,
443 'S-1-5-11111111111111111111111111111111111-579': ldb
.ERR_INVALID_DN_SYNTAX
,
444 'S-1-5-18446744073709551615-579': ldb
.ERR_INVALID_DN_SYNTAX
,
445 'S-1-5-18446744073709551616-579': ldb
.ERR_INVALID_DN_SYNTAX
,
446 'S-1-5-3 2-579': ldb
.ERR_NO_SUCH_OBJECT
,
447 'S-1-5-32 -11111579': None,
448 'S-1-5-32- 579': ldb
.ERR_INVALID_DN_SYNTAX
,
449 'S-1-5-32--579': ldb
.ERR_INVALID_DN_SYNTAX
,
450 'S-1-5-32-11579': ldb
.ERR_NO_SUCH_OBJECT
,
451 'S-1-5-4294967295-579': ldb
.ERR_NO_SUCH_OBJECT
,
452 'S-1-5-9999999999-579': ldb
.ERR_INVALID_DN_SYNTAX
,
453 'S-1-99999999999999999999999999999999999999-32-11111111111': ldb
.ERR_INVALID_DN_SYNTAX
,
454 'S-10-5-32-579': ldb
.ERR_INVALID_DN_SYNTAX
,
455 'S-2-5-32-579': ldb
.ERR_INVALID_DN_SYNTAX
,
456 's-1-5-32-5791': ldb
.ERR_NO_SUCH_OBJECT
,
457 's-1-5-32-545': None,
458 'AA': ldb
.ERR_INVALID_DN_SYNTAX
,
461 def _test_sid_string_with_args(self
, code
, expected
):
463 self
.ldb
.search(base
=f
"<SID={code}>",
464 scope
=ldb
.SCOPE_BASE
,
466 except ldb
.LdbError
as e
:
467 self
.assertEqual(e
.args
[0], expected
)
469 self
.assertIsNone(expected
)
473 class SidStringsAsDnSearchWithDnObject(SidStringBase
):
474 """How does a bad <SID=x> dn work as a search base, if at all?
476 This time we parse the DN in ldb first.
479 cases
= {' S-1-1-1-1-1-1-1': ('parse error', None),
480 'S-0-5-32-579': (None, ldb
.ERR_INVALID_DN_SYNTAX
),
481 'S-000000000001-5-20-243': ('parse error', None),
482 'S-000000001-5-32-579': ('parse error', None),
483 'S-01-05-020-0243': (None, ldb
.ERR_NO_SUCH_OBJECT
),
484 'S-0x1-0-0-579': ('parse error', None),
485 'S-0x1-0x5-020-0243': ('parse error', None),
486 'S-0x1-5-20-243': ('parse error', None),
487 'S-0x1-5-40-579': ('parse error', None),
488 'S-0x1-500000000-20-243': ('parse error', None),
489 'S-1-0': (None, ldb
.ERR_NO_SUCH_OBJECT
),
490 'S-1-0-0-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
491 'S-1-0x05-32-579': (None, None),
492 'S-1-0x5-0x20-0x221': (None, None),
493 'S-1-0x50000000-32-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
494 'S-1-0x500000000-0x500000000-579': ('parse error', None),
495 'S-1-0x500000000-32-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
496 'S-1-0xABcDef123-0xABCDef123-579': ('parse error', None),
497 'S-1-1-1-1-1-1-1': (None, ldb
.ERR_NO_SUCH_OBJECT
),
498 'S-1-21474836480-32-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
499 'S-1-22': (None, ldb
.ERR_NO_SUCH_OBJECT
),
500 'S-1-22-1': (None, ldb
.ERR_NO_SUCH_OBJECT
),
501 'S-1-22-1-0': (None, ldb
.ERR_NO_SUCH_OBJECT
),
502 'S-1-281474976710655-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
503 'S-1-281474976710656-579': ('parse error', None),
504 'S-1-3-0': (None, ldb
.ERR_NO_SUCH_OBJECT
),
505 'S-1-3-99': (None, ldb
.ERR_NO_SUCH_OBJECT
),
506 'S-1-5-0-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
507 'S-1-5-040-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
508 'S-1-5-0x20-545': (None, None),
509 'S-1-5-11111111111111111111111111111111111-579': ('parse error', None),
510 'S-1-5-18446744073709551615-579': ('parse error', None),
511 'S-1-5-18446744073709551616-579': ('parse error', None),
512 'S-1-5-3 2-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
513 'S-1-5-32- 579': ('parse error', None),
514 'S-1-5-32--579': ('parse error', None),
515 'S-1-5-4294967295-579': (None, ldb
.ERR_NO_SUCH_OBJECT
),
516 'S-1-5-9999999999-579': ('parse error', None),
517 'S-1-99999999999999999999999999999999999999-32-11111111111': ('parse error',
519 'S-10-5-32-579': (None, ldb
.ERR_INVALID_DN_SYNTAX
),
520 'S-2-5-32-579': (None, ldb
.ERR_INVALID_DN_SYNTAX
),
521 's-1-5-32-545': (None, None),
522 's-1-5-1234-5678': (None, ldb
.ERR_NO_SUCH_OBJECT
),
525 def _test_sid_string_with_args(self
, code
, expected
):
526 dn_err
, search_err
= expected
527 dn_str
= f
"<SID={code}>"
529 dn
= ldb
.Dn(self
.ldb
, dn_str
)
531 self
.assertEqual(dn_err
, 'parse error')
533 except ldb
.LdbError
as e
:
534 self
.assertEqual(dn_err
, e
.args
[0])
537 self
.assertIsNone(dn_err
)
540 self
.ldb
.search(dn
, scope
=ldb
.SCOPE_BASE
, attrs
=['*'])
541 except ldb
.LdbError
as e
:
542 self
.assertEqual(search_err
, e
.args
[0])
545 self
.assertIsNone(search_err
)
549 class SidStringsAsDnInSearchFilter(SidStringBase
):
550 """How does a bad <SID=x> dn work in a search filter?
552 Answer: on Windows it always works.
556 cases
.update(SidStringTests
.cases
)
557 cases
.update(SidStringsThatStartWithS
.cases
)
558 cases
.update(SidStringBehavioursThatSambaPrefers
.cases
)
560 def _test_sid_string_with_args(self
, code
, _dummy
):
561 basedn
= self
.ldb
.get_default_basedn()
563 self
.ldb
.search(base
=basedn
,
564 scope
=ldb
.SCOPE_ONELEVEL
,
565 expression
=f
"(distinguishedName=<SID={code}>)")
566 except ldb
.LdbError
as e
:
567 self
.fail(f
"expected no failure, got {e}")
571 class SidStringsForSimpleBind(SidStringBase
):
572 """Check whether dodgy SID strings work differently for simple-bind.
574 One of the many fallbacks for ldap simple bind is SID strings. We
575 just want to ensure that SIDs that might fail strangely in SID
576 parsing don't leak that strangeness (they don't).
579 # here we are testing only the SID-like SIDs ("S-1-...", not "AA")
581 cases
.update(SidStringsThatStartWithS
.cases
)
582 cases
.update(SidStringBehavioursThatSambaPrefers
.cases
)
587 server
= os
.environ
['DC_SERVER']
588 cls
.lp
= param
.LoadParm()
589 cls
.host
= f
'ldap://{server}'
591 def _test_sid_string_with_args(self
, code
, _dummy
):
592 bind_creds
= Credentials()
593 bind_creds
.set_username(code
)
594 bind_creds
.set_password("please")
599 credentials
=bind_creds
)
600 self
.fail(f
"{code} seems to have connected properly")
601 except ldb
.LdbError
as e
:
603 self
.assertIn("NT_STATUS_INVALID_PARAMETER", msg
)
606 if __name__
== '__main__':
607 global_asn1_print
= False
608 global_hexdump
= False