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>
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 *)
#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
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
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));