s4-provision: Create a samdb copy for access by dlz_bind9 module
authorAmitay Isaacs <amitay@gmail.com>
Mon, 19 Sep 2011 23:58:42 +0000 (09:58 +1000)
committerAmitay Isaacs <amitay@gmail.com>
Tue, 29 Nov 2011 05:00:36 +0000 (16:00 +1100)
This creates a copy of rootdse, configuration and schema partitions
for dlz_bind9 use in dns/ directory.  Since dlz_bind9 requires write
access to DNS partitions (DomainDnsZones and ForestDnsZones), those
partitions are hard-linked (or symlinked) to the actual partitions.
An empty domain partition is created so samdb layer can work.

source4/scripting/python/samba/provision/__init__.py
source4/scripting/python/samba/provision/descriptor.py
source4/scripting/python/samba/provision/sambadns.py
source4/setup/provision_basedn_options.ldif [new file with mode: 0644]

index 875e09f7ac515cc7d81cafc696022e396fe8ff7b..c3150a183c4f91e5a0543c3c19312c2785dafe50 100644 (file)
@@ -1558,7 +1558,6 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
                               'ipsecNFAReference'])
     samdb.transaction_commit()
 
                               'ipsecNFAReference'])
     samdb.transaction_commit()
 
-
 def provision(logger, session_info, credentials, smbconf=None,
         targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
         domaindn=None, schemadn=None, configdn=None, serverdn=None,
 def provision(logger, session_info, credentials, smbconf=None,
         targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
         domaindn=None, schemadn=None, configdn=None, serverdn=None,
index 3e4cf87bca62b2e54344309c796fd52a6d39918f..69c1be7197d8d529cd35a745b00a817f76dd7014 100644 (file)
@@ -105,3 +105,59 @@ def get_domain_descriptor(domain_sid):
     "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)"
     sec = security.descriptor.from_sddl(sddl, domain_sid)
     return ndr_pack(sec)
     "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)"
     sec = security.descriptor.from_sddl(sddl, domain_sid)
     return ndr_pack(sec)
+
+
+def get_dns_partition_descriptor(domainsid):
+    sddl = "O:SYG:BAD:AI" \
+    "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ER)" \
+    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a86-0de6-11d0-a285-00aa003049e2;ED)" \
+    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a9c-0de6-11d0-a285-00aa003049e2;ED)" \
+    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967aba-0de6-11d0-a285-00aa003049e2;ED)" \
+    "(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;BA)" \
+    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
+    "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
+    "(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
+    "(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
+    "(OA;;CR;1131f6ae-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
+    "(OA;;CR;e2a36dc9-ae17-47c3-b58b-be34c55ba633;;IF)" \
+    "(OA;;RP;c7407360-20bf-11d0-a768-00aa006e0529;;RU)" \
+    "(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;RU)" \
+    "(OA;CIIO;RPLCLORC;;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
+    "(OA;CIIO;RPLCLORC;;bf967a9c-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;CIIO;RPLCLORC;;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
+    "(OA;;CR;05c74c5e-4deb-43b4-bd9f-86664c2a7fd5;;AU)" \
+    "(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;ED)" \
+    "(OA;;CR;ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501;;AU)" \
+    "(OA;;CR;280f369c-67c7-438e-ae98-1d46f3c6f541;;AU)" \
+    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
+    "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
+    "(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
+    "(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
+    "(OA;;CR;1131f6ae-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
+    "(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;AU)" \
+    "(OA;CIIO;RPWPCR;91e647de-d96f-4b70-9557-d63ff4f3ccd8;;PS)" \
+    "(A;;RPWPCRCCLCLORCWOWDSW;;;DA)" \
+    "(A;CI;RPWPCRCCDCLCLORCWOWDSDDTSW;;;EA)" \
+    "(A;;RPRC;;;RU)" \
+    "(A;CI;LC;;;RU)" \
+    "(A;CI;RPWPCRCCLCLORCWOWDSDSW;;;BA)" \
+    "(A;;RP;;;WD)" \
+    "(A;;RPLCLORC;;;ED)" \
+    "(A;;RPLCLORC;;;AU)" \
+    "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \
+    "S:AI" \
+    "(OU;CISA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \
+    "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \
+    "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)"
+    sec = security.descriptor.from_sddl(sddl, domainsid)
+    return ndr_pack(sec)
index 37c0dff6565e5200079c5f9cd311fc0b8e4327d4..bbcd3a021c7b73d61ba977b719f42de8b528f119 100644 (file)
@@ -37,6 +37,10 @@ from samba.dsdb import (
     DS_DOMAIN_FUNCTION_2008_R2
     )
 from base64 import b64encode
     DS_DOMAIN_FUNCTION_2008_R2
     )
 from base64 import b64encode
+from samba.provision.descriptor import (
+    get_domain_descriptor,
+    get_dns_partition_descriptor
+    )
 
 
 def add_ldif(ldb, ldif_file, subst_vars, controls=["relax:0"]):
 
 
 def add_ldif(ldb, ldif_file, subst_vars, controls=["relax:0"]):
@@ -91,61 +95,6 @@ def get_ntdsguid(samdb, domaindn):
     ntdsguid = str(ndr_unpack(misc.GUID, res3[0]["objectGUID"][0]))
     return ntdsguid
 
     ntdsguid = str(ndr_unpack(misc.GUID, res3[0]["objectGUID"][0]))
     return ntdsguid
 
