provision: add get_config_ntds_quotas_descriptor()
[metze/samba/wip.git] / source4 / scripting / python / samba / provision / __init__.py
index b38555608ba5d735291350b1535742961634305f..221b580c46e575b61e05dc091bbdfc09a1e25d79 100644 (file)
@@ -77,8 +77,23 @@ from samba.provision.backend import (
     OpenLDAPBackend,
     )
 from samba.provision.descriptor import (
+    get_empty_descriptor,
     get_config_descriptor,
-    get_domain_descriptor
+    get_config_partitions_descriptor,
+    get_config_sites_descriptor,
+    get_config_ntds_quotas_descriptor,
+    get_config_delete_protected1_descriptor,
+    get_config_delete_protected1wd_descriptor,
+    get_config_delete_protected2_descriptor,
+    get_domain_descriptor,
+    get_domain_infrastructure_descriptor,
+    get_domain_builtin_descriptor,
+    get_domain_computers_descriptor,
+    get_domain_users_descriptor,
+    get_domain_controllers_descriptor,
+    get_domain_delete_protected1_descriptor,
+    get_domain_delete_protected2_descriptor,
+    get_dns_partition_descriptor,
     )
 from samba.provision.common import (
     setup_path,
@@ -127,10 +142,13 @@ class ProvisionPaths(object):
 class ProvisionNames(object):
 
     def __init__(self):
+        self.ncs = None
         self.rootdn = None
         self.domaindn = None
         self.configdn = None
         self.schemadn = None
+        self.dnsforestdn = None
+        self.dnsdomaindn = None
         self.ldapmanagerdn = None
         self.dnsdomain = None
         self.realm = None
@@ -176,7 +194,8 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf,
     current = samdb.search(expression="(objectClass=*)",
         base="", scope=ldb.SCOPE_BASE,
         attrs=["defaultNamingContext", "schemaNamingContext",
-               "configurationNamingContext","rootDomainNamingContext"])
+               "configurationNamingContext","rootDomainNamingContext",
+               "namingContexts"])
 
     names.configdn = current[0]["configurationNamingContext"]
     configdn = str(names.configdn)
@@ -190,6 +209,23 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf,
 
     names.domaindn=current[0]["defaultNamingContext"]
     names.rootdn=current[0]["rootDomainNamingContext"]
+    names.ncs=current[0]["namingContexts"]
+    names.dnsforestdn = None
+    names.dnsdomaindn = None
+
+    for i in range(0, len(names.ncs)):
+        nc = names.ncs[i]
+
+        dnsforestdn = "DC=ForestDnsZones,%s" % (str(names.rootdn))
+        if nc == dnsforestdn:
+            names.dnsforestdn = dnsforestdn
+            continue
+
+        dnsdomaindn = "DC=DomainDnsZones,%s" % (str(names.domaindn))
+        if nc == dnsdomaindn:
+            names.dnsdomaindn = dnsdomaindn
+            continue
+
     # default site name
     res3 = samdb.search(expression="(objectClass=site)",
         base="CN=Sites," + configdn, scope=ldb.SCOPE_ONELEVEL, attrs=["cn"])
@@ -1254,6 +1290,8 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid,
         # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
         if fill == FILL_FULL:
             logger.info("Setting up sam.ldb configuration data")
+            partitions_descr = b64encode(get_config_partitions_descriptor(domainsid))
+            sites_descr = b64encode(get_config_sites_descriptor(domainsid))
             setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
                     "CONFIGDN": names.configdn,
                     "NETBIOSNAME": names.netbiosname,
@@ -1265,6 +1303,8 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid,
                     "SERVERDN": names.serverdn,
                     "FOREST_FUNCTIONALITY": str(forestFunctionality),
                     "DOMAIN_FUNCTIONALITY": str(domainFunctionality),
+                    "PARTITIONS_DESCRIPTOR": partitions_descr,
+                    "SITES_DESCRIPTOR": sites_descr,
                     })
 
             logger.info("Setting up display specifiers")
@@ -1276,19 +1316,28 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid,
             samdb.add_ldif(display_specifiers_ldif)
 
         logger.info("Adding users container")
+        users_desc = b64encode(get_domain_users_descriptor(domainsid))
         setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), {
-                "DOMAINDN": names.domaindn})
+                "DOMAINDN": names.domaindn,
+                "USERS_DESCRIPTOR": users_desc
+                })
         logger.info("Modifying users container")
         setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), {
                 "DOMAINDN": names.domaindn})
         logger.info("Adding computers container")
+        computers_desc = b64encode(get_domain_computers_descriptor(domainsid))
         setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), {
-                "DOMAINDN": names.domaindn})
+                "DOMAINDN": names.domaindn,
+                "COMPUTERS_DESCRIPTOR": computers_desc
+                })
         logger.info("Modifying computers container")
         setup_modify_ldif(samdb,
             setup_path("provision_computers_modify.ldif"), {
                 "DOMAINDN": names.domaindn})
         logger.info("Setting up sam.ldb data")
