From d58351d5edbef6ff61b2565706bc86519cc50abe Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Thu, 18 Mar 2021 17:54:33 +0100 Subject: [PATCH 1/2] netcmd: Workaround issue backing up offline domain with lmdb >= 0.9.26 The LMDB change "ITS#9278 fix robust mutex cleanup for FreeBSD" released in version 0.9.26 makes samba-tool domain backup offline to fail with the following error: Failed to connect to 'mdb:///tmp/foo/private/sam.ldb.d/CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb' with backend 'mdb': Unable to load ltdb cache records for backend 'ldb_mdb backend' module samba_dsdb initialization failed : Operations error Unable to load modules for /tmp/foo/private/sam.ldb.bak-offline: Unable to load ltdb cache records for backend 'ldb_mdb backend' ERROR(ldb): uncaught exception - Unable to load ltdb cache records for backend 'ldb_mdb backend' File "/usr/local/samba/lib64/python3.6/site-packages/samba/netcmd/__init__.py", line 186, in _run return self.run(*args, **kwargs) File "/usr/local/samba/lib64/python3.6/site-packages/samba/netcmd/domain_backup.py", line 1147, in run session_info=system_session(), lp=lp) File "/usr/local/samba/lib64/python3.6/site-packages/samba/samdb.py", line 72, in __init__ options=options) File "/usr/local/samba/lib64/python3.6/site-packages/samba/__init__.py", line 114, in __init__ self.connect(url, flags, options) File "/usr/local/samba/lib64/python3.6/site-packages/samba/samdb.py", line 87, in connect options=options) The error occurs opening the backed ldb to write the backup date and the next SID, a call to pthread_mutex_lock in mdb_txn_renew0 (frame 8) returns EINVAL: #0 0x00007ff63c2f1bea in wait4 () from /lib64/libc.so.6 #1 0x00007ff63c26f3a3 in do_system () from /lib64/libc.so.6 #2 0x00007ff63bc71e94 in smb_panic_default (why=0x7ffed481b7d0 "Signal 6: Aborted") at ../../lib/util/fault.c:153 #3 0x00007ff63bc72168 in smb_panic (why=0x7ffed481b7d0 "Signal 6: Aborted") at ../../lib/util/fault.c:200 #4 0x00007ff63bc71c82 in fault_report (sig=6) at ../../lib/util/fault.c:81 #5 0x00007ff63bc71c97 in sig_fault (sig=6) at ../../lib/util/fault.c:92 #6 #7 0x00007ff63c2178b5 in raise () from /lib64/libpthread.so.0 #8 0x00007ff637602e65 in mdb_txn_renew0 (txn=txn@entry=0x55d6f97fb800) at mdb.c:2710 #9 0x00007ff637603ae8 in mdb_txn_begin (env=0x55d6f85dfa80, parent=0x0, flags=131072, ret=0x55d6f89c0928) at mdb.c:2912 #10 0x00007ff6376236cc in lmdb_lock_read (module=0x55d6f8c5f4b0) at ../../lib/ldb/ldb_mdb/ldb_mdb.c:585 #11 0x00007ff637641de6 in ldb_kv_cache_load (module=0x55d6f8c5f4b0) at ../../lib/ldb/ldb_key_value/ldb_kv_cache.c:450 #12 0x00007ff637638792 in ldb_kv_init_store (ldb_kv=0x55d6f8af2a80, name=0x7ff637625675 "ldb_mdb backend", ldb=0x55d6f8cd22b0, options=0x0, _module=0x7ffed481c248) at ../../lib/ldb/ldb_key_value/ldb_kv.c:2166 #13 0x00007ff6376247ba in lmdb_connect (ldb=0x55d6f8cd22b0, url=0x55d6f85d41f0 "mdb:///tmp/foo/private/sam.ldb.d/CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb", flags=64, options=0x0, _module=0x7ffed481c248) at ../../lib/ldb/ldb_mdb/ldb_mdb.c:1143 #14 0x00007ff63bd94d2f in ldb_module_connect_backend (ldb=0x55d6f8cd22b0, url=0x55d6f85d41f0 "mdb:///tmp/foo/private/sam.ldb.d/CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb", options=0x0, backend_module=0x7ffed481c248) at ../../lib/ldb/common/ldb_modules.c:221 #15 0x00007ff6375a4baf in new_partition_from_dn (ldb=0x55d6f8cd22b0, data=0x55d6f858bed0, mem_ctx=0x55d6f8a03cd0, dn=0x55d6f9865450, filename=0x55d6f860b6da "sam.ldb.d/CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb", backend_db_store=0x55d6f9d378e0 "mdb", partition=0x7ffed481c308) at ../../source4/dsdb/samdb/ldb_modules/partition_init.c:257 #16 0x00007ff6375a57b9 in partition_reload_if_required (module=0x55d6f8972d10, data=0x55d6f858bed0, parent=0x0) at ../../source4/dsdb/samdb/ldb_modules/partition_init.c:513 #17 0x00007ff6375a3b04 in partition_read_lock (module=0x55d6f8972d10) at ../../source4/dsdb/samdb/ldb_modules/partition.c:1492 #18 0x00007ff63bd9631e in ldb_next_read_lock (module=0x55d6f8972d10) at ../../lib/ldb/common/ldb_modules.c:662 #19 0x00007ff637484857 in schema_read_lock (module=0x55d6f9377e40) at ../../source4/dsdb/samdb/ldb_modules/schema_load.c:614 #20 0x00007ff63bd9631e in ldb_next_read_lock (module=0x55d6f9377e40) at ../../lib/ldb/common/ldb_modules.c:662 #21 0x00007ff6374b5402 in samba_dsdb_init (module=0x55d6f91c3cd0) at ../../source4/dsdb/samdb/ldb_modules/samba_dsdb.c:483 #22 0x00007ff63bd95283 in ldb_module_init_chain (ldb=0x55d6f8cd22b0, module=0x55d6f91c3cd0) at ../../lib/ldb/common/ldb_modules.c:363 #23 0x00007ff63bd95645 in ldb_load_modules (ldb=0x55d6f8cd22b0, options=0x0) at ../../lib/ldb/common/ldb_modules.c:445 #24 0x00007ff63bd90663 in ldb_connect (ldb=0x55d6f8cd22b0, url=0x7ff6377d98f8 "/tmp/foo/private/sam.ldb.bak-offline", flags=64, options=0x0) at ../../lib/ldb/common/ldb.c:274 #25 0x00007ff63bddb32f in py_ldb_connect (self=0x7ff63778afc0, args=(), Python Exception There is no member named ma_keys.: kwargs=) at ../../lib/ldb/pyldb.c:1235 Deleting the previous samdb instance by setting it to None before opening the backed ldb workaround the problem until we find the real problem here. Signed-off-by: Samuel Cabrero --- python/samba/netcmd/domain_backup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py index 799fd0593e5..aa050aaefb0 100644 --- a/python/samba/netcmd/domain_backup.py +++ b/python/samba/netcmd/domain_backup.py @@ -1137,6 +1137,7 @@ class cmd_domain_backup_offline(samba.netcmd.Command): # Backup secrets, sam.ldb and their downstream files self.backup_secrets(paths.private_dir, lp, logger) self.backup_smb_dbs(paths.private_dir, samdb, lp, logger) + samdb = None # Open the new backed up samdb, flag it as backed up, and write # the next SID so the restore tool can add objects. -- 2.25.1 From 421df3d89555c034a7c9c4dd4f8cc4f8b2cfbe1a Mon Sep 17 00:00:00 2001 From: Joseph Sutton Date: Mon, 22 Mar 2021 11:06:30 +1300 Subject: [PATCH 2/2] netcmd: Fix opening SamDB database for offline backup When opening the backed-up SamDB database, open the top-level database without loading any modules so the backend database files aren't unnecessarily opened. The domain SID is now fetched from the original database rather than from the backup. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14676 Signed-off-by: Joseph Sutton --- python/samba/netcmd/domain_backup.py | 19 +++++++++++++++---- python/samba/ntacls.py | 5 +---- python/samba/tests/ntacls_backup.py | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py index aa050aaefb0..087acd05da6 100644 --- a/python/samba/netcmd/domain_backup.py +++ b/python/samba/netcmd/domain_backup.py @@ -1137,20 +1137,31 @@ class cmd_domain_backup_offline(samba.netcmd.Command): # Backup secrets, sam.ldb and their downstream files self.backup_secrets(paths.private_dir, lp, logger) self.backup_smb_dbs(paths.private_dir, samdb, lp, logger) + + # Get the domain SID so we can later place it in the backup + dom_sid_str = samdb.get_domain_sid() + dom_sid = security.dom_sid(dom_sid_str) + + # Close the original samdb samdb = None # Open the new backed up samdb, flag it as backed up, and write - # the next SID so the restore tool can add objects. + # the next SID so the restore tool can add objects. We use + # options=["modules:"] here to prevent any modules from loading. # WARNING: Don't change this code unless you know what you're doing. # Writing to a .bak file only works because the DN being # written to happens to be top level. - samdb = SamDB(url=paths.samdb + self.backup_ext, - session_info=system_session(), lp=lp) + samdb = Ldb(url=paths.samdb + self.backup_ext, + session_info=system_session(), lp=lp, + options=["modules:"], flags=ldb.FLG_DONT_CREATE_DB) time_str = get_timestamp() add_backup_marker(samdb, "backupDate", time_str) add_backup_marker(samdb, "sidForRestore", sid) add_backup_marker(samdb, "backupType", "offline") + # Close the backed up samdb + samdb = None + # Now handle all the LDB and TDB files that are not linked to # anything else. Use transactions for LDBs. for path in all_files: @@ -1176,7 +1187,7 @@ class cmd_domain_backup_offline(samba.netcmd.Command): logger.info('running offline ntacl backup of sysvol') sysvol_tar_fn = 'sysvol.tar.gz' sysvol_tar = os.path.join(temp_tar_dir, sysvol_tar_fn) - backup_offline(paths.sysvol, sysvol_tar, samdb, paths.smbconf) + backup_offline(paths.sysvol, sysvol_tar, paths.smbconf, dom_sid) tar.add(sysvol_tar, sysvol_tar_fn) os.remove(sysvol_tar) diff --git a/python/samba/ntacls.py b/python/samba/ntacls.py index 4f189965d05..1bcb755c952 100644 --- a/python/samba/ntacls.py +++ b/python/samba/ntacls.py @@ -551,7 +551,7 @@ def backup_online(smb_conn, dest_tarfile_path, dom_sid): shutil.rmtree(localdir) -def backup_offline(src_service_path, dest_tarfile_path, samdb_conn, smb_conf_path): +def backup_offline(src_service_path, dest_tarfile_path, smb_conf_path, dom_sid): """ Backup files and ntacls to a tarfile for a service """ @@ -559,9 +559,6 @@ def backup_offline(src_service_path, dest_tarfile_path, samdb_conn, smb_conf_pat tempdir = tempfile.mkdtemp() session_info = system_session_unix() - dom_sid_str = samdb_conn.get_domain_sid() - dom_sid = security.dom_sid(dom_sid_str) - ntacls_helper = NtaclsHelper(service, smb_conf_path, dom_sid) for dirpath, dirnames, filenames in os.walk(src_service_path): diff --git a/python/samba/tests/ntacls_backup.py b/python/samba/tests/ntacls_backup.py index 265208805b7..03a9c0b22d8 100644 --- a/python/samba/tests/ntacls_backup.py +++ b/python/samba/tests/ntacls_backup.py @@ -184,7 +184,7 @@ class NtaclsBackupRestoreTests(SmbdBaseTests): """ ntacls.backup_offline( self.service_root, self.tarfile_path, - self.samdb_conn, self.smb_conf_path) + self.smb_conf_path, self.dom_sid) self._check_tarfile() self.smb_helper.delete_tree() -- 2.25.1