netcmd: domain backup offline command - offline test with ldapcmp
authorAaron Haslett <aaronhaslett@catalyst.net.nz>
Mon, 30 Apr 2018 23:10:31 +0000 (11:10 +1200)
committerGary Lockyer <gary@samba.org>
Mon, 6 Aug 2018 03:37:43 +0000 (05:37 +0200)
This test checks that when you do an offline backup and restore or untar it,
the restored database is the same as the original.  Test is repeated for
'mdb' and 'tdb' database backends.

Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
python/samba/tests/domain_backup_offline.py [new file with mode: 0644]
source4/selftest/tests.py

diff --git a/python/samba/tests/domain_backup_offline.py b/python/samba/tests/domain_backup_offline.py
new file mode 100644 (file)
index 0000000..6762e88
--- /dev/null
@@ -0,0 +1,117 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet@samba.org>
+#
+# 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/>.
+#
+
+import tarfile
+import os
+import shutil
+import tempfile
+from samba.tests.samba_tool.base import SambaToolCmdTest
+from samba.tests import TestCaseInTempDir
+from samba.netcmd import CommandError
+
+class DomainBackupOfflineCmp(SambaToolCmdTest, TestCaseInTempDir):
+
+    def test_domain_backup_offline_untar_tdb(self):
+        self.untar_testcase('tdb')
+
+    def test_domain_backup_offline_untar_mbd(self):
+        self.untar_testcase('mdb')
+
+    def test_domain_backup_offline_restore_tdb(self):
+        self.restore_testcase('tdb')
+
+    def test_domain_backup_offline_restore_mbd(self):
+        self.restore_testcase('mdb')
+
+    def restore_testcase(self, backend):
+        prov_dir, backup_file = self.provision_and_backup(backend)
+
+        extract_dir = tempfile.mkdtemp(dir=self.tempdir)
+        cmd = ("samba-tool domain backup restore --backup-file={f}"
+               " --targetdir={d} "
+               "--newservername=NEWSERVER").format(f=backup_file, d=extract_dir)
+        self.check_output(cmd)
+
+        # attrs that are altered by the restore process
+        ignore_attrs = ["servicePrincipalName", "lastLogonTimestamp",
+                        "rIDAllocationPool", "rIDAvailablePool",
+                        "localPolicyFlags", "operatingSystem", "displayName",
+                        "dnsRecord", "dNSTombstoned",
+                        "msDS-NC-Replica-Locations", "msDS-HasInstantiatedNCs",
+                        "interSiteTopologyGenerator"]
+        filter_arg = "--filter=" + ",".join(ignore_attrs)
+        args = ["--two", filter_arg]
+        self.ldapcmp(prov_dir, extract_dir, args)
+
+        shutil.rmtree(prov_dir)
+        shutil.rmtree(extract_dir)
+
+    def untar_testcase(self, backend):
+        prov_dir, backup_file = self.provision_and_backup(backend)
+
+        extract_dir = tempfile.mkdtemp(dir=self.tempdir)
+        tf = tarfile.open(backup_file)
+        tf.extractall(extract_dir)
+
+        self.ldapcmp(prov_dir, extract_dir)
+
+        shutil.rmtree(prov_dir)
+        shutil.rmtree(extract_dir)
+
+    def ldapcmp(self, prov_dir, ex_dir, args=[]):
+        sam_fn = os.path.join("private", "sam.ldb")
+        url1 = "tdb://" + os.path.join(os.path.realpath(prov_dir), sam_fn)
+        url2 = "tdb://" + os.path.join(os.path.realpath(ex_dir), sam_fn)
+
+        # Compare the restored sam.ldb with the old one
+        for partition in ["domain", "configuration", "schema",
+                          "dnsdomain", "dnsforest"]:
+            cmd = "samba-tool ldapcmp " + " ".join([url1, url2, partition] + args)
+            self.check_output(cmd)
+
+    # Test the "samba-tool domain backup" command with ldapcmp
+    def provision_and_backup(self, backend):
+        prov_dir = tempfile.mkdtemp(dir=self.tempdir)
+
+        # Provision domain.  Use fake ACLs and store xattrs in tdbs so that
+        # NTACL backup will work inside the testenv.
+        # host-name option must be given because if this test runs on a
+        # system with a very long hostname, it will be shortened in certain
+        # circumstances, causing the ldapcmp to fail.
+        prov_cmd = "samba-tool domain provision " +\
+                   "--domain FOO --realm foo.example.com " +\
+                   "--targetdir {prov_dir} " +\
+                   "--backend-store {backend} " +\
+                   "--host-name OLDSERVER "+\
+                   "--option=\"vfs objects=fake_acls xattr_tdb\""
+        prov_cmd = prov_cmd.format(prov_dir=prov_dir, backend=backend)
+        self.check_output(prov_cmd)
+
+        # Run the backup and check we got one backup tar file
+        cmd = ("samba-tool domain backup offline --targetdir={prov_dir} "
+               "-s {prov_dir}/etc/smb.conf").format(prov_dir=prov_dir)
+        self.check_output(cmd)
+
+        tar_files = [fn for fn in os.listdir(prov_dir)
+                     if fn.startswith("samba-backup-") and
+                     fn.endswith(".tar.bz2")]
+        if len(tar_files) != 1:
+            raise CommandError("expected domain backup to create one tar" +
+                               " file but got {}".format(len(tar_files)))
+
+        backup_file = os.path.join(prov_dir, tar_files[0])
+        return prov_dir, backup_file
index 4b77b7e8675075d13033918900401daa79004327..5bcaceab18888737296c2e27afc1c74ae0714cd0 100755 (executable)
@@ -734,6 +734,8 @@ planoldpythontestsuite("ad_dc",
 planoldpythontestsuite("ad_dc:local",
                        "samba.tests.domain_backup",
                        extra_args=['-U"$USERNAME%$PASSWORD"'])
+planoldpythontestsuite("none",
+                       "samba.tests.domain_backup_offline")
 # Encrypted secrets
 # ensure default provision (ad_dc) and join (vampire_dc)
 # encrypt secret values on disk.