-def get_dns_partition_descriptor(domainsid):
-    sddl = "O:SYG:BAD:AI" \
-    "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ER)" \
-    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a86-0de6-11d0-a285-00aa003049e2;ED)" \
-    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a9c-0de6-11d0-a285-00aa003049e2;ED)" \
-    "(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967aba-0de6-11d0-a285-00aa003049e2;ED)" \
-    "(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;BA)" \
-    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
-    "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
-    "(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
-    "(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
-    "(OA;;CR;1131f6ae-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
-    "(OA;;CR;e2a36dc9-ae17-47c3-b58b-be34c55ba633;;IF)" \
-    "(OA;;RP;c7407360-20bf-11d0-a768-00aa006e0529;;RU)" \
-    "(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;RU)" \
-    "(OA;CIIO;RPLCLORC;;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
-    "(OA;CIIO;RPLCLORC;;bf967a9c-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;CIIO;RPLCLORC;;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
-    "(OA;;CR;05c74c5e-4deb-43b4-bd9f-86664c2a7fd5;;AU)" \
-    "(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;ED)" \
-    "(OA;;CR;ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501;;AU)" \
-    "(OA;;CR;280f369c-67c7-438e-ae98-1d46f3c6f541;;AU)" \
-    "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
-    "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
-    "(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
-    "(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
-    "(OA;;CR;1131f6ae-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
-    "(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;AU)" \
-    "(OA;CIIO;RPWPCR;91e647de-d96f-4b70-9557-d63ff4f3ccd8;;PS)" \
-    "(A;;RPWPCRCCLCLORCWOWDSW;;;DA)" \
-    "(A;CI;RPWPCRCCDCLCLORCWOWDSDDTSW;;;EA)" \
-    "(A;;RPRC;;;RU)" \
-    "(A;CI;LC;;;RU)" \
-    "(A;CI;RPWPCRCCLCLORCWOWDSDSW;;;BA)" \
-    "(A;;RP;;;WD)" \
-    "(A;;RPLCLORC;;;ED)" \
-    "(A;;RPLCLORC;;;AU)" \
-    "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \
-    "S:AI" \
-    "(OU;CISA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \
-    "(OU;CISA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" \
-    "(AU;SA;CR;;;DU)(AU;SA;CR;;;BA)(AU;SA;WPWOWD;;;WD)"
-    sec = security.descriptor.from_sddl(sddl, domainsid)
-    return ndr_pack(sec)
-
 class ARecord(dnsp.DnssrvRpcRecord):
     def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE):
         super(ARecord, self).__init__()
 class ARecord(dnsp.DnssrvRpcRecord):
     def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE):
         super(ARecord, self).__init__()
@@ -671,6 +620,99 @@ def create_zone_file(lp, logger, paths, targetdir, dnsdomain,
         os.system(rndc + " unfreeze " + lp.get("realm"))
 
 
         os.system(rndc + " unfreeze " + lp.get("realm"))
 
 
+def create_samdb_copy(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
+    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))
+    except:
+        logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
+        raise
+
+    # Link metadata and dns partitions
+    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
+    try:
+        ldb = samba.Ldb(os.path.join(dns_samldb_dir, domainpart_file))
+        domainguid_line = "objectGUID: %s\n-" % domainguid
+        descr = b64encode(get_domain_descriptor(domainsid))
+        add_ldif(ldb, "provision_basedn.ldif", {
+            "DOMAINDN" : names.domaindn,
+            "DOMAINGUID" : domainguid_line,
+            "DOMAINSID" : str(domainsid),
+            "DESCRIPTOR" : descr})
+        add_ldif(ldb, "provision_basedn_options.ldif", None)
+    except:
+        logger.error("Failed to setup database for BIND, AD based DNS cannot be used")
+        raise
+
+    # Give bind read/write permissions dns partitions
+    if paths.bind_gid is not None:
+        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)
+        except OSError:
+            if not os.environ.has_key('SAMBA_SELFTEST'):
+                logger.error("Failed to set permissions to sam.ldb* files, fix manually")
+    else:
+        if not os.environ.has_key('SAMBA_SELFTEST'):
+            logger.warning("""Unable to find group id for BIND,
+                set permissions to sam.ldb* files manually""")
+
+
 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
 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
@@ -872,6 +914,9 @@ def setup_ad_dns(samdb, secretsdb, domainsid, names, paths, lp, logger, dns_back
                              hostname=names.hostname, realm=names.realm,
                              domainguid=domainguid, ntdsguid=names.ntdsguid)
 
                              hostname=names.hostname, realm=names.realm,
                              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_named_conf(paths, realm=names.realm,
                           dnsdomain=names.dnsdomain, dns_backend=dns_backend)
 
         create_named_conf(paths, realm=names.realm,
                           dnsdomain=names.dnsdomain, dns_backend=dns_backend)
 
diff --git a/source4/setup/provision_basedn_options.ldif b/source4/setup/provision_basedn_options.ldif
new file mode 100644 (file)
index 0000000..a4788aa
--- /dev/null
@@ -0,0 +1,2 @@
+dn: @OPTIONS
+checkBaseOnSearch: TRUE