The branch, master has been updated
       via  c49c48afe09 ldb:utf8: ldb_ascii_toupper() avoids real toupper()
       via  dca6b2d2552 ldb:attrib_handlers: use ldb_ascii_toupper() in first 
loop
       via  078ecf486a6 ldb:pytests: test for Turkic i-dots in 
ldb_comparison_fold
       via  a75c98ad688 ldb:attrib_handlers: make ldb_comparison_Boolean more 
consistent
       via  7280c8e53f4 ldb-samba:ldif_handlers: dn_link_comparison: sort 
invalid DNs
       via  341b8fb60e2 ldb-samba:ldif_handlers: dn_link_comparison leaks less
       via  70356592563 ldb-samba:ldif_handlers: dn_link_comparison correctly 
sorts deleted objects
       via  11d5a809325 ldb-samba:ldif_handlers: dn_link_comparison semi-sorts 
invalid DNs
       via  db963b1674e ldb-samba:ldif_handlers: dn_link_comparison semi-sorts 
deleted objects
       via  2d3b917d0a0 ldb-samba:ldif_handlers: extended_dn_read_Sid(): free 
on failure
       via  42f2d96f82a ldb-samba:ldif_handlers: ldif_read_objectSid(): free a 
thing on failure
       via  6722e80d1b3 ldb-samba: ldif-handlers: make 
ldif_comparison_objectSid() accurate
       via  4af670384a1 s4:dsdb: fix spelling in comment
       via  a9eaf8a3abe ldb: comment for ldb_dn_compare_base
       via  6229feab74a s4:rpcsrv:samr: improve a comment in compare_msgRid
       via  7be535315a5 s4:rpcsrv:dnsserver: make dns_name_compare transitive 
with NULLs
       via  31c322874b8 s3:libsmb:nmblib: use NUMERIC_CMP in status_compare
       via  7ba6fcb9365 lib/socket: rearrange iface_comp() to use NUMERIC_CMP
       via  acaa1323d03 gensec: sort_gensec uses NUMERIC_CMP
       via  75682e397b9 s3:rpc:wkssvc_nt: dom_user_cmp uses NUMERIC_CMP
       via  8317a617364 dsdb:schema: use NUMERIC_CMP in place of uint32_cmp
       via  386216d4a15 s3:mod:vfs_vxfs: use NUMERIC_CMP in vxfs_ace_cmp
       via  8b2605a5d9c s3:mod:posixacl_xattr: use NUMERIC_CMP in 
posixacl_xattr_entry_compare
       via  9b73235d495 s3:brlock: use NUMERIC_CMP in #ifdef-zeroed lock_compare
       via  5fe488d515a ldb:dn: make ldb_dn_compare() self-consistent
       via  531f31df993 ldb:sort: generalise both-NULL check to equality check
       via  d4e69734c65 ldb:sort: check that elements have values
       via  d785c1991c9 ldb:mod:sort: rearrange NULL checks
      from  20ce68f1594 tests/krb5: Test retrieving a denied gMSA password over 
an unsealed connection

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c49c48afe09a1a78989628bbffd49dd3efc154dd
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sat Apr 20 09:57:15 2024 +1200

    ldb:utf8: ldb_ascii_toupper() avoids real toupper()
    
    If a non-lowercase ASCII character has an uppercase counterpart in
    some locale, toupper() will convert it to an int codepoint. Probably
    that codepoint is too big to fit in our char return type, so we would
    truncate it to 8 bit. So it becomes an arbitrary mapping.
    
    It would also behave strangely with a byte with the top bit set, say
    0xE2. If char is unsigned on this system, that is 'â', which
    uppercases to 'Â', with the codepoint 0xC2. That seems fine in
    isolation, but remember this is ldb_utf8.c, and that byte was not a
    codepoint but a piece of a long utf-8 encoding. In the more likely
    case where char is signed, toupper() is being passed a negative
    number, the result of which is undefined.
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abart...@samba.org>
    Autobuild-Date(master): Tue Apr 23 02:37:25 UTC 2024 on atb-devel-224

