From a08a724a28e4796eb0c739a560b0192a8ac2e00d Mon Sep 17 00:00:00 2001 From: Joseph Sutton Date: Tue, 7 Nov 2023 16:50:49 +1300 Subject: [PATCH] =?utf8?q?netcmd:tests:=20Test=20authentication=20policies?= =?utf8?q?=20containing=20device=E2=80=90specific=20attributes=20and=20ope?= =?utf8?q?rators?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- .../tests/samba_tool/domain_auth_policy.py | 103 +++++++++++++++++- selftest/knownfail.d/device-in-sddl | 2 + 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 selftest/knownfail.d/device-in-sddl diff --git a/python/samba/tests/samba_tool/domain_auth_policy.py b/python/samba/tests/samba_tool/domain_auth_policy.py index a9401ab41ba..8233b7dd225 100644 --- a/python/samba/tests/samba_tool/domain_auth_policy.py +++ b/python/samba/tests/samba_tool/domain_auth_policy.py @@ -25,7 +25,7 @@ from optparse import OptionValueError from unittest.mock import patch from samba.dcerpc import security -from samba.ndr import ndr_unpack +from samba.ndr import ndr_pack, ndr_unpack from samba.netcmd.domain.models.exceptions import ModelError from samba.samdb import SamDB from samba.sd_utils import SDUtils @@ -339,6 +339,107 @@ class AuthPolicyCmdTestCase(BaseAuthCmdTest): self.assertIn("unknown error", err) self.assertNotIn(" File ", err) # traceback marker + def test_create__device_attribute_in_sddl_allowed_to(self): + """Test creating a new authentication policy that uses + user-allowed-to-authenticate-to with a device attribute.""" + + sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(@Device.claim == "foo"))' + + name = self.unique_name() + self.addCleanup(self.delete_authentication_policy, name=name) + result, _, err = self.runcmd("domain", "auth", "policy", "create", + "--name", name, + "--user-allowed-to-authenticate-to", + sddl) + self.assertIsNone(result, msg=err) + + def test_create__device_operator_in_sddl_allowed_to(self): + """Test creating a new authentication policy that uses + user-allowed-to-authenticate-to with a device operator.""" + + sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(Not_Device_Member_of {SID(WD)}))' + + name = self.unique_name() + self.addCleanup(self.delete_authentication_policy, name=name) + result, _, err = self.runcmd("domain", "auth", "policy", "create", + "--name", name, + "--user-allowed-to-authenticate-to", + sddl) + self.assertIsNone(result, msg=err) + + def test_create__device_attribute_in_sddl_allowed_from(self): + """Test creating a new authentication policy that uses + user-allowed-to-authenticate-from with a device attribute.""" + + sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(@Device.claim == "foo"))' + + name = self.unique_name() + result, _, err = self.runcmd("domain", "auth", "policy", "create", + "--name", name, + "--user-allowed-to-authenticate-from", + sddl) + self.assertEqual(result, -1) + self.assertIn("Unable to parse SDDL", err) + self.assertIn(sddl, err) + self.assertIn(f"\n{'^':>31}\n", err) + self.assertIn(" a device attribute is not applicable in this context " + "(did you intend a user attribute?)", + err) + self.assertNotIn(" File ", err) + + def test_create__device_operator_in_sddl_allowed_from(self): + """Test creating a new authentication policy that uses + user-allowed-to-authenticate-from with a device operator.""" + + sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(Not_Device_Member_of {SID(WD)}))' + + name = self.unique_name() + result, _, err = self.runcmd("domain", "auth", "policy", "create", + "--name", name, + "--user-allowed-to-authenticate-from", + sddl) + self.assertEqual(result, -1) + self.assertIn("Unable to parse SDDL", err) + self.assertIn(sddl, err) + self.assertIn(f"\n{'^':>30}\n", err) + self.assertIn(" a device‐relative expression will never evaluate to " + "true in this context (did you intend a user‐relative " + "expression?)", + err) + self.assertNotIn(" File ", err) + + def test_create__device_attribute_in_sddl_already_exists(self): + """Test modifying an existing authentication policy that uses + user-allowed-to-authenticate-from with a device attribute.""" + + # The SDDL refers to ‘Device.claim’. + sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(@Device.claim == "foo"))' + domain_sid = security.dom_sid(self.samdb.get_domain_sid()) + descriptor = security.descriptor.from_sddl(sddl, domain_sid) + + # Manually create an authentication policy that refers to a device + # attribute. + + name = self.unique_name() + dn = self.get_authn_policies_dn() + dn.add_child(f"CN={name}") + message = { + 'dn': dn, + 'msDS-AuthNPolicyEnforced': b'TRUE', + 'objectClass': b'msDS-AuthNPolicy', + 'msDS-UserAllowedToAuthenticateFrom': ndr_pack(descriptor), + } + + self.addCleanup(self.delete_authentication_policy, name=name) + self.samdb.add(message) + + # Change the policy description. This should succeed, in spite of the + # policy’s referring to a device attribute when it shouldn’t. + result, _, err = self.runcmd("domain", "auth", "policy", "modify", + "--name", name, + "--description", "NewDescription") + self.assertIsNone(result, msg=err) + def test_create__already_exists(self): """Test creating a new authentication policy that already exists.""" result, out, err = self.runcmd("domain", "auth", "policy", "create", diff --git a/selftest/knownfail.d/device-in-sddl b/selftest/knownfail.d/device-in-sddl new file mode 100644 index 00000000000..60dfaf2ed06 --- /dev/null +++ b/selftest/knownfail.d/device-in-sddl @@ -0,0 +1,2 @@ +^samba\.tests\.samba_tool\.domain_auth_policy\.samba\.tests\.samba_tool\.domain_auth_policy\.AuthPolicyCmdTestCase\.test_create__device_attribute_in_sddl_allowed_from\(ad_dc_default\)$ +^samba\.tests\.samba_tool\.domain_auth_policy\.samba\.tests\.samba_tool\.domain_auth_policy\.AuthPolicyCmdTestCase\.test_create__device_operator_in_sddl_allowed_from\(ad_dc_default\)$ -- 2.47.3