[SCM] Samba Shared Repository - branch master updated
Andrew Tridgell
tridge at samba.org
Fri Jan 8 19:54:19 MST 2010
The branch, master has been updated
via 349f7ba... s4-drs: added filtering by udv in getncchanges
via b0090d0... s4-idl: give a enum for attribute cn and a 'NONE' attribute
from 9e6eb22... s4-drs: fixed the NC in the getncchanges RID alloc reply
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 349f7ba09c4cda14eea4df69bd6dcb082fc23c8d
Author: Andrew Tridgell <tridge at samba.org>
Date: Sat Jan 9 13:11:27 2010 +1100
s4-drs: added filtering by udv in getncchanges
When a client supplied an uptodateness_vector, we can use it to filter
what objects we return. This greatly reduces the amount of replication
traffic between DCs.
commit b0090d01e061220d9b70a14e5a88b683949fe6a5
Author: Andrew Tridgell <tridge at samba.org>
Date: Sat Jan 9 13:10:28 2010 +1100
s4-idl: give a enum for attribute cn and a 'NONE' attribute
The 'NONE' attribute has value 0xFFFFFFFF. Adding this ensures the
compiler will complain if it is set to use 16 bit enums. We rely on
being able to store 32 bits in an attid enum.
-----------------------------------------------------------------------
Summary of changes:
librpc/gen_ndr/drsuapi.h | 6 ++-
librpc/gen_ndr/ndr_drsuapi.c | 2 +
librpc/idl/drsuapi.idl | 4 +-
source4/dsdb/common/util.c | 6 +++
source4/rpc_server/drsuapi/getncchanges.c | 66 +++++++++++++++++++++++++----
5 files changed, 73 insertions(+), 11 deletions(-)
Changeset truncated at 500 lines:
diff --git a/librpc/gen_ndr/drsuapi.h b/librpc/gen_ndr/drsuapi.h
index 8596bf3..1f5960d 100644
--- a/librpc/gen_ndr/drsuapi.h
+++ b/librpc/gen_ndr/drsuapi.h
@@ -326,6 +326,7 @@ enum drsuapi_DsAttributeId
#ifndef USE_UINT_ENUMS
{
DRSUAPI_ATTRIBUTE_objectClass=(int)(0x00000000),
+ DRSUAPI_ATTRIBUTE_cn=(int)(0x00000003),
DRSUAPI_ATTRIBUTE_description=(int)(0x0000000d),
DRSUAPI_ATTRIBUTE_member=(int)(0x0000001f),
DRSUAPI_ATTRIBUTE_instanceType=(int)(0x00020001),
@@ -396,11 +397,13 @@ enum drsuapi_DsAttributeId
DRSUAPI_ATTRIBUTE_msDS_Behavior_Version=(int)(0x000905b3),
DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber=(int)(0x000906f6),
DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs=(int)(0x0009071c),
- DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs=(int)(0x0009072c)
+ DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs=(int)(0x0009072c),
+ DRSUAPI_ATTRIBUTE_NONE=(int)(0xFFFFFFFF)
}
#else
{ __donnot_use_enum_drsuapi_DsAttributeId=0x7FFFFFFF}
#define DRSUAPI_ATTRIBUTE_objectClass ( 0x00000000 )
+#define DRSUAPI_ATTRIBUTE_cn ( 0x00000003 )
#define DRSUAPI_ATTRIBUTE_description ( 0x0000000d )
#define DRSUAPI_ATTRIBUTE_member ( 0x0000001f )
#define DRSUAPI_ATTRIBUTE_instanceType ( 0x00020001 )
@@ -472,6 +475,7 @@ enum drsuapi_DsAttributeId
#define DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber ( 0x000906f6 )
#define DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs ( 0x0009071c )
#define DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs ( 0x0009072c )
+#define DRSUAPI_ATTRIBUTE_NONE ( 0xFFFFFFFF )
#endif
;
diff --git a/librpc/gen_ndr/ndr_drsuapi.c b/librpc/gen_ndr/ndr_drsuapi.c
index 16388e7..5b31d1e 100644
--- a/librpc/gen_ndr/ndr_drsuapi.c
+++ b/librpc/gen_ndr/ndr_drsuapi.c
@@ -1379,6 +1379,7 @@ _PUBLIC_ void ndr_print_drsuapi_DsAttributeId(struct ndr_print *ndr, const char
ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX);
switch (r) {
case DRSUAPI_ATTRIBUTE_objectClass: val = "DRSUAPI_ATTRIBUTE_objectClass"; break;
+ case DRSUAPI_ATTRIBUTE_cn: val = "DRSUAPI_ATTRIBUTE_cn"; break;
case DRSUAPI_ATTRIBUTE_description: val = "DRSUAPI_ATTRIBUTE_description"; break;
case DRSUAPI_ATTRIBUTE_member: val = "DRSUAPI_ATTRIBUTE_member"; break;
case DRSUAPI_ATTRIBUTE_instanceType: val = "DRSUAPI_ATTRIBUTE_instanceType"; break;
@@ -1450,6 +1451,7 @@ _PUBLIC_ void ndr_print_drsuapi_DsAttributeId(struct ndr_print *ndr, const char
case DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber: val = "DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber"; break;
case DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs: val = "DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs"; break;
case DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs: val = "DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs"; break;
+ case DRSUAPI_ATTRIBUTE_NONE: val = "DRSUAPI_ATTRIBUTE_NONE"; break;
}
ndr_print_enum(ndr, name, "ENUM", val, r);
ndr->flags = _flags_save_ENUM;
diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
index 2994958..dadaeee 100644
--- a/librpc/idl/drsuapi.idl
+++ b/librpc/idl/drsuapi.idl
@@ -437,6 +437,7 @@ interface drsuapi
typedef [flag(NDR_PAHEX),v1_enum,public] enum {
DRSUAPI_ATTRIBUTE_objectClass = 0x00000000,
+ DRSUAPI_ATTRIBUTE_cn = 0x00000003,
DRSUAPI_ATTRIBUTE_description = 0x0000000d,
DRSUAPI_ATTRIBUTE_member = 0x0000001f,
DRSUAPI_ATTRIBUTE_instanceType = 0x00020001,
@@ -507,7 +508,8 @@ interface drsuapi
DRSUAPI_ATTRIBUTE_msDS_Behavior_Version = 0x000905b3,
DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber = 0x000906f6,
DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs = 0x0009071c,
- DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs = 0x0009072c
+ DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs = 0x0009072c,
+ DRSUAPI_ATTRIBUTE_NONE = 0xFFFFFFFF
} drsuapi_DsAttributeId;
typedef struct {
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 70750ca..632025d 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2810,6 +2810,12 @@ int drsuapi_DsReplicaCursor2_compare(const struct drsuapi_DsReplicaCursor2 *c1,
return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id);
}
+int drsuapi_DsReplicaCursor_compare(const struct drsuapi_DsReplicaCursor *c1,
+ const struct drsuapi_DsReplicaCursor *c2)
+{
+ return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id);
+}
+
/*
see if we are a RODC
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index d0ce819..46996c7 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -30,6 +30,7 @@
#include "rpc_server/dcerpc_server_proto.h"
#include "../libcli/drsuapi/drsuapi.h"
#include "libcli/security/security.h"
+#include "lib/util/binsearch.h"
/*
build a DsReplicaObjectIdentifier from a ldb msg
@@ -57,6 +58,29 @@ static struct drsuapi_DsReplicaObjectIdentifier *get_object_identifier(TALLOC_CT
return identifier;
}
+static int udv_compare(const struct GUID *guid1, struct GUID guid2)
+{
+ return GUID_compare(guid1, &guid2);
+}
+
+/*
+ see if we can filter an attribute using the uptodateness_vector
+ */
+static bool udv_filter(const struct drsuapi_DsReplicaCursorCtrEx *udv,
+ const struct GUID *originating_invocation_id,
+ uint64_t originating_usn)
+{
+ const struct drsuapi_DsReplicaCursor *c;
+ if (udv == NULL) return false;
+ BINARY_ARRAY_SEARCH(udv->cursors, udv->count, source_dsa_invocation_id,
+ originating_invocation_id, udv_compare, c);
+ if (c && originating_usn <= c->highest_usn) {
+ return true;
+ }
+ return false;
+
+}
+
/*
drsuapi_DsGetNCChanges for one object
*/
@@ -67,7 +91,8 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
struct dsdb_schema *schema,
DATA_BLOB *session_key,
uint64_t highest_usn,
- uint32_t replica_flags)
+ uint32_t replica_flags,
+ struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector)
{
const struct ldb_val *md_value;
int i, n;
@@ -156,6 +181,14 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
}
}
+ /* filter by uptodateness_vector */
+ if (md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType &&
+ udv_filter(uptodateness_vector,
+ &md.ctr.ctr1.array[i].originating_invocation_id,
+ md.ctr.ctr1.array[i].originating_usn)) {
+ continue;
+ }
+
obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time;
obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version;
obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id;
@@ -164,11 +197,15 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
n++;
}
- /*
- note that if n==0 we still need to send the change, as it
- could be a rename, which changes the uSNChanged, but not any
- of the replicated attributes
- */
+ /* ignore it if its an empty change. Note that renames always
+ * change the 'name' attribute, so they won't be ignored by
+ * this */
+ if (n == 0 ||
+ (n == 1 && attids[0] == DRSUAPI_ATTRIBUTE_instanceType)) {
+ talloc_free(obj->meta_data_ctr);
+ obj->meta_data_ctr = NULL;
+ return WERR_OK;
+ }
obj->meta_data_ctr->count = n;
@@ -302,7 +339,8 @@ static WERROR get_nc_changes_add_links(struct ldb_context *sam_ctx,
uint32_t replica_flags,
struct ldb_message *msg,
struct drsuapi_DsReplicaLinkedAttribute **la_list,
- uint32_t *la_count)
+ uint32_t *la_count,
+ struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector)
{
int i;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
@@ -668,6 +706,7 @@ struct drsuapi_getncchanges_state {
struct ldb_dn *last_dn;
struct drsuapi_DsReplicaLinkedAttribute *la_list;
uint32_t la_count;
+ struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector;
};
/*
@@ -880,6 +919,14 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
(comparison_fn_t)site_res_cmp_usn_order);
}
+ getnc_state->uptodateness_vector = talloc_steal(getnc_state, req8->uptodateness_vector);
+ if (getnc_state->uptodateness_vector) {
+ /* make sure its sorted */
+ qsort(getnc_state->uptodateness_vector->cursors,
+ getnc_state->uptodateness_vector->count,
+ sizeof(getnc_state->uptodateness_vector->cursors[0]),
+ (comparison_fn_t)drsuapi_DsReplicaCursor_compare);
+ }
}
/* Prefix mapping */
@@ -935,7 +982,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
werr = get_nc_changes_build_object(obj, msg,
b_state->sam_ctx, getnc_state->ncRoot_dn,
schema, &session_key, getnc_state->min_usn,
- req8->replica_flags);
+ req8->replica_flags, getnc_state->uptodateness_vector);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@@ -946,7 +993,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
req8->replica_flags,
msg,
&getnc_state->la_list,
- &getnc_state->la_count);
+ &getnc_state->la_count,
+ getnc_state->uptodateness_vector);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list