[SCM] Samba Shared Repository - branch master updated

Garming Sam garming at samba.org
Thu Jul 21 08:18:04 UTC 2016


The branch, master has been updated
       via  f757836 WHATSNEW: Add the update for the samba kcc
       via  fbc2628 samba_kcc: Enable the python samba_kcc
       via  10f256a kcc: correct a typo in the debug messages
       via  3eb7fab dbcheck: Add a rule regarding replica locations
       via  56771ec dbcheck/release-4-1-0rc3: Add a check regarding replica locations
       via  5d470d2 join.py: Don't add replica locations without the backend
       via  15ca517 join.py: Add Replica-Locations for DomainDNS and ForestDNS
       via  6212836 join.py: Ensure that all expressions are escaped
       via  289d090 dbcheck: Replica locations can now be leftover
       via  0c8e9a8 kcc: Make more fault tolerant on DC demotion
       via  a5e0a2f samba_kcc: match translate connection from old KCC for RWDC
       via  9206a10 samba_kcc: match translate connection from old KCC for RODC
       via  9dfd55c kcc: Prevent the KCC from doing work on the RODC
       via  cad1473 selftest: Add more information when KCC fails
       via  abb8d77 kcc: Make debug more scarce
       via  c11629b drepl: Fix a typo
       via  5707a80 WHATSNEW: Samba-tool speed-up
      from  e0aae9f ctdb-tests: Add shellcheck test suite

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f7578365924c916cd832bff744fc2a63d86fab66
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jun 30 12:19:32 2016 +1200

    WHATSNEW: Add the update for the samba kcc
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Garming Sam <garming at samba.org>
    Autobuild-Date(master): Thu Jul 21 10:17:52 CEST 2016 on sn-devel-144

