def join_clone(logger=None, server=None, creds=None, lp=None,
targetdir=None, domain=None, include_secrets=False,
- dns_backend="NONE"):
+ dns_backend="NONE", backend_store=None):
"""Creates a local clone of a remote DC."""
ctx = DCCloneContext(logger, server, creds, lp, targetdir=targetdir,
domain=domain, dns_backend=dns_backend,
- include_secrets=include_secrets)
+ include_secrets=include_secrets,
+ backend_store=backend_store)
lp.set("workgroup", ctx.domain_name)
logger.info("workgroup is %s" % ctx.domain_name)
def __init__(ctx, logger=None, server=None, creds=None, lp=None,
targetdir=None, domain=None, dns_backend=None,
- include_secrets=False):
+ include_secrets=False, backend_store=None):
super(DCCloneContext, ctx).__init__(logger, server, creds, lp,
targetdir=targetdir, domain=domain,
- dns_backend=dns_backend)
+ dns_backend=dns_backend,
+ backend_store=backend_store)
# As we don't want to create or delete these DNs, we set them to None
ctx.server_dn = None
def __init__(ctx, new_base_dn, new_domain_name, new_realm, logger=None,
server=None, creds=None, lp=None, targetdir=None, domain=None,
- dns_backend=None, include_secrets=True):
+ dns_backend=None, include_secrets=True, backend_store=None):
super(DCCloneAndRenameContext, ctx).__init__(logger, server, creds, lp,
targetdir=targetdir,
domain=domain,
dns_backend=dns_backend,
- include_secrets=include_secrets)
+ include_secrets=include_secrets,
+ backend_store=backend_store)
# store the new DN (etc) that we want the cloned DB to use
ctx.new_base_dn = new_base_dn
ctx.new_domain_name = new_domain_name
configdn=ctx.rename_dn(ctx.config_dn),
domain=ctx.new_domain_name, domainsid=ctx.domsid,
serverrole="active directory domain controller",
- dns_backend=ctx.dns_backend)
+ dns_backend=ctx.dns_backend,
+ backend_store=ctx.backend_store)
print("Provision OK for renamed domain DN %s" % presult.domaindn)
ctx.local_samdb = presult.samdb
import samba
import tdb
import samba.getopt as options
-from samba.samdb import SamDB
+from samba.samdb import SamDB, get_default_backend_store
import ldb
from samba import smb
from samba.ntacls import backup_online, backup_restore, backup_offline
Option("--targetdir", type=str,
help="Directory to write the backup file to"),
Option("--no-secrets", action="store_true", default=False,
- help="Exclude secret values from the backup created")
+ help="Exclude secret values from the backup created"),
+ Option("--backend-store", type="choice", metavar="BACKENDSTORE",
+ choices=["tdb", "mdb"],
+ help="Specify the database backend to be used "
+ "(default is %s)" % get_default_backend_store()),
]
def run(self, sambaopts=None, credopts=None, server=None, targetdir=None,
- no_secrets=False):
+ no_secrets=False, backend_store=None):
logger = self.get_logger()
logger.setLevel(logging.DEBUG)
include_secrets = not no_secrets
ctx = join_clone(logger=logger, creds=creds, lp=lp,
include_secrets=include_secrets, server=server,
- dns_backend='SAMBA_INTERNAL', targetdir=tmpdir)
+ dns_backend='SAMBA_INTERNAL', targetdir=tmpdir,
+ backend_store=backend_store)
# get the paths used for the clone, then drop the old samdb connection
paths = ctx.paths
Option("--keep-dns-realm", action="store_true", default=False,
help="Retain the DNS entries for the old realm in the backup"),
Option("--no-secrets", action="store_true", default=False,
- help="Exclude secret values from the backup created")
+ help="Exclude secret values from the backup created"),
+ Option("--backend-store", type="choice", metavar="BACKENDSTORE",
+ choices=["tdb", "mdb"],
+ help="Specify the database backend to be used "
+ "(default is %s)" % get_default_backend_store()),
]
takes_args = ["new_domain_name", "new_dns_realm"]
def run(self, new_domain_name, new_dns_realm, sambaopts=None,
credopts=None, server=None, targetdir=None, keep_dns_realm=False,
- no_secrets=False):
+ no_secrets=False, backend_store=None):
logger = self.get_logger()
logger.setLevel(logging.INFO)
creds=creds, lp=lp,
include_secrets=include_secrets,
dns_backend='SAMBA_INTERNAL',
- server=server, targetdir=tmpdir)
+ server=server, targetdir=tmpdir,
+ backend_store=backend_store)
# sanity-check we're not "renaming" the domain to the same values
old_domain = ctx.domain_name
self.backup_markers = ['sidForRestore', 'backupDate']
self.restore_domain = os.environ["DOMAIN"]
self.restore_realm = os.environ["REALM"]
+ self.backend = None
+
+ def use_backend(self, backend):
+ """Explicitly set the DB backend that the backup should use"""
+ self.backend = backend
+ self.base_cmd += ["--backend-store=" + backend]
def assert_partitions_present(self, samdb):
"""Asserts all expected partitions are present in the backup samdb"""
self.assertIsNone(res[0].get('repsFrom'))
self.assertIsNone(res[0].get('repsTo'))
+ # check the DB is using the backend we supplied
+ if self.backend:
+ res = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE,
+ attrs=["backendStore"])
+ backend = str(res[0].get("backendStore"))
+ self.assertEqual(backend, self.backend)
+
# check the restored DB has the expected partitions/DC/FSMO roles
self.assert_partitions_present(samdb)
self.assert_dcs_present(samdb, self.new_server, expected_count=1)
self._test_backup_untar()
def test_backup_restore(self):
+ self.use_backend("tdb")
self._test_backup_restore()
def test_backup_restore_with_conf(self):
+ self.use_backend("mdb")
self._test_backup_restore_with_conf()
def test_backup_restore_no_secrets(self):
+ self.use_backend("tdb")
self._test_backup_restore_no_secrets()
def test_backup_restore_into_site(self):
+ self.use_backend("mdb")
self._test_backup_restore_into_site()
self._test_backup_untar()
def test_backup_restore(self):
+ self.use_backend("mdb")
self._test_backup_restore()
def test_backup_restore_with_conf(self):
+ self.use_backend("tdb")
self._test_backup_restore_with_conf()
def test_backup_restore_no_secrets(self):
+ self.use_backend("mdb")
self._test_backup_restore_no_secrets()
def test_backup_restore_into_site(self):
+ self.use_backend("tdb")
self._test_backup_restore_into_site()
def test_backup_invalid_args(self):