samba-tool: Give better error information when the 'domain backup restore' fails...
authorAndrew Bartlett <abartlet@samba.org>
Fri, 13 Nov 2020 02:26:07 +0000 (15:26 +1300)
committerKarolin Seeger <kseeger@samba.org>
Tue, 13 Jul 2021 12:31:15 +0000 (12:31 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14575

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Autobuild-User(master): Gary Lockyer <gary@samba.org>
Autobuild-Date(master): Thu Nov 26 21:15:40 UTC 2020 on sn-devel-184

(cherry picked from commit 8ad82ae66157c893a2b84d353ec4d9feb4815ede)

python/samba/netcmd/domain_backup.py

index 25dba78fa03876d6485deedbbd71931eff33a664..fff39fcbc2a935427f877bcb858424530a478899 100644 (file)
@@ -27,6 +27,7 @@ import tdb
 import samba.getopt as options
 from samba.samdb import SamDB, get_default_backend_store
 import ldb
+from ldb import LdbError
 from samba.samba3 import libsmb_samba_internal as libsmb
 from samba.samba3 import param as s3param
 from samba.ntacls import backup_online, backup_restore, backup_offline
@@ -576,7 +577,49 @@ class cmd_domain_backup_restore(cmd_fsmo_seize):
                            attrs=['sidForRestore'])
         sid = res[0].get('sidForRestore')[0]
         logger.info('Creating account with SID: ' + str(sid))
-        ctx.join_add_objects(specified_sid=dom_sid(str(sid)))
+        try:
+            ctx.join_add_objects(specified_sid=dom_sid(str(sid)))
+        except LdbError as e:
+            (enum, emsg) = e.args
+            if enum != ldb.ERR_CONSTRAINT_VIOLATION:
+                raise
+
+            dup_res = []
+            try:
+                dup_res = samdb.search(base=ldb.Dn(samdb, "<SID=%s>" % sid),
+                                       scope=ldb.SCOPE_BASE,
+                                       attrs=['objectGUID'],
+                                       controls=["show_deleted:0",
+                                                 "show_recycled:0"])
+            except LdbError as dup_e:
+                if enum != ldb.ERR_NO_SUCH_OBJECT:
+                    raise e
+
+            if (len(dup_res) != 1):
+                raise e
+
+            objectguid = samdb.schema_format_value("objectGUID",
+                                                       dup_res[0]["objectGUID"][0])
+            objectguid = objectguid.decode('utf-8')
+            logger.error("The RID Pool on the source DC for the backup in %s "
+                         "may be corrupt "
+                         "or in conflict with SIDs already allocated "
+                         "in the domain. " % backup_file)
+            logger.error("Running 'samba-tool dbcheck' on the source "
+                         "DC (and obtaining a new backup) may correct the issue.")
+            logger.error("Alternatively please obtain a new backup "
+                         "against a different DC.")
+            logger.error("The SID we wish to use (%s) is recorded in "
+                         "@SAMBA_DSDB as the sidForRestore attribute."
+                         % sid)
+
+            raise CommandError("Domain restore failed because there "
+                               "is already an existing object (%s) "
+                               "with SID %s and objectGUID %s.  "
+                               "This conflicts with "
+                               "the new DC account we want to add "
+                               "for the restored domain.   " % (
+                                dup_res[0].dn, sid, objectguid))
 
         m = ldb.Message()
         m.dn = ldb.Dn(samdb, '@ROOTDSE')