commit fbc26289e5426f73a43b8d21f81c4bab08c8331b
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jun 30 10:54:29 2016 +1200

    samba_kcc: Enable the python samba_kcc
    
    For any reasonably large domain, the old KCC is impractical as the dense
    mesh topology causes replication pulses.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 10f256a7fefec8584008d5fe75611b913808c40e
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 18 14:38:40 2016 +1200

    kcc: correct a typo in the debug messages
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3eb7fab04b2c69142eb1bfb66140e1842ba3cd05
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 18 17:06:57 2016 +1200

    dbcheck: Add a rule regarding replica locations
    
    This fixes any RW DCs with repsFrom without the corresponding link. On
    any RODC, this just reports an error (and doesn't fix it).
    
    (the knownfail entry is also now removed)
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 56771ec6d0b01590caa702708a56d1e68e0dc70a
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 20 12:47:11 2016 +1200

    dbcheck/release-4-1-0rc3: Add a check regarding replica locations
    
    This DC has repsFrom for the DNS partitions, but not the corresponding
    link. This ensures that dbcheck has fixed them up. This will currently
    fail without the actual changes to dbcheck coming in the following
    commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5d470d2886a782ad887a3d290d600c5dfa244fc0
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 16:01:20 2016 +1200

    join.py: Don't add replica locations without the backend
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 15ca517da8eb5122fdf31b6554ebfda3073d2a64
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 18 13:09:59 2016 +1200

    join.py: Add Replica-Locations for DomainDNS and ForestDNS
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6212836e4e800bfb3e5c8e1253c215dc7744b030
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 20 13:37:47 2016 +1200

    join.py: Ensure that all expressions are escaped
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 289d0900ed1d0da4a3d1184938fac6a384db07a3
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 15:34:13 2016 +1200

    dbcheck: Replica locations can now be leftover
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9200
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0c8e9a862a11ffefc2e7829c8898e6fef3152651
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 13:08:31 2016 +1200

    kcc: Make more fault tolerant on DC demotion
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a5e0a2fef112f3edfaf6c3d61662f4ab5e4fe43f
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 10:42:14 2016 +1200

    samba_kcc: match translate connection from old KCC for RWDC
    
    This makes it so that repsTo are always regenerated on the target DCs.
    This also happens elsewhere in drepl_out, but is to be removed.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9206a10a8c73cab8e989dcec9b93a9216e5deba2
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Tue Jul 5 15:57:28 2016 +1200

    samba_kcc: match translate connection from old KCC for RODC
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9dfd55c83aeafc6fdd76db87b03db6687e27e1f7
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Jul 1 17:02:50 2016 +1200

    kcc: Prevent the KCC from doing work on the RODC
    
    This should never have done any real work, new code or not. This just removes
    the initial KCC calls and bails out in the KCC if we actually ran it.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit cad1473512dbd31140151280800edb3ccfe42496
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 13:08:56 2016 +1200

    selftest: Add more information when KCC fails
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit abb8d77c6ff9d12a82fd9fcb3d13b46d081d2e1d
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 4 11:17:45 2016 +1200

    kcc: Make debug more scarce
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c11629b6ad5a9c8af2f9316930b75e9d07215049
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 09:08:11 2016 +1200

    drepl: Fix a typo
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5707a8054e0d63f8a9ca7ea907a253bcd3f2c38e
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 21 16:30:35 2016 +1200

    WHATSNEW: Samba-tool speed-up
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 WHATSNEW.txt                                       | 17 ++++++
 lib/param/loadparm.c                               |  2 +-
 python/samba/dbchecker.py                          | 58 +++++++++++++++++++-
 python/samba/join.py                               | 46 +++++++++++++---
 python/samba/kcc/__init__.py                       | 62 +++++++++++++++++++---
 selftest/target/Samba4.pm                          | 31 ++---------
 source4/dsdb/kcc/kcc_service.c                     |  2 +-
 source4/dsdb/repl/drepl_out_helpers.c              |  2 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.c        |  2 +-
 .../expected-replica-locations-after-dbcheck.ldif  | 11 ++++
 .../expected-replica-locations-after-dbcheck2.ldif | 11 ++++
 testprogs/blackbox/dbcheck-oldrelease.sh           | 13 +++++
 testprogs/blackbox/dbcheck.sh                      |  2 +-
 13 files changed, 210 insertions(+), 49 deletions(-)
 create mode 100644 source4/selftest/provisions/release-4-1-0rc3/expected-replica-locations-after-dbcheck.ldif
 create mode 100644 source4/selftest/provisions/release-4-1-0rc3/expected-replica-locations-after-dbcheck2.ldif


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 2eaad94..6c86795 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -25,6 +25,16 @@ The ldap server has support for the LDAP_SERVER_NOTIFICATION_OID
 control. This can be used to monitor the active directory database
 for changes.
 
+KCC improvements for sparse network replication
+-----------------------------------------------
+
+The Samba KCC will now be the default knowledge consistency checker in
+Samba AD. Instead of using full mesh replication between every DC, the
+KCC will set up connections to optimize replication latency and cost
+(using site links to calculate the routes). This change should allow
+larger domains to function significantly better in terms of replication
+traffic and the time spent performing DRS replication.
+
 VLV - Virtual List View
 -----------------------
 
@@ -110,6 +120,12 @@ net ads dns unregister
 It is now possible to remove the DNS entries created with 'net ads register'
 with the matching 'net ads unregister' command.
 
+Samba-tool improvements
+------------------------
+
+Running samba-tool on the command line should now be a lot snappier. The tool
+now only loads the code specific to the subcommand that you wish to run.
+
 
 
 REMOVED FEATURES
@@ -127,6 +143,7 @@ smb.conf changes
   --------------		-----------		-------
   only user			Removed
   username			Removed
+  kccsrv:samba_kcc		Changed default		true
 
 KNOWN ISSUES
 ============
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index d6bd66d..515ed05 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2571,7 +2571,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 
 	lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
 	lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
-	lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "false");
+	lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
 	/* the winbind method for domain controllers is for both RODC
 	   auth forwarding and for trusted domains */
 	lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index 16258cf..e904b4a 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -90,6 +90,7 @@ class dbcheck(object):
         self.wellknown_sds = get_wellknown_sds(self.samdb)
         self.fix_all_missing_objectclass = False
         self.fix_missing_deleted_objects = False