commit dca6b2d25529288eaf7b31baf37ca4f6de4f4b9d
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 13:46:28 2024 +1200

    ldb:attrib_handlers: use ldb_ascii_toupper() in first loop
    
    In a dotless-I locale, we might meet an 'i' before we meet a byte with
    the high bit set, in which case we still want the ldb casefold
    comparison.
    
    Many ldb operations will do some case-folding before getting here, so
    hitting this might be quite rare even in those locales.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15637
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 078ecf486a62dc3aaa2842ada96456ac9870dad7
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Apr 17 11:42:30 2024 +1200

    ldb:pytests: test for Turkic i-dots in ldb_comparison_fold
    
    In tr_TR and some other locales where the letter 'i' uppercases to
    'İ', which is not ideal for LDB as we need certain strings like 'guid'
    to casefold in the ASCII way.
    
    In fixing https://bugzilla.samba.org/show_bug.cgi?id=15248) we solved
    this problem in many cases, but for unindexed searches where the 'i'
    is not the last character in the string. This test shows that.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15637
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit a75c98ad688415aec8afc617a759ba90cfd9f23b
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Apr 10 10:54:41 2024 +1200

    ldb:attrib_handlers: make ldb_comparison_Boolean more consistent
    
    This isn't supposed to be used for sorting, but it is hard to say it
    won't be, so we might as well make it sort properly.
    
    Following long-standing behaviour, we try to sort "FALSE" > "TRUE", by
    length, then switch to using strncasecmp().
    
    strncasecmp would sort the other way, so we swap the operands. This is
    to make e.g. "TRUE\0" sort the same as "TRUE".
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 7280c8e53f463108fe3de443ce63572dde689a30
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 18:08:54 2024 +1200

    ldb-samba:ldif_handlers: dn_link_comparison: sort invalid DNs
    
    If both DNs are invalid, we can say they are equal.
    
    This means invalid or NULL DNs will sort to the end of the array,
    before deleted DNs:
    
    [ valid DNs, sorted | invalid/NULL DNs | deleted DNs, sorted ]
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 341b8fb60e291ad598fafd7a09a75e9b249de07f
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:59:50 2024 +1200

    ldb-samba:ldif_handlers: dn_link_comparison leaks less
    
    dn1 and dn2 can be invalid but still occupying memory.
    (ldb_dn_validate(dn2) does contain a NULL check, but a lot more besides).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 70356592563bf758dbe509413445b77bb0d7da14
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:53:03 2024 +1200

    ldb-samba:ldif_handlers: dn_link_comparison correctly sorts deleted objects
    
    This changes the behaviour of the DN syntax .comparison_fn when being
    used in a search, if the search key is a deleted DN.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 11d5a809325369b48d14023adf109e418bb1c7af
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:26:03 2024 +1200

    ldb-samba:ldif_handlers: dn_link_comparison semi-sorts invalid DNs
    
    these tend to go to the end of the sorted array.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit db963b1674ede357d4edba578e0e0372dcb2f287
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:25:02 2024 +1200

    ldb-samba:ldif_handlers: dn_link_comparison semi-sorts deleted objects
    
    We were always returning -1 for a deleted object, which works for an
    equality test, but not a relative comparison.
    
    This sorts deleted DNs toward the end of the list -- except when both
    DNs are deleted. What should happen there is yet to be determined.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 2d3b917d0a078279853bb3926b7dc3584fe53627
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:17:23 2024 +1200

    ldb-samba:ldif_handlers: extended_dn_read_Sid(): free on failure
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 42f2d96f82a8156abb004c68d343c8b769ebea4b
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Apr 11 16:15:39 2024 +1200

    ldb-samba:ldif_handlers: ldif_read_objectSid(): free a thing on failure
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 6722e80d1b3a252a1ed714be4a35185cd99971e3
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Apr 10 10:54:31 2024 +1200

    ldb-samba: ldif-handlers: make ldif_comparison_objectSid() accurate
    
    This function compares blobs that might be SID strings or might be SID
    structures. Until now, if they were both (seemingly) strings, they were
    compared as strings, otherwise if either was a string it was converted to
    a structure blob, then the blobs were compared. This had two big problems:
    
    1. There is variety in the way a SID can be stringified. For example,
       "s-1-02-3" means the same SID as "S-1-2-3", but those wouldn't compare
       equal.
    
    2. SID comparison was crazily non-transitive. Consider the three values
         a = "S-1-2-3-4-5",
         b = "S-1-9-1",
         c = SID("S-1-11-1"), where c is a struct and the others are string.
    
       then we had,
         a < b, because the 5th character '2' < '9'.
         a > c, because when converted to a structure, the number of sub-auths
                is the first varying byte. a has 3, c has 0.
         b < c, because after the sub-auth count comes the id_auth value
                (big-endian, which doesn't matter in this case).
    
    That made the function unreliable for sorting, AND for simple equality
    tests. Also it leaked.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 4af670384a10a8571bc24ff2d7933160ee7adc62
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Apr 10 16:49:07 2024 +1200

    s4:dsdb: fix spelling in comment
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit a9eaf8a3abe66e1a5ff31fa405442f9a09f1dbc5
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Apr 10 16:48:39 2024 +1200

    ldb: comment for ldb_dn_compare_base
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 6229feab74a734190c302ee9b1cc36960669743d
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Mon Apr 8 22:55:50 2024 +1200

    s4:rpcsrv:samr: improve a comment in compare_msgRid
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 7be535315a5eed5d5b7eaea025ecf9f55e772e8e
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Mon Apr 8 22:54:49 2024 +1200

    s4:rpcsrv:dnsserver: make dns_name_compare transitive with NULLs
    
    Returning 0 on `(name1 == NULL || name2 == NULL)` made NULL equal to
    everything, which confuses a sort (consider {A, B, NULL} where A > B,
    but A == NULL == B).
    
    The only caller is dnsserver_enumerate_records() which fails if it
    finds a NULL in the sorted list. We make the happen more quickly by
    sorting NULLs to the front.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 31c322874b8b65518cec945e05a42fd014e6390b
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Mon Apr 8 17:08:03 2024 +1200

    s3:libsmb:nmblib: use NUMERIC_CMP in status_compare
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 7ba6fcb93656e5e88e1d5bcd6002747aa64f0a3a
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Mon Apr 8 17:06:57 2024 +1200

    lib/socket: rearrange iface_comp() to use NUMERIC_CMP
    
    We rearrange rather than just replacing the subtraction, because that
    would call ntohl() more than necessary, and I think the flow is a bit
    clearer this way.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit acaa1323d0337ae9339dfff9f856ea54725a86ac
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:54:02 2024 +1200

    gensec: sort_gensec uses NUMERIC_CMP
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 75682e397b9cf22d04a5d80252554c6b2e376793
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:47:12 2024 +1200

    s3:rpc:wkssvc_nt: dom_user_cmp uses NUMERIC_CMP
    
    usr->login_time is time_t, which is often bigger than int.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 8317a6173646d425dc99e08bbf3d6086b0086bc5
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:36:06 2024 +1200

    dsdb:schema: use NUMERIC_CMP in place of uint32_cmp
    
    uint32_cmp (introduced in 0c362597c0f933b3612bb17328c0a13b73d72e43
    "fixed the sorting of schema attributes") was doing what NUMERIC_CMP
    does, but it was adding an extra function call. This results in less
    code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 386216d4a158d8bafb0879a0a753da096a939b93
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:17:22 2024 +1200

    s3:mod:vfs_vxfs: use NUMERIC_CMP in vxfs_ace_cmp
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 8b2605a5d9cc14f9e6ddf2db704cdca2f523d74e
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:12:56 2024 +1200

    s3:mod:posixacl_xattr: use NUMERIC_CMP in posixacl_xattr_entry_compare
    
    The first subtraction was between uint16_t, so is safe with 32 bit
    int, but the second compared uint32_t, so was not safe.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 9b73235d4957a487fbb3214fdfda6461a2cf0b21
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:07:20 2024 +1200

    s3:brlock: use NUMERIC_CMP in #ifdef-zeroed lock_compare
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 5fe488d515a8bb719bdeafb8b64d8479732b5ac8
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 15:04:43 2024 +1200

    ldb:dn: make ldb_dn_compare() self-consistent
    
    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.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 531f31df99341b2cb1afc42538022451ca771983
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 14:58:48 2024 +1200

    ldb:sort: generalise both-NULL check to equality check
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit d4e69734c65ade0bbb398447012513a7f27e98bd
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 14:55:27 2024 +1200

    ldb:sort: check that elements have values
    
    We assume no values is unlikely, since we have been dereferencing
    ->values[0] forever, with no known reports of trouble.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit d785c1991c922150bab38c36cef3a799448ac304
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Sun Apr 7 14:54:34 2024 +1200

    ldb:mod:sort: rearrange NULL checks
    
    There are further changes coming here.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 auth/gensec/gensec_start.c                |  2 +-
 lib/ldb-samba/ldif_handlers.c             | 96 ++++++++++++++++++++-----------
 lib/ldb/common/attrib_handlers.c          | 32 +++++++++--
 lib/ldb/common/ldb_dn.c                   | 22 ++++++-
 lib/ldb/common/ldb_utf8.c                 | 12 +++-
 lib/ldb/modules/sort.c                    | 19 +++++-
 lib/ldb/tests/python/api.py               | 16 ++++++
 lib/socket/interfaces.c                   | 22 +++----
 source3/libsmb/nmblib.c                   |  6 +-
 source3/locking/brlock.c                  |  7 +--
 source3/modules/posixacl_xattr.c          |  6 +-
 source3/modules/vfs_vxfs.c                |  6 +-
 source3/rpc_server/wkssvc/srv_wkssvc_nt.c |  2 +-
 source4/dsdb/common/dsdb_dn.c             |  2 +-
 source4/dsdb/schema/schema_set.c          | 14 ++---
 source4/rpc_server/dnsserver/dnsdata.c    | 16 +++++-
 source4/rpc_server/samr/dcesrv_samr.c     |  5 +-
 17 files changed, 202 insertions(+), 83 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index 072188a6752..bcf98bd5968 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -1103,7 +1103,7 @@ _PUBLIC_ const struct gensec_critical_sizes 
*gensec_interface_version(void)
 }
 
 static int sort_gensec(const struct gensec_security_ops **gs1, const struct 
gensec_security_ops **gs2) {
-       return (*gs2)->priority - (*gs1)->priority;
+       return NUMERIC_CMP((*gs2)->priority, (*gs1)->priority);
 }
 
 int gensec_setting_int(struct gensec_settings *settings, const char 
*mechanism, const char *name, int default_value)
diff --git a/lib/ldb-samba/ldif_handlers.c b/lib/ldb-samba/ldif_handlers.c
index c30fd6358c8..f77f86fdcc0 100644
--- a/lib/ldb-samba/ldif_handlers.c
+++ b/lib/ldb-samba/ldif_handlers.c
@@ -110,6 +110,7 @@ static int ldif_read_objectSid(struct ldb_context *ldb, 
void *mem_ctx,
                ndr_err = ndr_push_struct_into_fixed_blob(out, &sid,
                                (ndr_push_flags_fn_t)ndr_push_dom_sid);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       TALLOC_FREE(out->data);
                        return -1;
                }
        }
