s4-samba_upgradedns: Do not set DNS account for internal server
[metze/samba/wip.git] / source4 / scripting / bin / samba_upgradedns
index 11472388d23d6f1c56cf8c30f44a13360617a479..c1220bcc264d2c242e4f091b73c057aba5a452b7 100755 (executable)
@@ -26,7 +26,7 @@ import grp
 from base64 import b64encode
 import shlex
 
-sys.path.insert(0, 'bin/python')
+sys.path.insert(0, "bin/python")
 
 import ldb
 import samba
@@ -56,7 +56,6 @@ from samba.provision.sambadns import (
     SRVRecord,
     TXTRecord,
     get_dnsadmins_sid,
-    get_domainguid,
     add_dns_accounts,
     create_dns_partitions,
     fill_dns_data_partitions,
@@ -324,6 +323,8 @@ if __name__ == '__main__':
         logger.info("Adding DNS accounts")
         add_dns_accounts(ldbs.sam, domaindn)
         dnsadmins_sid = get_dnsadmins_sid(ldbs.sam, domaindn)
+    else:
+        logger.info("DNS accounts already exist")
 
     # Import dns records from zone file
     if os.path.exists(paths.dns):
@@ -341,32 +342,94 @@ if __name__ == '__main__':
         logger.warn("DNS records will be automatically created")
         autofill = True
 
-    # Fill DNS information
-    logger.info("Creating DNS partitions")
-    create_dns_partitions(ldbs.sam, domainsid, names, domaindn, forestdn,
+    # Create DNS partitions if missing and fill DNS information
+    try:
+        expression = '(|(dnsRoot=DomainDnsZones.%s)(dnsRoot=ForestDnsZones.%s))' % \
+                     (dnsdomain, dnsforest)
+        msg = ldbs.sam.search(base=names.configdn, scope=ldb.SCOPE_DEFAULT,
+                              expression=expression, attrs=['nCName'])
+        ncname = msg[0]['nCName'][0]
+    except Exception, e:
+        logger.info("Creating DNS partitions")
+        create_dns_partitions(ldbs.sam, domainsid, names, domaindn, forestdn,
                           dnsadmins_sid)
 
-    logger.info("Populating DNS partitions")
-    fill_dns_data_partitions(ldbs.sam, domainsid, site, domaindn, forestdn,
+        logger.info("Populating DNS partitions")
+        fill_dns_data_partitions(ldbs.sam, domainsid, site, domaindn, forestdn,
                              dnsdomain, dnsforest, hostname, hostip, hostip6,
                              domainguid, ntdsguid, dnsadmins_sid,
                              autofill=autofill)
 
-    if not autofill:
-        logger.info("Importing records from zone file")
-        import_zone_data(ldbs.sam, logger, zone, serial, domaindn, forestdn,
-                         dnsdomain, dnsforest)
+        if not autofill:
+            logger.info("Importing records from zone file")
+            import_zone_data(ldbs.sam, logger, zone, serial, domaindn, forestdn,
+                             dnsdomain, dnsforest)
+    else:
+        logger.info("DNS partitions already exist")
 
-    if opts.dns_backend == "BIND9_DLZ":
-        create_dns_dir(logger, paths)
+    # Mark that we are hosting DNS partitions
+    try:
+        dns_nclist = [ 'DC=DomainDnsZones,%s' % domaindn,
+                       'DC=ForestDnsZones,%s' % forestdn ]
+
+        msgs = ldbs.sam.search(base=names.serverdn, scope=ldb.SCOPE_DEFAULT,
+                               expression='(objectclass=nTDSDSa)',
+                               attrs=['hasPartialReplicaNCs',
+                                      'msDS-hasMasterNCs'])
+        msg = msgs[0]
+
+        master_nclist = []
+        ncs = msg.get("msDS-hasMasterNCs")
+        if ncs:
+            for nc in ncs:
+                master_nclist.append(nc)
+
+        partial_nclist = []
+        ncs = msg.get("hasPartialReplicaNCs")
+        if ncs:
+            for nc in ncs:
+                partial_nclist.append(nc)
+
+        modified_master = False
+        modified_partial = False
+        for nc in dns_nclist:
+            if nc not in master_nclist:
+                master_nclist.append(nc)
+                modified_master = True
+            if nc in partial_nclist:
+                partial_nclist.remove(nc)
+                modified_partial = True
+
+        if modified_master or modified_partial:
+            logger.debug("Updating msDS-hasMasterNCs and hasPartialReplicaNCs attributes")
+            m = ldb.Message()
+            m.dn = msg.dn
+            if modified_master:
+                m["msDS-hasMasterNCs"] = ldb.MessageElement(master_nclist,
+                                                            ldb.FLAG_MOD_REPLACE,
+                                                            "msDS-hasMasterNCs")
+            if modified_partial:
+                if partial_nclist:
+                    m["hasPartialReplicaNCs"] = ldb.MessageElement(partial_nclist,
+                                                                   ldb.FLAG_MOD_REPLACE,
+                                                                   "hasPartialReplicaNCs")
+                else:
+                    m["hasPartialReplicaNCs"] = ldb.MessageElement(ncs,
+                                                                   ldb.FLAG_MOD_DELETE,
+                                                                   "hasPartialReplicaNCs")
+            ldbs.sam.modify(m)
+    except Exception:
+        raise
 
+    # Special stuff for DLZ backend
+    if opts.dns_backend == "BIND9_DLZ":
         # Check if dns-HOSTNAME account exists and create it if required
         try:
             dn = 'samAccountName=dns-%s,CN=Principals' % hostname
             msg = ldbs.secrets.search(expression='(dn=%s)' % dn, attrs=['secret'])
             dnssecret = msg[0]['secret'][0]
         except Exception:
-            logger.info("Creating DNS account for BIND9")
+            logger.info("Adding dns-%s account" % hostname)
 
             try:
                 msg = ldbs.sam.search(base=domaindn, scope=ldb.SCOPE_DEFAULT,
@@ -379,17 +442,24 @@ if __name__ == '__main__':
 
             dnspass = samba.generate_random_password(128, 255)
             setup_add_ldif(ldbs.sam, setup_path("provision_dns_add_samba.ldif"), {
-                           "DNSDOMAIN": dnsdomain,
-                           "DOMAINDN": domaindn,
-                           "DNSPASS_B64": b64encode(dnspass.encode('utf-16-le')),
-                           "HOSTNAME" : hostname,
-                           "DNSNAME" : dnsname }
+                    "DNSDOMAIN": dnsdomain,
+                    "DOMAINDN": domaindn,
+                    "DNSPASS_B64": b64encode(dnspass.encode('utf-16-le')),
+                    "HOSTNAME" : hostname,
+                    "DNSNAME" : dnsname }
                            )
 
             secretsdb_setup_dns(ldbs.secrets, names,
                                 paths.private_dir, realm=names.realm,
                                 dnsdomain=names.dnsdomain,
                                 dns_keytab_path=paths.dns_keytab, dnspass=dnspass)
+        else:
+            logger.info("dns-%s account already exists" % hostname)
+
+        # This forces a re-creation of dns directory and all the files within
+        # It's an overkill, but it's easier to re-create a samdb copy, rather
+        # than trying to fix a broken copy.
+        create_dns_dir(logger, paths)
 
         # Setup a copy of SAM for BIND9
         create_samdb_copy(ldbs.sam, logger, paths, names, domainsid,