The branch, master has been updated
via 55e448f s4 provision/dns: Move DNS-related setup to sambadns module
via eeb370f s4 provision/dns: Move secretsdb_setup_dns to the AD DNS
specific setup
from e308927 s3:selftest: improve logging in the registry upgrade test
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 55e448fe2d1ce63f1262bb02f8e0dd36e916ca32
Author: Kai Blin <[email protected]>
Date: Fri Oct 21 11:56:10 2011 +0200
s4 provision/dns: Move DNS-related setup to sambadns module
Autobuild-User: Kai Blin <[email protected]>
Autobuild-Date: Fri Nov 4 09:15:54 CET 2011 on sn-devel-104
commit eeb370f77a2cdbafe0b87a2af2299a8c5cdfcf6f
Author: Kai Blin <[email protected]>
Date: Fri Oct 21 11:04:07 2011 +0200
s4 provision/dns: Move secretsdb_setup_dns to the AD DNS specific setup
-----------------------------------------------------------------------
Summary of changes:
.../scripting/python/samba/provision/__init__.py | 216 +-----------------
.../scripting/python/samba/provision/sambadns.py | 250 +++++++++++++++++++-
2 files changed, 252 insertions(+), 214 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/scripting/python/samba/provision/__init__.py
b/source4/scripting/python/samba/provision/__init__.py
index a44bb8e..a8a5a57 100644
--- a/source4/scripting/python/samba/provision/__init__.py
+++ b/source4/scripting/python/samba/provision/__init__.py
@@ -74,7 +74,7 @@ from samba.provision.backend import (
LDBBackend,
OpenLDAPBackend,
)
-from samba.provision.sambadns import setup_ad_dns
+from samba.provision.sambadns import setup_ad_dns, create_dns_update_list
import samba.param
import samba.registry
@@ -922,29 +922,6 @@ def secretsdb_self_join(secretsdb, domain,
secretsdb.add(msg)
-def secretsdb_setup_dns(secretsdb, names, private_dir, realm,
- dnsdomain, dns_keytab_path, dnspass):
- """Add DNS specific bits to a secrets database.
-
- :param secretsdb: Ldb Handle to the secrets database
- :param machinepass: Machine password
- """
- try:
- os.unlink(os.path.join(private_dir, dns_keytab_path))
- except OSError:
- pass
-
- setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {
- "REALM": realm,
- "DNSDOMAIN": dnsdomain,
- "DNS_KEYTAB": dns_keytab_path,
- "DNSPASS_B64": b64encode(dnspass),
- "HOSTNAME": names.hostname,
- "DNSNAME" : '%s.%s' % (
- names.netbiosname.lower(), names.dnsdomain.lower())
- })
-
-
def setup_secretsdb(paths, session_info, backend_credentials, lp):
"""Setup the secrets database.
@@ -1616,40 +1593,15 @@ def provision_fill(samdb, secrets_ldb, logger, names,
paths,
# It might be that this attribute does not exist in this schema
raise
- secretsdb_setup_dns(secrets_ldb, names,
- paths.private_dir, realm=names.realm,
- dnsdomain=names.dnsdomain,
- dns_keytab_path=paths.dns_keytab, dnspass=dnspass)
-
- setup_ad_dns(samdb, names, logger, hostip=hostip, hostip6=hostip6,
- dns_backend=dns_backend, os_level=dom_for_fun_level)
+ setup_ad_dns(samdb, secrets_ldb, names, paths, lp, logger,
+ hostip=hostip, hostip6=hostip6, dns_backend=dns_backend,
+ dnspass=dnspass, os_level=dom_for_fun_level,
+ targetdir=targetdir, site=DEFAULTSITE)
domainguid = samdb.searchone(basedn=samdb.get_default_basedn(),
attribute="objectGUID")
assert isinstance(domainguid, str)
- create_dns_dir(logger, paths)
-
- # Only make a zone file on the first DC, it should be
- # replicated with DNS replication
- if dns_backend == "BIND9_FLATFILE":
- create_zone_file(lp, logger, paths, targetdir,
- dnsdomain=names.dnsdomain, hostip=hostip,
hostip6=hostip6,
- hostname=names.hostname, realm=names.realm,
- domainguid=domainguid, ntdsguid=names.ntdsguid)
-
- create_named_conf(paths, realm=names.realm,
- dnsdomain=names.dnsdomain, dns_backend=dns_backend)
-
- create_named_txt(paths.namedtxt,
- realm=names.realm, dnsdomain=names.dnsdomain,
- dnsname = "%s.%s" % (names.hostname, names.dnsdomain),
- private_dir=paths.private_dir,
- keytab_name=paths.dns_keytab)
- logger.info("See %s for an example configuration include file for
BIND", paths.namedconf)
- logger.info("and %s for further documentation required for secure DNS "
- "updates", paths.namedtxt)
-
lastProvisionUSNs = get_last_provision_usn(samdb)
maxUSN = get_max_usn(samdb, str(names.rootdn))
if lastProvisionUSNs is not None:
@@ -2004,164 +1956,6 @@ def create_phpldapadmin_config(path, ldapi_uri):
{"S4_LDAPI_URI": ldapi_uri})
-def create_dns_dir(logger, paths):
- """Write out a DNS zone file, from the info in the current database.
-
- :param logger: Logger object
- :param paths: paths object
- """
- dns_dir = os.path.dirname(paths.dns)
-
- try:
- shutil.rmtree(dns_dir, True)
- except OSError:
- pass
-
- os.mkdir(dns_dir, 0770)
-
- if paths.bind_gid is not None:
- try:
- os.chown(dns_dir, -1, paths.bind_gid)
- # chmod needed to cope with umask
- os.chmod(dns_dir, 0770)
- except OSError:
- if not os.environ.has_key('SAMBA_SELFTEST'):
- logger.error("Failed to chown %s to bind gid %u" % (
- dns_dir, paths.bind_gid))
-
-
-def create_zone_file(lp, logger, paths, targetdir, dnsdomain,
- hostip, hostip6, hostname, realm, domainguid,
- ntdsguid):
- """Write out a DNS zone file, from the info in the current database.
-
- :param paths: paths object
- :param dnsdomain: DNS Domain name
- :param domaindn: DN of the Domain
- :param hostip: Local IPv4 IP
- :param hostip6: Local IPv6 IP
- :param hostname: Local hostname
- :param realm: Realm name
- :param domainguid: GUID of the domain.
- :param ntdsguid: GUID of the hosts nTDSDSA record.
- """
- assert isinstance(domainguid, str)
-
- if hostip6 is not None:
- hostip6_base_line = " IN AAAA " + hostip6
- hostip6_host_line = hostname + " IN AAAA " + hostip6
- gc_msdcs_ip6_line = "gc._msdcs IN AAAA " + hostip6
- else:
- hostip6_base_line = ""
- hostip6_host_line = ""
- gc_msdcs_ip6_line = ""
-
- if hostip is not None:
- hostip_base_line = " IN A " + hostip
- hostip_host_line = hostname + " IN A " + hostip
- gc_msdcs_ip_line = "gc._msdcs IN A " + hostip
- else:
- hostip_base_line = ""
- hostip_host_line = ""
- gc_msdcs_ip_line = ""
-
- # we need to freeze the zone while we update the contents
- if targetdir is None:
- rndc = ' '.join(lp.get("rndc command"))
- os.system(rndc + " freeze " + lp.get("realm"))
-
- setup_file(setup_path("provision.zone"), paths.dns, {
- "HOSTNAME": hostname,
- "DNSDOMAIN": dnsdomain,
- "REALM": realm,
- "HOSTIP_BASE_LINE": hostip_base_line,
- "HOSTIP_HOST_LINE": hostip_host_line,
- "DOMAINGUID": domainguid,
- "DATESTRING": time.strftime("%Y%m%d%H"),
- "DEFAULTSITE": DEFAULTSITE,
- "NTDSGUID": ntdsguid,
- "HOSTIP6_BASE_LINE": hostip6_base_line,
- "HOSTIP6_HOST_LINE": hostip6_host_line,
- "GC_MSDCS_IP_LINE": gc_msdcs_ip_line,
- "GC_MSDCS_IP6_LINE": gc_msdcs_ip6_line,
- })
-
- if paths.bind_gid is not None:
- try:
- os.chown(paths.dns, -1, paths.bind_gid)
- # chmod needed to cope with umask
- os.chmod(paths.dns, 0664)
- except OSError:
- if not os.environ.has_key('SAMBA_SELFTEST'):
- logger.error("Failed to chown %s to bind gid %u" % (
- paths.dns, paths.bind_gid))
-
- if targetdir is None:
- os.system(rndc + " unfreeze " + lp.get("realm"))
-
-
-def create_dns_update_list(lp, logger, paths):
- """Write out a dns_update_list file"""
- # note that we use no variable substitution on this file
- # the substitution is done at runtime by samba_dnsupdate, samba_spnupdate
- setup_file(setup_path("dns_update_list"), paths.dns_update_list, None)
- setup_file(setup_path("spn_update_list"), paths.spn_update_list, None)
-
-
-def create_named_conf(paths, realm, dnsdomain, dns_backend):
- """Write out a file containing zone statements suitable for inclusion in a
- named.conf file (including GSS-TSIG configuration).
-
- :param paths: all paths
- :param realm: Realm name
- :param dnsdomain: DNS Domain name
- :param dns_backend: DNS backend type
- :param keytab_name: File name of DNS keytab file
- """
-
- if dns_backend == "BIND9_FLATFILE":
- setup_file(setup_path("named.conf"), paths.namedconf, {
- "DNSDOMAIN": dnsdomain,
- "REALM": realm,
- "ZONE_FILE": paths.dns,
- "REALM_WC": "*." + ".".join(realm.split(".")[1:]),
- "NAMED_CONF": paths.namedconf,
- "NAMED_CONF_UPDATE": paths.namedconf_update
- })
-
- setup_file(setup_path("named.conf.update"), paths.namedconf_update)
-
- elif dns_backend == "BIND9_DLZ":
- dlz_module_path = os.path.join(samba.param.modules_dir(),
- "bind9/dlz_bind9.so")
- setup_file(setup_path("named.conf.dlz"), paths.namedconf, {
- "NAMED_CONF": paths.namedconf,
- "BIND9_DLZ_MODULE": dlz_module_path,
- })
-
-
-
-def create_named_txt(path, realm, dnsdomain, dnsname, private_dir,
- keytab_name):
- """Write out a file containing zone statements suitable for inclusion in a
- named.conf file (including GSS-TSIG configuration).
-
- :param path: Path of the new named.conf file.
- :param realm: Realm name
- :param dnsdomain: DNS Domain name
- :param private_dir: Path to private directory
- :param keytab_name: File name of DNS keytab file
- """
- setup_file(setup_path("named.txt"), path, {
- "DNSDOMAIN": dnsdomain,
- "DNSNAME" : dnsname,
- "REALM": realm,
- "DNS_KEYTAB": keytab_name,
- "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
- "PRIVATE_DIR": private_dir
- })
-
-
def create_krb5_conf(path, dnsdomain, hostname, realm):
"""Write out a file containing zone statements suitable for inclusion in a
named.conf file (including GSS-TSIG configuration).
diff --git a/source4/scripting/python/samba/provision/sambadns.py
b/source4/scripting/python/samba/provision/sambadns.py
index 6e58f07..c45e04f 100644
--- a/source4/scripting/python/samba/provision/sambadns.py
+++ b/source4/scripting/python/samba/provision/sambadns.py
@@ -22,10 +22,12 @@
import os
import uuid
+import shutil
+import time
import ldb
import samba
from samba.ndr import ndr_pack, ndr_unpack
-from samba import read_and_sub_file
+from samba import read_and_sub_file, setup_file
from samba.dcerpc import dnsp, misc
from samba.dsdb import (
DS_DOMAIN_FUNCTION_2000,
@@ -33,6 +35,7 @@ from samba.dsdb import (
DS_DOMAIN_FUNCTION_2008,
DS_DOMAIN_FUNCTION_2008_R2
)
+from base64 import b64encode
def add_ldif(ldb, ldif_file, subst_vars, controls=["relax:0"]):
@@ -45,6 +48,30 @@ def modify_ldif(ldb, ldif_file, subst_vars,
controls=["relax:0"]):
data = read_and_sub_file(ldif_file_path, subst_vars)
ldb.modify_ldif(data, controls)
+def setup_ldb(ldb, ldif_path, subst_vars):
+ """Import a LDIF a file into a LDB handle, optionally substituting
+ variables.
+
+ :note: Either all LDIF data will be added or none (using transactions).
+
+ :param ldb: LDB file to import into.
+ :param ldif_path: Path to the LDIF file.
+ :param subst_vars: Dictionary with substitution variables.
+ """
+ assert ldb is not None
+ ldb.transaction_start()
+ try:
+ add_ldif(ldb, ldif_path, subst_vars)
+ except Exception:
+ ldb.transaction_cancel()
+ raise
+ else:
+ ldb.transaction_commit()
+
+def setup_path(file):
+ """Return an absolute path to the provision tempate file specified by
file"""
+ return os.path.join(samba.param.setup_dir(), file)
+
def get_domainguid(samdb, domaindn):
res = samdb.search(base=domaindn, scope=ldb.SCOPE_BASE,
attrs=["objectGUID"])
domainguid = str(ndr_unpack(misc.GUID, res[0]["objectGUID"][0]))
@@ -450,6 +477,188 @@ def add_dc_msdcs_records(samdb, forestdn, prefix, site,
dnsforest, hostname,
add_cname_record(samdb, forest_container_dn, "DC=%s" % ntdsguid,
fqdn_hostname)
+def secretsdb_setup_dns(secretsdb, names, private_dir, realm,
+ dnsdomain, dns_keytab_path, dnspass):
+ """Add DNS specific bits to a secrets database.
+
+ :param secretsdb: Ldb Handle to the secrets database
+ :param names: Names shortcut
+ :param machinepass: Machine password
+ """
+ try:
+ os.unlink(os.path.join(private_dir, dns_keytab_path))
+ except OSError:
+ pass
+
+ setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {
+ "REALM": realm,
+ "DNSDOMAIN": dnsdomain,
+ "DNS_KEYTAB": dns_keytab_path,
+ "DNSPASS_B64": b64encode(dnspass),
+ "HOSTNAME": names.hostname,
+ "DNSNAME" : '%s.%s' % (
+ names.netbiosname.lower(), names.dnsdomain.lower())
+ })
+
+
+def create_dns_dir(logger, paths):
+ """Write out a DNS zone file, from the info in the current database.
+
+ :param logger: Logger object
+ :param paths: paths object
+ """
+ dns_dir = os.path.dirname(paths.dns)
+
+ try:
+ shutil.rmtree(dns_dir, True)
+ except OSError:
+ pass
+
+ os.mkdir(dns_dir, 0770)
+
+ if paths.bind_gid is not None:
+ try:
+ os.chown(dns_dir, -1, paths.bind_gid)
+ # chmod needed to cope with umask
+ os.chmod(dns_dir, 0770)
+ except OSError:
+ if not os.environ.has_key('SAMBA_SELFTEST'):
+ logger.error("Failed to chown %s to bind gid %u" % (
+ dns_dir, paths.bind_gid))
+
+
+def create_zone_file(lp, logger, paths, targetdir, dnsdomain,
+ hostip, hostip6, hostname, realm, domainguid,
+ ntdsguid, site):
+ """Write out a DNS zone file, from the info in the current database.
+
+ :param paths: paths object
+ :param dnsdomain: DNS Domain name
+ :param domaindn: DN of the Domain
+ :param hostip: Local IPv4 IP
+ :param hostip6: Local IPv6 IP
+ :param hostname: Local hostname
+ :param realm: Realm name
+ :param domainguid: GUID of the domain.
+ :param ntdsguid: GUID of the hosts nTDSDSA record.
+ """
+ assert isinstance(domainguid, str)
+
+ if hostip6 is not None:
+ hostip6_base_line = " IN AAAA " + hostip6
+ hostip6_host_line = hostname + " IN AAAA " + hostip6
+ gc_msdcs_ip6_line = "gc._msdcs IN AAAA " + hostip6
+ else:
+ hostip6_base_line = ""
+ hostip6_host_line = ""
+ gc_msdcs_ip6_line = ""
+
+ if hostip is not None:
+ hostip_base_line = " IN A " + hostip
+ hostip_host_line = hostname + " IN A " + hostip
+ gc_msdcs_ip_line = "gc._msdcs IN A " + hostip
+ else:
+ hostip_base_line = ""
+ hostip_host_line = ""
+ gc_msdcs_ip_line = ""
+
+ # we need to freeze the zone while we update the contents
+ if targetdir is None:
+ rndc = ' '.join(lp.get("rndc command"))
+ os.system(rndc + " freeze " + lp.get("realm"))
+
+ setup_file(setup_path("provision.zone"), paths.dns, {
+ "HOSTNAME": hostname,
+ "DNSDOMAIN": dnsdomain,
+ "REALM": realm,
+ "HOSTIP_BASE_LINE": hostip_base_line,
+ "HOSTIP_HOST_LINE": hostip_host_line,
+ "DOMAINGUID": domainguid,
+ "DATESTRING": time.strftime("%Y%m%d%H"),
+ "DEFAULTSITE": site,
+ "NTDSGUID": ntdsguid,
+ "HOSTIP6_BASE_LINE": hostip6_base_line,
+ "HOSTIP6_HOST_LINE": hostip6_host_line,
+ "GC_MSDCS_IP_LINE": gc_msdcs_ip_line,
+ "GC_MSDCS_IP6_LINE": gc_msdcs_ip6_line,
+ })
+
+ if paths.bind_gid is not None:
+ try:
+ os.chown(paths.dns, -1, paths.bind_gid)
+ # chmod needed to cope with umask
+ os.chmod(paths.dns, 0664)
+ except OSError:
+ if not os.environ.has_key('SAMBA_SELFTEST'):
+ logger.error("Failed to chown %s to bind gid %u" % (
+ paths.dns, paths.bind_gid))
+
+ if targetdir is None:
+ os.system(rndc + " unfreeze " + lp.get("realm"))
+
+
+def create_dns_update_list(lp, logger, paths):
+ """Write out a dns_update_list file"""
+ # note that we use no variable substitution on this file
+ # the substitution is done at runtime by samba_dnsupdate, samba_spnupdate
+ setup_file(setup_path("dns_update_list"), paths.dns_update_list, None)
+ setup_file(setup_path("spn_update_list"), paths.spn_update_list, None)
+
+
+def create_named_conf(paths, realm, dnsdomain, dns_backend):
+ """Write out a file containing zone statements suitable for inclusion in a
+ named.conf file (including GSS-TSIG configuration).
+
+ :param paths: all paths
+ :param realm: Realm name
+ :param dnsdomain: DNS Domain name
+ :param dns_backend: DNS backend type
+ :param keytab_name: File name of DNS keytab file
+ """
+
+ if dns_backend == "BIND9_FLATFILE":
+ setup_file(setup_path("named.conf"), paths.namedconf, {
+ "DNSDOMAIN": dnsdomain,
+ "REALM": realm,
+ "ZONE_FILE": paths.dns,
+ "REALM_WC": "*." + ".".join(realm.split(".")[1:]),
+ "NAMED_CONF": paths.namedconf,
+ "NAMED_CONF_UPDATE": paths.namedconf_update
+ })
+
+ setup_file(setup_path("named.conf.update"), paths.namedconf_update)
+
+ elif dns_backend == "BIND9_DLZ":
+ dlz_module_path = os.path.join(samba.param.modules_dir(),
+ "bind9/dlz_bind9.so")
+ setup_file(setup_path("named.conf.dlz"), paths.namedconf, {
+ "NAMED_CONF": paths.namedconf,
+ "BIND9_DLZ_MODULE": dlz_module_path,
+ })
+
+
+
+def create_named_txt(path, realm, dnsdomain, dnsname, private_dir,
+ keytab_name):
+ """Write out a file containing zone statements suitable for inclusion in a
+ named.conf file (including GSS-TSIG configuration).
+
+ :param path: Path of the new named.conf file.
+ :param realm: Realm name
+ :param dnsdomain: DNS Domain name
+ :param private_dir: Path to private directory
+ :param keytab_name: File name of DNS keytab file
+ """
+ setup_file(setup_path("named.txt"), path, {
+ "DNSDOMAIN": dnsdomain,
+ "DNSNAME" : dnsname,
+ "REALM": realm,
+ "DNS_KEYTAB": keytab_name,
+ "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
+ "PRIVATE_DIR": private_dir
+ })
+
+
def is_valid_dns_backend(dns_backend):
return dns_backend in ("BIND9_FLATFILE", "BIND9_DLZ",
"SAMBA_INTERNAL", "NONE")
@@ -458,17 +667,24 @@ def is_valid_os_level(os_level):
--
Samba Shared Repository