+        self.fix_replica_locations = False
 
         self.dn_set = set()
         self.link_id_cache = {}
@@ -123,6 +124,7 @@ class dbcheck(object):
         res = self.samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=['namingContexts'])
         self.deleted_objects_containers = []
         self.ncs_lacking_deleted_containers = []
+        self.dns_partitions = []
         try:
             self.ncs = res[0]["namingContexts"]
         except KeyError:
@@ -138,6 +140,23 @@ class dbcheck(object):
             except KeyError:
                 self.ncs_lacking_deleted_containers.append(ldb.Dn(self.samdb, nc))
 
+        domaindns_zone = 'DC=DomainDnsZones,%s' % self.samdb.get_default_basedn()
+        forestdns_zone = 'DC=ForestDnsZones,%s' % self.samdb.get_root_basedn()
+        domain = self.samdb.search(scope=ldb.SCOPE_ONELEVEL,
+                                   attrs=["msDS-NC-Replica-Locations", "msDS-NC-RO-Replica-Locations"],
+                                   base=self.samdb.get_partitions_dn(),
+                                   expression="(&(objectClass=crossRef)(ncName=%s))" % domaindns_zone)
+        if len(domain) == 1:
+            self.dns_partitions.append((ldb.Dn(self.samdb, forestdns_zone), domain[0]))
+
+        forest = self.samdb.search(scope=ldb.SCOPE_ONELEVEL,
+                                   attrs=["msDS-NC-Replica-Locations", "msDS-NC-RO-Replica-Locations"],
+                                   base=self.samdb.get_partitions_dn(),
+                                   expression="(&(objectClass=crossRef)(ncName=%s))" % forestdns_zone)
+        if len(forest) == 1:
+            self.dns_partitions.append((ldb.Dn(self.samdb, domaindns_zone), forest[0]))
+
+
     def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=[], attrs=['*']):
         '''perform a database check, returning the number of errors found'''
         res = self.samdb.search(base=DN, scope=scope, attrs=['dn'], controls=controls)
@@ -161,7 +180,6 @@ class dbcheck(object):
         self.report('Checked %u objects (%u errors)' % (len(res), error_count))
         return error_count
 
-
     def check_deleted_objects_containers(self):
         """This function only fixes conflicts on the Deleted Objects
         containers, not the attributes"""
@@ -1382,6 +1400,23 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                           "Failed to fix Deleted Objects container  %s" % dn):
             self.report("Fixed Deleted Objects container '%s'\n" % (dn))
 
+    def err_replica_locations(self, obj, cross_ref, attr):
+        nmsg = ldb.Message()
+        nmsg.dn = cross_ref
+        target = self.samdb.get_dsServiceName()
+
+        if self.samdb.am_rodc():
+            self.report('Not fixing %s for the RODC' % (attr, obj.dn))
+            return
+
+        if not self.confirm_all('Add yourself to the replica locations for %s?'
+                                % (obj.dn), 'fix_replica_locations'):
+            self.report('Not fixing missing/incorrect attributes on %s\n' % (obj.dn))
+            return
+
+        nmsg[attr] = ldb.MessageElement(target, ldb.FLAG_MOD_ADD, attr)
+        if self.do_modify(nmsg, [], "Failed to add %s for %s" % (attr, obj.dn)):
+            self.report("Fixed %s for %s" % (attr, obj.dn))
 
     def is_fsmo_role(self, dn):
         if dn == self.samdb.domain_dn:
@@ -1784,6 +1819,27 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                 self.err_deleted_deleted_objects(obj)
                 error_count += 1
 