@@ -150,36 +151,47 @@ bool ldif_comparision_objectSid_isString(const struct 
ldb_val *v)
 
 /*
   compare two objectSids
+
+  If the SIDs seem to be strings, they are converted to binary form.
 */
 static int ldif_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
                                    const struct ldb_val *v1, const struct 
ldb_val *v2)
 {
-       if (ldif_comparision_objectSid_isString(v1) && 
ldif_comparision_objectSid_isString(v2)) {
-               return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
-       } else if (ldif_comparision_objectSid_isString(v1)
-                  && !ldif_comparision_objectSid_isString(v2)) {
-               struct ldb_val v;
-               int ret;
-               if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) {
-                       /* Perhaps not a string after all */
-                       return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
+       bool v1_is_string = ldif_comparision_objectSid_isString(v1);
+       bool v2_is_string = ldif_comparision_objectSid_isString(v2);
+       struct ldb_val parsed_1 = {};
+       struct ldb_val parsed_2 = {};
+       int ret;
+       /*
+        * If the ldb_vals look like SID strings (i.e. start with "S-"
+        * or "s-"), we try to parse them as such. If that fails, we
+        * assume they are binary SIDs, even though that's not really
+        * possible -- the first two bytes of a struct dom_sid are the
+        * version (1), and the number of sub-auths (<= 15), neither
+        * of which are close to 'S' or '-'.
+        */
+       if (v1_is_string) {
+               int r = ldif_read_objectSid(ldb, mem_ctx, v1, &parsed_1);
+               if (r == 0) {
+                       v1 = &parsed_1;
                }
-               ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
-               talloc_free(v.data);
-               return ret;
-       } else if (!ldif_comparision_objectSid_isString(v1)
-                  && ldif_comparision_objectSid_isString(v2)) {
-               struct ldb_val v;
-               int ret;
-               if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) {
-                       /* Perhaps not a string after all */
-                       return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
+       }
+       if (v2_is_string) {
+               int r = ldif_read_objectSid(ldb, mem_ctx, v2, &parsed_2);
+               if (r == 0) {
+                       v2 = &parsed_2;
                }
-               ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v);
-               talloc_free(v.data);
-               return ret;
        }
-       return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
+
+       ret = ldb_comparison_binary(ldb, mem_ctx, v1, v2);
+
+       if (v1_is_string) {
+               TALLOC_FREE(parsed_1.data);
+       }
+       if (v2_is_string) {
+               TALLOC_FREE(parsed_2.data);
+       }
+       return ret;
 }
 
 /*
@@ -223,6 +235,7 @@ static int extended_dn_read_SID(struct ldb_context *ldb, 
void *mem_ctx,
        ndr_err = ndr_pull_struct_blob_all_noalloc(out, &sid,
                                           
(ndr_pull_flags_fn_t)ndr_pull_dom_sid);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               TALLOC_FREE(out->data);
                return -1;
        }
        return 0;
@@ -1148,22 +1161,41 @@ static int samba_ldb_dn_link_comparison(struct 
ldb_context *ldb, void *mem_ctx,
        struct ldb_dn *dn1 = NULL, *dn2 = NULL;
        int ret;
 
+       /*
+        * In a sort context, Deleted DNs get shifted to the end.
+        * They never match in an equality
+        */
        if (dsdb_dn_is_deleted_val(v1)) {
-               /* If the DN is deleted, then we can't search for it */
-               return -1;
-       }
-
-       if (dsdb_dn_is_deleted_val(v2)) {
-               /* If the DN is deleted, then we can't search for it */
+               if (! dsdb_dn_is_deleted_val(v2)) {
+                       return 1;
+               }
+               /*
+                * They are both deleted!
+                *
+                * The soundest thing to do at this point is carry on
+                * and compare the DNs normally. This matches the
+                * behaviour of samba_dn_extended_match() below.
+                */
+       } else if (dsdb_dn_is_deleted_val(v2)) {
                return -1;
        }
 
        dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1);
