The branch, master has been updated via e3079c53877 python/samba/tests/blackbox: Tests with nested DFS container via 5b04affc73f s3/utils: restore client share connection after call to sec_desc_parse via 28719f3edc9 s3/utils: If dfs path is an ordinary path then really just return it via 7faab75b477 python/samba/tests/blackbox: python smbcacls '--propagate-inherit' test via c4707e1dd8e doc: describe smbcacls --propagate-inheritance expanding INHERITANCE section via 8c581758f65 doc: describe smbcacls --propagate-inheritance via 0248fdd09a6 add new '--propagate-inheritance' option for smbcacls via c681f5bfe36 python/samba/tests/blackbox: Preparatory change to support custom share via 8826d74ae8c python/samba/tests:blackbox: Fix local file delete test tree fallback via 05de29a4d08 python/samba/tests/blackbox: Fix undetected deltree fail from b02f1d676f6 s3:share_mode_lock: remove unused reproducer for bug #14428
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e3079c53877e48defe384efe713e8cfeb9d8fa86 Author: Noel Power <noel.po...@suse.com> Date: Mon Jul 27 16:58:31 2020 +0100 python/samba/tests/blackbox: Tests with nested DFS container Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Mon Aug 31 19:09:24 UTC 2020 on sn-devel-184 commit 5b04affc73f75d6b3e85eafb3fed0fe29c9c03db Author: Noel Power <noel.po...@suse.com> Date: Fri Jul 24 15:32:11 2020 +0100 s3/utils: restore client share connection after call to sec_desc_parse This normally isn't a problem *except* for when the share is a dfs root (which results in cli_resolve_patch creating an incorrect path) Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 28719f3edc9dc3ba13c3cd5382b4fb04a30af260 Author: Noel Power <noel.po...@suse.com> Date: Fri Jul 24 14:50:57 2020 +0100 s3/utils: If dfs path is an ordinary path then really just return it In cli_resolve_path if the share was a root dfs share then any self hosted dfs paths end up not being returned as is but being decorated with fileserver and share. This file path is not suitable for passing to cli_list so we adjust it here. Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 7faab75b4777ce886edf1422a901d3e75c132b6c Author: Noel Power <noel.po...@suse.com> Date: Fri Jul 3 10:55:44 2020 +0000 python/samba/tests/blackbox: python smbcacls '--propagate-inherit' test Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit c4707e1dd8e01d9d91e4b75c347c5e616c945aef Author: Noel Power <noel.po...@suse.com> Date: Fri Nov 15 11:53:35 2013 +0000 doc: describe smbcacls --propagate-inheritance expanding INHERITANCE section Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 8c581758f65ff60ba7fe0385c68137a6d62e5934 Author: David Disseldorp <dd...@samba.org> Date: Thu Nov 14 19:38:19 2013 +0100 doc: describe smbcacls --propagate-inheritance Signed-off-by: David Disseldorp <dd...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0248fdd09a68925e3720f67724463f0bce0d631a Author: Noel Power <noel.po...@suse.com> Date: Thu Nov 14 17:45:07 2013 +0000 add new '--propagate-inheritance' option for smbcacls smbcacls now can take a '--propagate-inheritance' flag to indicate that the add, delete, modify and set operations now support automatic propagation of inheritable ACE(s) Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit c681f5bfe3669f913a6e592844458e1fd6a9fa13 Author: Noel Power <noel.po...@suse.com> Date: Mon Jul 27 16:51:12 2020 +0100 python/samba/tests/blackbox: Preparatory change to support custom share tearDown method doesn't handle local file deletion fallback if a share other than 'tmp' is used Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 8826d74ae8cd807af84213abde5292b6f5ff293e Author: Noel Power <noel.po...@suse.com> Date: Mon Jul 27 17:02:28 2020 +0100 python/samba/tests:blackbox: Fix local file delete test tree fallback Wrong indentation ensures the fallback where we use file system removal of test files if the test's tearDown method fails. Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 05de29a4d08da37fc73ac4a297e43304240a3eb5 Author: Noel Power <noel.po...@suse.com> Date: Tue Jul 28 16:21:17 2020 +0100 python/samba/tests/blackbox: Fix undetected deltree fail With msdfs root share smbclient deltree command can fail without setting the errorcode (e.g. when do_list encounters an error it will log a warning message and continue rather than error out fatally) Signed-off-by: Noel Power <noel.po...@suse.com> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: docs-xml/manpages/smbcacls.1.xml | 110 +- python/samba/tests/blackbox/smbcacls.py | 24 +- .../blackbox/smbcacls_dfs_propagate_inherit.py | 96 ++ .../blackbox/smbcacls_propagate_inhertance.py | 1291 ++++++++++++++++++++ selftest/target/Samba3.pm | 11 + source3/utils/smbcacls.c | 826 ++++++++++++- source4/selftest/tests.py | 14 +- 7 files changed, 2333 insertions(+), 39 deletions(-) create mode 100644 python/samba/tests/blackbox/smbcacls_dfs_propagate_inherit.py create mode 100644 python/samba/tests/blackbox/smbcacls_propagate_inhertance.py Changeset truncated at 500 lines: diff --git a/docs-xml/manpages/smbcacls.1.xml b/docs-xml/manpages/smbcacls.1.xml index 7f87da80329..7efcc087cfd 100644 --- a/docs-xml/manpages/smbcacls.1.xml +++ b/docs-xml/manpages/smbcacls.1.xml @@ -28,6 +28,7 @@ <arg choice="opt">-C|--chown name</arg> <arg choice="opt">-G|--chgrp name</arg> <arg choice="opt">-I allow|remove|copy</arg> + <arg choice="opt">--propagate-inheritance</arg> <arg choice="opt">--numeric</arg> <arg choice="opt">-t</arg> <arg choice="opt">-U username</arg> @@ -132,11 +133,18 @@ permissions" check box using the <parameter>-I</parameter> option. To set the check box pass allow. To unset the check box pass either remove or copy. Remove will remove all - inherited acls. Copy will copy all the inherited acls. + inherited ACEs. Copy will copy all the inherited ACEs. </para></listitem> </varlistentry> + <varlistentry> + <term>--propagate-inheritance</term> + <listitem><para>Add, modify, delete or set ACEs on an entire + directory tree according to the inheritance flags. Refer to the + INHERITANCE section for details. + </para></listitem> + </varlistentry> <varlistentry> <term>--numeric</term> @@ -238,18 +246,22 @@ ACL:<sid or name>:<type>/<flags>/<mask> determine the type of access granted to the SID. </para> <para>The type can be either ALLOWED or DENIED to allow/deny access - to the SID. The flags values are generally zero for file ACEs and - either 9 or 2 for directory ACEs. Some common flags are: </para> + to the SID.</para> + + <para>The flags field defines how the ACE should be considered when + performing inheritance. <command>smbcacls</command> uses these flags + when run with <parameter>--propagate-inheritance</parameter>.</para> + + <para>Flags can be specified as decimal or hexadecimal values, or with + the respective (XX) aliases, separated by a vertical bar "|".</para> <itemizedlist> - <listitem><para><constant>#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1</constant></para></listitem> - <listitem><para><constant>#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2</constant></para></listitem> - <listitem><para><constant>#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4</constant></para></listitem> - <listitem><para><constant>#define SEC_ACE_FLAG_INHERIT_ONLY 0x8</constant></para></listitem> + <listitem><para><emphasis>(OI)</emphasis> Object Inherit 0x1</para></listitem> + <listitem><para><emphasis>(CI)</emphasis> Container Inherit 0x2</para></listitem> + <listitem><para><emphasis>(NP)</emphasis> No Propagate Inherit 0x4</para></listitem> + <listitem><para><emphasis>(IO)</emphasis> Inherit Only 0x8</para></listitem> </itemizedlist> - <para>At present, flags can only be specified as decimal or - hexadecimal values.</para> <para>The mask is a value which expresses the access right granted to the SID. It can be given as a decimal or hexadecimal value, @@ -279,6 +291,86 @@ ACL:<sid or name>:<type>/<flags>/<mask> </itemizedlist> </refsect1> +<refsect1> + <title>INHERITANCE</title> + + <para>Per-ACE inheritance flags can be set in the ACE flags field. By + default, inheritable ACEs e.g. those marked for object inheritance (OI) + or container inheritance (CI), are not propagated to sub-files or + folders. However, with the + <parameter>--propagate-inheritance</parameter> argument specified, such + ACEs are automatically propagated according to some inheritance + rules. + <itemizedlist> + <listitem><para>Inheritable (OI)(OI) ACE flags can only be + applied to folders. </para></listitem> + <listitem><para>Any inheritable ACEs applied to sub-files or + folders are marked with the inherited (I) flag. Inheritable + ACE(s) are applied to folders unless the no propagation (NP) + flag is set. </para> + </listitem> + <listitem><para>When an ACE with the (OI) flag alone set is + progagated to a child folder the inheritance only flag (IO) is + also applied. This indicates the permissions associated with + the ACE don't apply to the folder itself (only to it's + child files). When applying the ACE to a child file the ACE is + inherited as normal.</para></listitem> + <listitem><para>When an ace with the (CI) flag alone set is + propagated to a child file there is no effect, when propagated + to a child folder it is inherited as normal. + </para></listitem> + <listitem><para>When an ACE that has both (OI) & (CI) flags + set the ACE is inherited as normal by both folders and + files.</para></listitem> + </itemizedlist></para> +<para>(OI)(READ) added to parent folder</para> +<para><programlisting> ++-parent/ (OI)(READ) +| +-file.1 (I)(READ) +| +-nested/ (OI)(IO)(I)(READ) + | +-file.2 (I)(READ) +</programlisting></para> +<para>(CI)(READ) added to parent folder</para> +<para><programlisting> ++-parent/ (CI)(READ) +| +-file.1 +| +-nested/ (CI)(I)(READ) + | +-file.2 +</programlisting></para> +<para>(OI)(CI)(READ) added to parent folder</para> +<para><programlisting> ++-parent/ (OI)(CI)(READ) +| +-file.1 (I)(READ) +| +-nested/ (OI)(CI)(I)(READ) + | +-file.2 (I)(READ) +</programlisting></para> +<para>(OI)(NP)(READ) added to parent folder</para> +<para><programlisting> ++-oi_dir/ (OI)(NP)(READ) +| +-file.1 (I)(READ) +| +-nested/ +| +-file.2 +</programlisting></para> +<para>(CI)(NP)(READ) added to parent folder</para> +<para><programlisting> ++-oi_dir/ (CI)(NP)(READ) +| +-file.1 +| +-nested/ (I)(READ) +| +-file.2 +</programlisting></para> +<para>(OI)(CI)(NP)(READ) added to parent folder</para> +<para><programlisting> ++-parent/ (CI)(OI)(NP)(READ) +| +-file.1 (I)(READ) +| +-nested/ (I)(READ) +| +-file.2 +</programlisting></para> + <para>Files and folders with protected ACLs do not allow inheritable + permissions (set with <parameter>-I</parameter>). Such objects will + not receive ACEs flagged for inheritance with (CI) or (OI).</para> + +</refsect1> + <refsect1> <title>EXIT STATUS</title> diff --git a/python/samba/tests/blackbox/smbcacls.py b/python/samba/tests/blackbox/smbcacls.py index b749124ccac..3eca9602005 100644 --- a/python/samba/tests/blackbox/smbcacls.py +++ b/python/samba/tests/blackbox/smbcacls.py @@ -37,6 +37,7 @@ class SmbCaclsBlockboxTestBase(BlackboxTestCase): self.creds.set_password(self.passwd) self.testdir = os.getenv("TESTDIR", "smbcacls") self.share = os.getenv("SHARE", "tmp") + self.dirpath = os.path.join(os.environ["LOCAL_PATH"],self.testdir) def tearDown(self): try: @@ -45,19 +46,20 @@ class SmbCaclsBlockboxTestBase(BlackboxTestCase): # so if we fail with remote remove perform local remove # (of remote files) instead smbclient_args = self.build_test_cmd("smbclient", ["//%s/%s" % (self.server, self.share), "-c", "deltree %s/*" % self.testdir]) - self.check_output(smbclient_args) + out = self.check_output(smbclient_args) + if "NT_STATUS_OBJECT_PATH_NOT_FOUND" in out.decode(): + raise Exception("deltree: failed without setting errcode") except Exception as e: print("remote remove failed: %s" % str(e)) - dirpath = os.path.join(os.environ["LOCAL_PATH"],self.testdir) - print("falling back to removing contents of local dir: %s" % dirpath) - if os.path.exists(dirpath): - for entry in os.listdir(dirpath): - fullpath = os.path.join(dirpath, entry) - if os.path.isdir(fullpath): - import shutil - shutil.rmtree(fullpath) - else: - os.unlink(fullpath) + print("falling back to removing contents of local dir: %s" % self.dirpath) + if os.path.exists(self.dirpath): + for entry in os.listdir(self.dirpath): + fullpath = os.path.join(self.dirpath, entry) + if os.path.isdir(fullpath): + import shutil + shutil.rmtree(fullpath) + else: + os.unlink(fullpath) def ace_dump(self, ace): for key, value in ace.items(): diff --git a/python/samba/tests/blackbox/smbcacls_dfs_propagate_inherit.py b/python/samba/tests/blackbox/smbcacls_dfs_propagate_inherit.py new file mode 100644 index 00000000000..1df60149176 --- /dev/null +++ b/python/samba/tests/blackbox/smbcacls_dfs_propagate_inherit.py @@ -0,0 +1,96 @@ +# Blackbox tests for smbcaclcs +# +# Copyright (C) Noel Power noel.po...@suse.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import print_function +from samba.tests import BlackboxProcessError +import os +from samba.tests.blackbox.smbcacls_propagate_inhertance import InheritanceSmbCaclsTests +from samba.tests.blackbox.smbcacls import SmbCaclsBlockboxTestBase + +class DfsInheritanceSmbCaclsTests(InheritanceSmbCaclsTests): + + def setUp(self): + # This is some intentional trickery to ensure we skip + # InheritanceSmbCaclsTests.setUp so we can create a new + # test directory & file hierachy (including a nested dfs link) + SmbCaclsBlockboxTestBase.setUp(self) + smbclient_args = self.build_test_cmd("smbclient", ["//%s/%s" % (self.server, self.share), "-c", "mkdir %s" % os.getenv("TESTDIR", "smbcacls")]) + self.check_output(smbclient_args) + + # create toplevel testdir structure with desired ACL(s) + # + # +-tar_test_dir/ (OI)(CI)(I)(F) + # +-oi_dir/ (OI)(CI)(I)(F) + # | +-file.1 (I)(F) + # | +-nested/ (OI)(CI)(I)(F) + # | +-file.2 (I)(F) + # DFS=>| +-nested_again/ (OI)(CI)(I)(F) + # | +-file.3 (I)(F) + + self.toplevel = self.create_remote_test_file("tar_test_dir/file-0") + self.dfs_target_share = os.getenv("DFS_TARGET_SHARE", "smbcacls_sharedir_dfs") + self.f1 = self.create_remote_test_file("tar_test_dir/oi_dir/file-1") + self.f2 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/file-2") +# self.f3 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/nested_again/file-3") + + + self.tar_dir = os.path.split(self.toplevel)[0] + self.oi_dir = os.path.split(self.f1)[0] + self.nested_dir = os.path.split(self.f2)[0] + + self.nested_again_dir = os.path.join(self.nested_dir, "nested_again") + + # dfs link + link_val = "msdfs:%s\\%s" % (self.server, self.dfs_target_share) + dfs_share_path = "smbcacls_share" + local_link_path = os.path.join(os.environ["LOCAL_PATH"], dfs_share_path) + link_source = link_val + link_dest = os.path.join(local_link_path, self.nested_again_dir) + + + # unfortunately os.link won't work with a source file that doesn't + # exist, we need to run 'ln' directly + #os.link(link_source, link_dest) + link_args = ["ln", "-s", link_source, link_dest] + out = self.check_output(link_args) + + self.f3 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/nested_again/file-3") + + + + dir_acl_str = "ACL:%s:ALLOWED/OI|CI/FULL" % self.user + inherited_dir_acl_str = "ACL:%s:ALLOWED/OI|CI|I/FULL" % self.user + file_acl_str = "ACL:%s:ALLOWED/I/FULL" % self.user + + self.smb_cacls(["--modify", dir_acl_str, self.tar_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.oi_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_again_dir]) + self.smb_cacls(["--modify", file_acl_str, self.f1]) + self.smb_cacls(["--modify", file_acl_str, self.f2]) + self.smb_cacls(["--modify", file_acl_str, self.f3]) + + def tearDown(self): + super(DfsInheritanceSmbCaclsTests, self).tearDown() + # for dfs tests inevitably we fallback to remove the local files in + # the base class, the base class however doesn't know about the + # target dfs share (or its contents) so we have to assume we need to + # remove the file on the dfs share + smbclient_args = self.build_test_cmd("smbclient", ["//%s/%s" % (self.server, self.dfs_target_share), "-c", "rm file-3"]) + self.check_output(smbclient_args) + + diff --git a/python/samba/tests/blackbox/smbcacls_propagate_inhertance.py b/python/samba/tests/blackbox/smbcacls_propagate_inhertance.py new file mode 100644 index 00000000000..d4577805f4f --- /dev/null +++ b/python/samba/tests/blackbox/smbcacls_propagate_inhertance.py @@ -0,0 +1,1291 @@ +# Blackbox tests for smbcaclcs +# +# Copyright (C) Noel Power noel.po...@suse.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import print_function +from samba.tests.blackbox.smbcacls import SmbCaclsBlockboxTestBase +from samba.tests import BlackboxProcessError +import os + +class InheritanceSmbCaclsTests(SmbCaclsBlockboxTestBase): + + def setUp(self): + super(InheritanceSmbCaclsTests, self).setUp() + + # create toplevel testdir structure with desired ACL(s) + # + # +-tar_test_dir/ (OI)(CI)(I)(F) + # +-oi_dir/ (OI)(CI)(I)(F) + # | +-file.1 (I)(F) + # | +-nested/ (OI)(CI)(I)(F) + # | +-file.2 (I)(F) + # | +-nested_again/ (OI)(CI)(I)(F) + # | +-file.3 (I)(F) + + self.toplevel = self.create_remote_test_file("tar_test_dir/file-0") + self.f1 = self.create_remote_test_file("tar_test_dir/oi_dir/file-1") + self.f2 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/file-2") + self.f3 = self.create_remote_test_file("tar_test_dir/oi_dir/nested/nested_again/file-3") + self.tar_dir = os.path.split(self.toplevel)[0] + self.oi_dir = os.path.split(self.f1)[0] + self.nested_dir = os.path.split(self.f2)[0] + self.nested_again_dir = os.path.split(self.f3)[0] + + dir_acl_str = "ACL:%s:ALLOWED/OI|CI/FULL" % self.user + inherited_dir_acl_str = "ACL:%s:ALLOWED/OI|CI|I/FULL" % self.user + file_acl_str = "ACL:%s:ALLOWED/I/FULL" % self.user + + self.smb_cacls(["--modify", dir_acl_str, self.tar_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.oi_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_dir]) + self.smb_cacls(["--modify", inherited_dir_acl_str, self.nested_again_dir]) + self.smb_cacls(["--modify", file_acl_str, self.f1]) + self.smb_cacls(["--modify", file_acl_str, self.f2]) + self.smb_cacls(["--modify", file_acl_str, self.f3]) + + def tearDown(self): + # tmp is the default share which has an existing testdir smbcacls + # we need to be prepared to deal with a 'custom' share (which also + # would have an existing testdir) + if self.share != "tmp": + self.dirpath = os.path.join(os.environ["LOCAL_PATH"],self.share) + self.dirpath = os.path.join(self.dirpath,self.testdir) + super(InheritanceSmbCaclsTests, self).tearDown() + + def test_simple_oi_add(self): + """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL + for the file and additionally use inheritance rules to propagate appropriate + changes to children + + This test adds an ACL with (OI)(READ) + + before: + + +-tar_test_dir/ (OI)(CI)(I)(F) + +-oi_dir/ (OI)(CI)(I)(F) + | +-file.1 (I)(F) + | +-nested/ (OI)(CI)(I)(F) + | +-file.2 (I)(F) + | +-nested_again/ (OI)(CI)(I)(F) + | +-file.3 (I)(F) + + after/expected: + + +-tar_test_dir/ (OI)(CI)(I)(F) + +-oi_dir/ (OI)(CI)(I)(F), (OI)(READ) + | +-file.1 (I)(F), (I)(READ) + | +-nested/ (OI)(CI)(I)(F), (OI)(IO)(I)(READ) + | +-file.2 (I)(F), (I)(READ) + | +-nested_again/ (OI)(CI)(I)(F), (OI)(IO)(I)(READ) + | +-file.3 (I)(F), (I)(READ)""" + + dir_add_acl_str = "ACL:%s:ALLOWED/OI/READ" % self.user + obj_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user + dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|IO|I/READ" % self.user + + try: + + self.smb_cacls(["--propagate-inheritance", "--add", + dir_add_acl_str, self.oi_dir]) + + # check top level container 'oi_dir' has OI/READ + dir_ace = self.ace_parse_str(dir_add_acl_str) + self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace)) + + # file 'oi_dir/file-1' should have inherited I/READ + child_file_ace = self.ace_parse_str(obj_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.f1, child_file_ace)) + + # nested dir 'oi_dir/nested/' should have OI|IO/READ + child_dir_ace = self.ace_parse_str(dir_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace)) + + # nested file 'oi_dir/nested/file-2' should have inherited I/READ + self.assertTrue(self.file_ace_check(self.f2, child_file_ace)) + + # nested_again dir 'oi_dir/nested/nested_again' should have OI|IO/READ + child_dir_ace = self.ace_parse_str(dir_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace)) + # nested_again file 'oi_dir/nested/nested_again/file-3' should have inherited I/READ + self.assertTrue(self.file_ace_check(self.f3, child_file_ace)) + except BlackboxProcessError as e: + self.fail(str(e)) + + def test_simple_oi_delete(self): + """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL + for the file and additionally use inheritance rules to propagate appropriate + changes to children + + This test adds an ACL with (OI)(READ) + + before: + + +-tar_test_dir/ (OI)(CI)(I)(F) + +-oi_dir/ (OI)(CI)(I)(F), (OI)(IO)(READ) + | +-file.1 (I)(F), (I)(READ) + | +-nested/ (OI)(CI)(I)(F), (OI)(IO)(I)(READ) + | +-file.2 (I)(F), (I)(READ) + | +-nested_again/ (OI)(CI)(I)(F) + | +-file.3 (I)(F) + + after/expected: + + +-tar_test_dir/ (OI)(CI)(I)(F) + +-oi_dir/ (OI)(CI)(I)(F) + | +-file.1 (I)(F) + | +-nested/ (OI)(CI)(I)(F) + | +-file.2 (I)(F) + | +-nested_again/ (OI)(CI)(I)(F) + | +-file.3 (I)(F)""" + + dir_acl_str = "ACL:%s:ALLOWED/OI/READ" % self.user + obj_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user + dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|IO|I/READ" % self.user + try: + + # add flags on oi_dir + self.smb_cacls([ "--add", dir_acl_str, self.oi_dir]) + + # add flags on oi_dir/nested + self.smb_cacls([ "--add", dir_inherited_ace_str, self.nested_dir]) + + # add flags on oi_dir/nested/nested_again + self.smb_cacls([ "--add", dir_inherited_ace_str, self.nested_again_dir]) + + # add flags on oi_dir/file-1 + self.smb_cacls(["--add", obj_inherited_ace_str, self.f1]) + + # add flags on oi_dir/nested/file-2 + self.smb_cacls([ "--add", obj_inherited_ace_str, self.f2]) + + # add flags on oi_dir/nested/nested_again/file-3 + self.smb_cacls([ "--add", obj_inherited_ace_str, self.f3]) + + self.smb_cacls(["--propagate-inheritance", + "--delete", dir_acl_str, self.oi_dir]) + + # check top level container 'oi_dir' no longer has OI/READ + dir_ace = self.ace_parse_str(dir_acl_str) + self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace) == False) + + # file 'oi_dir/file-1' should no longer have inherited I/READ + child_file_ace = self.ace_parse_str(obj_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.f1, child_file_ace) == False) + + # nested dir 'oi_dir/nested/' should no longer have OI|IO/READ + child_dir_ace = self.ace_parse_str(dir_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace) == False) + + # nested file 'oi_dir/nested/file-2' should no longer have inherited I/READ + self.assertTrue(self.file_ace_check(self.f2, child_file_ace) == False) + + # nested dir 'oi_dir/nested/nested_agin' should no longer have OI|IO/READ + child_dir_ace = self.ace_parse_str(dir_inherited_ace_str) + self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace) == False) + -- Samba Shared Repository