ldb:dn: make ldb_dn_compare() self-consistent
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Sun, 7 Apr 2024 03:04:43 +0000 (15:04 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 23 Apr 2024 01:33:29 +0000 (01:33 +0000)
We were returning -1 in all these cases:

   ldb_dn_compare(dn, NULL);
   ldb_dn_compare(NULL, dn);
   ldb_dn_compare(NULL, NULL);

which would give strange results in sort, where this is often used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/common/ldb_dn.c

index 7325a000f0a97560fbab55c29ccdedb7aeea0efb..4204861c0f91f0e7745179bbde87ff09617b90bd 100644 (file)
@@ -1132,8 +1132,22 @@ int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
 {
        unsigned int i;
        int ret;
+       /*
+        * If used in sort, we shift NULL and invalid DNs to the end.
+        *
+        * If ldb_dn_casefold_internal() fails, that goes to the end too, so
+        * we end up with:
+        *
+        * | normal DNs, sorted | casefold failed DNs | invalid DNs | NULLs |
+        */
 
-       if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
+       if (dn0 == dn1 || (dn0->invalid && dn1->invalid)) {
+               return 0;
+       }
+       if (dn0 == NULL || dn0->invalid) {
+               return 1;
+       }
+       if (dn1 == NULL || dn1->invalid) {
                return -1;
        }