-       if ( ! ldb_dn_validate(dn1)) return -1;
-
        dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2);
+
+       if ( ! ldb_dn_validate(dn1)) {
+               TALLOC_FREE(dn1);
+               if ( ! ldb_dn_validate(dn2)) {
+                       TALLOC_FREE(dn2);
+                       return 0;
+               }
+               TALLOC_FREE(dn2);
+               return 1;
+       }
+
        if ( ! ldb_dn_validate(dn2)) {
-               talloc_free(dn1);
+               TALLOC_FREE(dn1);
+               TALLOC_FREE(dn2);
                return -1;
        }
 
diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c
index baccf193f88..6ae12c88eec 100644
--- a/lib/ldb/common/attrib_handlers.c
+++ b/lib/ldb/common/attrib_handlers.c
@@ -281,15 +281,36 @@ static int ldb_canonicalise_Boolean(struct ldb_context 
*ldb, void *mem_ctx,
 }
 
 /*
-  compare two Booleans
-*/
+ * compare two Booleans.
+ *
+ * According to RFC4517 4.2.2, "the booleanMatch rule is an equality matching
+ * rule", meaning it isn't used for ordering.
+ *
+ * However, it seems conceivable that Samba could be coerced into sorting on a
+ * field with Boolean syntax, so we might as well have consistent behaviour in
+ * that case.
+ *
+ * The most probably values are {"FALSE", 5} and {"TRUE", 4}. To save time we
+ * compare first by length, which makes FALSE > TRUE. This is somewhat
+ * contrary to convention, but is how Samba has worked forever.
+ *
+ * If somehow we are comparing incompletely normalised values where the length
+ * is the same (for example {"false", 5} and {"TRUE\0", 5}), the length is the
+ * same, and we fall back to a strncasecmp. In this case, since "FALSE" is
+ * alphabetically lower, we swap the order, so that "TRUE\0" again comes
+ * before "FALSE".
+ *
+ * ldb_canonicalise_Boolean (just above) gives us a clue as to what we might
+ * expect to cope with by way of invalid values.
+ */
 static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx,
                           const struct ldb_val *v1, const struct ldb_val *v2)
 {
        if (v1->length != v2->length) {
-               return NUMERIC_CMP(v1->length, v2->length);
+               return NUMERIC_CMP(v2->length, v1->length);
        }
-       return strncasecmp((char *)v1->data, (char *)v2->data, v1->length);
+       /* reversed, see long comment above */
+       return strncasecmp((char *)v2->data, (char *)v1->data, v1->length);
 }
 
 
