netcmd: Add tests for performing an offline backup immediately after joining a domain
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 24 May 2021 02:58:40 +0000 (14:58 +1200)
committerKarolin Seeger <kseeger@samba.org>
Mon, 12 Jul 2021 12:55:43 +0000 (12:55 +0000)
This currently fails due to the DC not having a rIDNextRID attribute,
which is required for the restore process.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14669

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit b7e6a1c5da7283c49586dc29f85ab19e0e57b0f6)

python/samba/tests/domain_backup_offline.py
selftest/knownfail.d/bug-14669 [new file with mode: 0644]
source4/selftest/tests.py

index 83cd6cfa57f88436c0ced7bc1ff2f223a472fcd6..21f42c6dab8406f6ff0136afac210b7aa3ab2346 100644 (file)
@@ -19,9 +19,12 @@ import tarfile
 import os
 import shutil
 import tempfile
-from samba.tests import BlackboxTestCase
+from samba.tests import BlackboxTestCase, BlackboxProcessError
 from samba.netcmd import CommandError
 from samba.param import LoadParm
+from samba.join import join_DC
+from samba.credentials import Credentials
+from samba.logger import get_samba_logger
 
 # The backup tests require that a completely clean LoadParm object gets used
 # for the restore. Otherwise the same global LP gets re-used, and the LP
@@ -62,6 +65,23 @@ class DomainBackupOfflineCmp(BlackboxTestCase):
         names = tf.getnames()
         self.assertEqual(len(names), len(set(names)))
 
+    def test_domain_backup_offline_join_restore_tdb(self):
+        self.join_restore_testcase('tdb')
+
+    def test_domain_backup_offline_join_restore_mdb(self):
+        self.join_restore_testcase('mdb')
+
+    def join_restore_testcase(self, backend):
+        self.prov_dir = self.join(backend)
+        self.extract_dir = None
+
+        try:
+            backup_file = self.backup(self.prov_dir)
+        except BlackboxProcessError as e:
+            self.fail(e)
+
+        self.extract_dir = self.restore(backup_file)
+
     def test_domain_backup_offline_hard_link_tdb(self):
         self.hard_link_testcase('tdb')
 
@@ -107,12 +127,7 @@ class DomainBackupOfflineCmp(BlackboxTestCase):
         self.extract_dir = None
         backup_file = self.backup(self.prov_dir)
 
-        self.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=self.extract_dir)
-        self.check_output(cmd)
+        self.extract_dir = self.restore(backup_file)
 
         # attrs that are altered by the restore process
         ignore_attrs = ["servicePrincipalName", "lastLogonTimestamp",
@@ -167,6 +182,27 @@ class DomainBackupOfflineCmp(BlackboxTestCase):
 
         return target
 
+    def join(self, backend):
+        target = tempfile.mkdtemp(dir=self.tempdir)
+
+        join_cmd = "samba-tool domain join {domain} DC " +\
+                   "--server {server} " +\
+                   "--realm {realm} " +\
+                   "--username {username}%{password} " +\
+                   "--targetdir {target} " +\
+                   "--backend-store {backend} " +\
+                   "--option=\"vfs objects=dfs_samba4 acl_xattr fake_acls xattr_tdb\""
+        join_cmd = join_cmd.format(server=os.environ["DC_SERVER"],
+                                   domain=os.environ["DOMAIN"],
+                                   realm=os.environ["REALM"],
+                                   username=os.environ["USERNAME"],
+                                   password=os.environ["PASSWORD"],
+                                   target=target,
+                                   backend=backend)
+        self.check_output(join_cmd)
+
+        return target
+
     def backup(self, prov_dir):
         # Run the backup and check we got one backup tar file
         cmd = ("samba-tool domain backup offline --targetdir={prov_dir} "
@@ -183,6 +219,17 @@ class DomainBackupOfflineCmp(BlackboxTestCase):
         backup_file = os.path.join(prov_dir, tar_files[0])
         return backup_file
 
+    def restore(self, backup_file):
+        # Restore from a backup file
+        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)
+
+        return extract_dir
+
     def tearDown(self):
         # Remove temporary directories
         shutil.rmtree(self.prov_dir)
diff --git a/selftest/knownfail.d/bug-14669 b/selftest/knownfail.d/bug-14669
new file mode 100644 (file)
index 0000000..83f8cbf
--- /dev/null
@@ -0,0 +1 @@
+^samba.tests.domain_backup_offline.samba.tests.domain_backup_offline.DomainBackupOfflineCmp.test_domain_backup_offline_join_restore
index 4c9ddccd01b53e54e9d7da7af81acb6451987a68..0a83bcd6987188561471a4f805deeaa7ca34c2b0 100755 (executable)
@@ -906,7 +906,7 @@ for env in ["ad_dc_backup", smbv1_disabled_testenv]:
     planoldpythontestsuite(env + ":local", "samba.tests.domain_backup",
                            extra_args=['-U"$USERNAME%$PASSWORD"'])
 
-planoldpythontestsuite("none",
+planoldpythontestsuite("ad_dc",
                        "samba.tests.domain_backup_offline")
 # Encrypted secrets
 # ensure default provision (ad_dc) and join (vampire_dc)