1 # Unix SMB/CIFS implementation.
3 # Tests for samba-tool domain auth policy command
5 # Copyright (C) Catalyst.Net Ltd. 2023
7 # Written by Rob van der Linde <rob@catalyst.net.nz>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 from optparse import OptionValueError
25 from unittest.mock import patch
27 from samba.dcerpc import security
28 from samba.ndr import ndr_unpack
29 from samba.netcmd.domain.models.exceptions import ModelError
30 from samba.samdb import SamDB
31 from samba.sd_utils import SDUtils
33 from .domain_auth_base import BaseAuthCmdTest
36 class AuthPolicyCmdTestCase(BaseAuthCmdTest):
39 """Test listing authentication policies in list format."""
40 result, out, err = self.runcmd("domain", "auth", "policy", "list")
41 self.assertIsNone(result, msg=err)
43 expected_policies = ["User Policy", "Service Policy", "Computer Policy"]
45 for policy in expected_policies:
46 self.assertIn(policy, out)
48 def test_list__json(self):
49 """Test listing authentication policies in JSON format."""
50 result, out, err = self.runcmd("domain", "auth", "policy",
52 self.assertIsNone(result, msg=err)
54 # we should get valid json
55 policies = json.loads(out)
57 expected_policies = ["User Policy", "Service Policy", "Computer Policy"]
59 for name in expected_policies:
60 policy = policies[name]
61 self.assertIn("name", policy)
62 self.assertIn("msDS-AuthNPolicy", list(policy["objectClass"]))
63 self.assertIn("msDS-AuthNPolicyEnforced", policy)
64 self.assertIn("msDS-StrongNTLMPolicy", policy)
65 self.assertIn("objectGUID", policy)
68 """Test viewing a single authentication policy."""
69 result, out, err = self.runcmd("domain", "auth", "policy", "view",
70 "--name", "User Policy")
71 self.assertIsNone(result, msg=err)
73 # we should get valid json
74 policy = json.loads(out)
76 # check a few fields only
77 self.assertEqual(policy["cn"], "User Policy")
78 self.assertEqual(policy["msDS-AuthNPolicyEnforced"], True)
80 def test_view__notfound(self):
81 """Test viewing an authentication policy that doesn't exist."""
82 result, out, err = self.runcmd("domain", "auth", "policy", "view",
83 "--name", "doesNotExist")
84 self.assertEqual(result, -1)
85 self.assertIn("Authentication policy doesNotExist not found.", err)
87 def test_view__name_required(self):
88 """Test view authentication policy without --name argument."""
89 result, out, err = self.runcmd("domain", "auth", "policy", "view")
90 self.assertEqual(result, -1)
91 self.assertIn("Argument --name is required.", err)
93 def test_create__success(self):
94 """Test creating a new authentication policy."""
95 self.addCleanup(self.delete_authentication_policy,
96 name="createTest", force=True)
98 result, out, err = self.runcmd("domain", "auth", "policy", "create",
99 "--name", "createTest")
100 self.assertIsNone(result, msg=err)
102 # Check policy that was created
103 policy = self.get_authentication_policy("createTest")
104 self.assertEqual(str(policy["cn"]), "createTest")
105 self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
107 def test_create__description(self):
108 """Test creating a new authentication policy with description set."""
109 self.addCleanup(self.delete_authentication_policy,
110 name="descriptionTest", force=True)
112 result, out, err = self.runcmd("domain", "auth", "policy", "create",
113 "--name", "descriptionTest",
114 "--description", "Custom Description")
115 self.assertIsNone(result, msg=err)
117 # Check policy description
118 policy = self.get_authentication_policy("descriptionTest")
119 self.assertEqual(str(policy["cn"]), "descriptionTest")
120 self.assertEqual(str(policy["description"]), "Custom Description")
122 def test_create__user_tgt_lifetime_mins(self):
123 """Test create a new authentication policy with --user-tgt-lifetime-mins.
125 Also checks the upper and lower bounds are handled.
127 self.addCleanup(self.delete_authentication_policy,
128 name="userTGTLifetime", force=True)
130 result, out, err = self.runcmd("domain", "auth", "policy", "create",
131 "--name", "userTGTLifetime",
132 "--user-tgt-lifetime-mins", "60")
133 self.assertIsNone(result, msg=err)
135 # Check policy fields.
136 policy = self.get_authentication_policy("userTGTLifetime")
137 self.assertEqual(str(policy["cn"]), "userTGTLifetime")
138 self.assertEqual(str(policy["msDS-UserTGTLifetime"]), "60")
140 # check lower bounds (45)
141 result, out, err = self.runcmd("domain", "auth", "policy", "create",
142 "--name", "userTGTLifetimeLower",
143 "--user-tgt-lifetime-mins", "44")
144 self.assertEqual(result, -1)
145 self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
148 # check upper bounds (2147483647)
149 result, out, err = self.runcmd("domain", "auth", "policy", "create",
150 "--name", "userTGTLifetimeUpper",
151 "--user-tgt-lifetime-mins", "2147483648")
152 self.assertEqual(result, -1)
153 self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
156 def test_create__service_tgt_lifetime_mins(self):
157 """Test create a new authentication policy with --service-tgt-lifetime-mins.
159 Also checks the upper and lower bounds are handled.
161 self.addCleanup(self.delete_authentication_policy,
162 name="serviceTGTLifetime", force=True)
164 result, out, err = self.runcmd("domain", "auth", "policy", "create",
165 "--name", "serviceTGTLifetime",
166 "--service-tgt-lifetime-mins", "60")
167 self.assertIsNone(result, msg=err)
169 # Check policy fields.
170 policy = self.get_authentication_policy("serviceTGTLifetime")
171 self.assertEqual(str(policy["cn"]), "serviceTGTLifetime")
172 self.assertEqual(str(policy["msDS-ServiceTGTLifetime"]), "60")
174 # check lower bounds (45)
175 result, out, err = self.runcmd("domain", "auth", "policy", "create",
176 "--name", "serviceTGTLifetimeLower",
177 "--service-tgt-lifetime-mins", "44")
178 self.assertEqual(result, -1)
179 self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
182 # check upper bounds (2147483647)
183 result, out, err = self.runcmd("domain", "auth", "policy", "create",
184 "--name", "serviceTGTLifetimeUpper",
185 "--service-tgt-lifetime-mins", "2147483648")
186 self.assertEqual(result, -1)
187 self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
190 def test_create__computer_tgt_lifetime_mins(self):
191 """Test create a new authentication policy with --computer-tgt-lifetime-mins.
193 Also checks the upper and lower bounds are handled.
195 self.addCleanup(self.delete_authentication_policy,
196 name="computerTGTLifetime", force=True)
198 result, out, err = self.runcmd("domain", "auth", "policy", "create",
199 "--name", "computerTGTLifetime",
200 "--computer-tgt-lifetime-mins", "60")
201 self.assertIsNone(result, msg=err)
203 # Check policy fields.
204 policy = self.get_authentication_policy("computerTGTLifetime")
205 self.assertEqual(str(policy["cn"]), "computerTGTLifetime")
206 self.assertEqual(str(policy["msDS-ComputerTGTLifetime"]), "60")
208 # check lower bounds (45)
209 result, out, err = self.runcmd("domain", "auth", "policy", "create",
210 "--name", "computerTGTLifetimeLower",
211 "--computer-tgt-lifetime-mins", "44")
212 self.assertEqual(result, -1)
213 self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
216 # check upper bounds (2147483647)
217 result, out, err = self.runcmd("domain", "auth", "policy", "create",
218 "--name", "computerTGTLifetimeUpper",
219 "--computer-tgt-lifetime-mins", "2147483648")
220 self.assertEqual(result, -1)
221 self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
224 def test_create__valid_sddl(self):
225 """Test creating a new authentication policy with valid SDDL in a field."""
226 expected = "O:SYG:SYD:(XA;OICI;CR;;;WD;(Member_of {SID(AO)}))"
228 self.addCleanup(self.delete_authentication_policy,
229 name="validSDDLPolicy", force=True)
231 result, out, err = self.runcmd("domain", "auth", "policy", "create",
232 "--name", "validSDDLPolicy",
233 "--user-allowed-to-authenticate-from",
235 self.assertIsNone(result, msg=err)
237 # Check policy fields.
238 policy = self.get_authentication_policy("validSDDLPolicy")
239 self.assertEqual(str(policy["cn"]), "validSDDLPolicy")
240 desc = policy["msDS-UserAllowedToAuthenticateFrom"][0]
241 sddl = ndr_unpack(security.descriptor, desc).as_sddl()
242 self.assertEqual(sddl, expected)
244 def test_create__invalid_sddl(self):
245 """Test creating a new authentication policy with invalid SDDL in a field."""
246 result, out, err = self.runcmd("domain", "auth", "policy", "create",
247 "--name", "invalidSDDLPolicy",
248 "--user-allowed-to-authenticate-from",
250 self.assertEqual(result, -1)
252 "msDS-UserAllowedToAuthenticateFrom: Unable to parse SDDL", err)
254 def test_create__already_exists(self):
255 """Test creating a new authentication policy that already exists."""
256 result, out, err = self.runcmd("domain", "auth", "policy", "create",
257 "--name", "User Policy")
258 self.assertEqual(result, -1)
259 self.assertIn("Authentication policy User Policy already exists", err)
261 def test_create__name_missing(self):
262 """Test create authentication policy without --name argument."""
263 result, out, err = self.runcmd("domain", "auth", "policy", "create")
264 self.assertEqual(result, -1)
265 self.assertIn("Argument --name is required.", err)
267 def test_create__audit(self):
268 """Test create authentication policy with --audit flag."""
269 result, out, err = self.runcmd("domain", "auth", "policy", "create",
270 "--name", "auditPolicy",
272 self.assertIsNone(result, msg=err)
274 # fetch and check policy
275 policy = self.get_authentication_policy("auditPolicy")
276 self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "FALSE")
278 def test_create__enforce(self):
279 """Test create authentication policy with --enforce flag."""
280 result, out, err = self.runcmd("domain", "auth", "policy", "create",
281 "--name", "enforcePolicy",
283 self.assertIsNone(result, msg=err)
285 # fetch and check policy
286 policy = self.get_authentication_policy("enforcePolicy")
287 self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
289 def test_create__audit_enforce_together(self):
290 """Test create auth policy using both --audit and --enforce."""
291 result, out, err = self.runcmd("domain", "auth", "policy", "create",
292 "--name", "enforceTogether",
293 "--audit", "--enforce")
294 self.assertEqual(result, -1)
295 self.assertIn("--audit and --enforce cannot be used together.", err)
297 def test_create__protect_unprotect_together(self):
298 """Test create authentication policy using --protect and --unprotect."""
299 result, out, err = self.runcmd("domain", "auth", "policy", "create",
300 "--name", "protectTogether",
301 "--protect", "--unprotect")
302 self.assertEqual(result, -1)
303 self.assertIn("--protect and --unprotect cannot be used together.", err)
305 def test_create__fails(self):
306 """Test creating an authentication policy, but it fails."""
307 # Raise ModelError when ldb.add() is called.
308 with patch.object(SamDB, "add") as add_mock:
309 add_mock.side_effect = ModelError("Custom error message")
310 result, out, err = self.runcmd("domain", "auth", "policy", "create",
311 "--name", "createFails")
312 self.assertEqual(result, -1)
313 self.assertIn("Custom error message", err)
315 def test_modify__description(self):
316 """Test modifying an authentication policy description."""
317 # Create a policy to modify for this test.
318 name = "modifyDescription"
319 self.runcmd("domain", "auth", "policy", "create", "--name", name)
320 self.addCleanup(self.delete_authentication_policy,
321 name=name, force=True)
323 # Change the policy description.
324 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
326 "--description", "NewDescription")
327 self.assertIsNone(result, msg=err)
329 # Verify fields were changed.
330 policy = self.get_authentication_policy(name)
331 self.assertEqual(str(policy["description"]), "NewDescription")
333 def test_modify__strong_ntlm_policy(self):
334 """Test modify strong ntlm policy on the authentication policy."""
335 # Create a policy to modify for this test.
336 name = "modifyStrongNTLMPolicy"
337 self.runcmd("domain", "auth", "policy", "create", "--name", name)
338 self.addCleanup(self.delete_authentication_policy,
339 name=name, force=True)
341 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
343 "--strong-ntlm-policy", "Required")
344 self.assertIsNone(result, msg=err)
346 # Verify fields were changed.
347 policy = self.get_authentication_policy(name)
348 self.assertEqual(str(policy["msDS-StrongNTLMPolicy"]), "2")
350 # Check an invalid choice.
351 with self.assertRaises((OptionValueError, SystemExit)):
352 self.runcmd("domain", "auth", "policy", "modify",
354 "--strong-ntlm-policy", "Invalid")
356 # It is difficult to test the error message text for invalid
357 # choices because inside optparse it will raise OptionValueError
358 # followed by raising SystemExit(2).
360 def test_modify__user_tgt_lifetime_mins(self):
361 """Test modifying an authentication policy --user-tgt-lifetime-mins.
363 This includes checking the upper and lower bounds.
365 # Create a policy to modify for this test.
366 name = "modifyUserTGTLifetime"
367 self.runcmd("domain", "auth", "policy", "create", "--name", name)
368 self.addCleanup(self.delete_authentication_policy,
369 name=name, force=True)
371 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
373 "--user-tgt-lifetime-mins", "120")
374 self.assertIsNone(result, msg=err)
376 # Verify field was changed.
377 policy = self.get_authentication_policy(name)
378 self.assertEqual(str(policy["msDS-UserTGTLifetime"]), "120")
380 # check lower bounds (45)
381 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
383 "--user-tgt-lifetime-mins", "44")
384 self.assertEqual(result, -1)
385 self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
388 # check upper bounds (2147483647)
389 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
391 "--user-tgt-lifetime-mins", "2147483648")
392 self.assertEqual(result, -1)
393 self.assertIn("--user-tgt-lifetime-mins must be between 45 and 2147483647",
396 def test_modify__service_tgt_lifetime_mins(self):
397 """Test modifying an authentication policy --service-tgt-lifetime-mins.
399 This includes checking the upper and lower bounds.
401 # Create a policy to modify for this test.
402 name = "modifyServiceTGTLifetime"
403 self.runcmd("domain", "auth", "policy", "create", "--name", name)
404 self.addCleanup(self.delete_authentication_policy,
405 name=name, force=True)
407 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
409 "--service-tgt-lifetime-mins", "120")
410 self.assertIsNone(result, msg=err)
412 # Verify field was changed.
413 policy = self.get_authentication_policy(name)
414 self.assertEqual(str(policy["msDS-ServiceTGTLifetime"]), "120")
416 # check lower bounds (45)
417 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
419 "--service-tgt-lifetime-mins", "44")
420 self.assertEqual(result, -1)
421 self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
424 # check upper bounds (2147483647)
425 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
427 "--service-tgt-lifetime-mins", "2147483648")
428 self.assertEqual(result, -1)
429 self.assertIn("--service-tgt-lifetime-mins must be between 45 and 2147483647",
432 def test_modify__computer_tgt_lifetime_mins(self):
433 """Test modifying an authentication policy --computer-tgt-lifetime-mins.
435 This includes checking the upper and lower bounds.
437 # Create a policy to modify for this test.
438 name = "modifyComputerTGTLifetime"
439 self.runcmd("domain", "auth", "policy", "create", "--name", name)
440 self.addCleanup(self.delete_authentication_policy,
441 name=name, force=True)
443 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
445 "--computer-tgt-lifetime-mins", "120")
446 self.assertIsNone(result, msg=err)
448 # Verify field was changed.
449 policy = self.get_authentication_policy(name)
450 self.assertEqual(str(policy["msDS-ComputerTGTLifetime"]), "120")
452 # check lower bounds (45)
453 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
455 "--computer-tgt-lifetime-mins", "44")
456 self.assertEqual(result, -1)
457 self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
460 # check upper bounds (2147483647)
461 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
463 "--computer-tgt-lifetime-mins", "2147483648")
464 self.assertEqual(result, -1)
465 self.assertIn("--computer-tgt-lifetime-mins must be between 45 and 2147483647",
468 def test_modify__name_missing(self):
469 """Test modify authentication but the --name argument is missing."""
470 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
471 "--description", "NewDescription")
472 self.assertEqual(result, -1)
473 self.assertIn("Argument --name is required.", err)
475 def test_modify__notfound(self):
476 """Test modify an authentication silo that doesn't exist."""
477 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
478 "--name", "doesNotExist",
479 "--description", "NewDescription")
480 self.assertEqual(result, -1)
481 self.assertIn("Authentication policy doesNotExist not found.", err)
483 def test_modify__audit_enforce(self):
484 """Test modify authentication policy using --audit and --enforce."""
485 # Create a policy to modify for this test.
486 name = "modifyEnforce"
487 self.runcmd("domain", "auth", "policy", "create", "--name", name)
488 self.addCleanup(self.delete_authentication_policy,
489 name=name, force=True)
491 # Change to audit, the default is --enforce.
492 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
495 self.assertIsNone(result, msg=err)
497 # Check that the policy was changed to --audit.
498 policy = self.get_authentication_policy(name)
499 self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "FALSE")
501 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
504 self.assertIsNone(result, msg=err)
506 # Check if the policy was changed back to --enforce.
507 policy = self.get_authentication_policy(name)
508 self.assertEqual(str(policy["msDS-AuthNPolicyEnforced"]), "TRUE")
510 def test_modify__protect_unprotect(self):
511 """Test modify authentication policy using --protect and --unprotect."""
512 # Create a policy to modify for this test.
513 name = "modifyProtect"
514 self.runcmd("domain", "auth", "policy", "create", "--name", name)
515 self.addCleanup(self.delete_authentication_policy,
516 name=name, force=True)
518 utils = SDUtils(self.samdb)
519 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
522 self.assertIsNone(result, msg=err)
524 # Check that claim type was protected.
525 policy = self.get_authentication_policy(name)
526 desc = utils.get_sd_as_sddl(policy["dn"])
527 self.assertIn("(D;;DTSD;;;WD)", desc)
529 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
532 self.assertIsNone(result, msg=err)
534 # Check that claim type was unprotected.
535 policy = self.get_authentication_policy(name)
536 desc = utils.get_sd_as_sddl(policy["dn"])
537 self.assertNotIn("(D;;DTSD;;;WD)", desc)
539 def test_modify__audit_enforce_together(self):
540 """Test modify auth policy using both --audit and --enforce."""
541 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
542 "--name", "User Policy",
543 "--audit", "--enforce")
544 self.assertEqual(result, -1)
545 self.assertIn("--audit and --enforce cannot be used together.", err)
547 def test_modify__protect_unprotect_together(self):
548 """Test modify authentication policy using --protect and --unprotect."""
549 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
550 "--name", "User Policy",
551 "--protect", "--unprotect")
552 self.assertEqual(result, -1)
553 self.assertIn("--protect and --unprotect cannot be used together.", err)
555 def test_modify__fails(self):
556 """Test modifying an authentication policy, but it fails."""
557 # Raise ModelError when ldb.add() is called.
558 with patch.object(SamDB, "modify") as modify_mock:
559 modify_mock.side_effect = ModelError("Custom error message")
560 result, out, err = self.runcmd("domain", "auth", "policy", "modify",
561 "--name", "User Policy",
562 "--description", "New description")
563 self.assertEqual(result, -1)
564 self.assertIn("Custom error message", err)
566 def test_delete__success(self):
567 """Test deleting an authentication policy that is not protected."""
568 # Create non-protected authentication policy.
569 result, out, err = self.runcmd("domain", "auth", "policy", "create",
571 self.assertIsNone(result, msg=err)
572 policy = self.get_authentication_policy("deleteTest")
573 self.assertIsNotNone(policy)
576 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
577 "--name", "deleteTest")
578 self.assertIsNone(result, msg=err)
580 # Authentication policy shouldn't exist anymore.
581 policy = self.get_authentication_policy("deleteTest")
582 self.assertIsNone(policy)
584 def test_delete__protected(self):
585 """Test deleting a protected auth policy, with and without --force."""
586 # Create protected authentication policy.
587 result, out, err = self.runcmd("domain", "auth", "policy", "create",
588 "--name=deleteProtected",
590 self.assertIsNone(result, msg=err)
591 policy = self.get_authentication_policy("deleteProtected")
592 self.assertIsNotNone(policy)
595 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
596 "--name=deleteProtected")
597 self.assertEqual(result, -1)
599 # Authentication silo should still exist.
600 policy = self.get_authentication_policy("deleteProtected")
601 self.assertIsNotNone(policy)
603 # Try a force delete instead.
604 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
605 "--name=deleteProtected", "--force")
606 self.assertIsNone(result, msg=err)
608 # Authentication silo shouldn't exist anymore.
609 policy = self.get_authentication_policy("deleteProtected")
610 self.assertIsNone(policy)
612 def test_delete__notfound(self):
613 """Test deleting an authentication policy that doesn't exist."""
614 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
615 "--name", "doesNotExist")
616 self.assertEqual(result, -1)
617 self.assertIn("Authentication policy doesNotExist not found.", err)
619 def test_delete__name_required(self):
620 """Test deleting an authentication policy without --name argument."""
621 result, out, err = self.runcmd("domain", "auth", "policy", "delete")
622 self.assertEqual(result, -1)
623 self.assertIn("Argument --name is required.", err)
625 def test_delete__force_fails(self):
626 """Test deleting an authentication policy with --force, but it fails."""
627 # Create protected authentication policy.
628 result, out, err = self.runcmd("domain", "auth", "policy", "create",
629 "--name=deleteForceFail",
631 self.assertIsNone(result, msg=err)
632 policy = self.get_authentication_policy("deleteForceFail")
633 self.assertIsNotNone(policy)
635 # Try delete with --force.
636 # Patch SDUtils.dacl_delete_aces with a Mock that raises ModelError.
637 with patch.object(SDUtils, "dacl_delete_aces") as delete_mock:
638 delete_mock.side_effect = ModelError("Custom error message")
639 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
640 "--name", "deleteForceFail",
642 self.assertEqual(result, -1)
643 self.assertIn("Custom error message", err)
645 def test_delete__fails(self):
646 """Test deleting an authentication policy, but it fails."""
647 # Create regular authentication policy.
648 result, out, err = self.runcmd("domain", "auth", "policy", "create",
649 "--name=regularPolicy")
650 self.assertIsNone(result, msg=err)
651 policy = self.get_authentication_policy("regularPolicy")
652 self.assertIsNotNone(policy)
654 # Raise ModelError when ldb.delete() is called.
655 with patch.object(SamDB, "delete") as delete_mock:
656 delete_mock.side_effect = ModelError("Custom error message")
657 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
658 "--name", "regularPolicy")
659 self.assertEqual(result, -1)
660 self.assertIn("Custom error message", err)
662 # When not using --force we get a hint.
663 self.assertIn("Try --force", err)
665 def test_delete__protected_fails(self):
666 """Test deleting an authentication policy, but it fails."""
667 # Create protected authentication policy.
668 result, out, err = self.runcmd("domain", "auth", "policy", "create",
669 "--name=protectedPolicy",
671 self.assertIsNone(result, msg=err)
672 policy = self.get_authentication_policy("protectedPolicy")
673 self.assertIsNotNone(policy)
675 # Raise ModelError when ldb.delete() is called.
676 with patch.object(SamDB, "delete") as delete_mock:
677 delete_mock.side_effect = ModelError("Custom error message")
678 result, out, err = self.runcmd("domain", "auth", "policy", "delete",
679 "--name", "protectedPolicy",
681 self.assertEqual(result, -1)
682 self.assertIn("Custom error message", err)
684 # When using --force we don't get the hint.
685 self.assertNotIn("Try --force", err)