mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
|
# Unix SMB/CIFS implementation.
|
||
|
# Copyright © Catalyst IT 2023
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 3 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
#
|
||
|
"""Fine-grained control over conditional ACE contents.
|
||
|
|
||
|
This deliberately allows you to do broken things that SDDL doesn't.
|
||
|
|
||
|
- token sequences that make no real sense
|
||
|
- sequences that make sense which SDDL can't encode
|
||
|
- strings that aren't proper utf-16
|
||
|
- etc.
|
||
|
"""
|
||
|
|
||
|
import samba
|
||
|
|
||
|
from samba.security import access_check
|
||
|
from samba.tests import DynamicTestCase, TestCase, get_env_dir
|
||
|
from samba.tests import conditional_ace_assembler as caa
|
||
|
from samba.tests.token_factory import token as Token
|
||
|
from samba.dcerpc import security
|
||
|
from samba.ndr import ndr_unpack, ndr_pack
|
||
|
from samba import NTSTATUSError
|
||
|
from samba.ntstatus import NT_STATUS_ACCESS_DENIED
|
||
|
from samba.colour import colourdiff
|
||
|
|
||
|
|
||
|
class ConditionalAceBytesBase(TestCase):
|
||
|
maxDiff = 0
|
||
|
@classmethod
|
||
|
def setUpClass(cls):
|
||
|
cls.domain_sid = security.dom_sid("S-1-2-3")
|
||
|
cls.token = Token(sids=['WD', 'AA'],
|
||
|
device_claims={"colour": ["orange", "blue"]})
|
||
|
|
||
|
@classmethod
|
||
|
def setUpDynamicTestCases(cls):
|
||
|
for i, row in enumerate(cls.data):
|
||
|
assembly, sddl, access_desired, name = row
|
||
|
if name is None:
|
||
|
name = sddl
|
||
|
name = f'{i+1:03}-{name}'
|
||
|
if len(name) > 150:
|
||
|
name = f"{name[:125]}+{len(name) - 125}-more-characters"
|
||
|
|
||
|
cls.generate_dynamic_test('test_assembly',
|
||
|
name, assembly, sddl, access_desired)
|
||
|
|
||
|
def _test_assembly_with_args(self, assembly, sddl_ref, access_desired):
|
||
|
sd_bytes = caa.assemble(*assembly)
|
||
|
if sddl_ref is None:
|
||
|
raise ValueError("for this test we need reference SDDL")
|
||
|
|
||
|
sddl_ref_full = f'D:(XA;;;;;WD;{sddl_ref})'
|
||
|
sd_ref = security.descriptor.from_sddl(sddl_ref_full, self.domain_sid)
|
||
|
sd_ref_bytes = ndr_pack(sd_ref)
|
||
|
header, artx, conditions = sd_ref_bytes.partition(b'artx')
|
||
|
ref_bytes = artx + conditions
|
||
|
print(colourdiff(sd_bytes, ref_bytes))
|
||
|
|
||
|
self.assertEqual(sd_bytes, ref_bytes)
|
||
|
|
||
|
if access_desired is not None:
|
||
|
try:
|
||
|
granted = security.access_check(sd, self.token, access_desired)
|
||
|
except NTSTATUSError as e:
|
||
|
if e.args[0] != NT_STATUS_ACCESS_DENIED:
|
||
|
raise
|
||
|
if self.allow:
|
||
|
self.fail(f"{assembly}: access was denied")
|
||
|
self.assertEqual(granted, access_desired)
|
||
|
|
||
|
else:
|
||
|
if not self.allow:
|
||
|
self.fail(f"{assembly}: unexpected access")
|
||
|
|
||
|
@DynamicTestCase
|
||
|
class ConditionalAceAssemblySDDL(ConditionalAceBytesBase):
|
||
|
allow = True
|
||
|
data = [
|
||
|
((caa.LocalAttr("x"), 41, caa.EQUAL,
|
||
|
caa.LocalAttr("x"), caa.DeviceAttr("x"), caa.GREATER_THAN,
|
||
|
caa.AND),
|
||
|
"((x == 41) && (x > @device.x))",
|
||
|
None, None),
|
||
|
]
|