1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Martin Kraemer 2019 <mk.maddin@gmail.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 from samba
.tests
.samba_tool
.base
import SambaToolCmdTest
22 class DSaclSetSddlTestCase(SambaToolCmdTest
):
23 """Tests for samba-tool dsacl set --sddl subcommand"""
24 sddl
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;PS)"
25 sddl_lc
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;PS)"
26 sddl_uc
= "(OA;CIIO;RPWP;AAAAAAAA-1111-BBBB-2222-DDDDDDDDDDDD;33333333-EEEE-4444-FFFF-555555555555;PS)"
27 sddl_sid
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;S-1-5-10)"
28 sddl_multi
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;PS)(OA;CIIO;RPWP;cccccccc-9999-ffff-8888-eeeeeeeeeeee;77777777-dddd-6666-bbbb-555555555555;PS)"
32 self
.samdb
= self
.getSamDB("-H", "ldap://%s" % os
.environ
["DC_SERVER"],"-U%s%%%s" % (os
.environ
["DC_USERNAME"], os
.environ
["DC_PASSWORD"]))
33 self
.dn
="OU=DSaclSetSddlTestCase,%s" % self
.samdb
.domain_dn()
34 self
.samdb
.create_ou(self
.dn
)
38 # clean-up the created test ou
39 self
.samdb
.delete(self
.dn
)
42 """Tests if a sddl string can be added 'the normal way'"""
43 (result
, out
, err
) = self
.runsubcmd("dsacl", "set","--objectdn=%s" % self
.dn
, "--sddl=%s" % self
.sddl
)
44 self
.assertCmdSuccess(result
, out
, err
)
45 self
.assertEqual(err
, "", "Shouldn't be any error messages")
46 #extract only the two sddl strings from samba-tool output
47 acl_list
=re
.findall('.*descriptor for.*:\n(.*?)\n',out
)
48 self
.assertNotEqual(acl_list
[0], acl_list
[1], "new and old SDDL string differ")
49 self
.assertMatch(acl_list
[1], self
.sddl
, "new SDDL string should be contained within second sddl output")
51 def test_sddl_set_get(self
):
52 """Tests if a sddl string can be added 'the normal way' and the output of 'get' is the same"""
53 (result
, out
, err
) = self
.runsubcmd("dsacl", "get",
54 "--objectdn=%s" % self
.dn
)
55 self
.assertCmdSuccess(result
, out
, err
)
56 self
.assertEqual(err
, "", "Shouldn't be any error messages")
57 #extract only the two sddl strings from samba-tool output
58 acl_list_get
=re
.findall('^descriptor for.*:\n(.*?)\n', out
)
60 (result
, out
, err
) = self
.runsubcmd("dsacl", "set",
61 "--objectdn=%s" % self
.dn
,
62 "--sddl=%s" % self
.sddl
)
63 self
.assertCmdSuccess(result
, out
, err
)
64 self
.assertEqual(err
, "", "Shouldn't be any error messages")
65 #extract only the two sddl strings from samba-tool output
66 acl_list_old
=re
.findall('old descriptor for.*:\n(.*?)\n', out
)
67 self
.assertEqual(acl_list_old
, acl_list_get
,
68 "output of dsacl get should be the same as before set")
70 acl_list
=re
.findall('new descriptor for.*:\n(.*?)\n', out
)
72 (result
, out
, err
) = self
.runsubcmd("dsacl", "get",
73 "--objectdn=%s" % self
.dn
)
74 self
.assertCmdSuccess(result
, out
, err
)
75 self
.assertEqual(err
, "", "Shouldn't be any error messages")
76 #extract only the two sddl strings from samba-tool output
77 acl_list_get2
=re
.findall('^descriptor for.*:\n(.*?)\n', out
)
78 self
.assertEqual(acl_list
, acl_list_get2
,
79 "output of dsacl get should be the same as after set")
81 def test_multisddl(self
):
82 """Tests if we can add multiple, different sddl strings at the same time"""
83 (result
, out
, err
) = self
.runsubcmd("dsacl", "set","--objectdn=%s" % self
.dn
, "--sddl=%s" % self
.sddl_multi
)
84 self
.assertCmdSuccess(result
, out
, err
)
85 self
.assertEqual(err
, "", "Shouldn't be any error messages")
86 #extract only the two sddl strings from samba-tool output
87 acl_list
=re
.findall('.*descriptor for.*:\n(.*?)\n',out
)
88 for ace
in re
.findall(r
'\(.*?\)',self
.sddl_multi
):
89 self
.assertMatch(acl_list
[1], ace
, "new SDDL string should be contained within second sddl output")
91 def test_duplicatesddl(self
):
92 """Tests if an already existing sddl string can be added causing duplicate entry"""
93 acl_list
= self
._double
_sddl
_check
(self
.sddl
,self
.sddl
)
94 self
.assertEqual(acl_list
[0],acl_list
[1])
96 def test_casesensitivesddl(self
):
97 """Tests if an already existing sddl string can be added in different cases causing duplicate entry"""
98 acl_list
= self
._double
_sddl
_check
(self
.sddl_lc
,self
.sddl_uc
)
99 self
.assertEqual(acl_list
[0],acl_list
[1])
101 def test_sidsddl(self
):
102 """Tests if an already existing sddl string can be added with SID instead of SDDL SIDString causing duplicate entry"""
103 acl_list
= self
._double
_sddl
_check
(self
.sddl
,self
.sddl_sid
)
104 self
.assertEqual(acl_list
[0],acl_list
[1])
106 def test_twosddl(self
):
107 """Tests if an already existing sddl string can be added by using it twice/in combination with non existing sddl string causing duplicate entry"""
108 acl_list
= self
._double
_sddl
_check
(self
.sddl
,self
.sddl
+ self
.sddl
)
109 self
.assertEqual(acl_list
[0],acl_list
[1])
111 def _double_sddl_check(self
,sddl1
,sddl2
):
112 """Adds two sddl strings and checks if there was an ace change after the second adding"""
113 (result
, out
, err
) = self
.runsubcmd("dsacl", "set","--objectdn=%s" % self
.dn
, "--sddl=%s" % sddl1
)
114 self
.assertCmdSuccess(result
, out
, err
)
115 self
.assertEqual(err
, "", "Shouldn't be any error messages")
116 acl_list
= re
.findall('.*descriptor for.*:\n(.*?)\n',out
)
117 self
.assertMatch(acl_list
[1], sddl1
, "new SDDL string should be contained within second sddl output - is not")
119 (result
, out
, err
) = self
.runsubcmd("dsacl", "set","--objectdn=%s" % self
.dn
, "--sddl=%s" % sddl2
)
120 self
.assertCmdSuccess(result
, out
, err
)
121 self
.assertEqual(err
, "", "Shouldn't be any error messages")
122 acl_list
= re
.findall('.*descriptor for.*:\n(.*?)\n',out
)
125 def test_add_delete_sddl(self
):
126 """Tests if a sddl string can be added 'the normal way', deleted and
127 final state is the same as initial.
129 (result
, out
, err
) = self
.runsubcmd("dsacl", "get",
130 "--objectdn=%s" % self
.dn
)
131 self
.assertCmdSuccess(result
, out
, err
)
132 self
.assertEqual(err
, "", "Shouldn't be any error messages")
133 # extract only the two sddl strings from samba-tool output
134 acl_list_orig
= re
.findall('^descriptor for.*:\n(.*?)\n', out
)[0]
136 (result
, out
, err
) = self
.runsubcmd("dsacl", "set",
137 "--objectdn=%s" % self
.dn
,
138 "--sddl=%s" % self
.sddl
)
139 self
.assertCmdSuccess(result
, out
, err
)
140 self
.assertEqual(err
, "", "Shouldn't be any error messages")
141 acl_list_added
= re
.findall('new descriptor for.*:\n(.*?)\n', out
)[0]
142 self
.assertNotEqual(acl_list_added
, acl_list_orig
, "After adding the SD should be different.")
143 self
.assertMatch(acl_list_added
, self
.sddl
, "The added ACE should be part of the new SD.")
145 (result
, out
, err
) = self
.runsubcmd("dsacl", "delete",
146 "--objectdn=%s" % self
.dn
,
147 "--sddl=%s" % self
.sddl
)
148 self
.assertCmdSuccess(result
, out
, err
)
149 self
.assertEqual(err
, "", "Shouldn't be any error messages")
150 acl_list_final
= re
.findall('new descriptor for.*:\n(.*?)\n', out
)[0]
151 self
.assertEqual(acl_list_orig
, acl_list_final
,
152 "output of dsacl delete should be the same as before adding")
154 (result
, out
, err
) = self
.runsubcmd("dsacl", "get",
155 "--objectdn=%s" % self
.dn
)
156 self
.assertCmdSuccess(result
, out
, err
)
157 self
.assertEqual(err
, "", "Shouldn't be any error messages")
158 # extract only the two sddl strings from samba-tool output
159 acl_list_final_get
= re
.findall('^descriptor for.*:\n(.*?)\n', out
)[0]
160 self
.assertEqual(acl_list_orig
, acl_list_final_get
,
161 "output of dsacl get should be the same as after adding and deleting again")
163 def test_delete(self
):
164 # add sddl_multi first
165 (result
, out
, err
) = self
.runsubcmd("dsacl", "set",
166 "--objectdn=%s" % self
.dn
,
167 "--sddl=%s" % self
.sddl_multi
)
169 self
.assertCmdSuccess(result
, out
, err
)
170 self
.assertEqual(err
, "", "Shouldn't be any error messages")
172 (result
, out
, err
) = self
.runsubcmd("dsacl", "delete",
173 "--objectdn=%s" % self
.dn
,
174 "--sddl=%s" % self
.sddl
)
175 self
.assertCmdSuccess(result
, out
, err
)
176 self
.assertEqual(err
, "", "Shouldn't be any error messages")
177 acl_list_deleted
= re
.findall('new descriptor for.*:\n(.*?)\n', out
)[0]
179 self
.assertNotRegex(acl_list_deleted
, re
.escape(self
.sddl
))
180 left_sddl
= self
.sddl_multi
.replace(self
.sddl
, "")
181 self
.assertRegex(acl_list_deleted
, re
.escape(left_sddl
))
183 def test_delete_twice(self
):
184 """Tests if deleting twice the same ACEs returns the expected warning."""
185 # add sddl_multi first
186 (result
, out
, err
) = self
.runsubcmd("dsacl", "set",
187 "--objectdn=%s" % self
.dn
,
188 "--sddl=%s" % self
.sddl_multi
)
190 self
.assertCmdSuccess(result
, out
, err
)
191 self
.assertEqual(err
, "", "Shouldn't be any error messages")
194 (result
, out
, err
) = self
.runsubcmd("dsacl", "delete",
195 "--objectdn=%s" % self
.dn
,
196 "--sddl=%s" % self
.sddl
)
197 self
.assertCmdSuccess(result
, out
, err
)
198 self
.assertEqual(err
, "", "Shouldn't be any error messages")
201 (result
, out
, err
) = self
.runsubcmd("dsacl", "delete",
202 "--objectdn=%s" % self
.dn
,
203 "--sddl=%s" % self
.sddl_multi
)
204 self
.assertCmdSuccess(result
, out
, err
)
205 self
.assertEqual(err
, "", "Shouldn't be any error messages")
206 self
.assertRegex(out
, "WARNING", "Should throw a warning about deleting non existent ace.")
207 warn
= re
.findall("WARNING: (.*?)\n", out
)[0]
208 left_sddl
= self
.sddl_multi
.replace(self
.sddl
, "")
209 self
.assertRegex(warn
, re
.escape(self
.sddl
), "Should point out the non existent ace.")
210 self
.assertNotRegex(warn
, re
.escape(left_sddl
),
211 "Should not complain about all aces, since one of them is not deleted twice.")