From 1325e01303499b7d94e3b781bee3672c2a94f190 Mon Sep 17 00:00:00 2001 From: Rob van der Linde Date: Wed, 20 Sep 2023 12:52:31 +1200 Subject: [PATCH] netcmd: models: add SDDL model field Signed-off-by: Rob van der Linde Reviewed-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- python/samba/netcmd/domain/models/fields.py | 31 ++++++++++++++ .../samba/tests/samba_tool/domain_models.py | 42 ++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/python/samba/netcmd/domain/models/fields.py b/python/samba/netcmd/domain/models/fields.py index b60f2e4d4b4..845b34d10ab 100644 --- a/python/samba/netcmd/domain/models/fields.py +++ b/python/samba/netcmd/domain/models/fields.py @@ -28,6 +28,7 @@ from datetime import datetime from xml.etree import ElementTree from ldb import Dn, MessageElement, string_to_time, timestring +from samba.dcerpc import security from samba.dcerpc.misc import GUID from samba.ndr import ndr_pack, ndr_unpack @@ -311,6 +312,36 @@ class GUIDField(Field): return MessageElement(ndr_pack(GUID(value)), flags, self.name) +class SDDLField(Field): + """A SDDL field encodes and decodes SDDL data.""" + + def from_db_value(self, ldb, value): + if value is None: + return + elif len(value) > 1 or self.many: + return [ndr_unpack(security.descriptor, item).as_sddl() + for item in value] + else: + return ndr_unpack(security.descriptor, value[0]).as_sddl() + + def to_db_value(self, ldb, value, flags): + domain_sid = security.dom_sid(ldb.get_domain_sid()) + if value is None: + return + elif isinstance(value, list): + return MessageElement([ndr_pack(security.descriptor.from_sddl( + item, domain_sid)) for item in value], + flags, + self.name) + else: + return MessageElement( + ndr_pack(security.descriptor.from_sddl(value, + domain_sid)), + flags, + self.name + ) + + class BooleanField(Field): """A simple boolean field, can be a bool or list of bool.""" diff --git a/python/samba/tests/samba_tool/domain_models.py b/python/samba/tests/samba_tool/domain_models.py index 54505018446..548444b83cb 100644 --- a/python/samba/tests/samba_tool/domain_models.py +++ b/python/samba/tests/samba_tool/domain_models.py @@ -25,10 +25,11 @@ from datetime import datetime from xml.etree import ElementTree from ldb import FLAG_MOD_ADD, MessageElement, SCOPE_ONELEVEL +from samba.dcerpc import security from samba.dcerpc.misc import GUID from samba.netcmd.domain.models import User, fields from samba.netcmd.domain.models.auth_policy import StrongNTLMPolicy -from samba.ndr import ndr_unpack +from samba.ndr import ndr_pack, ndr_unpack from .base import SambaToolCmdTest @@ -276,6 +277,45 @@ class GUIDFieldTest(FieldTestMixin, SambaToolCmdTest): ] +class SDDLFieldTest(FieldTestMixin, SambaToolCmdTest): + field = fields.SDDLField("FieldName") + + def setUp(self): + super().setUp() + self.domain_sid = security.dom_sid(self.samdb.get_domain_sid()) + + def encode(self, value): + return ndr_pack(security.descriptor.from_sddl(value, self.domain_sid)) + + @property + def to_db_value(self): + values = [ + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AU)}))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;((Member_of {SID(AO)}) || (Member_of {SID(BO)})))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(%s)}))" % self.domain_sid, + ] + expected = [ + (value, MessageElement(self.encode(value))) for value in values + ] + expected.append((None, None)) + return expected + + @property + def from_db_value(self): + values = [ + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AU)}))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;((Member_of {SID(AO)}) || (Member_of {SID(BO)})))", + "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(%s)}))" % self.domain_sid, + ] + expected = [ + (MessageElement(self.encode(value)), value) for value in values + ] + expected.append((None, None)) + return expected + + class PossibleClaimValuesFieldTest(FieldTestMixin, SambaToolCmdTest): field = fields.PossibleClaimValuesField("FieldName") -- 2.47.3