]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
netcmd: models: add SDDL model field
authorRob van der Linde <rob@catalyst.net.nz>
Wed, 20 Sep 2023 00:52:31 +0000 (12:52 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 29 Sep 2023 02:18:34 +0000 (02:18 +0000)
Signed-off-by: Rob van der Linde <rob@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/netcmd/domain/models/fields.py
python/samba/tests/samba_tool/domain_models.py

index b60f2e4d4b4f64a9db07643d7bf9ae3070ed35e8..845b34d10ab5618f07418a43bece2bbee4352219 100644 (file)
@@ -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."""
 
index 545050184466c5bd9ea9a310657e1d69f552ec90..548444b83cb72e395b378f663ac3aba63e5d7a08 100644 (file)
@@ -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")