s4:provision - Removed dependency on full Samba 3 schema from FDS
[samba.git] / source4 / scripting / python / samba / provision.py
index d797dc9d212c29c01a7d7a0a9aa225bc924406e9..e2f7cd7953475b006273d7518fbbdf235006ae49 100644 (file)
@@ -52,7 +52,7 @@ import urllib
 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
 from ms_display_specifiers import read_ms_ldif
 from schema import Schema
-from provisionbackend import ProvisionBackend
+from provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend
 from signal import SIGTERM
 from dcerpc.misc import SEC_CHAN_BDC, SEC_CHAN_WKSTA
 
@@ -73,6 +73,10 @@ def find_setup_dir():
         return ret
     raise Exception("Unable to find setup directory.")
 
+# descriptors of the naming contexts
+# hard coded at this point, but will probably be changed when
+# we enable different fsmo roles
+
 def get_config_descriptor(domain_sid):
     sddl = "O:EAG:EAD:(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
            "(OA;;CR;1131f6ab-9c07-11d1-f79f-00c04fc2dcd2;;ED)" \
@@ -92,6 +96,58 @@ def get_config_descriptor(domain_sid):
     sec = security.descriptor.from_sddl(sddl, domain_sid)
     return b64encode(ndr_pack(sec))
 
+def get_domain_descriptor(domain_sid):
+    sddl= "O:BAG: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;;S-1-5-21-832762594-175224951-1765713900-498)" \
+    "(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;DD)" \
+    "(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;;S-1-5-32-557)" \
+    "(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;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, domain_sid)
+    return b64encode(ndr_pack(sec))
 
 DEFAULTSITE = "Default-First-Site-Name"
 
@@ -127,15 +183,6 @@ class ProvisionPaths(object):
         self.slapdconf = None
         self.modulesconf = None
         self.memberofconf = None
-        self.fedoradsinf = None
-        self.fedoradspartitions = None
-        self.fedoradssasl = None
-        self.fedoradsdna = None
-        self.fedoradspam = None
-        self.fedoradsrefint = None
-        self.fedoradslinkedattributes = None
-        self.fedoradsindex = None
-        self.fedoradssamba = None
         self.olmmron = None
         self.olmmrserveridsconf = None
         self.olmmrsyncreplconf = None
@@ -150,7 +197,6 @@ class ProvisionNames(object):
         self.domaindn = None
         self.configdn = None
         self.schemadn = None
-        self.sambadn = None
         self.ldapmanagerdn = None
         self.dnsdomain = None
         self.realm = None
@@ -279,24 +325,6 @@ def provision_paths_from_lp(lp, dnsdomain):
                                      "modules.conf")
     paths.memberofconf = os.path.join(paths.ldapdir, 
                                       "memberof.conf")
-    paths.fedoradsinf = os.path.join(paths.ldapdir, 
-                                     "fedorads.inf")
-    paths.fedoradspartitions = os.path.join(paths.ldapdir, 
-                                            "fedorads-partitions.ldif")
-    paths.fedoradssasl = os.path.join(paths.ldapdir, 
-                                      "fedorads-sasl.ldif")
-    paths.fedoradsdna = os.path.join(paths.ldapdir, 
-                                     "fedorads-dna.ldif")
-    paths.fedoradspam = os.path.join(paths.ldapdir,
-                                     "fedorads-pam.ldif")
-    paths.fedoradsrefint = os.path.join(paths.ldapdir,
-                                        "fedorads-refint.ldif")
-    paths.fedoradslinkedattributes = os.path.join(paths.ldapdir,
-                                                  "fedorads-linked-attributes.ldif")
-    paths.fedoradsindex = os.path.join(paths.ldapdir,
-                                       "fedorads-index.ldif")
-    paths.fedoradssamba = os.path.join(paths.ldapdir, 
-                                       "fedorads-samba.ldif")
     paths.olmmrserveridsconf = os.path.join(paths.ldapdir, 
                                             "mmr_serverids.conf")
     paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, 
@@ -323,7 +351,7 @@ def provision_paths_from_lp(lp, dnsdomain):
 
 def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
                 serverrole=None, rootdn=None, domaindn=None, configdn=None,
-                schemadn=None, serverdn=None, sitename=None, sambadn=None):
+                schemadn=None, serverdn=None, sitename=None):
     """Guess configuration settings to use."""
 
     if hostname is None:
@@ -385,8 +413,6 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
         configdn = "CN=Configuration," + rootdn
     if schemadn is None:
         schemadn = "CN=Schema," + configdn
-    if sambadn is None:
-        sambadn = "CN=Samba"
 
     if sitename is None:
         sitename=DEFAULTSITE
@@ -396,7 +422,6 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
     names.domaindn = domaindn
     names.configdn = configdn
     names.schemadn = schemadn
