s4-selftest: silence warnings about bind chown
[samba.git] / source4 / scripting / python / samba / provision.py
index 6429251850364c5c896cfe3e74f84a8ec4ba7df3..96e7aa502fee9aba4aca47eafe6c57702cc7e30d 100644 (file)
@@ -389,6 +389,7 @@ def provision_paths_from_lp(lp, dnsdomain):
     # This is stored without path prefix for the "privateKeytab" attribute in
     # "secrets_dns.ldif".
     paths.dns_keytab = "dns.keytab"
+    paths.keytab = "secrets.keytab"
 
     paths.shareconf = os.path.join(paths.private_dir, "share.ldb")
     paths.samdb = os.path.join(paths.private_dir, lp.get("sam database") or "samdb.ldb")
@@ -687,21 +688,26 @@ def secretsdb_self_join(secretsdb, domain,
            "priorChanged",
            "krb5Keytab",
            "privateKeytab"]
+
+    if realm is not None:
+      if dnsdomain is None:
+          dnsdomain = realm.lower()
+      dnsname = '%s.%s' % (netbiosname.lower(), dnsdomain.lower())
+    else:
+      dnsname = None
+    shortname = netbiosname.lower()
     
     #We don't need to set msg["flatname"] here, because rdn_name will handle it, and it causes problems for modifies anyway
     msg = ldb.Message(ldb.Dn(secretsdb, "flatname=%s,cn=Primary Domains" % domain))
     msg["secureChannelType"] = [str(secure_channel_type)]
     msg["objectClass"] = ["top", "primaryDomain"]
-    if realm is not None:
-      if dnsdomain is None:
-        dnsdomain = realm.lower()
+    if dnsname is not None:
       msg["objectClass"] = ["top", "primaryDomain", "kerberosSecret"]
       msg["realm"] = [realm]
-      msg["saltPrincipal"] = ["host/%s.%s@%s" % (netbiosname.lower(), dnsdomain.lower(), realm.upper())]
+      msg["saltPrincipal"] = ["host/%s@%s" % (dnsname, realm.upper())]
       msg["msDS-KeyVersionNumber"] = [str(key_version_number)]
       msg["privateKeytab"] = ["secrets.keytab"]
 
-
     msg["secret"] = [machinepass]
     msg["samAccountName"] = ["%s$" % netbiosname]
     msg["secureChannelType"] = [str(secure_channel_type)]