@@ -330,8 +351,9 @@ int ldb_comparison_fold(struct ldb_context *ldb, void 
*mem_ctx,
                 * never appear in multibyte sequences */
                if (((unsigned char)s1[0]) & 0x80) goto utf8str;
                if (((unsigned char)s2[0]) & 0x80) goto utf8str;
-               if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2))
+               if (ldb_ascii_toupper(*s1) != ldb_ascii_toupper(*s2)) {
                        break;
+               }
                if (*s1 == ' ') {
                        while (n1 > 1 && s1[0] == s1[1]) { s1++; n1--; }
                        while (n2 > 1 && s2[0] == s2[1]) { s2++; n2--; }
diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c
index 7325a000f0a..d2517089da5 100644
--- a/lib/ldb/common/ldb_dn.c
+++ b/lib/ldb/common/ldb_dn.c
@@ -1038,7 +1038,11 @@ char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct 
ldb_dn *dn)
 
 /* Determine if dn is below base, in the ldap tree.  Used for
  * evaluating a subtree search.
- * 0 if they match, otherwise non-zero
+ *
+ * 0 if they match, otherwise non-zero.
+ *
+ * This is not for use in a qsort()-like function, as the comparison
+ * is not symmetric.
  */
 
 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
@@ -1132,8 +1136,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;
        }
 
