[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Feb 9 02:17:02 UTC 2017


The branch, master has been updated
       via  5c918e2 torture/drs: expand test for DRSUAPI_DRS_GET_ANC
       via  5109e77 getncchanges: implement DRSUAPI_DRS_GET_ANC more correctly
       via  c61d0c8 getncchanges: calculate getnc_state->min_usn calculation based on the uptodateness vector
       via  02f11b9 getncchanges: improve get_nc_changes_add_links() by checking uSNChanged
       via  c31777a getncchanges: improve get_nc_changes_build_object() by checking uSNChanged
       via  5138634 getncchanges: fix highest_usn off by one calculation in get_nc_changes_add_links()
       via  7d8c409 getncchanges: remove unused c++ comments/code in getncchanges_collect_objects()
       via  1a328bf getncchanges: do not replicate links for non critical objects if DRSUAPI_DRS_CRITICAL_ONLY is set
       via  1e15cda getncchanges: don't process DRSUAPI_DRS_CRITICAL_ONLY for EXOPs
       via  488eed6 getncchanges: remember the ncRoot_guid on the getncchanges state
       via  23e45b4 getncchanges: pass struct ldb_message as const
       via  e935a04 getncchanges: only set nc_{object,linked_attributes}_count with DRSUAPI_DRS_GET_NC_SIZE
       via  41bc007 torture/drs: remove pointless nc_object_count replication checks in test_link_utdv_hwm()
       via  dd6d119 python/join: use DRSUAPI_DRS_GET_NC_SIZE for the initial replication
       via  330ef9e python/join: set common replica_flags in dc_join.__init__()
       via  f5d3b86 drsuapi.idl: make drsuapi_DsGetNCChangesRequest10 [public]
       via  0c77567 drsuapi.idl: add drsuapi_DrsMoreOptions with DRSUAPI_DRS_GET_TGT
       via  2ef7594 s4:libnet: s/highestCommitedUSN/highestCommittedUSN
       via  7888c25 s4:dsdb/repl: s/highestCommitedUsn/highestCommittedUSN
      from  ce9b72c ctdb-build: Install CTDB tests correctly from toplevel

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


- Log -----------------------------------------------------------------
commit 5c918e29429f4a0c5a4383b33eaa10a66dfdd2f2
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date:   Mon Dec 12 16:00:35 2016 +1300

    torture/drs: expand test for DRSUAPI_DRS_GET_ANC
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Feb  9 03:16:09 CET 2017 on sn-devel-144

commit 5109e777f75670958d193a269bbb575cdf0a67ce
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 11:12:22 2016 +0100

    getncchanges: implement DRSUAPI_DRS_GET_ANC more correctly
    
    The most important case is the combination of
    DRSUAPI_DRS_CRITICAL_ONLY and DRSUAPI_DRS_GET_ANC.
    
    With DRSUAPI_DRS_GET_ANC we need to make sure all ancestors
    included even if they're not marked with
    isCriticalSystemObject=TRUE.
    
    I guess we still don't behave exactly as Windows, but it's much
    better than before and fixes the initial replication if
    someone moved the administrator account to an OU.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Pair-Programmed-With: Bob Campbell <bobcampbell at catalyst.net.nz>
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c61d0c8957bf4eade5da93f4f22ae5f3ce2e7403
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 12:37:16 2017 +0100

    getncchanges: calculate getnc_state->min_usn calculation based on the uptodateness vector
    
    This should improve initial replication of a fresh destination dsa with
    a zero highwatermark.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 02f11b925c44ecc0b333f1a5593b7d01dc05560a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 12:28:33 2017 +0100

    getncchanges: improve get_nc_changes_add_links() by checking uSNChanged
    
    This will make a difference once we handle DRSUAPI_DRS_GET_ANC correctly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c31777a7010e8fb914ae8450a476d7f9ee2a4c39
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 12:28:33 2017 +0100

    getncchanges: improve get_nc_changes_build_object() by checking uSNChanged
    
    This will make a difference once we handle DRSUAPI_DRS_GET_ANC correctly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 51386342d5f6df2d9aaf801a4137300569458f3d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 12:34:45 2017 +0100

    getncchanges: fix highest_usn off by one calculation in get_nc_changes_add_links()
    
    highest_usn is the the highest usn the destination dsa already knows about.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7d8c409792e93490bc4c357436200289df54d3ce
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 8 10:24:56 2017 +0100

    getncchanges: remove unused c++ comments/code in getncchanges_collect_objects()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1a328bf404d9b3e6db4b2db963b186223297463a
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Dec 14 16:04:32 2016 +1300

    getncchanges: do not replicate links for non critical objects if DRSUAPI_DRS_CRITICAL_ONLY is set
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Pair-programmed-with: Bob Campbell <bobcampbell at catalyst.net.nz>
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1e15cdaa01fdee60f8bd57db41f062ace77c216d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Nov 30 09:11:31 2016 +0100

    getncchanges: don't process DRSUAPI_DRS_CRITICAL_ONLY for EXOPs
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 488eed6977e6bb04be2b1a736115d8887516ebbe
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 11:09:46 2016 +0100

    getncchanges: remember the ncRoot_guid on the getncchanges state
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 23e45b493803b3b2b548b4a3dbec0525feeb928f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 1 11:50:34 2016 +0100

    getncchanges: pass struct ldb_message as const
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e935a04afb017ff52b6caf9bfa66888ab541c894
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 13:23:23 2016 +0100

    getncchanges: only set nc_{object,linked_attributes}_count with DRSUAPI_DRS_GET_NC_SIZE
    
    The main change is that we return 0 values if DRSUAPI_DRS_GET_NC_SIZE is not
    present in order to get the same result as a Windows server in that case.
    
    If DRSUAPI_DRS_GET_NC_SIZE is return the number of links we found so far
    during the cycle in addition the number of objects returned in this cycle.
    Both values doesn't match what Windows returns, but doing that
    correctly and efficient is a task for another day.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 41bc007d49e8bb304cdfb07231d402fa9ad828d7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 17:06:47 2017 +0100

    torture/drs: remove pointless nc_object_count replication checks in test_link_utdv_hwm()
    
    nc_object_count and nc_linked_attributes_count are only filled if
    DRSUAPI_DRS_GET_NC_SIZE is requested. And they should contain
    the total number. This is only useful for the initial replication.
    
    Samba ignores DRSUAPI_DRS_GET_NC_SIZE currently but that will change in
    the following commits.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit dd6d119c801076547fc0d087a2b959100146ba95
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 14:29:59 2016 +0100

    python/join: use DRSUAPI_DRS_GET_NC_SIZE for the initial replication
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 330ef9e572b9cf408ccb7721e86dc2afff245637
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 14:27:57 2016 +0100

    python/join: set common replica_flags in dc_join.__init__()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12398
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f5d3b863c75af5373a2044b184a8c9be1f32e60a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 7 16:22:41 2017 +0100

    drsuapi.idl: make drsuapi_DsGetNCChangesRequest10 [public]
    
    This allows ndr_print to work.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0c77567a4e23bc87c249066319724413e9f9916e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 09:22:44 2016 +0100

    drsuapi.idl: add drsuapi_DrsMoreOptions with DRSUAPI_DRS_GET_TGT
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2ef7594eca19b4448f04b138e97768965dc34242
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 1 11:49:25 2016 +0100

    s4:libnet: s/highestCommitedUSN/highestCommittedUSN
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7888c250da03b0deaafed0932f9d6bcb1dd296a4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 1 11:49:07 2016 +0100

    s4:dsdb/repl: s/highestCommitedUsn/highestCommittedUSN
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 librpc/idl/drsuapi.idl                    |   8 +-
 python/samba/join.py                      |  40 +--
 source4/dsdb/repl/drepl_service.h         |   2 +-
 source4/libnet/libnet_become_dc.c         |   2 +-
 source4/rpc_server/drsuapi/getncchanges.c | 418 +++++++++++++++++++++++++-----
 source4/torture/drs/python/getnc_exop.py  | 332 +++++++++++++++++++++---
 6 files changed, 683 insertions(+), 119 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
index c3af8a5..d08054f 100644
--- a/librpc/idl/drsuapi.idl
+++ b/librpc/idl/drsuapi.idl
@@ -58,6 +58,10 @@ interface drsuapi
 		DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP  = 0x80000000
 	} drsuapi_DrsOptions;
 