+        for (dns_part, msg) in self.dns_partitions:
+            if dn == dns_part and 'repsFrom' in obj:
+                location = "msDS-NC-Replica-Locations"
+                if self.samdb.am_rodc():
+                    location = "msDS-NC-RO-Replica-Locations"
+
+                if location not in msg:
+                    # There are no replica locations!
+                    self.err_replica_locations(obj, msg.dn, location)
+                    error_count += 1
+                    continue
+
+                found = False
+                for loc in msg[location]:
+                    if loc == self.samdb.get_dsServiceName():
+                        found = True
+                if not found:
+                    # This DC is not in the replica locations
+                    self.err_replica_locations(obj, msg.dn, location)
+                    error_count += 1
+
         return error_count
 
     ################################################################
diff --git a/python/samba/join.py b/python/samba/join.py
index 10cc5a3..d1a1b08 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -140,10 +140,11 @@ class dc_join(object):
         ctx.domaindns_zone = 'DC=DomainDnsZones,%s' % ctx.base_dn
         ctx.forestdns_zone = 'DC=ForestDnsZones,%s' % ctx.root_dn
 
+        expr = "(&(objectClass=crossRef)(ncName=%s))" % ldb.binary_encode(ctx.domaindns_zone)
         res_domaindns = ctx.samdb.search(scope=ldb.SCOPE_ONELEVEL,
                                          attrs=[],
                                          base=ctx.samdb.get_partitions_dn(),
-                                         expression="(&(objectClass=crossRef)(ncName=%s))" % ctx.domaindns_zone)
+                                         expression=expr)
         if dns_backend is None:
             ctx.dns_backend = "NONE"
         else:
@@ -320,21 +321,22 @@ class dc_join(object):
         '''get netbios name of the domain from the partitions record'''
         partitions_dn = ctx.samdb.get_partitions_dn()
         res = ctx.samdb.search(base=partitions_dn, scope=ldb.SCOPE_ONELEVEL, attrs=["nETBIOSName"],
-                               expression='ncName=%s' % ctx.samdb.get_default_basedn())
+                               expression='ncName=%s' % ldb.binary_encode(str(ctx.samdb.get_default_basedn())))
         return res[0]["nETBIOSName"][0]
 
     def get_forest_domain_name(ctx):
         '''get netbios name of the domain from the partitions record'''
         partitions_dn = ctx.samdb.get_partitions_dn()
         res = ctx.samdb.search(base=partitions_dn, scope=ldb.SCOPE_ONELEVEL, attrs=["nETBIOSName"],
-                               expression='ncName=%s' % ctx.samdb.get_root_basedn())
+                               expression='ncName=%s' % ldb.binary_encode(str(ctx.samdb.get_root_basedn())))
         return res[0]["nETBIOSName"][0]
 
     def get_parent_partition_dn(ctx):
         '''get the parent domain partition DN from parent DNS name'''
         res = ctx.samdb.search(base=ctx.config_dn, attrs=[],
                                expression='(&(objectclass=crossRef)(dnsRoot=%s)(systemFlags:%s:=%u))' %
-                               (ctx.parent_dnsdomain, ldb.OID_COMPARATOR_AND, samba.dsdb.SYSTEM_FLAG_CR_NTDS_DOMAIN))
+                               (ldb.binary_encode(ctx.parent_dnsdomain),
+                                ldb.OID_COMPARATOR_AND, samba.dsdb.SYSTEM_FLAG_CR_NTDS_DOMAIN))
         return str(res[0].dn)
 
     def get_naming_master(ctx):
@@ -598,6 +600,35 @@ class dc_join(object):
         if ctx.ntds_dn:
             ctx.join_add_ntdsdsa()
 
