dsdb: Ensure to sort replPropertyMetaData as UNSIGNED, not SIGNED quantities
authorAndrew Bartlett <abartlet@samba.org>
Fri, 28 Feb 2014 09:59:06 +0000 (22:59 +1300)
committerKarolin Seeger <kseeger@samba.org>
Tue, 15 Jul 2014 10:46:14 +0000 (12:46 +0200)
enum is an int, and therefore signed.  Some attributes have the high bit set.

Andrew Bartlett

Change-Id: I39a5499b7c6bbb763e15977d802cda8c69b94618
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-on: https://gerrit.samba.org/163
Reviewed-by: Kamen Mazdrashki <kamenim@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Fri Mar 14 10:16:41 CET 2014 on sn-devel-104

(cherry picked from commit 61b978872fe86906611f64430b2608f5e7ea7ad8)

source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 9d1bac43456885de90828339a8aa957ae649d08f..6455ef93953783ba1aa10d8f42cc969699135b83 100644 (file)
@@ -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,