@@ -742,10 +748,17 @@ def secretsdb_self_join(secretsdb, domain,
       secretsdb.modify(msg)
       secretsdb.rename(res[0].dn, msg.dn)
     else:
+      spn = [ 'HOST/%s' % shortname ]
+      if secure_channel_type == SEC_CHAN_BDC and dnsname is not None:
+          # we are a domain controller then we add servicePrincipalName entries
+          # for the keytab code to update
+          spn.extend([ 'HOST/%s' % dnsname ])
+      msg["servicePrincipalName"] = spn
+
       secretsdb.add(msg)
 
 
-def secretsdb_setup_dns(secretsdb, setup_path, private_dir,
+def secretsdb_setup_dns(secretsdb, setup_path, names, private_dir,
                         realm, dnsdomain,
                         dns_keytab_path, dnspass):
     """Add DNS specific bits to a secrets database.
@@ -764,10 +777,12 @@ def secretsdb_setup_dns(secretsdb, setup_path, private_dir,
             "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(path, setup_path, session_info, backend_credentials, lp):
+def setup_secretsdb(paths, setup_path, session_info, backend_credentials, lp):
     """Setup the secrets database.
 
    :note: This function does not handle exceptions and transaction on purpose,
@@ -780,8 +795,19 @@ def setup_secretsdb(path, setup_path, session_info, backend_credentials, lp):
     :param lp: Loadparm context
     :return: LDB handle for the created secrets database
     """
-    if os.path.exists(path):
-        os.unlink(path)
+    if os.path.exists(paths.secrets):
+        os.unlink(paths.secrets)
+
+    keytab_path = os.path.join(paths.private_dir, paths.keytab)
+    if os.path.exists(keytab_path):
+        os.unlink(keytab_path)
+
+    dns_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
+    if os.path.exists(dns_keytab_path):
+        os.unlink(dns_keytab_path)
+
+    path = paths.secrets
+
     secrets_ldb = Ldb(path, session_info=session_info, 
                       lp=lp)
     secrets_ldb.erase()
@@ -873,10 +899,6 @@ def setup_samdb_rootdse(samdb, setup_path, names):
     """
     setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), {
         "SCHEMADN": names.schemadn, 
-        "NETBIOSNAME": names.netbiosname,
-        "DNSDOMAIN": names.dnsdomain,
-        "REALM": names.realm,
-        "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain),
         "DOMAINDN": names.domaindn,
         "ROOTDN": names.rootdn,
         "CONFIGDN": names.configdn,
@@ -922,7 +944,7 @@ def setup_self_join(samdb, names,
               "DOMAINDN": names.domaindn})
     
     # add the NTDSGUID based SPNs
-    ntds_dn = "CN=NTDS Settings,CN=%s,CN=Servers,CN=%s,CN=Sites,CN=Configuration,%s" % (names.hostname, names.sitename, names.domaindn)
+    ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
     names.ntdsguid = samdb.searchone(basedn=ntds_dn, attribute="objectGUID",
                                      expression="", scope=ldb.SCOPE_BASE)
     assert isinstance(names.ntdsguid, str)
@@ -948,6 +970,8 @@ def setup_self_join(samdb, names,
               "DNSDOMAIN": names.dnsdomain,
               "DOMAINDN": names.domaindn,
               "DNSPASS_B64": b64encode(dnspass),
+              "HOSTNAME" : names.hostname,
+              "DNSNAME" : '%s.%s' % (names.netbiosname.lower(), names.dnsdomain.lower())
               })
 
 def getpolicypath(sysvolpath, dnsdomain, guid):
@@ -966,15 +990,15 @@ def getpolicypath(sysvolpath, dnsdomain, guid):
 
 def create_gpo_struct(policy_path):
     if not os.path.exists(policy_path):
-        os.makedirs(policy_path, 0755)
+        os.makedirs(policy_path, 0775)
     open(os.path.join(policy_path, "GPT.INI"), 'w').write(
-                      "[General]\r\nVersion=65543")
+                      "[General]\r\nVersion=0")
     p = os.path.join(policy_path, "MACHINE")
     if not os.path.exists(p):
-        os.makedirs(p, 0755)
+        os.makedirs(p, 0775)
     p = os.path.join(policy_path, "USER")
     if not os.path.exists(p):
-        os.makedirs(p, 0755)
+        os.makedirs(p, 0775)
 
 
 def create_default_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc):
@@ -1043,6 +1067,10 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp, names,
     # Load the schema from the one we computed earlier
     samdb.set_schema(schema)
 
+    # Set the NTDS settings DN manually - in order to have it already around
+    # before the provisioned tree exists and we connect
+    samdb.set_ntds_settings_dn("CN=NTDS Settings,%s" % names.serverdn)
+
     # And now we can connect to the DB - the schema won't be loaded from the DB
     samdb.connect(path)
 
@@ -1063,7 +1091,6 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp, names,
 
         samdb.set_domain_sid(str(domainsid))
         samdb.set_invocation_id(invocationid)
-        samdb.set_ntds_settings_dn("CN=NTDS Settings,%s" % names.serverdn)
 
         logger.info("Adding DomainDN: %s" % names.domaindn)
 
@@ -1121,10 +1148,16 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp, names,
     else:
         samdb.transaction_commit()
 
-    samdb = SamDB(session_info=admin_session_info,
+    samdb = SamDB(session_info=admin_session_info, auto_connect=False,
                 credentials=provision_backend.credentials, lp=lp,
                 global_schema=False, am_rodc=am_rodc)
+
+    # Set the NTDS settings DN manually - in order to have it already around
+    # before the provisioned tree exists and we connect
+    samdb.set_ntds_settings_dn("CN=NTDS Settings,%s" % names.serverdn)
+
     samdb.connect(path)
+
     samdb.transaction_start()
     try:
         samdb.invocation_id = invocationid
@@ -1201,7 +1234,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp, names,
                             domainControllerFunctionality=domainControllerFunctionality,
                             ntdsguid=ntdsguid)
 
