[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Tue Apr 23 02:38:02 UTC 2024
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.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Tue Apr 23 02:37:25 UTC 2024 on atb-devel-224
commit dca6b2d25529288eaf7b31baf37ca4f6de4f4b9d
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 078ecf486a62dc3aaa2842ada96456ac9870dad7
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit a75c98ad688415aec8afc617a759ba90cfd9f23b
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 7280c8e53f463108fe3de443ce63572dde689a30
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 341b8fb60e291ad598fafd7a09a75e9b249de07f
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 70356592563bf758dbe509413445b77bb0d7da14
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 11d5a809325369b48d14023adf109e418bb1c7af
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit db963b1674ede357d4edba578e0e0372dcb2f287
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 2d3b917d0a078279853bb3926b7dc3584fe53627
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 42f2d96f82a8156abb004c68d343c8b769ebea4b
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 6722e80d1b3a252a1ed714be4a35185cd99971e3
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 4af670384a10a8571bc24ff2d7933160ee7adc62
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed Apr 10 16:49:07 2024 +1200
s4:dsdb: fix spelling in comment
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit a9eaf8a3abe66e1a5ff31fa405442f9a09f1dbc5
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 6229feab74a734190c302ee9b1cc36960669743d
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 7be535315a5eed5d5b7eaea025ecf9f55e772e8e
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 31c322874b8b65518cec945e05a42fd014e6390b
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 7ba6fcb93656e5e88e1d5bcd6002747aa64f0a3a
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit acaa1323d0337ae9339dfff9f856ea54725a86ac
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 75682e397b9cf22d04a5d80252554c6b2e376793
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8317a6173646d425dc99e08bbf3d6086b0086bc5
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 386216d4a158d8bafb0879a0a753da096a939b93
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8b2605a5d9cc14f9e6ddf2db704cdca2f523d74e
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 9b73235d4957a487fbb3214fdfda6461a2cf0b21
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 5fe488d515a8bb719bdeafb8b64d8479732b5ac8
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 531f31df99341b2cb1afc42538022451ca771983
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit d4e69734c65ade0bbb398447012513a7f27e98bd
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit d785c1991c922150bab38c36cef3a799448ac304
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at 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
More information about the samba-cvs
mailing list