cc13727b8fb6fc357fde7cac84c85c70f3655af4
[samba.git] / python / samba / tests / blackbox / smbcacls_propagate_inhertance.py
1 # Blackbox tests for smbcacls
2 #
3 # Copyright (C) Noel Power noel.power@suse.com
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 from samba.tests.blackbox.smbcacls import SmbCaclsBlockboxTestBase
19 from samba.tests import BlackboxProcessError
20 import os
21
22 class InheritanceSmbCaclsTests(SmbCaclsBlockboxTestBase):
23
24     def setUp(self):
25         super().setUp()
26
27         # create toplevel testdir structure with desired ACL(s)
28         #
29         #  +-tar_test_dir/    (OI)(CI)(I)(F)
30         #  +-oi_dir/        (OI)(CI)(I)(F)
31         #  | +-file.1            (I)(F)
32         #  | +-nested/      (OI)(CI)(I)(F)
33         #  |   +-file.2          (I)(F)
34         #  |   +-nested_again/     (OI)(CI)(I)(F)
35         #  |     +-file.3          (I)(F)
36
37         self.toplevel = self.create_remote_test_file("tar_test_dir/file-0")
38         self.f1 = self.create_remote_test_file("tar_test_dir/oi_dir/file-1")
39         self.f2 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/file-2")
40         self.f3 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/nested_again/file-3")
41         self.tar_dir = os.path.split(self.toplevel)[0]
42         self.oi_dir = os.path.split(self.f1)[0]
43         self.nested_dir = os.path.split(self.f2)[0]
44         self.nested_again_dir = os.path.split(self.f3)[0]
45
46         dir_acl_str = "ACL:%s:ALLOWED/OI|CI/FULL" % self.user
47         inherited_dir_acl_str = "ACL:%s:ALLOWED/OI|CI|I/FULL" % self.user
48         file_acl_str = "ACL:%s:ALLOWED/I/FULL" % self.user
49
50         self.smb_cacls(["--modify", dir_acl_str, self.tar_dir])
51         self.smb_cacls(["--modify", inherited_dir_acl_str, self.oi_dir])
52         self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_dir])
53         self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_again_dir])
54         self.smb_cacls(["--modify", file_acl_str, self.f1])
55         self.smb_cacls(["--modify", file_acl_str, self.f2])
56         self.smb_cacls(["--modify", file_acl_str, self.f3])
57
58     def tearDown(self):
59         # tmp is the default share which has an existing testdir smbcacls
60         # we need to be prepared to deal with a 'custom' share (which also
61         # would have an existing testdir)
62         if self.share != "tmp":
63             self.dirpath = os.path.join(os.environ["LOCAL_PATH"],self.share)
64             self.dirpath = os.path.join(self.dirpath,self.testdir)
65         super().tearDown()
66
67     def test_simple_oi_add(self):
68         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
69         for the file and additionally use inheritance rules to propagate appropriate
70         changes to children
71
72         This test adds an ACL with (OI)(READ)
73
74         before:
75
76         +-tar_test_dir/    (OI)(CI)(I)(F)
77           +-oi_dir/        (OI)(CI)(I)(F)
78           | +-file.1            (I)(F)
79           | +-nested/      (OI)(CI)(I)(F)
80           |   +-file.2          (I)(F)
81           |   +-nested_again/     (OI)(CI)(I)(F)
82           |     +-file.3          (I)(F)
83
84         after/expected:
85
86         +-tar_test_dir/    (OI)(CI)(I)(F)
87           +-oi_dir/        (OI)(CI)(I)(F), (OI)(READ)
88           | +-file.1            (I)(F), (I)(READ)
89           | +-nested/      (OI)(CI)(I)(F), (OI)(IO)(I)(READ)
90           |   +-file.2          (I)(F), (I)(READ)
91           |   +-nested_again/     (OI)(CI)(I)(F), (OI)(IO)(I)(READ)
92           |     +-file.3          (I)(F), (I)(READ)"""
93
94         dir_add_acl_str = "ACL:%s:ALLOWED/OI/READ" % self.user
95         obj_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
96         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|IO|I/READ" % self.user
97
98         try:
99
100             self.smb_cacls(["--propagate-inheritance", "--add",
101                             dir_add_acl_str, self.oi_dir])
102
103             # check top level container 'oi_dir' has OI/READ
104             dir_ace = self.ace_parse_str(dir_add_acl_str)
105             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
106
107             # file 'oi_dir/file-1' should  have inherited I/READ
108             child_file_ace = self.ace_parse_str(obj_inherited_ace_str)
109             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
110
111             # nested dir  'oi_dir/nested/' should have OI|IO/READ
112             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
113             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
114
115             # nested file 'oi_dir/nested/file-2' should  have inherited I/READ
116             self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
117
118             # nested_again dir  'oi_dir/nested/nested_again' should have OI|IO/READ
119             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
120             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
121             # nested_again file 'oi_dir/nested/nested_again/file-3' should  have inherited I/READ
122             self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
123         except BlackboxProcessError as e:
124             self.fail(str(e))
125
126     def test_simple_oi_delete(self):
127         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
128         for the file and additionally use inheritance rules to propagate appropriate
129         changes to children
130
131         This test adds an ACL with (OI)(READ)
132
133         before:
134
135         +-tar_test_dir/    (OI)(CI)(I)(F)
136           +-oi_dir/        (OI)(CI)(I)(F), (OI)(IO)(READ)
137           | +-file.1            (I)(F), (I)(READ)
138           | +-nested/      (OI)(CI)(I)(F), (OI)(IO)(I)(READ)
139           |   +-file.2          (I)(F), (I)(READ)
140           |   +-nested_again/     (OI)(CI)(I)(F)
141           |     +-file.3          (I)(F)
142
143         after/expected:
144
145         +-tar_test_dir/    (OI)(CI)(I)(F)
146           +-oi_dir/        (OI)(CI)(I)(F)
147           | +-file.1            (I)(F)
148           | +-nested/      (OI)(CI)(I)(F)
149           |   +-file.2          (I)(F)
150           |   +-nested_again/     (OI)(CI)(I)(F)
151           |     +-file.3          (I)(F)"""
152
153         dir_acl_str = "ACL:%s:ALLOWED/OI/READ" % self.user
154         obj_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
155         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|IO|I/READ" % self.user
156         try:
157
158             # add flags on oi_dir
159             self.smb_cacls([ "--add", dir_acl_str, self.oi_dir])
160
161             # add flags on oi_dir/nested
162             self.smb_cacls([ "--add", dir_inherited_ace_str, self.nested_dir])
163
164             # add flags on oi_dir/nested/nested_again
165             self.smb_cacls([ "--add", dir_inherited_ace_str, self.nested_again_dir])
166
167             # add flags on oi_dir/file-1
168             self.smb_cacls(["--add", obj_inherited_ace_str, self.f1])
169
170             # add flags on oi_dir/nested/file-2
171             self.smb_cacls([ "--add", obj_inherited_ace_str, self.f2])
172
173             # add flags on oi_dir/nested/nested_again/file-3
174             self.smb_cacls([ "--add", obj_inherited_ace_str, self.f3])
175
176             self.smb_cacls(["--propagate-inheritance",
177                             "--delete", dir_acl_str, self.oi_dir])
178
179             # check top level container 'oi_dir' no longer has OI/READ
180             dir_ace = self.ace_parse_str(dir_acl_str)
181             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
182
183             # file 'oi_dir/file-1' should  no longer have inherited I/READ
184             child_file_ace = self.ace_parse_str(obj_inherited_ace_str)
185             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
186
187             # nested dir  'oi_dir/nested/' should no longer have OI|IO/READ
188             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
189             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
190
191             # nested file 'oi_dir/nested/file-2' should no longer have inherited I/READ
192             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
193
194             # nested dir  'oi_dir/nested/nested_agin' should no longer have OI|IO/READ
195             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
196             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False)
197
198             # nested file 'oi_dir/nested/nested_again/file-3' should no longer have inherited I/READ
199             self.assertTrue(self.file_ace_check(self.f3, child_file_ace) == False)
200
201         except BlackboxProcessError as e:
202             self.fail(str(e))
203
204     def test_simple_oi_modify(self):
205         """test smbcacls '--propagate-inheritance --modify' which attempts to modify ACL
206         for the file and additionally use inheritance rules to propagate appropriate
207         changes to children
208
209         This test first adds an ACL with (OI)(R), then it modifies that acl to be
210         (OI)(D) - where D == 0x00110000
211
212         before:
213
214         +-tar_test_dir/    (OI)(CI)(I)(F)
215           +-oi_dir/        (OI)(IO)(R)
216           | +-file.1       (I)(R)
217           | +-nested/      (OI)(IO)(I)(R)
218           |   +-file.2     (I)(R)
219           |   +-nested_again/     (OI)(IO)(I)(R)
220           |     +-file.3          (I)(R)
221
222         after/expected:
223
224         +-tar_test_dir/    (OI)(CI)(I)(F)
225           +-oi_dir/        (OI)(IO)(CHANGE)
226           | +-file.1       (I)(CHANGED)
227           | +-nested/      (OI)(IO)(I)(CHANGED)
228           |   +-file.2     (I)(CHANGED)
229           |   +-nested_again/     (OI)(IO)(I)(CHANGE)
230           |     +-file.3          (I)(CHANGE)"""
231
232         explict_access_ace_str = "ACL:%s:ALLOWED/0x0/RWD" % self.user
233         dir_mod_acl_str = "ACL:%s:ALLOWED/OI/CHANGE" % self.user
234         file_mod_inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
235         dir_mod_inherited_ace_str = "ACL:%s:ALLOWED/OI|IO|I/CHANGE" % self.user
236
237         try:
238             # add flags on oi_dir
239
240             # This is somewhat artificial, we need to add a new acl to the directory
241             # so that the following modify operation doesn't fail. Previously
242             # '--modify' was used in place of '--add' but that resulted in failure
243             # to access the directory ( or even modify the acl ).
244             # Note: when running this test against a windows server it seems that
245             # running as Administrator ensures best results
246
247             # add flags on oi_dir/oi_dir
248             self.smb_cacls(["--add", explict_access_ace_str, self.oi_dir])
249
250             # add flags on oi_dir/nested
251             self.smb_cacls(["--add", explict_access_ace_str, self.nested_dir])
252
253             # add flags on oi_dir/nested/nested_again
254             self.smb_cacls(["--add", explict_access_ace_str, self.nested_again_dir])
255
256             # add flags on oi_dir/file-1
257             self.smb_cacls([ "--add", explict_access_ace_str, self.f1])
258
259             # add flags on oi_dir/nested/file-2
260             self.smb_cacls(["--add", explict_access_ace_str, self.f2])
261
262             # add flags on oi_dir/nested/nested_again/file-3
263             self.smb_cacls(["--add", explict_access_ace_str, self.f3])
264
265             self.smb_cacls(["--propagate-inheritance", "--modify",
266                             dir_mod_acl_str, self.oi_dir])
267
268
269             # check top level container 'oi_dir' has OI/CHANGE
270             dir_ace = self.ace_parse_str(dir_mod_acl_str)
271             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
272
273             # file 'oi_dir/file-1' should  have inherited I/CHANGE
274             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
275             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
276
277             # nested dir  'oi_dir/nested/' should have OI|IO/CHANGE
278             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
279             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
280
281             # nested file 'oi_dir/nested/file-2' should  have inherited I/CHANGE
282             self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
283
284             # nested dir  'oi_dir/nested/nested_again' should have OI|IO/CHANGE
285             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
286             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
287
288             # nested file 'oi_dir/nested/nested_agsin/file-3' should  have inherited I/CHANGE
289             self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
290
291         except BlackboxProcessError as e:
292             self.fail(str(e))
293
294     def test_simple_ci_add(self):
295         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
296         for the file and additionally use inheritance rules to propagate appropriate
297         changes to children
298
299         This test adds an ACL with (CI)(READ)
300
301         before:
302
303         +-tar_test_dir/    (OI)(CI)(I)(F)
304           +-oi_dir/        (OI)(CI)(I)(F)
305           | +-file.1            (I)(F)
306           | +-nested/      (OI)(CI)(I)(F)
307           |   +-file.2          (I)(F)
308           |   +-nested_again/     (OI)(CI)(I)(F)
309           |     +-file.3          (I)(F)
310
311         after/expected:
312
313         +-tar_test_dir/    (OI)(CI)(I)(F)
314           +-oi_dir/        (OI)(CI)(I)(F), (CI)(READ)
315           | +-file.1            (I)(F)
316           | +-nested/      (OI)(CI)(I)(F), (CI)((I)(READ)
317           |   +-file.2          (I)(F)
318           |   +-nested_again/     (OI)(CI)(I)(F), (CI)((I)(READ)
319           |     +-file.3          (I)(F)"""
320         try:
321             dir_add_acl_str = "ACL:%s:ALLOWED/CI/READ" % self.user
322             file_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
323             dir_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/READ" % self.user
324
325             self.smb_cacls(["--propagate-inheritance", "--add",
326                            dir_add_acl_str, self.oi_dir])
327
328             # check top level container 'oi_dir' has CI/READ
329             dir_ace = self.ace_parse_str(dir_add_acl_str)
330             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
331
332             # nested file 'oi_dir/file-1' should NOT have inherited I/READ
333             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
334             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
335
336             # nested dir  'oi_dir/nested/' should have CI|I|READ
337             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
338             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
339
340             # nested file 'oi_dir/nested/file-2' should NOT have inherited I/READ
341             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
342             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
343
344             # nested dir  'oi_dir/nested/nested_again' should have CI|I|READ
345             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
346             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
347
348             # nested file 'oi_dir/nested/nested_again/file-3' should NOT have inherited I/READ
349             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
350             self.assertTrue(self.file_ace_check(self.f3, child_file_ace) == False)
351
352         except BlackboxProcessError as e:
353             self.fail(str(e))
354
355     def test_simple_ci_delete(self):
356         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
357         for the file and additionally use inheritance rules to propagate appropriate
358         changes to children
359
360         This test delete an ACL with (CI)(READ)
361
362         before:
363
364         +-tar_test_dir/    (OI)(CI)(I)(F)
365            +-oi_dir/        (OI)(CI)(I)(F), (CI)(READ)
366            | +-file.1            (I)(F)
367            | +-nested/      (OI)(CI)(I)(F), (CI)((I)(READ)
368            |   +-file.2          (I)(F)
369            |   +-nested_again/     (OI)(CI)(I)(F), (CI)((I)(READ)
370            |     +-file.3          (I)(F)
371
372         after/expected:
373
374         +-tar_test_dir/    (OI)(CI)(I)(F)
375            +-oi_dir/        (OI)(CI)(I)(F)
376            | +-file.1            (I)(F)
377            | +-nested/      (OI)(CI)(I)(F)
378            |   +-file.2          (I)(F)
379            |   +-nested_again/     (OI)(CI)(I)(F)
380            |     +-file.3          (I)(F)"""
381
382         dir_acl_str = "ACL:%s:ALLOWED/CI/READ" % self.user
383         file_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
384         dir_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/READ" % self.user
385         try:
386
387             # add flags on oi_dir
388             self.smb_cacls(["--add", dir_acl_str, self.oi_dir])
389
390             # add flags on oi_dir/nested
391             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_dir])
392
393             # add flags on oi_dir/nested/nested_again
394             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_dir])
395
396             # make sure no (I|READ) flags on oi_dir/file-1
397             self.smb_cacls(["--delete", file_inherited_ace_str, self.f1])
398
399             # make sure no (I|READ) flags on oi_dir/nested/file-2
400             self.smb_cacls(["--delete", file_inherited_ace_str, self.f2])
401
402             # make sure no (I|READ) flags on oi_dir/nested/nested_again/file-3
403             self.smb_cacls(["--delete", file_inherited_ace_str, self.f2])
404
405             self.smb_cacls(["--propagate-inheritance",
406                             "--delete",
407                             dir_acl_str, self.oi_dir])
408
409             # check top level container 'oi_dir' no longer has CI/READ
410             dir_ace = self.ace_parse_str(dir_acl_str)
411             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
412
413             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
414             # nested file 'oi_dir/file-1' should NOT have inherited I/READ
415             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
416
417             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
418             # nested dir  'oi_dir/nested/' should no longer have CI|I|READ
419             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
420
421             # nested dir  'oi_dir/nested/nested_again' should no longer have CI|I|READ
422             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False)
423
424         except BlackboxProcessError as e:
425             self.fail(str(e))
426
427     def test_simple_ci_modify(self):
428         """test smbcacls '--propagate-inheritance --modify' which attempts to modify ACL
429         for the file and additionally use inheritance rules to propagate appropriate
430         changes to children
431
432         This test first adds an ACL with (CI)(R), then it modifies that acl to be
433         (CI)(D) - where D == 0x00110000
434
435         before:
436
437         +-tar_test_dir/    (OI)(CI)(I)(F)
438           +-oi_dir/        (CI)(R)
439           | +-file.1            (I)(F)
440           | +-nested/      (CI)(I)(R)
441           |   +-file.2          (I)(F)
442           |   +-nested_again/     (CI)(I)(R)
443           |     +-file.3          (I)(F)
444
445
446         after/expected:
447
448         +-tar_test_dir/    (OI)(CI)(I)(F)
449           +-oi_dir/        (CI)(CHANGE)
450           | +-file.1            (I)(F)
451           | +-nested/      (CI)(I)(CHANGE)
452           |   +-file.2          (I)(F)
453           |   +-nested_again/     (CI)(I)(CHANGE)
454           |     +-file.3          (I)(F)"""
455
456         dir_acl_str = "ACL:%s:ALLOWED/CI/READ" % self.user
457         file_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
458         dir_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/READ" % self.user
459         dir_mod_acl_str = "ACL:%s:ALLOWED/CI/CHANGE" % self.user
460         file_mod_inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
461         dir_mod_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/CHANGE" % self.user
462         delete_ace_str = "ACL:%s:ALLOWED/0x0/RWD" % self.user
463
464         try:
465             # This is somewhat artificial, we need to add a new acl to the
466             # directory so that the following modify operation doesn't fail.
467             # Previously '--modify' was used in place of '--add' but that
468             # resulted in failure to access the directory ( or even modify
469             # the acl ).
470             # Note: when running this test against a windows server it seems
471             # that running as Administrator ensures best results
472             self.smb_cacls(["--add", dir_acl_str, self.oi_dir])
473
474             # add flags on oi_dir/nested
475             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_dir])
476
477             # add flags on oi_dir/nested/nested_again
478             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_again_dir])
479
480             self.smb_cacls(["--propagate-inheritance", "--modify",
481                             dir_mod_acl_str, self.oi_dir])
482
483             # check top level container 'oi_dir' has CI/CHANGE
484             dir_ace = self.ace_parse_str(dir_mod_acl_str)
485             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
486
487             # nested file 'oi_dir/file-1' should NOT have inherited I/CHANGE
488             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
489             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
490
491             # nested dir  'oi_dir/nested/' should have OI|I/CHANGE
492             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
493             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
494
495             # nested file 'oi_dir/nested/file-2' should NOT have inherited I/CHANGE
496             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
497             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
498
499             # nested dir  'oi_dir/nested/nested_again' should have OI|I/CHANGE
500             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
501             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
502
503             # nested file 'oi_dir/nested/nested_again/file-3' should NOT have inherited I/CHANGE
504             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
505             self.assertTrue(self.file_ace_check(self.f3, child_file_ace) == False)
506
507             # set some flags to allow us to delete the files
508             self.smb_cacls(["--set", delete_ace_str, self.f1])
509             self.smb_cacls(["--set", delete_ace_str, self.f2])
510             self.smb_cacls(["--set", delete_ace_str, self.f3])
511
512         except BlackboxProcessError as e:
513             self.fail(str(e))
514
515     def test_simple_cioi_add(self):
516         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
517         for the file and additionally use inheritance rules to propagate appropriate
518         changes to children
519
520         This test adds an ACL with (CI)(OI)(READ)
521
522         before:
523
524         +-tar_test_dir/    (OI)(CI)(I)(F)
525           +-oi_dir/        (OI)(CI)(I)(F)
526           | +-file.1            (I)(F)
527           | +-nested/      (OI)(CI)(I)(F)
528           |   +-file.2          (I)(F)
529           |   +-nested_again/     (OI)(CI)(I)(F)
530           |     +-file.3          (I)(F)
531
532         after/expected:
533
534         +-tar_test_dir/    (OI)(CI)(I)(F)
535           +-oi_dir/        (OI)(CI)(I)(F), (CI)(OI)READ)
536           | +-file.1            (I)(F), (I)(READ)
537           | +-nested/      (OI)(CI)(I)(F), (CI)(OI)(I)(READ)
538           |   +-file.2          (I)(F), (I)(READ)
539           |   +-nested_again/     (OI)(CI)(I)(F), (CI)(OI)(I)(READ)
540           |     +-file.3          (I)(F), (I)(READ)"""
541
542         dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI/READ" % self.user
543         file_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
544         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/READ" % self.user
545
546         try:
547
548             self.smb_cacls(["--propagate-inheritance", "--add",
549                            dir_add_acl_str, self.oi_dir])
550
551             # check top level container 'oi_dir' has OI|CI/READ
552             dir_ace = self.ace_parse_str(dir_add_acl_str)
553             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
554
555             # nested file 'oi_dir/file-1' should have inherited I/READ
556             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
557             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
558
559             # nested dir  'oi_dir/nested/' should have OI|CI|I|READ
560             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
561             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
562
563             # nested file 'oi_dir/nested/file-2' should have inherited I/READ
564             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
565             self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
566
567             # nested dir  'oi_dir/nested/nested_again' should have OI|CI|I|READ
568             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
569             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
570
571             # nested file 'oi_dir/nested/nested_again/file-3' should have inherited I/READ
572             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
573             self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
574
575         except BlackboxProcessError as e:
576             self.fail(str(e))
577
578     def test_simple_cioi_delete(self):
579         """test smbcacls '--propagate-inheritance --delete' which attempts to delete the
580         ACL for the file and additionally use inheritance rules to propagate
581         appropriate changes to children
582
583         This test deletes an ACL with (CI)(OI)(READ)
584
585         before:
586
587         +-tar_test_dir/    (OI)(CI)(I)(F)
588           +-oi_dir/        (OI)(CI)(I)(F), (CI)(OI)(READ)
589           | +-file.1            (I)(F), (I)(READ)
590           | +-nested/      (OI)(CI)(I)(F), (CI)(OI)(I)(READ)
591           |   +-file.2          (I)(F), (I)(READ)
592           |   +-nested_again/     (OI)(CI)(I)(F), (CI)(OI)(I)(READ)
593           |     +-file.3          (I)(F), (I)(READ)
594
595         after/expected:
596
597         +-tar_test_dir/    (OI)(CI)(I)(F)
598           +-oi_dir/        (OI)(CI)(I)(F)
599           | +-file.1            (I)(F)
600           | +-nested/      (OI)(CI)(I)(F)
601           |   +-file.2          (I)(F)
602           |   +-nested_again/     (OI)(CI)(I)(F)
603           |     +-file.3          (I)(F)"""
604
605
606         dir_acl_str = "ACL:%s:ALLOWED/OI|CI/READ" % self.user
607         file_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
608         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/READ" % self.user
609
610         try:
611
612             # add flags on oi_dir
613             self.smb_cacls(["--add", dir_acl_str, self.oi_dir])
614
615             # add flags on oi_dir/nested
616             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_dir])
617
618             # add flags on oi_dir/file-1
619             self.smb_cacls(["--add", file_inherited_ace_str, self.f1])
620
621             # add flags on oi_dir/nested/file-2
622             self.smb_cacls(["--add", file_inherited_ace_str, self.f2])
623
624             # add flags on oi_dir/nested/nested_again/file-3
625             self.smb_cacls(["--add", file_inherited_ace_str, self.f2])
626
627             self.smb_cacls(["--propagate-inheritance", "--delete",
628                                 dir_acl_str, self.oi_dir])
629
630             # check top level container 'oi_dir' no longer has OI|CI/READ
631             dir_ace = self.ace_parse_str(dir_acl_str)
632             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
633
634             # nested file 'oi_dir/file-1' should NOT have inherited I/READ
635             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
636             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
637
638             # nested dir  'oi_dir/nested/' should no longer have OI|CI|I|READ
639             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
640             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
641             # nested file 'oi_dir/nested/file-2' should NOT have inherited I/READ
642             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
643             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
644             # nested dir  'oi_dir/nested/nested_again' should no longer have OI|CI|I|READ
645             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
646             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False)
647             # nested file 'oi_dir/nested/nested_againfile-2' should NOT have inherited I/READ
648             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
649             self.assertTrue(self.file_ace_check(self.f3, child_file_ace) == False)
650         except BlackboxProcessError as e:
651             self.fail(str(e))
652
653     def test_simple_cioi_modify(self):
654         """test smbcacls '--propagate-inheritance --modify' which attempts to modify the
655         ACLfor the file and additionally use inheritance rules to propagate
656         appropriate changes to children
657
658         This test first adds an ACL with (CI)(OI)(R), then it modifies that acl to be
659         (CI)(OI)(D) - where D == 0x00110000
660
661         before:
662
663         +-tar_test_dir/    (OI)(CI)(I)(F)
664           +-oi_dir/        (CI)(OI)(R)
665           | +-file.1       (I)(R)
666           | +-nested/      (CI)(OI)(I)(R)
667           |   +-file.2     (I)(R)
668           |   +-nested_again/     (CI)(OI)(I)(R)
669           |     +-file.3          (I)(R)
670
671         after/expected:
672
673         +-tar_test_dir/    (OI)(CI)(I)(F)
674           +-oi_dir/        (CI)(OI)(CHANGE)
675           | +-file.1       (I)(CHANGE)
676           | +-nested/      (CI)(OI)(I)(CHANGE)
677           |   +-file.2     (I)(CHANGE)
678           |   +-nested_again/     (CI)(OI)(I)(CHANGE)
679           |     +-file.3          (I)(CHANGE)"""
680
681         dir_acl_str = "ACL:%s:ALLOWED/OI|CI/R" % self.user
682         file_inherited_ace_str = "ACL:%s:ALLOWED/I/R" % self.user
683         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/R" % self.user
684
685         dir_mod_acl_str = "ACL:%s:ALLOWED/OI|CI/CHANGE" % self.user
686         file_mod_inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
687         dir_mod_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/CHANGE" % self.user
688         try:
689             # add flags on oi_dir
690
691             # This is somewhat artificial, we need to add a new acl to the
692             # directory so that the following modify operation doesn't fail.
693             # Previously '--modify' was used in place of '--add' but that
694             # resulted in failure to access the directory ( or even modify
695             # the acl ). Note: when running this test against a windows server
696             # it seems that running as Administrator ensures best results
697
698             self.smb_cacls(["--add", dir_acl_str, self.oi_dir])
699
700             # add flags on oi_dir/nested
701             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_dir])
702
703             # add flags on oi_dir/nested/nested_again
704             self.smb_cacls(["--add", dir_inherited_ace_str, self.nested_again_dir])
705
706             # add flags on oi_dir/file-1
707             self.smb_cacls(["--add", file_inherited_ace_str, self.f1])
708
709             # add flags on oi_dir/nested/file-2
710             self.smb_cacls(["--add", file_inherited_ace_str, self.f2])
711
712             # add flags on oi_dir/nested/nested_again/file-2
713             self.smb_cacls(["--add", file_inherited_ace_str, self.f3])
714
715             self.smb_cacls(["--propagate-inheritance", "--modify",
716                             dir_mod_acl_str, self.oi_dir])
717
718             # check top level container 'oi_dir' has OI|CI/CHANGE
719             dir_ace = self.ace_parse_str(dir_mod_acl_str)
720             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
721
722             # nested file 'oi_dir/file-1' should have inherited I|CHANGE
723             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
724             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
725
726             # nested dir  'oi_dir/nested/' should have OI|CI|I|CHANGE
727             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
728             self.file_ace_check(self.nested_dir, child_dir_ace)
729
730             # nested file 'oi_dir/nested/file-2' should have inherited I|CHANGE
731             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
732             self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
733
734             # nested dir  'oi_dir/nested/nested_again' should have OI|CI|I|CHANGE
735             child_dir_ace = self.ace_parse_str(dir_mod_inherited_ace_str)
736             self.file_ace_check(self.nested_again_dir, child_dir_ace)
737
738             # nested file 'oi_dir/nested/nested_again/file-3' should have inherited I|CHANGE
739             child_file_ace = self.ace_parse_str(file_mod_inherited_ace_str)
740             self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
741
742         except BlackboxProcessError as e:
743             self.fail(str(e))
744
745     def test_simple_set_fail(self):
746         """test smbcacls '--propagate-inheritance --set' which attempts to set the ACL
747         for the file and additionally use inheritance rules to propagate appropriate
748         changes to children
749
750         This test adds an ACL with (CI)(OI)(READ)
751
752         before:
753
754         +-tar_test_dir/    (OI)(CI)(I)(F)
755           +-oi_dir/        (OI)(CI)(I)(F)
756           | +-file.1            (I)(F)
757           | +-nested/      (OI)(CI)(I)(F)
758           |   +-file.2          (I)(F)
759           |   +-nested_again/     (OI)(CI)(I)(F)
760           |     +-file.3          (I)(F)
761
762         after/expected:
763         fail, oid_dir has inheritance enabled, set should fail and exit with '1'"""
764         dir_acl_str = "ACL:%s:ALLOWED/OI|CI/R" % self.user
765         file_inherited_ace_str = "ACL:%s:ALLOWED/I/R" % self.user
766         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/R" % self.user
767
768         try:
769             f1 = self.create_remote_test_file("oi_dir/file-1")
770             f2 = self.create_remote_test_file("oi_dir/nested/file-2")
771             oi_dir = os.path.split(f1)[0]
772             nested_dir = os.path.split(f2)[0]
773
774             try:
775                 self.smb_cacls(["--propagate-inheritance", "--set",
776                                dir_acl_str, oi_dir])
777                 self.fail("%s succeeded unexpectedly while processing container with inheritance enabled")
778             except BlackboxProcessError as e:
779                 pass
780
781         except BlackboxProcessError as e:
782             self.fail(str(e))
783
784     def test_simple_oici_set(self):
785         """test smbcacls '--propagate-inheritance --set' which attempts to set the ACL
786         for the file and additionally use inheritance rules to propagate appropriate
787         changes to children
788
789         This test adds an ACL with (CI)(OI)(RWD) additionally it removes
790         inheritance from oi_dir
791
792         before:
793
794         +-tar_test_dir/    (OI)(CI)(I)(F)
795           +-oi_dir/        (OI)(CI)(I)(F)
796           | +-file.1            (I)(F)
797           | +-nested/      (OI)(CI)(I)(F)
798           |   +-file.2          (I)(F)
799           |   +-nested_again/     (OI)(CI)(I)(F)
800           |     +-file.3          (I)(F)
801
802         after/expected:
803
804         +-tar_test_dir/    (OI)(CI)(I)(F)
805           +-oi_dir/        (OI)(CI)(RWD)
806           | +-file.1            (I)(RWD)
807           | +-nested/      (OI)(CI)(I)(RWD)
808           |   +-file.2          (I)(RWD)
809           |   +-nested_again/     (OI)(CI)(I)(RWD)
810           |     +-file.3          (I)(RWD)"""
811
812         dir_acl_str = "ACL:%s:ALLOWED/OI|CI/RWD" % self.user
813         file_inherited_ace_str = "ACL:%s:ALLOWED/I/RWD" % self.user
814         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/RWD" % self.user
815
816         try:
817             # smb_cacls --inherit=copy
818             self.smb_cacls(["--inherit=copy", self.oi_dir])
819
820             self.smb_cacls(["--propagate-inheritance", "--set",
821                             dir_acl_str, self.oi_dir])
822
823             # check top level container 'oi_dir' has OI|CI/RWD
824             dir_ace = self.ace_parse_str(dir_acl_str)
825             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
826
827             # check nested file oi_dir/file-1 has I/RWD
828             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
829             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
830
831             # check nested dir oi_dir/nested has OI|CI|I/RWD
832             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
833             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
834
835             # check nested file oi_dir/nested/file-2 has I/RWD
836             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
837             self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
838
839             # check nested dir oi_dir/nested/nested_again has OI|CI|I/RWD
840             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
841             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
842
843             # check nested file oi_dir/nested/nested_again/file-3 has I/RWD
844             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
845             self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
846
847         except BlackboxProcessError as e:
848             self.fail(str(e))
849
850     def test_simple_ci_set(self):
851         """test smbcacls '--propagate-inheritance --set' which attempts to set the ACL
852         for the file and additionally use inheritance rules to propagate appropriate
853         changes to children
854
855         This test adds an ACL with (CI)(RWD) additionally it removes
856         inheritance from oi_dir
857
858         before:
859
860         +-tar_test_dir/    (OI)(CI)(I)(F)
861           +-oi_dir/        (OI)(CI)(I)(F)
862           | +-file.1            (I)(F)
863           | +-nested/      (OI)(CI)(I)(F)
864           |   +-file.2          (I)(F)
865           |   +-nested_again/     (OI)(CI)(I)(F)
866           |     +-file.3          (I)(F)
867
868         after/expected:
869
870         +-tar_test_dir/    (OI)(CI)(I)(RWD)
871           +-oi_dir/        (CI)(RWD)
872           | +-file.1
873           | +-nested/      (CI)(I)(RWD)
874           |   +-file.2
875           |   +-nested_again/     (CI)(I)(RWD)
876           |     +-file.3          """
877         dir_acl_str = "ACL:%s:ALLOWED/CI/RWD" % self.user
878         file_inherited_ace_str = "ACL:%s:ALLOWED/I/RWD" % self.user
879         dir_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/RWD" % self.user
880         delete_ace_str = "ACL:%s:ALLOWED/0x0/RWD" % self.user
881
882         try:
883             # smb_cacls --inherit=copy
884             self.smb_cacls(["--inherit=copy", self.oi_dir])
885
886             self.smb_cacls(["--propagate-inheritance", "--set",
887                             dir_acl_str, self.oi_dir])
888
889             out = self.smb_cacls([self.oi_dir])
890             #count the ACL(s)
891             nacls = len([i for i in out.decode().split("\n") if i.startswith("ACL")])
892
893             # Although there maybe a couple of users with associated acl(s)
894             # before set, after set there should only be 1 acl
895
896             self.assertEqual(nacls, 1)
897
898             # check top level container 'oi_dir' has OI|CI/RWD
899             dir_ace = self.ace_parse_str(dir_acl_str)
900             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
901
902             # note can't check file because it has no ACL ( due to CI )
903             # check nested dir 'oi_dir/nested' has CI|I/RWD
904             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
905             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
906
907             # check nested dir 'oi_dir/nested/nested_again' has CI|I/RWD
908             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
909             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
910             self.smb_cacls(["--set", delete_ace_str, self.f1])
911             self.smb_cacls(["--set", delete_ace_str, self.f2])
912             self.smb_cacls(["--set", delete_ace_str, self.f3])
913         except BlackboxProcessError as e:
914             self.fail(str(e))
915
916     def test_simple_cioinp_add(self):
917         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
918         for the file and additionally use inheritance rules to propagate appropriate
919         changes to children
920
921         This test adds an ACL with (CI)(OI)(NP)(CHANGE)
922         (NP) - no propagation should not propagate the changes any further containers
923
924         before:
925
926         +-tar_test_dir/    (OI)(CI)(I)(F)
927           +-oi_dir/        (OI)(CI)(I)(F)
928           | +-file.1            (I)(F)
929           | +-nested/      (OI)(CI)(I)(F)
930           |   +-file.2          (I)(F)
931           |   +-nested_again/     (OI)(CI)(I)(F)
932           |     +-file.3          (I)(F)
933
934         after/expected:
935
936         +-tar_test_dir/    (OI)(CI)(I)(F)
937           +-oi_dir/        (OI)(CI)(I)(F), (CI)(OI)(NP)(CHANGE)
938           | +-file.1            (I)(F), (I)(CHANGE)
939           | +-nested/      (OI)(CI)(I)(F), (I)(M)
940           |   +-file.2          (I)(F)
941           |   +-nested_again/     (OI)(CI)(I)(F)
942           |     +-file.3          (I)(F)"""
943
944         dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI|NP/CHANGE" % self.user
945         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
946         try:
947             self.smb_cacls(["--propagate-inheritance", "--add",
948                             dir_add_acl_str, self.oi_dir])
949
950             # check top level container 'oi_dir' has OI|CI|NP/READ
951             dir_ace = self.ace_parse_str(dir_add_acl_str)
952             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
953
954             child_file_ace = self.ace_parse_str(inherited_ace_str)
955             # nested file 'oi_dir/file-1' should have inherited I/CHANGE
956             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
957
958             # nested dir  'oi_dir/nested' should have inherited I/CHANGE
959             child_dir_ace = self.ace_parse_str(inherited_ace_str)
960             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
961             # nested file  'oi_dir/nested/file-2' should NOT have I/CHANGE
962             child_dir_ace = self.ace_parse_str(inherited_ace_str)
963             self.assertTrue(self.file_ace_check(self.f2, child_dir_ace) == False)
964             # nested dir  'oi_dir/nested/nested_again/' should NOT have I/CHANGE
965             child_dir_ace = self.ace_parse_str(inherited_ace_str)
966             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False)
967             # nested file  'oi_dir/nested/nested_again/file-3' should NOT have I/CHANGE
968             child_dir_ace = self.ace_parse_str(inherited_ace_str)
969             self.assertTrue(self.file_ace_check(self.f3, child_dir_ace) == False)
970
971         except BlackboxProcessError as e:
972             self.fail(str(e))
973
974     def test_simple_oinp_add(self):
975         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
976         for the file and additionally use inheritance rules to propagate appropriate
977         changes to children
978
979         This test adds an ACL with (OI)(NP)(CHANGE)
980         (NP) - no propagation should not propagate the changes any further containers
981
982         before:
983
984         +-tar_test_dir/    (OI)(CI)(I)(F)
985           +-oi_dir/        (OI)(CI)(I)(F)
986           | +-file.1            (I)(F)
987           | +-nested/      (OI)(CI)(I)(F)
988           |   +-file.2          (I)(F)
989           |   +-nested_again/     (OI)(CI)(I)(F)
990           |     +-file.3          (I)(F)
991
992         after/expected:
993
994         +-tar_test_dir/    (OI)(CI)(I)(F)
995           +-oi_dir/        (OI)(CI)(I)(F), (OI)(NP)(CHANGE)
996           | +-file.1            (I)(F), (I)(CHANGE)
997           | +-nested/      (OI)(CI)(I)(F)
998           |   +-file.2          (I)(F)
999           |   +-nested_again/     (OI)(CI)(I)(F)
1000           |     +-file.3          (I)(F)"""
1001
1002         dir_add_acl_str = "ACL:%s:ALLOWED/OI|NP/CHANGE" % self.user
1003         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1004         try:
1005             self.smb_cacls(["--propagate-inheritance",
1006                             "--add",
1007                             dir_add_acl_str, self.oi_dir])
1008
1009             # check top level container 'oi_dir' has OI|NP/CHANGE
1010             dir_ace = self.ace_parse_str(dir_add_acl_str)
1011             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
1012
1013             child_file_ace = self.ace_parse_str(inherited_ace_str)
1014             # nested file 'oi_dir/file-1' should have inherited I/CHANGE
1015             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
1016
1017             # nested dir  'oi_dir/nested' should NOT have I/CHANGE
1018             child_dir_ace = self.ace_parse_str(inherited_ace_str)
1019             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
1020
1021             child_file_ace = self.ace_parse_str(inherited_ace_str)
1022             # nested file 'oi_dir/nested/file-1' should NOT have inherited I/CHANGE
1023             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
1024
1025         except BlackboxProcessError as e:
1026             self.fail(str(e))
1027
1028     def test_simple_cinp_add(self):
1029         """# test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
1030         for the file and additionally use inheritance rules to propagate appropriate
1031         changes to children
1032
1033         This test adds an ACL with (CI)(NP)(CHANGE)
1034         (NP) - no propagation should not propagate the changes any further containers
1035
1036         before:
1037
1038         +-tar_test_dir/    (OI)(CI)(I)(F)
1039           +-oi_dir/        (OI)(CI)(I)(F)
1040           | +-file.1            (I)(F)
1041           | +-nested/      (OI)(CI)(I)(F)
1042           |   +-file.2          (I)(F)
1043           |   +-nested_again/     (OI)(CI)(I)(F)
1044           |     +-file.3          (I)(F)
1045
1046         after/expected:
1047
1048         +-tar_test_dir/    (OI)(CI)(I)(F)
1049           +-oi_dir/        (OI)(CI)(I)(F), (CI)(NP)(CHANGE)
1050           | +-file.1            (I)(F)
1051           | +-nested/      (OI)(CI)(I)(F), (I)(CHANGE)
1052           |   +-file.2          (I)(F)
1053           |   +-nested_again/     (OI)(CI)(I)(F)
1054           |     +-file.3          (I)(F)"""
1055
1056         dir_add_acl_str = "ACL:%s:ALLOWED/CI|NP/CHANGE" % self.user
1057         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1058         try:
1059             self.smb_cacls(["--propagate-inheritance", "--add",
1060                             dir_add_acl_str, self.oi_dir])
1061
1062             # check top level container 'oi_dir' has CI|NP/READ
1063             dir_ace = self.ace_parse_str(dir_add_acl_str)
1064             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
1065
1066             # nested file 'oi_dir/file-1' should NOT have inherited I/CHANGE
1067             child_file_ace = self.ace_parse_str(inherited_ace_str)
1068             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
1069
1070             # nested dir  'oi_dir/nested' should have I/CHANGE
1071             child_dir_ace = self.ace_parse_str(inherited_ace_str)
1072             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
1073
1074             # nested file 'oi_dir/nested/file-2' should NOT have inherited I/CHANGE
1075             child_file_ace = self.ace_parse_str(inherited_ace_str)
1076             self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False)
1077
1078             # nested dir  'oi_dir/nested/nested_again' should have NOT I/CHANGE
1079             child_dir_ace = self.ace_parse_str(inherited_ace_str)
1080             self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False)
1081             # nested file 'oi_dir/nested/nested_again/file-3' should NOT have inherited I/CHANGE
1082             child_file_ace = self.ace_parse_str(inherited_ace_str)
1083             self.assertTrue(self.file_ace_check(self.f3, child_file_ace) == False)
1084
1085         except BlackboxProcessError as e:
1086             self.fail(str(e))
1087
1088     def test_simple_cioinp_delete(self):
1089         """test smbcacls '--propagate-inheritance --delete' which attempts to delete
1090         the ACL for the file and additionally use inheritance rules to propagate
1091         appropriate changes to children
1092
1093         This test adds an ACL with (CI)(OI)(NP)(CHANGE)
1094         (NP) - no propagation should not propagate the changes any further containers
1095
1096         before:
1097
1098         +-tar_test_dir/    (OI)(CI)(I)(F)
1099           +-oi_dir/        (OI)(CI)(I)(F), (CI)(OI)(NP)(CHANGE)
1100           | +-file.1            (I)(F), (I)(CHANGE)
1101           | +-nested/      (OI)(CI)(I)(F), (I)(CHANGE)
1102           |   +-file.2          (I)(F)
1103
1104         after/expected:
1105
1106         +-tar_test_dir/    (OI)(CI)(I)(F)
1107           +-oi_dir/        (OI)(CI)(I)(F)
1108           | +-file.1            (I)(F)
1109           | +-nested/      (OI)(CI)(I)(F)
1110           |   +-file.2          (I)(F)"""
1111
1112         dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI|NP/CHANGE" % self.user
1113         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1114
1115         try:
1116             self.smb_cacls(["--add", dir_add_acl_str, self.oi_dir])
1117
1118             self.smb_cacls(["--add", inherited_ace_str, self.f1])
1119
1120             self.smb_cacls(["--add", inherited_ace_str, self.nested_dir])
1121
1122             self.smb_cacls(["--propagate-inheritance", "--delete",
1123                             dir_add_acl_str, self.oi_dir])
1124
1125             # check top level container 'oi_dir' does NOT have OI|CI|NP/READ
1126             dir_ace = self.ace_parse_str(dir_add_acl_str)
1127             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
1128
1129             # nested file 'oi_dir/file-1' should NOT have inherited I/CHANGE
1130             child_file_ace = self.ace_parse_str(inherited_ace_str)
1131             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
1132
1133             # nested dir 'oi_dir/nested' should NOT have inherited I/CHANGE
1134             child_dir_ace = self.ace_parse_str(inherited_ace_str)
1135             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
1136         except BlackboxProcessError as e:
1137             self.fail(str(e))
1138
1139     def test_simple_oinp_delete(self):
1140         """test smbcacls '--propagate-inheritance --delete' which attempts to delete the
1141         ACL for the file and additionally use inheritance rules to propagate
1142         appropriate changes to children
1143
1144         This test adds an ACL with (OI)(NP)(CHANGE)
1145         (NP) - no propagation should not propagate the changes any further containers
1146
1147         before:
1148
1149         +-tar_test_dir/    (OI)(CI)(I)(F)
1150         +-oi_dir/        (OI)(CI)(I)(F), (OI)(NP)(CHANGE)
1151         | +-file.1            (I)(F), (I)(CHANGE)
1152         | +-nested/      (OI)(CI)(I)(F)
1153         |   +-file.2          (I)(F)
1154
1155         after/expected:
1156
1157         +-tar_test_dir/    (OI)(CI)(I)(F)
1158           +-oi_dir/        (OI)(CI)(I)(F)
1159           | +-file.1            (I)(F)
1160           | +-nested/      (OI)(CI)(I)(F)
1161           |   +-file.2          (I)(F)"""
1162
1163         dir_add_acl_str = "ACL:%s:ALLOWED/OI|NP/CHANGE" % self.user
1164         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1165         try:
1166
1167             # set up 'before' permissions
1168             self.smb_cacls(["--add", dir_add_acl_str, self.oi_dir])
1169
1170             self.smb_cacls(["--add", inherited_ace_str, self.f1])
1171
1172             self.smb_cacls(["--propagate-inheritance", "--delete",
1173                             dir_add_acl_str, self.oi_dir])
1174
1175             # check top level container 'oi_dir' does NOT have OI|NP/READ
1176             dir_ace = self.ace_parse_str(dir_add_acl_str)
1177             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
1178
1179             child_file_ace = self.ace_parse_str(inherited_ace_str)
1180             # nested file 'oi_dir/file-1' should NOT have inherited I/CHANGE
1181             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
1182
1183         except BlackboxProcessError as e:
1184             self.fail(str(e))
1185
1186     def test_simple_cinp_delete(self):
1187         """test smbcacls '--propagate-inheritance --delete' which attempts to delete the
1188         ACL for the file and additionally use inheritance rules to propagate
1189         appropriate changes to children
1190
1191         This test adds an ACL with (CI)(NP)(CHANGE)
1192         (NP) - no propagation should not propagate the changes any further containers
1193
1194         before:
1195
1196         +-tar_test_dir/    (OI)(CI)(I)(F)
1197           +-oi_dir/        (OI)(CI)(I)(F), (CI)(NP)(CHANGE)
1198           | +-file.1            (I)(F)
1199           | +-nested/      (OI)(CI)(I)(F), (I)(CHANGE)
1200           |   +-file.2          (I)(F)
1201
1202         after/expected:
1203
1204         +-tar_test_dir/    (OI)(CI)(I)(F)
1205           +-oi_dir/        (OI)(CI)(I)(F)
1206           | +-file.1            (I)(F)
1207           | +-nested/      (OI)(CI)(I)(F)
1208           |   +-file.2          (I)(F)"""
1209
1210         dir_add_acl_str = "ACL:%s:ALLOWED/CI|NP/CHANGE" % self.user
1211         inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1212
1213         try:
1214             self.smb_cacls(["--add", dir_add_acl_str, self.oi_dir])
1215
1216             self.smb_cacls(["--add", inherited_ace_str, self.nested_dir])
1217
1218             self.smb_cacls(["--propagate-inheritance", "--delete",
1219                             dir_add_acl_str, self.oi_dir])
1220
1221             # check top level container 'oi_dir' doesn't have CI|NP/READ
1222             dir_ace = self.ace_parse_str(dir_add_acl_str)
1223             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False)
1224
1225             child_file_ace = self.ace_parse_str(inherited_ace_str)
1226             # nested file 'oi_dir/file-1' should NOT have inherited I/CHANGE
1227             self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False)
1228
1229             # nested dir  'oi_dir/nested' should NOT have I/CHANGE
1230             child_dir_ace = self.ace_parse_str(inherited_ace_str)
1231             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
1232
1233         except BlackboxProcessError as e:
1234             self.fail(str(e))
1235
1236     def test_simple_cioi_inhibit(self):
1237         """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
1238         for the file and additionally use inheritance rules to propagate appropriate
1239         changes to children. In particular it tests that inheritance removed does
1240         indeed prevent inheritance propagation
1241
1242         This test adds an ACL with (CI)(OI)(CHANGE) at oi_dir
1243
1244         Note: Inheritance has been removed ( and ace(s) copied ) at
1245         tar_test_dir/oi_dir/nested
1246
1247         before:
1248
1249         +-tar_test_dir/    (OI)(CI)(I)(F)
1250           +-oi_dir/        (OI)(CI)(I)(F)
1251           | +-file.1            (I)(F)
1252           | +-nested/      (OI)(CI)(F)
1253           |   +-file.2          (I)(F)
1254
1255         after/expected:
1256
1257         +-tar_test_dir/    (OI)(CI)(I)(F)
1258           +-oi_dir/        (OI)(CI)(I)(F), (CI)(OI)(CHANGE)
1259           | +-file.1            (I)(F), (I)((CHANGE)
1260           | +-nested/      (OI)(CI)(F)
1261           |   +-file.2          (I)(F)"""
1262         dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI/CHANGE" % self.user
1263         file_inherited_ace_str = "ACL:%s:ALLOWED/I/CHANGE" % self.user
1264         dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/CHANGE" % self.user
1265
1266         try:
1267             # smb_cacls --inherit=copy
1268             self.smb_cacls(["--inherit=copy", self.nested_dir])
1269
1270             self.smb_cacls(["--propagate-inheritance", "--add",
1271                            dir_add_acl_str, self.oi_dir])
1272
1273             # check top level container 'oi_dir' has OI|CI/CHANGE
1274             dir_ace = self.ace_parse_str(dir_add_acl_str)
1275             self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
1276
1277             # nested file 'oi_dir/file-1' should have inherited I/CHANGE
1278             child_file_ace = self.ace_parse_str(file_inherited_ace_str)
1279             self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
1280
1281             # nested dir  'oi_dir/nested/' should NOT have OI|CI|I/CHANGE
1282             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
1283             self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False)
1284
1285             # nested file  'oi_dir/nested/file-2' should NOT have I/CHANGE
1286             child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
1287             self.assertTrue(self.file_ace_check(self.f2, child_dir_ace) == False)
1288
1289         except BlackboxProcessError as e:
1290             self.fail(str(e))