-            ntds_dn = "CN=NTDS Settings,CN=%s,CN=Servers,CN=%s,CN=Sites,CN=Configuration,%s" % (names.hostname, names.sitename, names.domaindn)
+            ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
             names.ntdsguid = samdb.searchone(basedn=ntds_dn,
                 attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE)
             assert isinstance(names.ntdsguid, str)
@@ -1492,7 +1525,7 @@ def provision(setup_dir, logger, session_info,
         share_ldb.load_ldif_file_add(setup_path("share.ldif"))
 
     logger.info("Setting up secrets.ldb")
-    secrets_ldb = setup_secretsdb(paths.secrets, setup_path, 
+    secrets_ldb = setup_secretsdb(paths, setup_path,
         session_info=session_info,
         backend_credentials=provision_backend.secrets_credentials, lp=lp)
 
@@ -1578,7 +1611,7 @@ def provision(setup_dir, logger, session_info,
 
 
             if serverrole == "domain controller":
-                secretsdb_setup_dns(secrets_ldb, setup_path,
+                secretsdb_setup_dns(secrets_ldb, setup_path, names,
                                     paths.private_dir,
                                     realm=names.realm, dnsdomain=names.dnsdomain,
                                     dns_keytab_path=paths.dns_keytab,
@@ -1604,12 +1637,6 @@ def provision(setup_dir, logger, session_info,
                 logger.info("and %s for further documentation required for secure DNS "
                         "updates", paths.namedtxt)
 
-                create_krb5_conf(paths.krb5conf, setup_path,
-                                 dnsdomain=names.dnsdomain, hostname=names.hostname,
-                                 realm=names.realm)
-                logger.info("A Kerberos configuration suitable for Samba 4 has been "
-                        "generated at %s", paths.krb5conf)
-
             lastProvisionUSNs = get_last_provision_usn(samdb)
             maxUSN = get_max_usn(samdb, str(names.rootdn))
             if lastProvisionUSNs is not None:
@@ -1617,6 +1644,12 @@ def provision(setup_dir, logger, session_info,
             else:
                 set_provision_usn(samdb, 0, maxUSN)
 
+        create_krb5_conf(paths.krb5conf, setup_path,
+                         dnsdomain=names.dnsdomain, hostname=names.hostname,
+                         realm=names.realm)
+        logger.info("A Kerberos configuration suitable for Samba 4 has been "
+                    "generated at %s", paths.krb5conf)
+
         if serverrole == "domain controller":
             create_dns_update_list(lp, logger, paths, setup_path)
 
@@ -1639,8 +1672,9 @@ def provision(setup_dir, logger, session_info,
             os.chmod(dns_keytab_path, 0640)
             os.chown(dns_keytab_path, -1, paths.bind_gid)
         except OSError:
-            logger.info("Failed to chown %s to bind gid %u", dns_keytab_path,
-                paths.bind_gid)
+            if not os.environ.has_key('SAMBA_SELFTEST'):
+                logger.info("Failed to chown %s to bind gid %u", dns_keytab_path,
+                            paths.bind_gid)
 
 
     logger.info("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php",
@@ -1793,7 +1827,8 @@ def create_zone_file(lp, logger, paths, targetdir, setup_path, dnsdomain,
             os.chmod(dns_dir, 0775)
             os.chmod(paths.dns, 0664)
         except OSError:
-            logger.error("Failed to chown %s to bind gid %u" % (dns_dir, paths.bind_gid))
+            if not os.environ.has_key('SAMBA_SELFTEST'):
+                logger.error("Failed to chown %s to bind gid %u" % (dns_dir, paths.bind_gid))
 
     if targetdir is None:
         os.system(rndc + " unfreeze " + lp.get("realm"))