+            # Add the Replica-Locations or RO-Replica-Locations attributes
+            # TODO Is this supposed to be for the schema partition too?
+            expr = "(&(objectClass=crossRef)(ncName=%s))" % ldb.binary_encode(ctx.domaindns_zone)
+            domain = (ctx.samdb.search(scope=ldb.SCOPE_ONELEVEL,
+                                      attrs=[],
+                                      base=ctx.samdb.get_partitions_dn(),
+                                      expression=expr), ctx.domaindns_zone)
+
+            expr = "(&(objectClass=crossRef)(ncName=%s))" % ldb.binary_encode(ctx.forestdns_zone)
+            forest = (ctx.samdb.search(scope=ldb.SCOPE_ONELEVEL,
+                                      attrs=[],
+                                      base=ctx.samdb.get_partitions_dn(),
+                                      expression=expr), ctx.forestdns_zone)
+
+            for part, zone in (domain, forest):
+                if zone not in ctx.nc_list:
+                    continue
+
+                if len(part) == 1:
+                    m = ldb.Message()
+                    m.dn = part[0].dn
+                    attr = "msDS-NC-Replica-Locations"
+                    if ctx.RODC:
+                        attr = "msDS-NC-RO-Replica-Locations"
+
+                    m[attr] = ldb.MessageElement(ctx.ntds_dn,
+                                                 ldb.FLAG_MOD_ADD, attr)
+                    ctx.samdb.modify(m)
+
         if ctx.connection_dn is not None:
             print "Adding %s" % ctx.connection_dn
             rec = {
@@ -865,6 +896,9 @@ class dc_join(object):
                                replica_flags=ctx.domain_replica_flags)
             print "Done with always replicated NC (base, config, schema)"
 
+            # At this point we should already have an entry in the ForestDNS
+            # and DomainDNS NC (those under CN=Partions,DC=...) in order to
+            # indicate that we hold a replica for this NC.
             for nc in (ctx.domaindns_zone, ctx.forestdns_zone):
                 if nc in ctx.nc_list:
                     print "Replicating %s" % (str(nc))
@@ -872,10 +906,6 @@ class dc_join(object):
                                     destination_dsa_guid, rodc=ctx.RODC,
                                     replica_flags=ctx.replica_flags)
 