+        infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(domainsid))
+        builtin_desc = b64encode(get_domain_builtin_descriptor(domainsid))
+        controllers_desc = b64encode(get_domain_controllers_descriptor(domainsid))
         setup_add_ldif(samdb, setup_path("provision.ldif"), {
             "CREATTIME": str(samba.unix2nttime(int(time.time()))),
             "DOMAINDN": names.domaindn,
@@ -1297,7 +1346,10 @@ def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid,
             "CONFIGDN": names.configdn,
             "SERVERDN": names.serverdn,
             "RIDAVAILABLESTART": str(next_rid + 600),
-            "POLICYGUID_DC": policyguid_dc
+            "POLICYGUID_DC": policyguid_dc,
+            "INFRASTRUCTURE_DESCRIPTOR": infrastructure_desc,
+            "BUILTIN_DESCRIPTOR": builtin_desc,
+            "DOMAIN_CONTROLLERS_DESCRIPTOR": controllers_desc,
             })
 
         # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
@@ -1357,17 +1409,17 @@ FILL_NT4SYNC = "NT4SYNC"
 FILL_DRS = "DRS"
 SYSVOL_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)"
 POLICIES_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001301bf;;;PA)"
+SYSVOL_SERVICE="sysvol"
 
-
-def set_dir_acl(path, acl, lp, domsid, use_ntvfs, passdb):
-    setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb)
+def set_dir_acl(path, acl, lp, domsid, use_ntvfs, passdb, service=SYSVOL_SERVICE):
+    setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
     for root, dirs, files in os.walk(path, topdown=False):
         for name in files:
             setntacl(lp, os.path.join(root, name), acl, domsid,
-                    use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb)
+                    use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
         for name in dirs:
             setntacl(lp, os.path.join(root, name), acl, domsid,
-                    use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb)
+                    use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
 
 
 def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb):
@@ -1385,7 +1437,7 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, p
     # Set ACL for GPO root folder
     root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
     setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid),
-            use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb)
+            use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=SYSVOL_SERVICE)
 
     res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
                         attrs=["cn", "nTSecurityDescriptor"],
@@ -1395,7 +1447,7 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, p
         acl = ndr_unpack(security.descriptor,
                          str(policy["nTSecurityDescriptor"])).as_sddl()
         policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
-        set_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,
+        set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
                     str(domainsid), use_ntvfs,
                     passdb=passdb)
 
@@ -1449,16 +1501,22 @@ def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
         canchown = True
 
     # Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
-    setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb)
+    setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs,
+             skip_invalid_chown=True, passdb=s4_passdb,
+             service=SYSVOL_SERVICE)
     for root, dirs, files in os.walk(sysvol, topdown=False):
         for name in files:
             if use_ntvfs and canchown:
                 os.chown(os.path.join(root, name), -1, gid)
-            setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb)
+            setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+                     use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+                     passdb=s4_passdb, service=SYSVOL_SERVICE)
         for name in dirs:
             if use_ntvfs and canchown:
                 os.chown(os.path.join(root, name), -1, gid)
-            setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb)
+            setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+                     use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+                     passdb=s4_passdb, service=SYSVOL_SERVICE)
 
     # Set acls on Policy folder and policies folders
     set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb=s4_passdb)
@@ -1470,22 +1528,24 @@ def acl_type(direct_db_access):
         return "VFS"
 
 def check_dir_acl(path, acl, lp, domainsid, direct_db_access):
-    fsacl = getntacl(lp, path, direct_db_access=direct_db_access)
+    fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
     fsacl_sddl = fsacl.as_sddl(domainsid)
     if fsacl_sddl != acl:
         raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), path, fsacl_sddl, acl))
 
     for root, dirs, files in os.walk(path, topdown=False):
         for name in files:
-            fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access)
+            fsacl = getntacl(lp, os.path.join(root, name),
+                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
             if fsacl is None:
                 raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
             fsacl_sddl = fsacl.as_sddl(domainsid)
             if fsacl_sddl != acl:
                 raise ProvisioningError('%s ACL on GPO file %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl))
 
-        for name in files:
-            fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access)
+        for name in dirs:
+            fsacl = getntacl(lp, os.path.join(root, name),
+                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
             if fsacl is None:
                 raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
             fsacl_sddl = fsacl.as_sddl(domainsid)
@@ -1508,7 +1568,8 @@ def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
 
     # Set ACL for GPO root folder
     root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
-    fsacl = getntacl(lp, root_policy_path, direct_db_access=direct_db_access)
+    fsacl = getntacl(lp, root_policy_path,
+                     direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
     if fsacl is None:
         raise ProvisioningError('DB ACL on policy root %s %s not found!' % (acl_type(direct_db_access), root_policy_path))
     fsacl_sddl = fsacl.as_sddl(domainsid)
@@ -1522,7 +1583,7 @@ def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
         acl = ndr_unpack(security.descriptor,
                          str(policy["nTSecurityDescriptor"])).as_sddl()
         policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
-        check_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,
+        check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
                       domainsid, direct_db_access)
 
 
@@ -1563,7 +1624,7 @@ def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn,
     for direct_db_access in [True, False]:
         # Check the SYSVOL_ACL on the sysvol folder and subfolder (first level)
         for dir_path in [os.path.join(sysvol, dnsdomain), netlogon]:
-            fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access)
+            fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
             if fsacl is None:
                 raise ProvisioningError('%s ACL on sysvol directory %s not found!' % (acl_type(direct_db_access), dir_path))
             fsacl_sddl = fsacl.as_sddl(domainsid)