]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ldb: add ldb_set_utf8_functions() for setting casefold functions
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 16 May 2024 23:34:35 +0000 (11:34 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 22 May 2024 23:12:32 +0000 (23:12 +0000)
This replaces ldb_set_utf8_fns(), which will be deprecated really soon.

The reason for this, as shown in surrounding commits, is that without
an explicit case-insensitive comparison we need to rely on the casefold,
and if the casefold can fail (because, e.g. bad utf-8) the comparison
ends up being a bit chaotic. The strings being compared are generally
user controlled, and a malicious user might find ways of hiding values
or perhaps fooling a binary search.

A case-insensitive comparisons that works gradually through the string
without an all-at-once casefold is better placed to deal with problems
where they happen, and we are able to separately specialise for the
ASCII case (used by SSSD) and the UTF-8 case (Samba).

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/ABI/ldb-2.10.0.sigs
lib/ldb/common/ldb_utf8.c
lib/ldb/include/ldb.h

index 2266387cd60e2b94c1c316aa569ed375ba7d48b5..18b2d5f35269db764ca80846619a11eafdd2ce6c 100644 (file)
@@ -275,6 +275,7 @@ ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int)
 ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *)
 ldb_set_utf8_default: void (struct ldb_context *)
 ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t))
+ldb_set_utf8_functions: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t), int (*)(void *, const struct ldb_val *, const struct ldb_val *))
 ldb_setup_wellknown_attributes: int (struct ldb_context *)
 ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *)
 ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *)
index 178bdd86de109e8267b19fcc5a7ee6d9b8036f07..a59c20c582708c306a596f331741803611202dc4 100644 (file)
 #include "ldb_private.h"
 #include "system/locale.h"
 
+/*
+ * Set functions for comparing and case-folding case-insensitive ldb val
+ * strings.
+ */
+void ldb_set_utf8_functions(struct ldb_context *ldb,
+                           void *context,
+                           char *(*casefold)(void *, void *, const char *, size_t),
+                           int (*casecmp)(void *ctx,
+                                          const struct ldb_val *v1,
+                                          const struct ldb_val *v2))
+{
+       if (context)
+               ldb->utf8_fns.context = context;
+       if (casefold)
+               ldb->utf8_fns.casefold = casefold;
+       if (casecmp)
+               ldb->utf8_fns.casecmp = casecmp;
+}
 
 /*
   this allow the user to pass in a caseless comparison
@@ -43,12 +61,10 @@ void ldb_set_utf8_fns(struct ldb_context *ldb,
                      void *context,
                      char *(*casefold)(void *, void *, const char *, size_t))
 {
-       if (context)
-               ldb->utf8_fns.context = context;
-       if (casefold)
-               ldb->utf8_fns.casefold = casefold;
+       ldb_set_utf8_functions(ldb, context, casefold, NULL);
 }
 
+
 /*
   a simple case folding function
   NOTE: does not handle UTF8
index a3436359559677e9d3f7ff2e4a9e33c825f8e8d6..61651f4e54d79343db83eb7bcd5ac294d9898e71 100644 (file)
@@ -2205,10 +2205,34 @@ int ldb_set_debug(struct ldb_context *ldb,
                  void *context);
 
 /**
-  this allows the user to set custom utf8 function for error reporting. make
-  sure it is able to handle ASCII first, so it prevents issues with dotted
-  languages.
-*/
+ * This allows the user to set custom utf8 functions.
+ *
+ * Be aware that casefold in some locales will break ldb expectations. In
+ * particular, if 'i' is uppercased to 'İ' (a capital I with a dot, used in
+ * some languages), the string '<guid=' will not equal '<GUID='.
+ *
+ * The default functions casefold ASCII only, and those used by Samba use a
+ * version of the NTFS UCS-2 upcase table which is dotted-i safe.
+ *
+ * The context argument will be passed to the casefold() and casecmp()
+ * functions as the first argument. It is unused in the default and Samba
+ * implementations, but could for example be used to hold a libICU context.
+ *
+ * The second argument for the casefold function is a TALLOC context.
+ */
+void ldb_set_utf8_functions(struct ldb_context *ldb,
+                           void *context,
+                           char *(*casefold)(void *, void *, const char *, size_t n),
+                           int (*casecmp)(void *ctx, const struct ldb_val *v1,
+                                          const struct ldb_val *v2));
+
+/**
+ * This legacy function is for setting a custom utf8 casefold function. It
+ * cannot set a comparison function, which makes it very difficult for a
+ * comparison to be both efficient and correct.
+ *
+ * Use ldb_set_utf8_functions() instead!
+ */
 void ldb_set_utf8_fns(struct ldb_context *ldb,
                      void *context,
                      char *(*casefold)(void *, void *, const char *, size_t n));