diff --git a/lib/ldb/common/ldb_utf8.c b/lib/ldb/common/ldb_utf8.c
index f45b72dde50..178bdd86de1 100644
--- a/lib/ldb/common/ldb_utf8.c
+++ b/lib/ldb/common/ldb_utf8.c
@@ -136,5 +136,15 @@ int ldb_attr_dn(const char *attr)
 }
 
 _PRIVATE_ char ldb_ascii_toupper(char c) {
-       return ('a' <= c && c <= 'z') ? c ^ 0x20 : toupper(c);
+       /*
+        * We are aiming for a 1970s C-locale toupper(), when all letters
+        * were 7-bit and behaved with true American spirit.
+        *
+        * For example, we don't want the "i" in "<guid=" to be upper-cased to
+        * "İ" as would happen in some locales, or we won't be able to parse
+        * that properly. This is unfortunate for cases where we are dealing
+        * with real text; a search for the name "Ali" would need to be
+        * written "Alİ" to match.
+        */
+       return ('a' <= c && c <= 'z') ? c ^ 0x20 : c;
 }
diff --git a/lib/ldb/modules/sort.c b/lib/ldb/modules/sort.c
index cb6f8df440f..72c60fc894a 100644
--- a/lib/ldb/modules/sort.c
+++ b/lib/ldb/modules/sort.c
@@ -121,15 +121,28 @@ static int sort_compare(struct ldb_message **msg1, struct 
ldb_message **msg2, vo
        el1 = ldb_msg_find_element(*msg1, ac->attributeName);
        el2 = ldb_msg_find_element(*msg2, ac->attributeName);
 
-       if (!el1 && el2) {
+       /*
+        * NULL and empty elements sort at the end (regardless of ac->reverse 
flag).
+        * NULL elements come after empty ones.
+        */
+       if (el1 == el2) {
+               return 0;
+       }
+       if (el1 == NULL) {
                return 1;
        }
-       if (el1 && !el2) {
+       if (el2 == NULL) {
                return -1;
        }
-       if (!el1 && !el2) {
+       if (unlikely(el1->num_values == 0 && el2->num_values == 0)) {
                return 0;
        }
+       if (unlikely(el1->num_values == 0)) {
+               return 1;
+       }
+       if (unlikely(el2->num_values == 0)) {
+               return -1;
+       }
 
        if (ac->reverse)
                return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], 
&el1->values[0]);
diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py
index 88dfa8c3b71..0fc31e3fe09 100755
--- a/lib/ldb/tests/python/api.py
+++ b/lib/ldb/tests/python/api.py
@@ -1341,6 +1341,22 @@ class SearchTests(LdbBaseTest):
                               expression="(ou=unique)")
         self.assertEqual(len(res11), 1)
 
+    def test_subtree_uni123_elsewhere(self):
+        """Testing a search, where the search term contains a (normal ASCII)
+        dotted-i, that will be upper-cased to 'İ', U+0130, LATIN
+        CAPITAL LETTER I WITH DOT ABOVE in certain locales including
+        tr_TR in which this test is sometimes run.
+
+        The search term should fail because the ou does not exist, but
+        we used to get it wrong in unindexed searches which stopped
+        comparing at the i, ignoring the rest of the string, which is
+        not the same as the existing ou ('123' != 'que').
+        """
+        res11 = self.l.search(base="DC=EXAMPLE,DC=NET",
+                              scope=ldb.SCOPE_SUBTREE,
+                              expression="(ou=uni123)")
+        self.assertEqual(len(res11), 0)
+
     def test_subtree_unique_elsewhere3(self):
         """Testing a search"""
 
diff --git a/lib/socket/interfaces.c b/lib/socket/interfaces.c
index 4908b0f55e2..2426ce2b52a 100644
--- a/lib/socket/interfaces.c
+++ b/lib/socket/interfaces.c
@@ -386,18 +386,18 @@ static int iface_comp(struct iface_struct *i1, struct 
iface_struct *i2)
        if (((struct sockaddr *)&i1->ip)->sa_family == AF_INET) {
                struct sockaddr_in *s1 = (struct sockaddr_in *)&i1->ip;
                struct sockaddr_in *s2 = (struct sockaddr_in *)&i2->ip;
-
-               r = ntohl(s1->sin_addr.s_addr) -
-                       ntohl(s2->sin_addr.s_addr);
-               if (r) {
-                       return r;
+               uint32_t a1 = ntohl(s1->sin_addr.s_addr);
+               uint32_t a2 = ntohl(s2->sin_addr.s_addr);
+               r = NUMERIC_CMP(a1, a2);
+               if (r == 0) {
+                       /* compare netmasks as a tiebreaker */
+                       s1 = (struct sockaddr_in *)&i1->netmask;
+                       s2 = (struct sockaddr_in *)&i2->netmask;
+                       a1 = ntohl(s1->sin_addr.s_addr);
+                       a2 = ntohl(s2->sin_addr.s_addr);
+                       r = NUMERIC_CMP(a1, a2);
                }
-
-               s1 = (struct sockaddr_in *)&i1->netmask;
-               s2 = (struct sockaddr_in *)&i2->netmask;
-
-               return ntohl(s1->sin_addr.s_addr) -
-                       ntohl(s2->sin_addr.s_addr);
+               return r;
        }
        return 0;
 }
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 232b8003973..2297dd9ded9 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -1235,8 +1235,10 @@ static unsigned char sort_ip[4];
 
 static int name_query_comp(unsigned char *p1, unsigned char *p2)
 {
-       return matching_len_bits(p2+2, sort_ip, 4) -
-               matching_len_bits(p1+2, sort_ip, 4);
+       int a = matching_len_bits(p1+2, sort_ip, 4);
+       int b = matching_len_bits(p2+2, sort_ip, 4);
+       /* reverse sort -- p2 derived value comes first */
+       return NUMERIC_CMP(b, a);
 }
 
 /****************************************************************************
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 905da049c58..328a9bfba3d 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -408,12 +408,9 @@ static int lock_compare(const struct lock_struct *lck1,
                         const struct lock_struct *lck2)
 {
        if (lck1->start != lck2->start) {
-               return (lck1->start - lck2->start);
+               return NUMERIC_CMP(lck1->start, lck2->start);
        }
-       if (lck2->size != lck1->size) {
-               return ((int)lck1->size - (int)lck2->size);
-       }
-       return 0;
+       return NUMERIC_CMP(lck1->size, lck2->size);
 }
 #endif
 
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index 365cdc79973..5d0516cf754 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -226,14 +226,14 @@ static int posixacl_xattr_entry_compare(const void *left, 
const void *right)
        tag_left = SVAL(left, 0);
        tag_right = SVAL(right, 0);
 
-       ret = (tag_left - tag_right);
-       if (!ret) {
+       ret = NUMERIC_CMP(tag_left, tag_right);
+       if (ret == 0) {
                /* ID is the third element in the entry, after two short
                   integers (tag and perm), i.e at offset 4.
                */
                id_left = IVAL(left, 4);
                id_right = IVAL(right, 4);
-               ret = id_left - id_right;
+               ret = NUMERIC_CMP(id_left, id_right);
        }
 
        return ret;
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index aae2ca17337..ecc53d015f2 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -111,13 +111,13 @@ static int vxfs_ace_cmp(const void *ace1, const void 
*ace2)
        type_a1 = SVAL(ace1, 0);
        type_a2 = SVAL(ace2, 0);
 
