From 61b978872fe86906611f64430b2608f5e7ea7ad8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Feb 2014 22:59:06 +1300 Subject: [PATCH] dsdb: Ensure to sort replPropertyMetaData as UNSIGNED, not SIGNED quantities enum is an int, and therefore signed. Some attributes have the high bit set. Andrew Bartlett Change-Id: I39a5499b7c6bbb763e15977d802cda8c69b94618 Signed-off-by: Andrew Bartlett Reviewed-on: https://gerrit.samba.org/163 Reviewed-by: Kamen Mazdrashki Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Mar 14 10:16:41 CET 2014 on sn-devel-104 --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index c5dcf2140f1..e96bdf14495 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -660,7 +660,15 @@ static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMeta const struct replPropertyMetaData1 *m2, const uint32_t *rdn_attid) { - if (m1->attid == m2->attid) { + /* + * This assignment seems inoccous, but it is critical for the + * system, as we need to do the comparisons as a unsigned + * quantity, not signed (enums are signed integers) + */ + uint32_t attid_1 = m1->attid; + uint32_t attid_2 = m2->attid; + + if (attid_1 == attid_2) { return 0; } @@ -669,7 +677,7 @@ static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMeta * so we need to return a value greater than zero * which means m1 is greater than m2 */ - if (m1->attid == *rdn_attid) { + if (attid_1 == *rdn_attid) { return 1; } @@ -678,11 +686,17 @@ static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMeta * so we need to return a value less than zero * which means m2 is greater than m1 */ - if (m2->attid == *rdn_attid) { + if (attid_2 == *rdn_attid) { return -1; } - return m1->attid > m2->attid ? 1 : -1; + /* + * See above regarding this being an unsigned comparison. + * Otherwise when the high bit is set on non-standard + * attributes, they would end up first, before objectClass + * (0). + */ + return attid_1 > attid_2 ? 1 : -1; } static int replmd_replPropertyMetaDataCtr1_sort(struct replPropertyMetaDataCtr1 *ctr1, -- 2.11.4.GIT