python/samba/tests: Add smbcacl tests for save/restore
authorNoel Power <noel.power@suse.com>
Fri, 2 Sep 2022 11:48:08 +0000 (11:48 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 15 Nov 2023 04:05:34 +0000 (04:05 +0000)
Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/blackbox/smbcacls_save_restore.py [new file with mode: 0644]
selftest/target/Samba3.pm
source4/selftest/tests.py

diff --git a/python/samba/tests/blackbox/smbcacls_save_restore.py b/python/samba/tests/blackbox/smbcacls_save_restore.py
new file mode 100644 (file)
index 0000000..896e337
--- /dev/null
@@ -0,0 +1,205 @@
+# Blackbox tests for smbcacls
+#
+# Copyright (C) Noel Power noel.power@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 samba.tests.blackbox.smbcacls import SmbCaclsBlockboxTestBase
+from samba.tests import BlackboxProcessError
+import os
+
+class SaveRestoreSmbCaclsTests(SmbCaclsBlockboxTestBase):
+
+    def setUp(self):
+        super(SaveRestoreSmbCaclsTests, 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(SaveRestoreSmbCaclsTests, self).tearDown()
+
+    def test_simple_save_dir(self):
+        try:
+            # simple test to just store dacl of directory
+            with self.mktemp() as tmpfile:
+                out = self.smb_cacls(["--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    contents = infile.read().decode('utf16')
+                    lines = contents.splitlines()
+                    # should be 2 lines
+                    self.assertEqual(len(lines), 2)
+                    # first line should be the path
+                    self.assertEqual(self.oi_dir.replace('/','\\'), lines[0])
+
+        except BlackboxProcessError as e:
+            self.fail(str(e))
+
+    def test_simple_save_dir_r(self):
+        try:
+            # simple test to just store dacl of directory (recursively)
+            with self.mktemp() as tmpfile:
+                out = self.smb_cacls(["--recurse", "--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    contents = infile.read().decode('utf16')
+                    print("contents = %s" % contents)
+                    lines = contents.splitlines()
+                    # should be 12 lines
+                    self.assertEqual(len(lines), 12)
+                    paths = [
+                            self.oi_dir.replace('/','\\'),
+                            self.f1.replace('/','\\'),
+                            self.nested_dir.replace('/','\\'),
+                            self.f2.replace('/','\\'),
+                            self.nested_again_dir.replace('/','\\'),
+                            self.f3.replace('/','\\')
+                            ]
+                    i = 0
+                    for line in lines:
+                        if not i % 2:
+                            paths.remove(line)
+                        i = i + 1
+                    self.assertEqual(0, len(paths))
+
+        except BlackboxProcessError as e:
+            self.fail(str(e))
+
+    def test_simple_restore_dir(self):
+        try:
+            # simple test to just store dacl of directory
+            orig_saved = None
+            modified = None
+            restored = None
+            with self.mktemp() as tmpfile:
+                self.smb_cacls(["--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    orig_saved = infile.read()
+
+            # modify directory structure
+            dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI/READ" % self.user
+            self.smb_cacls(["--propagate-inheritance", "--add",
+                           dir_add_acl_str, self.oi_dir])
+
+            # save modified directory dacls to file
+            with self.mktemp() as tmpfile:
+                self.smb_cacls(["--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    modified = infile.read()
+
+            # compare orig and unmodified dacls
+            # they shouldn't match
+            self.assertNotEqual(orig_saved.decode('utf16'), modified.decode('utf16'))
+            # restore original dacls from file
+            with self.mktemp() as tmpfile:
+                with open(tmpfile, 'wb') as outfile:
+                    outfile.write(orig_saved)
+                    outfile.close()
+                    out = self.smb_cacls([".", "--restore", tmpfile])
+
+            # save newly restored dacls to file
+            with self.mktemp() as tmpfile:
+                self.smb_cacls(["--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    restored = infile.read()
+
+            # after restoring the dalcs, orig unmodified dacls should match
+            # restored dacls
+            self.assertEqual(orig_saved.decode('utf16'), restored.decode('utf16'))
+
+        except BlackboxProcessError as e:
+            self.fail(str(e))
+
+    def test_simple_restore_dir_r(self):
+        try:
+            # simple test to just store dacl(s) of directory recursively
+            orig_saved = None
+            modified = None
+            restored = None
+            with self.mktemp() as tmpfile:
+                self.smb_cacls(["--recurse", "--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    orig_saved = infile.read()
+
+            # modify directory's dacls recursively
+            dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI/READ" % self.user
+            self.smb_cacls(["--propagate-inheritance", "--add",
+                           dir_add_acl_str, self.oi_dir])
+
+            # save modified directories dacls recursively
+            with self.mktemp() as tmpfile:
+                self.smb_cacls(["--recurse", "--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    modified = infile.read()
+
+            # the unmodified stringified dacls shouldn't match
+            # modified
+            self.assertNotEqual(orig_saved.decode('utf16'), modified.decode('utf16'))
+            # restore original dacls from file
+            with self.mktemp() as tmpfile:
+                with open(tmpfile, 'wb') as outfile:
+                    outfile.write(orig_saved)
+                    outfile.close()
+                    out = self.smb_cacls([".", "--restore", tmpfile])
+
+            with self.mktemp() as tmpfile:
+                out = self.smb_cacls(["--recurse", "--save", tmpfile,
+                            self.oi_dir])
+                with open(tmpfile, 'rb') as infile:
+                    restored = infile.read()
+            # after restoring the dalcs orig unmodified dacls should match
+            # current dacls
+            self.assertEqual(orig_saved.decode('utf16'), restored.decode('utf16'))
+        except BlackboxProcessError as e:
+            self.fail(str(e))
index ef68f63e3481cf44fd000431216d3d65504af3a7..d56f12ee57a6b5119214c4135365c3e9d6ca6bd5 100755 (executable)
@@ -746,6 +746,9 @@ sub provision_ad_member
        $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice/g_$dcvars->{DOMAIN}/domain users";
        push(@dirs, $substitution_path);
 
+       my $smbcacls_sharedir="$share_dir/smbcacls";
+       push(@dirs,$smbcacls_sharedir);
+
        my $option_offline_logon = "no";
        if (defined($offline_logon)) {
                $option_offline_logon = "yes";
index 35e6d691c9120ae084c211732b490be5eee40ea2..1492e13a7c1cf75c2a7f86a3b2812f8cfbb9ef51 100755 (executable)
@@ -1445,6 +1445,14 @@ planoldpythontestsuite("fileserver",
 # Run smbcacls_propagate_inhertance tests on non msdfs root share
 planoldpythontestsuite("fileserver",
                        "samba.tests.blackbox.smbcacls_propagate_inhertance")
+planoldpythontestsuite("fileserver",
+                       "samba.tests.blackbox.smbcacls_save_restore")
+planoldpythontestsuite("ad_member",
+                       "samba.tests.blackbox.smbcacls_save_restore",
+                       environ={'USER': '$DC_USERNAME',
+                                'PASSWORD' : '$DC_PASSWORD'}
+                       )
+
 #
 # A) Run the smbcacls_propagate_inhertance tests on a msdfs root share
 #    *without* any nested dfs links