-            # FIXME At this point we should add an entry in the forestdns and domaindns NC
-            # (those under CN=Partions,DC=...)
-            # in order to indicate that we hold a replica for this NC
-
             if ctx.RODC:
                 repl.replicate(ctx.acct_dn, source_dsa_invocation_id,
                         destination_dsa_guid,
diff --git a/python/samba/kcc/__init__.py b/python/samba/kcc/__init__.py
index c3e92b7..e96ff83 100644
--- a/python/samba/kcc/__init__.py
+++ b/python/samba/kcc/__init__.py
@@ -486,7 +486,12 @@ class KCC(object):
 
         mydsa = self.my_dsa
 
-        self._ensure_connections_are_loaded(mydsa.connect_table.values())
+        try:
+            self._ensure_connections_are_loaded(mydsa.connect_table.values())
+        except KCCError:
+            # RODC never actually added any connections to begin with
+            if mydsa.is_ro():
+                return
 
         local_connections = []
 
@@ -518,14 +523,28 @@ class KCC(object):
 
         :return: None
         """
+        # TODO Figure out how best to handle the RODC case
+        # The RODC is ITSG, but shouldn't act on anyone's behalf.
+        if self.my_dsa.is_ro():
+            return
+
         # Find the intersite connections
         local_dsas = self.my_site.dsa_table
         connections_and_dsas = []
         for dsa in local_dsas.values():
             for cn in dsa.connect_table.values():
+                if cn.to_be_deleted:
+                    continue
                 s_dnstr = cn.get_from_dnstr()
+                if s_dnstr is None:
+                    continue
                 if s_dnstr not in local_dsas:
                     from_dsa = self.get_dsa(s_dnstr)
+                    # Samba ONLY: ISTG removes connections to dead DCs
+                    if from_dsa is None and '\\0ADEL' in s_dnstr:
+                        logger.info("DSA appears deleted, removing connection %s" % s_dnstr)
+                        cn.to_be_deleted = True
+                        continue
                     connections_and_dsas.append((cn, dsa, from_dsa))
 
         self._ensure_connections_are_loaded(x[0] for x in connections_and_dsas)
@@ -618,6 +637,12 @@ class KCC(object):
         if times != t_repsFrom.schedule:
             t_repsFrom.schedule = times
 
+        # Bit DRS_ADD_REF is set in replicaFlags unconditionally
+        # Samba ONLY:
+        if ((t_repsFrom.replica_flags &
+             drsuapi.DRSUAPI_DRS_ADD_REF) == 0x0):
+            t_repsFrom.replica_flags |= drsuapi.DRSUAPI_DRS_ADD_REF
+
         # Bit DRS_PER_SYNC is set in replicaFlags if and only
         # if nTDSConnection schedule has a value v that specifies
         # scheduled replication is to be performed at least once
@@ -840,9 +865,13 @@ class KCC(object):
         """
         count = 0
 
+        ro = False
         if current_dsa is None:
             current_dsa = self.my_dsa
 
+        if current_dsa.is_ro():
+            ro = True
+
         if current_dsa.is_translate_ntdsconn_disabled():
             DEBUG_FN("skipping translate_ntdsconn() "
                      "because disabling flag is set")
@@ -871,8 +900,23 @@ class KCC(object):
         # If we have the replica and its not needed
         # then we add it to the "to be deleted" list.
         for dnstr in current_rep_table:
-            if dnstr not in needed_rep_table:
-                delete_reps.add(dnstr)
+            # If we're on the RODC, hardcode the update flags
+            if ro:
+                c_rep = current_rep_table[dnstr]
+                c_rep.load_repsFrom(self.samdb)
+                for t_repsFrom in c_rep.rep_repsFrom:
+                    replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
+                                     drsuapi.DRSUAPI_DRS_PER_SYNC |
+                                     drsuapi.DRSUAPI_DRS_ADD_REF |
+                                     drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
+                                     drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP |
+                                     drsuapi.DRSUAPI_DRS_NONGC_RO_REP)
+                    if t_repsFrom.replica_flags != replica_flags:
+                        t_repsFrom.replica_flags = replica_flags
+                c_rep.commit_repsFrom(self.samdb)
+            else:
+                if dnstr not in needed_rep_table:
+                    delete_reps.add(dnstr)
 
         DEBUG_FN('current %d needed %d delete %d' % (len(current_rep_table),
                  len(needed_rep_table), len(delete_reps)))
@@ -978,7 +1022,7 @@ class KCC(object):
                 if t_repsFrom.is_modified():
                     n_rep.rep_repsFrom.append(t_repsFrom)
 
-            if self.readonly:
+            if self.readonly or ro:
                 # Display any to be deleted or modified repsFrom
                 text = n_rep.dumpstr_to_be_deleted()
                 if text:
@@ -1770,7 +1814,9 @@ class KCC(object):
         DEBUG_FN("intersite(): exit all_connected=%d" % all_connected)
         return all_connected
 
-    def update_rodc_connection(self):
+    # This function currently does no actions. The reason being that we cannot
+    # perform modifies in this way on the RODC.
+    def update_rodc_connection(self, ro=True):
         """Updates the RODC NTFRS connection object.
 
         If the local DSA is not an RODC, this does nothing.
@@ -1804,7 +1850,7 @@ class KCC(object):
                 con.schedule = cn2.schedule
                 con.to_be_modified = True
 
-            self.my_dsa.commit_connections(self.samdb, ro=self.readonly)
+            self.my_dsa.commit_connections(self.samdb, ro=ro)
 
     def intrasite_max_node_edges(self, node_count):
         """Find the maximum number of edges directed to an intrasite node
@@ -2189,9 +2235,9 @@ class KCC(object):
 
                 while candidates and not tnode.has_sufficient_edges():
                     other = random.choice(candidates)
