1
0
mirror of https://github.com/samba-team/samba.git synced 2025-06-12 23:17:06 +03:00
samba-mirror/python/samba/tests/samba_tool/domain_auth_policy.py
Andréas Leroux 3766b6a126 netcmd:domain:policy: Fix missing conversion from tgt_lifetime minutes to 10^(-7) seconds
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15692
Signed-off-by: Andréas Leroux <aleroux@tranquil.it>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jennifer Sutton <jennifersutton@catalyst.net.nz>

Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
Autobuild-Date(master): Fri Oct  4 04:01:22 UTC 2024 on atb-devel-224
2024-10-04 04:01:22 +00:00

1329 lines
61 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Unix SMB/CIFS implementation.
#
# Tests for samba-tool domain auth policy command
#
# Copyright (C) Catalyst.Net Ltd. 2023
#
# Written by Rob van der Linde <rob@catalyst.net.nz>
#
# 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/>.
#
import json
from optparse import OptionValueError
from unittest.mock import patch
from samba.dcerpc import security
from samba.domain.models.exceptions import ModelError
from samba.ndr import ndr_pack, ndr_unpack
from samba.nt_time import NT_TICKS_PER_SEC
from samba.samdb import SamDB
from samba.sd_utils import SDUtils
from .silo_base import SiloTest
def mins_to_tgt_lifetime(minutes):
"""Convert minutes to the tgt_lifetime attributes unit which is 10^-7 seconds"""
if minutes is not None:
return minutes * 60 * NT_TICKS_PER_SEC
return minutes
class AuthPolicyCmdTestCase(SiloTest):
def test_list(self):
"""Test listing authentication policies in list format."""
result, out, err = self.runcmd("domain", "auth", "policy", "list")
self.assertIsNone(result, msg=err)
expected_policies = ["User Policy", "Service Policy", "Computer Policy"]
for policy in expected_policies:
self.assertIn(policy, out)
def test_list__json(self):
"""Test listing authentication policies in JSON format."""
result, out, err = self.runcmd("domain", "auth", "policy",
"list", "--json")
self.assertIsNone(result, msg=err)
# we should get valid json
policies = json.loads(out)
expected_policies = ["User Policy", "Service Policy", "Computer Policy"]
for name in expected_policies:
policy = policies[name]
self.assertIn("name", policy)
self.assertIn("msDS-AuthNPolicy", list(policy["objectClass"]))
self.assertIn("msDS-AuthNPolicyEnforced", policy)
self.assertIn("msDS-StrongNTLMPolicy", policy)
self.assertIn("objectGUID", policy)
def test_view(self):
"""Test viewing a single authentication policy."""
result, out, err = self.runcmd("domain", "auth", "policy", "view",
"--name", "User Policy")
self.assertIsNone(result, msg=err)
# we should get valid json
policy = json.loads(out)
# check a few fields only
self.assertEqual(policy["cn"], "User Policy")
self.assertEqual(policy["msDS-AuthNPolicyEnforced"], True)
def test_view__notfound(self):
"""Test viewing an authentication policy that doesn't exist."""
result, out, err = self.runcmd("domain", "auth", "policy", "view",
"--name", "doesNotExist")
self.assertEqual(result, -1)
self.assertIn("Authentication policy doesNotExist not found.", err)
def test_view__name_required(self):
"""Test view authentication policy without --name argument."""
result, out, err = self.runcmd("domain", "auth", "policy", "view")
self.assertEqual(result, -1)
self.assertIn("Argument --name is required.", err)
def test_create__success(self):
"""Test creating a new authentication policy."""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name)
self.assertIsNone(result, msg=err)
# Check policy that was created
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
def test_create__description(self):
"""Test creating a new authentication policy with description set."""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--description", "Custom Description")
self.assertIsNone(result, msg=err)
# Check policy description
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
self.assertEqual(str(policy["description"]), "Custom Description")
def test_create__user_tgt_lifetime_mins(self):
"""Test create a new authentication policy with --user-tgt-lifetime-mins.
Also checks the upper and lower bounds are handled.
"""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--user-tgt-lifetime-mins", "60")
self.assertIsNone(result, msg=err)
# Check policy fields.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
self.assertEqual(str(policy["msDS-UserTGTLifetime"]), str(mins_to_tgt_lifetime(60)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name + "Lower",
"--user-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name + "Upper",
"--user-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_create__service_tgt_lifetime_mins(self):
"""Test create a new authentication policy with --service-tgt-lifetime-mins.
Also checks the upper and lower bounds are handled.
"""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--service-tgt-lifetime-mins", "60")
self.assertIsNone(result, msg=err)
# Check policy fields.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
self.assertEqual(str(policy["msDS-ServiceTGTLifetime"]), str(mins_to_tgt_lifetime(60)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--service-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--service-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_create__computer_tgt_lifetime_mins(self):
"""Test create a new authentication policy with --computer-tgt-lifetime-mins.
Also checks the upper and lower bounds are handled.
"""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--computer-tgt-lifetime-mins", "60")
self.assertIsNone(result, msg=err)
# Check policy fields.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
self.assertEqual(str(policy["msDS-ComputerTGTLifetime"]), str(mins_to_tgt_lifetime(60)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name + "Lower",
"--computer-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name + "Upper",
"--computer-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_create__valid_sddl(self):
"""Test creating a new authentication policy with valid SDDL in a field."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--user-allowed-to-authenticate-from",
expected)
self.assertIsNone(result, msg=err)
# Check policy fields.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-UserAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_create__invalid_sddl(self):
"""Test creating a new authentication policy with invalid SDDL in a field."""
name = self.unique_name()
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--user-allowed-to-authenticate-from",
"*INVALID SDDL*")
self.assertEqual(result, -1)
self.assertIn("Unable to parse SDDL", err)
self.assertIn(" *INVALID SDDL*\n ^\n expected '[OGDS]:' section start ", err)
def test_create__invalid_sddl_conditional_ace(self):
"""Test creating a new authentication policy with invalid SDDL in a field."""
sddl = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {secret club}))"
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", "invalidSDDLPolicy2",
"--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{'^':>41}", err)
self.assertIn("unexpected byte 0x73 's' parsing literal", err)
self.assertNotIn(" File ", err)
def test_create__invalid_sddl_conditional_ace_non_ascii(self):
"""Test creating a new authentication policy with invalid SDDL in a field."""
sddl = 'O:SYG:SYD:(XA;OICI;CR;;;WD;(@User.āāēē == "łē¶ŧ¹⅓þōīŋ“đ¢ð»" && Member_of {secret club}))'
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", "invalidSDDLPolicy2",
"--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{'^':>76}\n", err)
self.assertIn(" unexpected byte 0x73 's' parsing literal", err)
self.assertNotIn(" File ", err)
def test_create__invalid_sddl_normal_ace(self):
"""Test creating a new authentication policy with invalid SDDL in a field."""
sddl = "O:SYG:SYD:(A;;;;ZZ)(XA;OICI;CR;;;WD;(Member_of {WD}))"
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", "invalidSDDLPolicy3",
"--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{'^':>13}", err)
self.assertIn("\n malformed ACE with only 4 ';'\n", 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 devicerelative expression will never evaluate to "
"true in this context (did you intend a userrelative "
"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
# policys referring to a device attribute when it shouldnt.
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",
"--name", "User Policy")
self.assertEqual(result, -1)
self.assertIn("Authentication policy User Policy already exists", err)
def test_create__name_missing(self):
"""Test create authentication policy without --name argument."""
result, out, err = self.runcmd("domain", "auth", "policy", "create")
self.assertEqual(result, -1)
self.assertIn("Argument --name is required.", err)
def test_create__audit(self):
"""Test create authentication policy with --audit flag."""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--audit")
self.assertIsNone(result, msg=err)
# fetch and check policy
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "FALSE")
def test_create__enforce(self):
"""Test create authentication policy with --enforce flag."""
name = self.unique_name()
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--enforce")
self.assertIsNone(result, msg=err)
# fetch and check policy
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
def test_create__audit_enforce_together(self):
"""Test create auth policy using both --audit and --enforce."""
name = self.unique_name()
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--audit", "--enforce")
self.assertEqual(result, -1)
self.assertIn("--audit and --enforce cannot be used together.", err)
def test_create__protect_unprotect_together(self):
"""Test create authentication policy using --protect and --unprotect."""
name = self.unique_name()
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--protect", "--unprotect")
self.assertEqual(result, -1)
self.assertIn("--protect and --unprotect cannot be used together.", err)
def test_user_allowed_to_authenticate_from__set_repeated(self):
"""Test repeating similar arguments doesn't make sense to use together.
user-allowed-to-authenticate-from set --device-group
user-allowed-to-authenticate-from set --device-silo
"""
name = self.unique_name()
self.runcmd("domain", "auth", "policy", "create", "--name", name)
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-from",
"set", "--name", name,
"--device-group",
self.device_group.name,
"--device-silo",
"Managers")
self.assertEqual(result, -1)
self.assertIn("Cannot have both --device-group and --device-silo options.", err)
def test_user_allowed_to_authenticate_to__set_repeated(self):
"""Test repeating similar arguments doesn't make sense to use together.
user-allowed-to-authenticate-to set --by-group
user-allowed-to-authenticate-to set --by-silo
"""
name = self.unique_name()
self.runcmd("domain", "auth", "policy", "create", "--name", name)
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-to",
"set", "--name", name,
"--by-group",
self.device_group.name,
"--by-silo",
"Managers")
self.assertEqual(result, -1)
self.assertIn("Cannot have both --by-group and --by-silo options.", err)
def test_service_allowed_to_authenticate_from__set_repeated(self):
"""Test repeating similar arguments doesn't make sense to use together.
service-allowed-to-authenticate-from set --device-group
service-allowed-to-authenticate-from set --device-silo
"""
name = self.unique_name()
self.runcmd("domain", "auth", "policy", "create", "--name", name)
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-from",
"set", "--name", name,
"--device-group",
self.device_group.name,
"--device-silo",
"QA")
self.assertEqual(result, -1)
self.assertIn("Cannot have both --device-group and --device-silo options.", err)
def test_service_allowed_to_authenticate_to__set_repeated(self):
"""Test repeating similar arguments doesn't make sense to use together.
service-allowed-to-authenticate-to set --by-group
service-allowed-to-authenticate-to set --by-silo
"""
name = self.unique_name()
self.runcmd("domain", "auth", "policy", "create", "--name", name)
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-to",
"set", "--name", name,
"--by-group",
self.device_group.name,
"--by-silo",
"QA")
self.assertEqual(result, -1)
self.assertIn("Cannot have both --by-group and --by-silo options.", err)
def test_computer_allowed_to_authenticate_to__set_repeated(self):
"""Test repeating similar arguments doesn't make sense to use together.
computer-allowed-to-authenticate-to set --by-group
computer-allowed-to-authenticate-to set --by-silo
"""
name = self.unique_name()
self.runcmd("domain", "auth", "policy", "create", "--name", name)
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy",
"computer-allowed-to-authenticate-to",
"set", "--name", name,
"--by-group",
self.device_group.name,
"--by-silo",
"QA")
self.assertEqual(result, -1)
self.assertIn("Cannot have both --by-group and --by-silo options.", err)
def test_create__fails(self):
"""Test creating an authentication policy, but it fails."""
name = self.unique_name()
# Raise ModelError when ldb.add() is called.
with patch.object(SamDB, "add") as add_mock:
add_mock.side_effect = ModelError("Custom error message")
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name)
self.assertEqual(result, -1)
self.assertIn("Custom error message", err)
def test_modify__description(self):
"""Test modifying an authentication policy description."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Change the policy description.
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--description", "NewDescription")
self.assertIsNone(result, msg=err)
# Verify fields were changed.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["description"]), "NewDescription")
def test_modify__strong_ntlm_policy(self):
"""Test modify strong ntlm policy on the authentication policy."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--strong-ntlm-policy", "Required")
self.assertIsNone(result, msg=err)
# Verify fields were changed.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-StrongNTLMPolicy"]), "2")
# Check an invalid choice.
with self.assertRaises((OptionValueError, SystemExit)):
self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--strong-ntlm-policy", "Invalid")
# It is difficult to test the error message text for invalid
# choices because inside optparse it will raise OptionValueError
# followed by raising SystemExit(2).
def test_modify__user_tgt_lifetime_mins(self):
"""Test modifying an authentication policy --user-tgt-lifetime-mins.
This includes checking the upper and lower bounds.
"""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--user-tgt-lifetime-mins", "120")
self.assertIsNone(result, msg=err)
# Verify field was changed.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-UserTGTLifetime"]), str(mins_to_tgt_lifetime(120)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Lower",
"--user-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Upper",
"--user-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_modify__service_tgt_lifetime_mins(self):
"""Test modifying an authentication policy --service-tgt-lifetime-mins.
This includes checking the upper and lower bounds.
"""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--service-tgt-lifetime-mins", "120")
self.assertIsNone(result, msg=err)
# Verify field was changed.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-ServiceTGTLifetime"]), str(mins_to_tgt_lifetime(120)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Lower",
"--service-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Upper",
"--service-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_modify__computer_tgt_lifetime_mins(self):
"""Test modifying an authentication policy --computer-tgt-lifetime-mins.
This includes checking the upper and lower bounds.
"""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--computer-tgt-lifetime-mins", "120")
self.assertIsNone(result, msg=err)
# Verify field was changed.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-ComputerTGTLifetime"]), str(mins_to_tgt_lifetime(120)))
# check lower bounds (45)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Lower",
"--computer-tgt-lifetime-mins", "44")
self.assertEqual(result, -1)
self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
err)
# check upper bounds (2147483647)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name + "Upper",
"--computer-tgt-lifetime-mins", "2147483648")
self.assertEqual(result, -1)
self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
err)
def test_modify__user_allowed_to_authenticate_from(self):
"""Modify authentication policy user allowed to authenticate from."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate from field
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--user-allowed-to-authenticate-from",
expected)
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate from field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-UserAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_user_allowed_to_authenticate_from__set_device_group(self):
"""Tests the user-allowed-to-authenticate-from set --device-group shortcut."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of_any {SID(%s)}))" % (
self.device_group.object_sid)
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate from silo field
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-from",
"set", "--name", name,
"--device-group", self.device_group.name)
self.assertIsNone(result, msg=err)
# Check generated SDDL.
policy = self.get_authentication_policy(name)
desc = policy["msDS-UserAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_user_allowed_to_authenticate_from__set_device_silo(self):
"""Tests the user-allowed-to-authenticate-from set --device-silo shortcut."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate from silo field
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-from",
"set", "--name", name,
"--device-silo", "QA")
self.assertIsNone(result, msg=err)
# Check generated SDDL.
policy = self.get_authentication_policy(name)
desc = policy["msDS-UserAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(
sddl,
'O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/AuthenticationSilo == "QA"))')
def test_modify__user_allowed_to_authenticate_to(self):
"""Modify authentication policy user allowed to authenticate to."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--user-allowed-to-authenticate-to",
expected)
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-UserAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_user_allowed_to_authenticate_to__set_by_group(self):
"""Tests the user-allowed-to-authenticate-to set --by-group shortcut."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of_any {SID(%s)}))" % (
self.device_group.object_sid)
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-to",
"set", "--name", name,
"--by-group", self.device_group.name)
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-UserAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_user_allowed_to_authenticate_to__set_by_silo(self):
"""Tests the user-allowed-to-authenticate-to set --by-silo shortcut."""
name = self.unique_name()
expected = ('O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/'
'AuthenticationSilo == "Developers"))')
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"user-allowed-to-authenticate-to",
"set", "--name", name,
"--by-silo", "Developers")
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-UserAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_modify__service_allowed_to_authenticate_from(self):
"""Modify authentication policy service allowed to authenticate from."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify service allowed to authenticate from field
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--service-allowed-to-authenticate-from",
expected)
self.assertIsNone(result, msg=err)
# Check service allowed to authenticate from field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ServiceAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_service_allowed_to_authenticate_from__set_device_group(self):
"""Tests the service-allowed-to-authenticate-from set --device-group shortcut."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of_any {SID(%s)}))" % (
self.device_group.object_sid)
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate from silo field
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-from",
"set", "--name", name,
"--device-group", self.device_group.name)
self.assertIsNone(result, msg=err)
# Check generated SDDL.
policy = self.get_authentication_policy(name)
desc = policy["msDS-ServiceAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_service_allowed_to_authenticate_from__set_device_silo(self):
"""Tests the service-allowed-to-authenticate-from set --device-silo shortcut."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate from silo field
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-from",
"set", "--name", name,
"--device-silo", "Developers")
self.assertIsNone(result, msg=err)
# Check generated SDDL.
policy = self.get_authentication_policy(name)
desc = policy["msDS-ServiceAllowedToAuthenticateFrom"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(
sddl,
'O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/AuthenticationSilo == "Developers"))')
def test_modify__service_allowed_to_authenticate_to(self):
"""Modify authentication policy service allowed to authenticate to."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify service allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--service-allowed-to-authenticate-to",
expected)
self.assertIsNone(result, msg=err)
# Check service allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ServiceAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_service_allowed_to_authenticate_to__set_by_group(self):
"""Tests the service-allowed-to-authenticate-to set --by-group shortcut."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of_any {SID(%s)}))" % (
self.device_group.object_sid)
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-to",
"set", "--name", name,
"--by-group", self.device_group.name)
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ServiceAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_service_allowed_to_authenticate_to__set_by_silo(self):
"""Tests the service-allowed-to-authenticate-to set --by-silo shortcut."""
name = self.unique_name()
expected = ('O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/'
'AuthenticationSilo == "QA"))')
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"service-allowed-to-authenticate-to",
"set", "--name", name,
"--by-silo", "QA")
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ServiceAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_modify__computer_allowed_to_authenticate_to(self):
"""Modify authentication policy computer allowed to authenticate to."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify computer allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--computer-allowed-to-authenticate-to",
expected)
self.assertIsNone(result, msg=err)
# Check computer allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ComputerAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_computer_allowed_to_authenticate_to__set_by_group(self):
"""Tests the computer-allowed-to-authenticate-to set --by-group shortcut."""
name = self.unique_name()
expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of_any {SID(%s)}))" % (
self.device_group.object_sid)
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"computer-allowed-to-authenticate-to",
"set", "--name", name, "--by-group",
self.device_group.name)
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ComputerAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_computer_allowed_to_authenticate_to__set_by_silo(self):
"""Tests the computer-allowed-to-authenticate-to set --by-silo shortcut."""
name = self.unique_name()
expected = ('O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/'
'AuthenticationSilo == "QA"))')
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Modify user allowed to authenticate to field
result, out, err = self.runcmd("domain", "auth", "policy",
"computer-allowed-to-authenticate-to",
"set", "--name", name, "--by-silo",
"QA")
self.assertIsNone(result, msg=err)
# Check user allowed to authenticate to field was modified.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["cn"]), name)
desc = policy["msDS-ComputerAllowedToAuthenticateTo"][0]
sddl = ndr_unpack(security.descriptor, desc).as_sddl()
self.assertEqual(sddl, expected)
def test_modify__name_missing(self):
"""Test modify authentication but the --name argument is missing."""
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--description", "NewDescription")
self.assertEqual(result, -1)
self.assertIn("Argument --name is required.", err)
def test_modify__notfound(self):
"""Test modify an authentication silo that doesn't exist."""
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", "doesNotExist",
"--description", "NewDescription")
self.assertEqual(result, -1)
self.assertIn("Authentication policy doesNotExist not found.", err)
def test_modify__audit_enforce(self):
"""Test modify authentication policy using --audit and --enforce."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy,
name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
# Change to audit, the default is --enforce.
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--audit")
self.assertIsNone(result, msg=err)
# Check that the policy was changed to --audit.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "FALSE")
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--enforce")
self.assertIsNone(result, msg=err)
# Check if the policy was changed back to --enforce.
policy = self.get_authentication_policy(name)
self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
def test_modify__protect_unprotect(self):
"""Test modify authentication policy using --protect and --unprotect."""
name = self.unique_name()
# Create a policy to modify for this test.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
self.runcmd("domain", "auth", "policy", "create", "--name", name)
utils = SDUtils(self.samdb)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--protect")
self.assertIsNone(result, msg=err)
# Check that claim type was protected.
policy = self.get_authentication_policy(name)
desc = utils.get_sd_as_sddl(policy["dn"])
self.assertIn("(D;;DTSD;;;WD)", desc)
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", name,
"--unprotect")
self.assertIsNone(result, msg=err)
# Check that claim type was unprotected.
policy = self.get_authentication_policy(name)
desc = utils.get_sd_as_sddl(policy["dn"])
self.assertNotIn("(D;;DTSD;;;WD)", desc)
def test_modify__audit_enforce_together(self):
"""Test modify auth policy using both --audit and --enforce."""
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", "User Policy",
"--audit", "--enforce")
self.assertEqual(result, -1)
self.assertIn("--audit and --enforce cannot be used together.", err)
def test_modify__protect_unprotect_together(self):
"""Test modify authentication policy using --protect and --unprotect."""
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", "User Policy",
"--protect", "--unprotect")
self.assertEqual(result, -1)
self.assertIn("--protect and --unprotect cannot be used together.", err)
def test_modify__fails(self):
"""Test modifying an authentication policy, but it fails."""
# Raise ModelError when ldb.add() is called.
with patch.object(SamDB, "modify") as modify_mock:
modify_mock.side_effect = ModelError("Custom error message")
result, out, err = self.runcmd("domain", "auth", "policy", "modify",
"--name", "User Policy",
"--description", "New description")
self.assertEqual(result, -1)
self.assertIn("Custom error message", err)
def test_delete__success(self):
"""Test deleting an authentication policy that is not protected."""
# Create non-protected authentication policy.
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name=deleteTest")
self.assertIsNone(result, msg=err)
policy = self.get_authentication_policy("deleteTest")
self.assertIsNotNone(policy)
# Do the deletion.
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name", "deleteTest")
self.assertIsNone(result, msg=err)
# Authentication policy shouldn't exist anymore.
policy = self.get_authentication_policy("deleteTest")
self.assertIsNone(policy)
def test_delete__protected(self):
"""Test deleting a protected auth policy, with and without --force."""
# Create protected authentication policy.
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name=deleteProtected",
"--protect")
self.assertIsNone(result, msg=err)
policy = self.get_authentication_policy("deleteProtected")
self.assertIsNotNone(policy)
# Do the deletion.
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name=deleteProtected")
self.assertEqual(result, -1)
# Authentication silo should still exist.
policy = self.get_authentication_policy("deleteProtected")
self.assertIsNotNone(policy)
# Try a force delete instead.
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name=deleteProtected", "--force")
self.assertIsNone(result, msg=err)
# Authentication silo shouldn't exist anymore.
policy = self.get_authentication_policy("deleteProtected")
self.assertIsNone(policy)
def test_delete__notfound(self):
"""Test deleting an authentication policy that doesn't exist."""
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name", "doesNotExist")
self.assertEqual(result, -1)
self.assertIn("Authentication policy doesNotExist not found.", err)
def test_delete__name_required(self):
"""Test deleting an authentication policy without --name argument."""
result, out, err = self.runcmd("domain", "auth", "policy", "delete")
self.assertEqual(result, -1)
self.assertIn("Argument --name is required.", err)
def test_delete__force_fails(self):
"""Test deleting an authentication policy with --force, but it fails."""
name = self.unique_name()
# Create protected authentication policy.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--protect")
self.assertIsNone(result, msg=err)
# Policy exists
policy = self.get_authentication_policy(name)
self.assertIsNotNone(policy)
# Try doing delete with --force.
# Patch SDUtils.dacl_delete_aces with a Mock that raises ModelError.
with patch.object(SDUtils, "dacl_delete_aces") as delete_mock:
delete_mock.side_effect = ModelError("Custom error message")
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name", name,
"--force")
self.assertEqual(result, -1)
self.assertIn("Custom error message", err)
def test_delete__fails(self):
"""Test deleting an authentication policy, but it fails."""
name = self.unique_name()
# Create regular authentication policy.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name)
self.assertIsNone(result, msg=err)
# Policy exists
policy = self.get_authentication_policy(name)
self.assertIsNotNone(policy)
# Raise ModelError when ldb.delete() is called.
with patch.object(SamDB, "delete") as delete_mock:
delete_mock.side_effect = ModelError("Custom error message")
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name", name)
self.assertEqual(result, -1)
self.assertIn("Custom error message", err)
# When not using --force we get a hint.
self.assertIn("Try --force", err)
def test_delete__protected_fails(self):
"""Test deleting an authentication policy, but it fails."""
name = self.unique_name()
# Create protected authentication policy.
self.addCleanup(self.delete_authentication_policy, name=name, force=True)
result, out, err = self.runcmd("domain", "auth", "policy", "create",
"--name", name,
"--protect")
self.assertIsNone(result, msg=err)
# Policy exists
policy = self.get_authentication_policy(name)
self.assertIsNotNone(policy)
# Raise ModelError when ldb.delete() is called.
with patch.object(SamDB, "delete") as delete_mock:
delete_mock.side_effect = ModelError("Custom error message")
result, out, err = self.runcmd("domain", "auth", "policy", "delete",
"--name", name,
"--force")
self.assertEqual(result, -1)
self.assertIn("Custom error message", err)
# When using --force we don't get the hint.
self.assertNotIn("Try --force", err)