summaryrefslogtreecommitdiff
path: root/source4/scripting/python
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2011-12-12 10:53:55 +1100
committerAmitay Isaacs <amitay@samba.org>2011-12-13 03:28:03 +0100
commit21424056bb4ad914871b009aee3a7567a3efdec0 (patch)
tree62551d1fe64d18b7e42b99ac59434b3245e3cccb /source4/scripting/python
parent7f50890cd67fed69b049bde5328c4f662bab1806 (diff)
downloadsamba-21424056bb4ad914871b009aee3a7567a3efdec0.tar.gz
samba-21424056bb4ad914871b009aee3a7567a3efdec0.tar.bz2
samba-21424056bb4ad914871b009aee3a7567a3efdec0.zip
s4-provision: Do not guess partition file names, use @PARTITION record
This is to avoid duplicating the logic of generating partition file names. (partition file names are encoded partially as per RFC1738). Also, use tdb_copy() instead of filesystem copy function to copy database files, which guarantees correct database copy. Autobuild-User: Amitay Isaacs <amitay@samba.org> Autobuild-Date: Tue Dec 13 03:28:03 CET 2011 on sn-devel-104
Diffstat (limited to 'source4/scripting/python')
-rw-r--r--source4/scripting/python/samba/provision/sambadns.py135
1 files changed, 76 insertions, 59 deletions
diff --git a/source4/scripting/python/samba/provision/sambadns.py b/source4/scripting/python/samba/provision/sambadns.py
index 8ccb054785..335ea8d965 100644
--- a/source4/scripting/python/samba/provision/sambadns.py
+++ b/source4/scripting/python/samba/provision/sambadns.py
@@ -596,66 +596,88 @@ def create_zone_file(lp, logger, paths, targetdir, dnsdomain,
if targetdir is None:
os.system(rndc + " unfreeze " + lp.get("realm"))
+def tdb_copy(logger, file1, file2):
+ """Copy tdb file using tdbbackup utility and rename it
+ """
+ # Find the location of tdbbackup tool
+ dirs = ["bin", samba.param.bin_dir()]
+ for d in dirs:
+ toolpath = os.path.join(d, "tdbbackup")
+ if os.path.exists(toolpath):
+ break
+ status = os.system("%s -s '.dns' %s" % (toolpath, file1))
+ if status == 0:
+ os.rename("%s.dns" % file1, file2)
+ else:
+ raise Exception("Error copying %s" % file1)
-def create_samdb_copy(logger, paths, names, domainsid, domainguid):
+def create_samdb_copy(samdb, logger, paths, names, domainsid, domainguid):
"""Create a copy of samdb and give write permissions to named for dns partitions
"""
private_dir = paths.private_dir
samldb_dir = os.path.join(private_dir, "sam.ldb.d")
dns_dir = os.path.dirname(paths.dns)
dns_samldb_dir = os.path.join(dns_dir, "sam.ldb.d")
- domainpart_file = "%s.ldb" % names.domaindn.upper()
- configpart_file = "%s.ldb" % names.configdn.upper()
- schemapart_file = "%s.ldb" % names.schemadn.upper()
- domainzone_file = "DC=DOMAINDNSZONES,%s.ldb" % names.domaindn.upper()
- forestzone_file = "DC=FORESTDNSZONES,%s.ldb" % names.rootdn.upper()
- metadata_file = "metadata.tdb"
- # Copy config, schema partitions, create empty domain partition
+ # Find the partitions and corresponding filenames
+ partfile = {}
+ res = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE, attrs=["partition"])
+ for tmp in res[0]["partition"]:
+ (nc, fname) = tmp.split(':')
+ partfile[nc.upper()] = fname
+
+ # Create empty domain partition
+ domaindn = names.domaindn.upper()
+ domainpart_file = os.path.join(dns_dir, partfile[domaindn])
try:
- shutil.copyfile(os.path.join(private_dir, "sam.ldb"),
- os.path.join(dns_dir, "sam.ldb"))
os.mkdir(dns_samldb_dir)
- file(os.path.join(dns_samldb_dir, domainpart_file), 'w').close()
- shutil.copyfile(os.path.join(samldb_dir, configpart_file),
- os.path.join(dns_samldb_dir, configpart_file))
- shutil.copyfile(os.path.join(samldb_dir, schemapart_file),
- os.path.join(dns_samldb_dir, schemapart_file))
+ file(domainpart_file, 'w').close()
+
+ # Fill the basedn and @OPTION records in domain partition
+ dom_ldb = samba.Ldb(domainpart_file)
+ domainguid_line = "objectGUID: %s\n-" % domainguid
+ descr = b64encode(get_domain_descriptor(domainsid))
+ setup_add_ldif(dom_ldb, setup_path("provision_basedn.ldif"), {
+ "DOMAINDN" : names.domaindn,
+ "DOMAINGUID" : domainguid_line,
+ "DOMAINSID" : str(domainsid),
+ "DESCRIPTOR" : descr})
+ setup_add_ldif(dom_ldb, setup_path("provision_basedn_options.ldif"), None)
except:
logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
raise
+ del partfile[domaindn]
- # Link metadata and dns partitions
+ # Link dns partitions and metadata
+ domainzonedn = "DC=DOMAINDNSZONES,%s" % names.domaindn.upper()
+ forestzonedn = "DC=FORESTDNSZONES,%s" % names.rootdn.upper()
+ domainzone_file = partfile[domainzonedn]
+ forestzone_file = partfile[forestzonedn]
+ metadata_file = "metadata.tdb"
try:
os.link(os.path.join(samldb_dir, metadata_file),
os.path.join(dns_samldb_dir, metadata_file))
- os.link(os.path.join(samldb_dir, domainzone_file),
- os.path.join(dns_samldb_dir, domainzone_file))
- os.link(os.path.join(samldb_dir, forestzone_file),
- os.path.join(dns_samldb_dir, forestzone_file))
- except OSError, e:
- try:
- os.symlink(os.path.join(samldb_dir, metadata_file),
- os.path.join(dns_samldb_dir, metadata_file))
- os.symlink(os.path.join(samldb_dir, domainzone_file),
- os.path.join(dns_samldb_dir, domainzone_file))
- os.symlink(os.path.join(samldb_dir, forestzone_file),
- os.path.join(dns_samldb_dir, forestzone_file))
- except OSError, e:
- logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
- raise
-
- # Fill the basedn and @OPTION records in domain partition
+ os.link(os.path.join(private_dir, domainzone_file),
+ os.path.join(dns_dir, domainzone_file))
+ os.link(os.path.join(private_dir, forestzone_file),
+ os.path.join(dns_dir, forestzone_file))
+ except OSError:
+ logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
+ raise
+ del partfile[domainzonedn]
+ del partfile[forestzonedn]
+
+ # Copy root, config, schema partitions (and any other if any)
+ # Since samdb is open in the current process, copy them in a child process
try:
- ldb = samba.Ldb(os.path.join(dns_samldb_dir, domainpart_file))
- domainguid_line = "objectGUID: %s\n-" % domainguid
- descr = b64encode(get_domain_descriptor(domainsid))
- setup_add_ldif(ldb, setup_path("provision_basedn.ldif"), {
- "DOMAINDN" : names.domaindn,
- "DOMAINGUID" : domainguid_line,
- "DOMAINSID" : str(domainsid),
- "DESCRIPTOR" : descr})
- setup_add_ldif(ldb, setup_path("provision_basedn_options.ldif"), None)
+ tdb_copy(logger,
+ os.path.join(private_dir, "sam.ldb"),
+ os.path.join(dns_dir, "sam.ldb"))
+ for nc in partfile:
+ pfile = partfile[nc]
+ tdb_copy(logger,
+ os.path.join(private_dir, pfile),
+ os.path.join(dns_dir, pfile))
except:
logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
raise
@@ -665,22 +687,17 @@ def create_samdb_copy(logger, paths, names, domainsid, domainguid):
try:
os.chown(samldb_dir, -1, paths.bind_gid)
os.chmod(samldb_dir, 0750)
- os.chown(os.path.join(dns_dir, "sam.ldb"), -1, paths.bind_gid)
- os.chmod(os.path.join(dns_dir, "sam.ldb"), 0660)
- os.chown(dns_samldb_dir, -1, paths.bind_gid)
- os.chmod(dns_samldb_dir, 0770)
- os.chown(os.path.join(dns_samldb_dir, domainpart_file), -1, paths.bind_gid)
- os.chmod(os.path.join(dns_samldb_dir, domainpart_file), 0660)
- os.chown(os.path.join(dns_samldb_dir, configpart_file), -1, paths.bind_gid)
- os.chmod(os.path.join(dns_samldb_dir, configpart_file), 0660)
- os.chown(os.path.join(dns_samldb_dir, schemapart_file), -1, paths.bind_gid)
- os.chmod(os.path.join(dns_samldb_dir, schemapart_file), 0660)
- os.chown(os.path.join(samldb_dir, metadata_file), -1, paths.bind_gid)
- os.chmod(os.path.join(samldb_dir, metadata_file), 0660)
- os.chown(os.path.join(samldb_dir, domainzone_file), -1, paths.bind_gid)
- os.chmod(os.path.join(samldb_dir, domainzone_file), 0660)
- os.chown(os.path.join(samldb_dir, forestzone_file), -1, paths.bind_gid)
- os.chmod(os.path.join(samldb_dir, forestzone_file), 0660)
+
+ for dirname, dirs, files in os.walk(dns_dir):
+ for d in dirs:
+ dpath = os.path.join(dirname, d)
+ os.chown(dpath, -1, paths.bind_gid)
+ os.chmod(dpath, 0770)
+ for f in files:
+ if f.endswith('.ldb') or f.endswith('.tdb'):
+ fpath = os.path.join(dirname, f)
+ os.chown(fpath, -1, paths.bind_gid)
+ os.chmod(fpath, 0660)
except OSError:
if not os.environ.has_key('SAMBA_SELFTEST'):
logger.error("Failed to set permissions to sam.ldb* files, fix manually")
@@ -894,7 +911,7 @@ def setup_ad_dns(samdb, secretsdb, domainsid, names, paths, lp, logger, dns_back
domainguid=domainguid, ntdsguid=names.ntdsguid)
if dns_backend == "BIND9_DLZ" and os_level >= DS_DOMAIN_FUNCTION_2003:
- create_samdb_copy(logger, paths, names, domainsid, domainguid)
+ create_samdb_copy(samdb, logger, paths, names, domainsid, domainguid)
create_named_conf(paths, realm=names.realm,
dnsdomain=names.dnsdomain, dns_backend=dns_backend)