+	typedef [public,bitmap32bit] bitmap {
+		DRSUAPI_DRS_GET_TGT                   = 0x00000001
+	} drsuapi_DrsMoreOptions;
+
 	/* see DRS_MSG_REPMOD_V1 */
 	typedef [public,bitmap32bit] bitmap {
 		DRSUAPI_DRS_UPDATE_FLAGS              = 0x00000001,
@@ -573,7 +577,7 @@ interface drsuapi
 		drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr;
 	} drsuapi_DsGetNCChangesRequest8;
 
-	typedef struct {
+	typedef [public] struct {
 		GUID destination_dsa_guid;
 		GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */
 		[ref] drsuapi_DsReplicaObjectIdentifier *naming_context;
@@ -587,7 +591,7 @@ interface drsuapi
 		drsuapi_DsPartialAttributeSet *partial_attribute_set;
 		drsuapi_DsPartialAttributeSet *partial_attribute_set_ex;
 		drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr;
-		uint32 more_flags;
+		drsuapi_DrsMoreOptions more_flags;
 	} drsuapi_DsGetNCChangesRequest10;
 
 	typedef [switch_type(uint32)] union {
diff --git a/python/samba/join.py b/python/samba/join.py
index c56f8d9..4eb8c58 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -165,6 +165,12 @@ class dc_join(object):
 
         ctx.tmp_samdb = None
 
+        ctx.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
+                             drsuapi.DRSUAPI_DRS_PER_SYNC |
+                             drsuapi.DRSUAPI_DRS_GET_ANC |
+                             drsuapi.DRSUAPI_DRS_GET_NC_SIZE |
+                             drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+
         # these elements are optional
         ctx.never_reveal_sid = None
         ctx.reveal_sid = None
@@ -891,13 +897,11 @@ class dc_join(object):
                 # Replicate first the critical object for the basedn
                 if not ctx.domain_replica_flags & drsuapi.DRSUAPI_DRS_CRITICAL_ONLY:
                     print "Replicating critical objects from the base DN of the domain"
-                    ctx.domain_replica_flags |= drsuapi.DRSUAPI_DRS_CRITICAL_ONLY | drsuapi.DRSUAPI_DRS_GET_ANC
+                    ctx.domain_replica_flags |= drsuapi.DRSUAPI_DRS_CRITICAL_ONLY
                     repl.replicate(ctx.base_dn, source_dsa_invocation_id,
                                 destination_dsa_guid, rodc=ctx.RODC,
                                 replica_flags=ctx.domain_replica_flags)
                     ctx.domain_replica_flags ^= drsuapi.DRSUAPI_DRS_CRITICAL_ONLY
-                else:
-                    ctx.domain_replica_flags |= drsuapi.DRSUAPI_DRS_GET_ANC
                 repl.replicate(ctx.base_dn, source_dsa_invocation_id,
                                destination_dsa_guid, rodc=ctx.RODC,
                                replica_flags=ctx.domain_replica_flags)
@@ -1226,11 +1230,7 @@ def join_RODC(logger=None, server=None, creds=None, lp=None, site=None, netbios_
     ctx.connection_dn = "CN=RODC Connection (FRS),%s" % ctx.ntds_dn
     ctx.secure_channel_type = misc.SEC_CHAN_RODC
     ctx.RODC = True
-    ctx.replica_flags  =  (drsuapi.DRSUAPI_DRS_INIT_SYNC |
-                           drsuapi.DRSUAPI_DRS_PER_SYNC |
-                           drsuapi.DRSUAPI_DRS_GET_ANC |
-                           drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
-                           drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
+    ctx.replica_flags |= ( drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
                            drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
     ctx.domain_replica_flags = ctx.replica_flags
     if domain_critical_only:
@@ -1260,12 +1260,8 @@ def join_DC(logger=None, server=None, creds=None, lp=None, site=None, netbios_na
     ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
     ctx.secure_channel_type = misc.SEC_CHAN_BDC
 
-    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
-                         drsuapi.DRSUAPI_DRS_INIT_SYNC |
-                         drsuapi.DRSUAPI_DRS_PER_SYNC |
-                         drsuapi.DRSUAPI_DRS_GET_ANC |
-                         drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
-                         drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+    ctx.replica_flags |= (drsuapi.DRSUAPI_DRS_WRIT_REP |
+                          drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS)
     ctx.domain_replica_flags = ctx.replica_flags
     if domain_critical_only:
         ctx.domain_replica_flags |= drsuapi.DRSUAPI_DRS_CRITICAL_ONLY
@@ -1285,12 +1281,8 @@ def join_clone(logger=None, server=None, creds=None, lp=None,
     lp.set("realm", ctx.realm)
     logger.info("realm is %s" % ctx.realm)
 
-    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
-                         drsuapi.DRSUAPI_DRS_INIT_SYNC |
-                         drsuapi.DRSUAPI_DRS_PER_SYNC |
-                         drsuapi.DRSUAPI_DRS_GET_ANC |
-                         drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
-                         drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+    ctx.replica_flags |= (drsuapi.DRSUAPI_DRS_WRIT_REP |
+                          drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS)
     if not include_secrets:
         ctx.replica_flags |= drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING
     ctx.domain_replica_flags = ctx.replica_flags
@@ -1341,12 +1333,8 @@ def join_subdomain(logger=None, server=None, creds=None, lp=None, site=None,
     ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
     ctx.secure_channel_type = misc.SEC_CHAN_BDC
 
-    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
-                         drsuapi.DRSUAPI_DRS_INIT_SYNC |
-                         drsuapi.DRSUAPI_DRS_PER_SYNC |
-                         drsuapi.DRSUAPI_DRS_GET_ANC |
-                         drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
-                         drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+    ctx.replica_flags |= (drsuapi.DRSUAPI_DRS_WRIT_REP |
+                          drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS)
     ctx.domain_replica_flags = ctx.replica_flags
 
     ctx.do_join()
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index edba4c4..6b85ad6 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -89,7 +89,7 @@ struct dreplsrv_partition {
 	/* 
 	 * uptodate vector needs to be updated before and after each DsGetNCChanges() call
 	 *
-	 * - before: we need to use our own invocationId together with our highestCommitedUsn
+	 * - before: we need to use our own invocationId together with our highestCommittedUSN
 	 * - after: we need to merge in the remote uptodatevector, to avoid reading it again
 	 */
 	struct replUpToDateVectorCtr2 uptodatevector;
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index fdd2a63..43a3209 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -84,7 +84,7 @@
  *		supportedLDAPVersion:	3
  *					2
  *		supportedLDAPPolicies:	...
- *		highestCommitedUSN:	...
+ *		highestCommittedUSN:	...
  *		supportedSASLMechanisms:GSSAPI
  *					GSS-SPNEGO
  *					EXTERNAL
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index 705c8cf..09b6d89 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -37,13 +37,18 @@
 #include "lib/util/tsort.h"
 #include "auth/session.h"
 #include "dsdb/common/util.h"
+#include "lib/dbwrap/dbwrap.h"
+#include "lib/dbwrap/dbwrap_rbt.h"
+#include "librpc/gen_ndr/ndr_misc.h"
 
 /* state of a partially completed getncchanges call */
 struct drsuapi_getncchanges_state {
+	struct db_context *anc_cache;
 	struct GUID *guids;
 	uint32_t num_records;
 	uint32_t num_processed;
 	struct ldb_dn *ncRoot_dn;
+	struct GUID ncRoot_guid;
 	bool is_schema_nc;
 	uint64_t min_usn;
 	uint64_t max_usn;
@@ -88,7 +93,7 @@ static int drsuapi_DsReplicaHighWaterMark_cmp(const struct drsuapi_DsReplicaHigh
   build a DsReplicaObjectIdentifier from a ldb msg
  */
 static struct drsuapi_DsReplicaObjectIdentifier *get_object_identifier(TALLOC_CTX *mem_ctx,
-								       struct ldb_message *msg)
+								       const struct ldb_message *msg)
 {
 	struct drsuapi_DsReplicaObjectIdentifier *identifier;
 	struct dom_sid *sid;
@@ -189,7 +194,7 @@ fail:
   drsuapi_DsGetNCChanges for one object
 */
 static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItemEx *obj,
-					  struct ldb_message *msg,
+					  const struct ldb_message *msg,
 					  struct ldb_context *sam_ctx,
 					  struct ldb_dn *ncRoot_dn,
 					  bool   is_schema_nc,
@@ -211,6 +216,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
 	uint32_t *attids;
 	const char *rdn;
 	const struct dsdb_attribute *rdn_sa;
+	uint64_t uSNChanged;
 	unsigned int instanceType;
 	struct dsdb_syntax_ctx syntax_ctx;
 
@@ -218,6 +224,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
 	dsdb_syntax_ctx_init(&syntax_ctx, sam_ctx, schema);
 	syntax_ctx.is_schema_nc = is_schema_nc;
 
+	uSNChanged = ldb_msg_find_attr_as_uint64(msg, "uSNChanged", 0);
 	instanceType = ldb_msg_find_attr_as_uint(msg, "instanceType", 0);
 	if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
 		obj->is_nc_prefix = true;
@@ -248,6 +255,11 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
 		return WERR_OK;
 	}
 
+	if (uSNChanged <= highest_usn) {
+		/* nothing to send */
+		return WERR_OK;
+	}
+
 	ndr_err = ndr_pull_struct_blob(md_value, obj, &md,
 				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -446,7 +458,7 @@ static WERROR get_nc_changes_add_la(TALLOC_CTX *mem_ctx,
 				    struct ldb_context *sam_ctx,
 				    const struct dsdb_schema *schema,
 				    const struct dsdb_attribute *sa,
-				    struct ldb_message *msg,
+				    const struct ldb_message *msg,
 				    struct dsdb_dn *dsdb_dn,
 				    struct drsuapi_DsReplicaLinkedAttribute **la_list,
 				    uint32_t *la_count,
@@ -575,14 +587,30 @@ static WERROR get_nc_changes_add_links(struct ldb_context *sam_ctx,
 				       struct dsdb_schema *schema,
 				       uint64_t highest_usn,
 				       uint32_t replica_flags,
-				       struct ldb_message *msg,
+				       const struct ldb_message *msg,
 				       struct drsuapi_DsReplicaLinkedAttribute **la_list,
 				       uint32_t *la_count,
 				       struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector)
 {
 	unsigned int i;
-	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-	uint64_t uSNChanged = ldb_msg_find_attr_as_int(msg, "uSNChanged", -1);
+	TALLOC_CTX *tmp_ctx = NULL;
+	uint64_t uSNChanged = ldb_msg_find_attr_as_uint64(msg, "uSNChanged", 0);
+	bool is_critical = ldb_msg_find_attr_as_bool(msg, "isCriticalSystemObject", false);
+
+	if (replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) {
+		if (!is_critical) {
+			return WERR_OK;
+		}
+	}
+
+	if (uSNChanged <= highest_usn) {
+		return WERR_OK;
+	}
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		return WERR_NOT_ENOUGH_MEMORY;
+	}
 
 	for (i=0; i<msg->num_elements; i++) {
 		struct ldb_message_element *el = &msg->elements[i];
@@ -633,7 +661,7 @@ static WERROR get_nc_changes_add_links(struct ldb_context *sam_ctx,
 				return WERR_DS_DRA_INTERNAL_ERROR;
 			}
 
-			if (local_usn < highest_usn) {
+			if (local_usn <= highest_usn) {
 				continue;
 			}
 
@@ -724,16 +752,6 @@ struct drsuapi_changed_objects {
 };
 
 /*
-  sort the objects we send by tree order
- */
-static int site_res_cmp_anc_order(struct drsuapi_changed_objects *m1,
-				  struct drsuapi_changed_objects *m2,
-				  struct drsuapi_getncchanges_state *getnc_state)
-{
-	return ldb_dn_compare(m2->dn, m1->dn);
-}
-
-/*
   sort the objects we send first by uSNChanged
  */
 static int site_res_cmp_usn_order(struct drsuapi_changed_objects *m1,
@@ -1468,18 +1486,19 @@ static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state,
 	int ret;
 	char* search_filter;
 	enum ldb_scope scope = LDB_SCOPE_SUBTREE;
-	//const char *extra_filter;
 	struct drsuapi_getncchanges_state *getnc_state = b_state->getncchanges_state;
+	bool critical_only = false;
+
+	if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) {
+		critical_only = true;
+	}
 
 	if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ ||
 	    req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) {
 		scope = LDB_SCOPE_BASE;
+		critical_only = false;
 	}
 
-	//extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter");
-
-	//getnc_state->min_usn = req10->highwatermark.highest_usn;
-
 	/* Construct response. */
 	search_filter = talloc_asprintf(mem_ctx,
 					"(uSNChanged>=%llu)",
@@ -1489,7 +1508,7 @@ static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state,
 		search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter);
 	}
 
-	if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) {
+	if (critical_only) {
 		search_filter = talloc_asprintf(mem_ctx,
 						"(&%s(isCriticalSystemObject=TRUE))",
 						search_filter);
@@ -1684,6 +1703,95 @@ static WERROR getncchanges_collect_objects_exop(struct drsuapi_bind_state *b_sta
 	}
 }
 
+static void dcesrv_drsuapi_update_highwatermark(const struct ldb_message *msg,
+						uint64_t max_usn,
+						struct drsuapi_DsReplicaHighWaterMark *hwm)
+{
+	uint64_t uSN = ldb_msg_find_attr_as_uint64(msg, "uSNChanged", 0);
+
+	if (uSN > max_usn) {
+		/*
+		 * Only report the max_usn we had at the start
+		 * of the replication cycle.
+		 *
+		 * If this object has changed lately we better
+		 * let the destination dsa refetch the change.
+		 * This is better than the risk of loosing some
+		 * objects or linked attributes.
+		 */
+		return;
+	}
+
+	if (uSN <= hwm->tmp_highest_usn) {
+		return;
+	}
+
+	hwm->tmp_highest_usn = uSN;
+	hwm->reserved_usn = 0;
+}
+
+static WERROR dcesrv_drsuapi_anc_cache_add(struct db_context *anc_cache,
+					   const struct GUID *guid)
+{
+	enum ndr_err_code ndr_err;
+	uint8_t guid_buf[16] = { 0, };
+	DATA_BLOB b = {
+		.data = guid_buf,
+		.length = sizeof(guid_buf),
+	};
+	TDB_DATA key = {
+		.dptr = b.data,
+		.dsize = b.length,
+	};
+	TDB_DATA val = {
+		.dptr = NULL,
+		.dsize = 0,
+	};
+	NTSTATUS status;
+
+	ndr_err = ndr_push_struct_into_fixed_blob(&b, guid,
+			(ndr_push_flags_fn_t)ndr_push_GUID);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return WERR_DS_DRA_INTERNAL_ERROR;
+	}
+
+	status = dbwrap_store(anc_cache, key, val, TDB_REPLACE);
+	if (!NT_STATUS_IS_OK(status)) {
+		return WERR_DS_DRA_INTERNAL_ERROR;
+	}
+
+	return WERR_OK;
+}
+
+static WERROR dcesrv_drsuapi_anc_cache_exists(struct db_context *anc_cache,
+					      const struct GUID *guid)
+{
+	enum ndr_err_code ndr_err;
+	uint8_t guid_buf[16] = { 0, };
+	DATA_BLOB b = {
+		.data = guid_buf,
+		.length = sizeof(guid_buf),
+	};
+	TDB_DATA key = {
+		.dptr = b.data,
+		.dsize = b.length,
+	};
+	bool exists;
+
+	ndr_err = ndr_push_struct_into_fixed_blob(&b, guid,
+			(ndr_push_flags_fn_t)ndr_push_GUID);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return WERR_DS_DRA_INTERNAL_ERROR;
+	}
+
+	exists = dbwrap_exists(anc_cache, key);
+	if (!exists) {
+		return WERR_OBJECT_NOT_FOUND;
+	}
+
+	return WERR_OBJECT_NAME_EXISTS;
+}
+
 /* 
   drsuapi_DsGetNCChanges
 
@@ -1932,6 +2040,19 @@ allowed:
 		}
 		b_state->getncchanges_state = getnc_state;
 		getnc_state->ncRoot_dn = drs_ObjectIdentifier_to_dn(getnc_state, sam_ctx, ncRoot);
+		if (getnc_state->ncRoot_dn == NULL) {
+			return WERR_NOT_ENOUGH_MEMORY;
+		}
+
+		ret = dsdb_find_guid_by_dn(b_state->sam_ctx_system,
+					   getnc_state->ncRoot_dn,
+					   &getnc_state->ncRoot_guid);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(0,(__location__ ": Failed to find GUID of ncRoot_dn %s\n",
+				 ldb_dn_get_linearized(getnc_state->ncRoot_dn)));
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+		ncRoot->guid = getnc_state->ncRoot_guid;
 
 		/* find out if we are to replicate Schema NC */
 		ret = ldb_dn_compare_base(ldb_get_schema_basedn(b_state->sam_ctx),
@@ -2009,6 +2130,8 @@ allowed:
 		return WERR_DS_DRA_INVALID_PARAMETER;
 	}
 
+	ncRoot->guid = getnc_state->ncRoot_guid;
+
 	/* we need the session key for encrypting password attributes */
 	status = dcesrv_inherited_session_key(dce_call->conn, &session_key);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -2023,10 +2146,33 @@ allowed:
 	if (getnc_state->guids == NULL) {
 		const char *extra_filter;
 		struct ldb_result *search_res = NULL;
+		static const struct drsuapi_DsReplicaCursorCtrEx empty_udv;
+		const struct drsuapi_DsReplicaCursorCtrEx *udv = NULL;
 
 		extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter");
 
+		if (req10->uptodateness_vector != NULL) {
+			udv = req10->uptodateness_vector;
+		} else {
+			udv = &empty_udv;
+		}
+
 		getnc_state->min_usn = req10->highwatermark.highest_usn;
+		for (i = 0; i < udv->count; i++) {
+			bool match;
+			const struct drsuapi_DsReplicaCursor *cur =
+				&udv->cursors[i];
+
+			match = GUID_equal(&invocation_id,
+					   &cur->source_dsa_invocation_id);
+			if (!match) {
+				continue;
+			}
+			if (cur->highest_usn > getnc_state->min_usn) {
+				getnc_state->min_usn = cur->highest_usn;
+			}
+			break;
+		}
 		getnc_state->max_usn = getnc_state->min_usn;
 
 		getnc_state->final_udv = talloc_zero(getnc_state,
@@ -2075,11 +2221,6 @@ allowed:
 		/* RID_ALLOC returns 3 objects in a fixed order */
 		if (req10->extended_op == DRSUAPI_EXOP_FSMO_RID_ALLOC) {
 			/* Do nothing */
-		} else if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) {
-			LDB_TYPESAFE_QSORT(changes,
-					   getnc_state->num_records,
-					   getnc_state,
-					   site_res_cmp_anc_order);
 		} else {
 			LDB_TYPESAFE_QSORT(changes,
 					   getnc_state->num_records,
@@ -2102,6 +2243,15 @@ allowed:
 
 		talloc_free(search_res);
 		talloc_free(changes);
+
+		if (req10->extended_op != DRSUAPI_EXOP_NONE) {
+			/* Do nothing */
+		} else if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list