Skip to content

Commit

Permalink
getncchanges: Match Windows on linked attribute sort
Browse files Browse the repository at this point in the history
The order of linked attributes depends on comparison of the NDR packed
GUIDs (not its struct GUID form).

Signed-off-by: Garming Sam <[email protected]>
Reviewed-by: Andrew Bartlett <[email protected]>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11960
  • Loading branch information
GSam authored and abartlet committed Jun 17, 2016
1 parent 570237f commit 8dc3110
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
1 change: 0 additions & 1 deletion selftest/knownfail
Original file line number Diff line number Diff line change
Expand Up @@ -330,4 +330,3 @@
# ad_dc requires signing
#
^samba4.smb.signing.*disabled.*signing=off.*\(ad_dc\)
^samba4.drs.getnc_exop.python.*.getnc_exop.DrsReplicaSyncSortTestCase
30 changes: 22 additions & 8 deletions source4/rpc_server/drsuapi/getncchanges.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ struct drsuapi_getncchanges_state {
uint32_t la_idx;
};

/* We must keep the GUIDs in NDR form for sorting */
struct la_for_sorting {
struct drsuapi_DsReplicaLinkedAttribute *link;
struct GUID target_guid;
DATA_BLOB target_guid;
DATA_BLOB source_guid;
};

static int drsuapi_DsReplicaHighWaterMark_cmp(const struct drsuapi_DsReplicaHighWaterMark *h1,
Expand Down Expand Up @@ -636,8 +638,8 @@ static int linked_attribute_compare(const struct la_for_sorting *la1,
void *opaque)
{
int c;
c = GUID_compare(&la1->link->identifier->guid,
&la2->link->identifier->guid);
c = data_blob_cmp(&la1->source_guid,
&la2->source_guid);
if (c != 0) {
return c;
}
Expand All @@ -652,7 +654,7 @@ static int linked_attribute_compare(const struct la_for_sorting *la1,
DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)? 1:-1;
}

return GUID_compare(&la1->target_guid, &la2->target_guid);
return data_blob_cmp(&la1->target_guid, &la2->target_guid);
}

struct drsuapi_changed_objects {
Expand Down Expand Up @@ -2205,8 +2207,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
/* we need to get the target GUIDs to compare */
struct dsdb_dn *dn;
const struct drsuapi_DsReplicaLinkedAttribute *la = &getnc_state->la_list[j];
struct GUID guid;
const struct dsdb_attribute *schema_attrib;
const struct ldb_val *target_guid;
DATA_BLOB source_guid;

schema_attrib = dsdb_attribute_by_attributeID_id(schema, la->attid);

Expand All @@ -2217,7 +2220,17 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
return werr;
}

status = dsdb_get_extended_dn_guid(dn->dn, &guid, "GUID");
/* Extract the target GUID in NDR form */
target_guid = ldb_dn_get_extended_component(dn->dn, "GUID");
if (target_guid == NULL) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
} else {
/* Repack the source GUID as NDR for sorting */
status = GUID_to_ndr_blob(&la->identifier->guid,
tmp_ctx,
&source_guid);
}

if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,(__location__ ": Bad la guid in sort\n"));
talloc_free(tmp_ctx);
Expand All @@ -2226,12 +2239,12 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_

guid_array[j] = (struct la_for_sorting)
{
.target_guid = guid,
.source_guid = source_guid,
.target_guid = *target_guid,
.link = &getnc_state->la_list[j]
};
}

TALLOC_FREE(tmp_ctx);
LDB_TYPESAFE_QSORT(guid_array, getnc_state->la_count, NULL, linked_attribute_compare);

/* apply the sort to the original list */
Expand All @@ -2242,6 +2255,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
getnc_state->la_count * sizeof(struct drsuapi_DsReplicaLinkedAttribute));

getnc_state->la_sorted = true;
TALLOC_FREE(tmp_ctx);
}

link_count = getnc_state->la_count - getnc_state->la_idx;
Expand Down

0 comments on commit 8dc3110

Please sign in to comment.