-                    DEBUG("trying to add candidate %s" % other.dsa_dstr)
+                    DEBUG("trying to add candidate %s" % other.dsa_dnstr)
                     if not tnode.add_edge_from(other):
-                        debug.DEBUG_RED("could not add %s" % other.dsa_dstr)
+                        debug.DEBUG_RED("could not add %s" % other.dsa_dnstr)
                     candidates.remove(other)
             else:
                 DEBUG_FN("not adding links to %s: nodes %s, links is %s/%s" %
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 7778615..b09bb66 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -2117,7 +2117,7 @@ sub setup_vampire_dc($$$)
 		$cmd .= " $env->{CONFIGURATION}";
 		$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
 		unless (system($cmd) == 0) {
-			warn("Failed to exec kcc\n$cmd");
+			warn("Failed to exec kcc on remote DC\n$cmd");
 			return undef;
 		}
 
@@ -2175,7 +2175,7 @@ sub setup_promoted_dc($$$)
 		$cmd .= " $env->{CONFIGURATION}";
 		$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
 		unless (system($cmd) == 0) {
-			warn("Failed to exec kcc\n$cmd");
+			warn("Failed to exec kcc on remote DC\n$cmd");
 			return undef;
 		}
 
@@ -2187,7 +2187,7 @@ sub setup_promoted_dc($$$)
 		$cmd .= " $env->{CONFIGURATION}";
 		$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
 		unless (system($cmd) == 0) {
-			warn("Failed to exec kcc\n$cmd");
+			warn("Failed to exec kcc on promoted DC\n$cmd");
 			return undef;
 		}
 
@@ -2239,7 +2239,7 @@ sub setup_subdom_dc($$$)
 		$cmd .= " $env->{CONFIGURATION}";
 		$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
 		unless (system($cmd) == 0) {
-			warn("Failed to exec kcc\n$cmd");
+			warn("Failed to exec kcc on remote DC\n$cmd");
 			return undef;
 		}
 
@@ -2283,31 +2283,8 @@ sub setup_rodc($$$)
 	    return undef;
 	}
 
-	# force source and replicated DC to update repsTo/repsFrom
-	# for vampired partitions
 	my $samba_tool =  Samba::bindir_path($self, "samba-tool");
 	my $cmd = "";
-	$cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
-	$cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
-	$cmd .= " $samba_tool drs kcc -k no $env->{DC_SERVER}";
-	$cmd .= " $env->{CONFIGURATION}";
-	$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
-	unless (system($cmd) == 0) {
-	    warn("Failed to exec kcc\n$cmd");
-	    return undef;
-	}
-
-	my $samba_tool =  Samba::bindir_path($self, "samba-tool");
-	my $cmd = "";
-	$cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
-	$cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
-	$cmd .= " $samba_tool drs kcc -k no $env->{SERVER}";
-	$cmd .= " $env->{CONFIGURATION}";
-	$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
-	unless (system($cmd) == 0) {
-	    warn("Failed to exec kcc\n$cmd");
-	    return undef;
-	}
 
 	my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
 	$cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index 985692f..ccc252c 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -327,7 +327,7 @@ static void kccsrv_task_init(struct task_server *task)
 	 * topology generation code.
 	 */
 	service->samba_kcc_code = lpcfg_parm_bool(task->lp_ctx, NULL,
-						"kccsrv", "samba_kcc", false);
+						"kccsrv", "samba_kcc", true);
 
 	status = kccsrv_periodic_schedule(service, periodic_startup_interval);
 	if (!W_ERROR_IS_OK(status)) {
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index a2b9a02..bf8a372 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -835,7 +835,7 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
 			}
 		}
 
-		/* Find schmea naming context to be synchronized first */
+		/* Find schema naming context to be synchronized first */
 		status = dreplsrv_partition_find_for_nc(service,
 							NULL, NULL,
 							ldb_dn_get_linearized(schema_dn),
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index 949dea8..35aeedb 100644


-- 
Samba Shared Repository



More information about the samba-cvs mailing list