vfs_ceph_new: common prefix to debug-log messages
[Samba.git] / python / samba / tests / conditional_ace_bytes.py
blobf7e7cfe423a37fc69fe5e5640068b7f6d213d255
1 # Unix SMB/CIFS implementation.
2 # Copyright © Catalyst IT 2023
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/>.
17 """Fine-grained control over conditional ACE contents.
19 This deliberately allows you to do broken things that SDDL doesn't.
21 - token sequences that make no real sense
22 - sequences that make sense which SDDL can't encode
23 - strings that aren't proper utf-16
24 - etc.
25 """
27 from samba.tests import DynamicTestCase, TestCase
28 from samba.tests import conditional_ace_assembler as caa
29 from samba.tests.token_factory import token as Token
30 from samba.dcerpc import security
31 from samba.ndr import ndr_pack
32 from samba import NTSTATUSError
33 from samba.ntstatus import NT_STATUS_ACCESS_DENIED
34 from samba.colour import colourdiff
37 class ConditionalAceBytesBase(TestCase):
38 maxDiff = 0
39 @classmethod
40 def setUpClass(cls):
41 cls.domain_sid = security.dom_sid("S-1-2-3")
42 cls.token = Token(sids=['WD', 'AA'],
43 device_claims={"colour": ["orange", "blue"]})
45 @classmethod
46 def setUpDynamicTestCases(cls):
47 for i, row in enumerate(cls.data):
48 assembly, sddl, access_desired, name = row
49 if name is None:
50 name = sddl
51 name = f'{i+1:03}-{name}'
52 if len(name) > 150:
53 name = f"{name[:125]}+{len(name) - 125}-more-characters"
55 cls.generate_dynamic_test('test_assembly',
56 name, assembly, sddl, access_desired)
58 def _test_assembly_with_args(self, assembly, sddl_ref, access_desired):
59 sd_bytes = caa.assemble(*assembly)
60 if sddl_ref is None:
61 raise ValueError("for this test we need reference SDDL")
63 sddl_ref_full = f'D:(XA;;;;;WD;{sddl_ref})'
64 sd_ref = security.descriptor.from_sddl(sddl_ref_full, self.domain_sid)
65 sd_ref_bytes = ndr_pack(sd_ref)
66 header, artx, conditions = sd_ref_bytes.partition(b'artx')
67 ref_bytes = artx + conditions
68 print(colourdiff(sd_bytes, ref_bytes))
70 self.assertEqual(sd_bytes, ref_bytes)
72 if access_desired is not None:
73 try:
74 granted = security.access_check(sd, self.token, access_desired)
75 except NTSTATUSError as e:
76 if e.args[0] != NT_STATUS_ACCESS_DENIED:
77 raise
78 if self.allow:
79 self.fail(f"{assembly}: access was denied")
80 self.assertEqual(granted, access_desired)
82 else:
83 if not self.allow:
84 self.fail(f"{assembly}: unexpected access")
86 @DynamicTestCase
87 class ConditionalAceAssemblySDDL(ConditionalAceBytesBase):
88 allow = True
89 data = [
90 ((caa.LocalAttr("x"), 41, caa.EQUAL,
91 caa.LocalAttr("x"), caa.DeviceAttr("x"), caa.GREATER_THAN,
92 caa.AND),
93 "((x == 41) && (x > @device.x))",
94 None, None),