-    names.sambadn = sambadn
     names.ldapmanagerdn = "CN=Manager," + rootdn
     names.dnsdomain = dnsdomain
     names.domain = domain
@@ -537,7 +562,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
     modules_list = ["resolve_oids",
                     "rootdse",
                     "lazy_commit",
-                    "acl",
                     "paged_results",
                     "ranged_results",
                     "anr",
@@ -548,6 +572,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
                     "rdn_name",
                     "objectclass",
                     "descriptor",
+                    "acl",
                     "samldb",
                     "password_hash",
                     "operational",
@@ -571,7 +596,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
             backend_modules = ["nsuniqueid", "paged_searches"]
             # We can handle linked attributes here, as we don't have directory-side subtree operations
             tdb_modules_list = ["extended_dn_out_fds"]
-        elif ldap_backend.ldap_backend_type == "openldap":
+        elif provision_backend.ldap_backend_type == "openldap":
             backend_modules = ["entryuuid", "paged_searches"]
             # OpenLDAP handles subtree renames, so we don't want to do any of these things
             tdb_modules_list = ["extended_dn_out_openldap"]
@@ -900,8 +925,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
                            serverrole=serverrole, schema=schema)
 
     if (schema == None):
-        schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
-                        sambadn=names.sambadn)
+        schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
 
     # Load the database, but importantly, use Ldb not SamDB as we don't want to load the global schema
     samdb = Ldb(session_info=session_info, 
@@ -943,9 +967,12 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
             domainguid_line = "objectGUID: %s\n-" % domainguid
         else:
             domainguid_line = ""
+
+        descr = get_domain_descriptor(domainsid)
         setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
                 "DOMAINDN": names.domaindn,
-                "DOMAINGUID": domainguid_line
+                "DOMAINGUID": domainguid_line,
+                "DESCRIPTOR": descr
                 })
 
 
@@ -1177,22 +1204,55 @@ def provision(setup_dir, message, session_info,
 
     ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
     
-    schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
-                    sambadn=names.sambadn)
+    schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
     
-    provision_backend = ProvisionBackend(backend_type,
+    if backend_type == "ldb":
+        provision_backend = LDBBackend(backend_type,
+                                         paths=paths, setup_path=setup_path,
+                                         lp=lp, credentials=credentials, 
+                                         names=names,
+                                         message=message)
+    elif backend_type == "existing":
+        provision_backend = ExistingBackend(backend_type,
+                                         paths=paths, setup_path=setup_path,
+                                         lp=lp, credentials=credentials, 
+                                         names=names,
+                                         message=message)
+    elif backend_type == "fedora-ds":
+        provision_backend = FDSBackend(backend_type,
                                          paths=paths, setup_path=setup_path,
                                          lp=lp, credentials=credentials, 
                                          names=names,
-                                         message=message, hostname=hostname,
-                                         root=root, schema=schema,
+                                         message=message,
+                                         domainsid=domainsid,
+                                         schema=schema,
+                                         hostname=hostname,
                                          ldapadminpass=ldapadminpass,
+                                         slapd_path=slapd_path,
                                          ldap_backend_extra_port=ldap_backend_extra_port,
-                                         ol_mmr_urls=ol_mmr_urls, 
+                                         ldap_dryrun_mode=ldap_dryrun_mode,
+                                         root=root,
+                                         setup_ds_path=setup_ds_path)
+    elif backend_type == "openldap":
+        provision_backend = OpenLDAPBackend(backend_type,
+                                         paths=paths, setup_path=setup_path,
+                                         lp=lp, credentials=credentials, 
+                                         names=names,
+                                         message=message,
+                                         domainsid=domainsid,
+                                         schema=schema,
+                                         hostname=hostname,
+                                         ldapadminpass=ldapadminpass,
                                          slapd_path=slapd_path,
-                                         setup_ds_path=setup_ds_path,
+                                         ldap_backend_extra_port=ldap_backend_extra_port,
                                          ldap_dryrun_mode=ldap_dryrun_mode,
-                                         domainsid=domainsid)
+                                         ol_mmr_urls=ol_mmr_urls, 
+                                         nosync=nosync)
+    else:
+        raise ProvisioningError("Unknown LDAP backend type selected")
+
+    provision_backend.init()
+    provision_backend.start()
 
     # only install a new shares config db if there is none
     if not os.path.exists(paths.shareconf):
@@ -1312,11 +1372,8 @@ def provision(setup_dir, message, session_info,
                              realm=names.realm)
             message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf)
 
-    if provision_backend.post_setup is not None:
-        provision_backend.post_setup()
-
-    if provision_backend.shutdown is not None:
-        provision_backend.shutdown()
+    provision_backend.post_setup()
+    provision_backend.shutdown()
     
     create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, 
                                ldapi_url)