-       ret = (type_a1 - type_a2);
-       if (!ret) {
+       ret = NUMERIC_CMP(type_a1, type_a2);
+       if (ret == 0) {
                /* Compare ID under type */
                /* skip perm thus take offset as 4*/
                id_a1 = IVAL(ace1, 4);
                id_a2 = IVAL(ace2, 4);
-               ret = id_a1 - id_a2;
+               ret = NUMERIC_CMP(id_a1, id_a2);
        }
 
        return ret;
diff --git a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c 
b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
index 0724dd00af5..ed16278b9fc 100644
--- a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+++ b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
@@ -50,7 +50,7 @@ static int dom_user_cmp(const struct dom_usr *usr1, const 
struct dom_usr *usr2)
        /* Called from qsort to compare two domain users in a dom_usr_t array
         * for sorting by login time. Return >0 if usr1 login time was later
         * than usr2 login time, <0 if it was earlier */
-       return (usr1->login_time - usr2->login_time);
+       return NUMERIC_CMP(usr1->login_time, usr2->login_time);
 }
 
 /*******************************************************************
diff --git a/source4/dsdb/common/dsdb_dn.c b/source4/dsdb/common/dsdb_dn.c
index 63a8628d6d3..9886d831488 100644
--- a/source4/dsdb/common/dsdb_dn.c
+++ b/source4/dsdb/common/dsdb_dn.c
@@ -530,7 +530,7 @@ static struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX 
*mem_ctx,
  * not valid or able to parse as a DN.
  *
  * Finally, we must return the DN as found in the DB, as otherwise a
- * subsequence ldb_dn_compare(dn, nc_root) will fail (as this is based
+ * subsequent ldb_dn_compare(dn, nc_root) will fail (as this is based
  * on the string components).
  */
 int drs_ObjectIdentifier_to_dn_and_nc_root(TALLOC_CTX *mem_ctx,
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 398091c6375..8b90e7f7b7f 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -478,19 +478,13 @@ static void dsdb_setup_attribute_shortcuts(struct 
ldb_context *ldb, struct dsdb_
        TALLOC_FREE(frame);
 }
 
-static int uint32_cmp(uint32_t c1, uint32_t c2)
-{
-       if (c1 == c2) return 0;
-       return c1 > c2 ? 1 : -1;
-}
-
 static int dsdb_compare_class_by_lDAPDisplayName(struct dsdb_class **c1, 
struct dsdb_class **c2)
 {
        return strcasecmp((*c1)->lDAPDisplayName, (*c2)->lDAPDisplayName);
 }
 static int dsdb_compare_class_by_governsID_id(struct dsdb_class **c1, struct 
dsdb_class **c2)
 {
-       return uint32_cmp((*c1)->governsID_id, (*c2)->governsID_id);
+       return NUMERIC_CMP((*c1)->governsID_id, (*c2)->governsID_id);
 }
 static int dsdb_compare_class_by_governsID_oid(struct dsdb_class **c1, struct 
dsdb_class **c2)
 {


-- 
Samba Shared Repository


Reply via email to