From 04396c36d3ee8300b2b73ea8b43a45ea1b250828 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 4 Feb 2006 06:57:28 +0000 Subject: r13333: revert previous commit I will use ldb_caseless_cmp in attrib_handlers to correctly support utf8 comparisons add an ldb_attr_Casefold function for attribute names and use it instead of casefold in the right places (This used to be commit 3b4eb2413bbce059dde69f35c03cdc3cc2ba85c5) --- source4/lib/db_wrap.c | 9 ++++++-- source4/lib/ldb/common/ldb_dn.c | 2 +- source4/lib/ldb/common/ldb_utf8.c | 37 +++++++++++++++++++++++++++++-- source4/lib/ldb/include/ldb.h | 17 ++++++++++++++ source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 16 ++++++------- source4/lib/ldb/ldb_tdb/ldb_index.c | 2 +- source4/lib/ldb/tools/cmdline.c | 2 +- 7 files changed, 70 insertions(+), 15 deletions(-) (limited to 'source4') diff --git a/source4/lib/db_wrap.c b/source4/lib/db_wrap.c index 4223d19b3f..f3358bff98 100644 --- a/source4/lib/db_wrap.c +++ b/source4/lib/db_wrap.c @@ -55,7 +55,12 @@ static void ldb_wrap_debug(void *context, enum ldb_debug_level level, free(s); } -char *wrap_casefold(void *context, void *mem_ctx, const char *s) +static int wrap_caseless_cmp(void *context, const char *s1, const char *s2) +{ + return strcasecmp_m(s1, s2); +} + +static char *wrap_casefold(void *context, void *mem_ctx, const char *s) { return strupper_talloc(mem_ctx, s); } @@ -128,7 +133,7 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, ldb_set_debug(ldb, ldb_wrap_debug, NULL); - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); + ldb_set_utf8_fns(ldb, NULL, wrap_caseless_cmp, wrap_casefold); return ldb; } diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index bcd5a067a6..9f3374bceb 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -581,7 +581,7 @@ struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, const struct ldb_dn *edn struct ldb_dn_component dc; const struct ldb_attrib_handler *h; - dc.name = ldb_casefold(ldb, cedn, edn->components[i].name); + dc.name = ldb_attr_casefold(cedn, edn->components[i].name); LDB_DN_NULL_FAILED(dc.name); h = ldb_attrib_handler(ldb, dc.name); diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c index 1b7319915b..743e976e84 100644 --- a/source4/lib/ldb/common/ldb_utf8.c +++ b/source4/lib/ldb/common/ldb_utf8.c @@ -42,10 +42,13 @@ */ void ldb_set_utf8_fns(struct ldb_context *ldb, void *context, + int (*cmp)(void *, const char *, const char *), char *(*casefold)(void *, void *, const char *)) { if (context) ldb->utf8_fns.context = context; + if (cmp) + ldb->utf8_fns.caseless_cmp = cmp; if (casefold) ldb->utf8_fns.casefold = casefold; } @@ -68,9 +71,19 @@ char *ldb_casefold_default(void *context, void *mem_ctx, const char *s) return ret; } +/* + a caseless compare, optimised for 7 bit + NOTE: doesn't handle UTF8 +*/ + +int ldb_caseless_cmp_default(void *context, const char *s1, const char *s2) +{ + return strcasecmp(s1,s2); +} + void ldb_set_utf8_default(struct ldb_context *ldb) { - ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); + ldb_set_utf8_fns(ldb, NULL, ldb_caseless_cmp_default, ldb_casefold_default); } char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s) @@ -78,6 +91,11 @@ char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s) return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s); } +int ldb_caseless_cmp(struct ldb_context *ldb, const char *s1, const char *s2) +{ + return ldb->utf8_fns.caseless_cmp(ldb->utf8_fns.context, s1, s2); +} + /* check the attribute name is valid according to rfc2251 returns 1 if the name is ok @@ -112,7 +130,8 @@ int ldb_valid_attr_name(const char *s) /* compare two attribute names - attribute names are restricted by rfc2251 so using strcasecmp here is ok. + attribute names are restricted by rfc2251 so using + strcasecmp and toupper here is ok. return 0 for match */ int ldb_attr_cmp(const char *attr1, const char *attr2) @@ -120,6 +139,20 @@ int ldb_attr_cmp(const char *attr1, const char *attr2) return strcasecmp(attr1, attr2); } +char *ldb_attr_casefold(void *mem_ctx, const char *s) +{ + int i; + char *ret = talloc_strdup(mem_ctx, s); + if (!s) { + errno = ENOMEM; + return NULL; + } + for (i = 0; ret[i]; i++) { + ret[i] = toupper((unsigned char)ret[i]); + } + return ret; +} + /* we accept either 'dn' or 'distinguishedName' for a distinguishedName */ diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 0e192c2e31..7c39aeeeb9 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -214,6 +214,7 @@ struct ldb_debug_ops { */ struct ldb_utf8_fns { void *context; + int (*caseless_cmp)(void *context, const char *s1, const char *s2); char *(*casefold)(void *context, void *mem_ctx, const char *s); }; @@ -747,6 +748,21 @@ void ldb_set_utf8_default(struct ldb_context *ldb); */ char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s); +/** + Compare two strings, without regard to case. + + \param ldb the ldb context + \param s1 the first string to compare + \param s2 the second string to compare + + \return 0 if the strings are the same, non-zero if there are any + differences except for case. + + \note The default function is not yet UTF8 aware. Provide your own + set of functions through ldb_set_utf8_fns() +*/ +int ldb_caseless_cmp(struct ldb_context *ldb, const char *s1, const char *s2); + /** Check the attribute name is valid according to rfc2251 \param s tthe string to check @@ -1101,6 +1117,7 @@ int ldb_set_debug(struct ldb_context *ldb, */ void ldb_set_utf8_fns(struct ldb_context *ldb, void *context, + int (*cmp)(void *, const char *, const char *), char *(*casefold)(void *, void *, const char *)); /** diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index fbbbf037b3..3e24093118 100644 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -289,7 +289,7 @@ static char *parsetree_to_sql(struct ldb_module *module, * For simple searches, we want to retrieve the list of EIDs that * match the criteria. */ - attr = ldb_casefold(module->ldb, mem_ctx, t->u.equality.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; h = ldb_attrib_handler(module->ldb, attr); @@ -353,7 +353,7 @@ static char *parsetree_to_sql(struct ldb_module *module, wild_card_string[strlen(wild_card_string) - 1] = '\0'; } - attr = ldb_casefold(module->ldb, mem_ctx, t->u.substring.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.substring.attr); if (attr == NULL) return NULL; h = ldb_attrib_handler(module->ldb, attr); @@ -374,7 +374,7 @@ static char *parsetree_to_sql(struct ldb_module *module, value.data); case LDB_OP_GREATER: - attr = ldb_casefold(module->ldb, mem_ctx, t->u.equality.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; h = ldb_attrib_handler(module->ldb, attr); @@ -393,7 +393,7 @@ static char *parsetree_to_sql(struct ldb_module *module, attr); case LDB_OP_LESS: - attr = ldb_casefold(module->ldb, mem_ctx, t->u.equality.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; h = ldb_attrib_handler(module->ldb, attr); @@ -416,7 +416,7 @@ static char *parsetree_to_sql(struct ldb_module *module, return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); } - attr = ldb_casefold(module->ldb, mem_ctx, t->u.present.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.present.attr); if (attr == NULL) return NULL; return lsqlite3_tprintf(mem_ctx, @@ -425,7 +425,7 @@ static char *parsetree_to_sql(struct ldb_module *module, attr); case LDB_OP_APPROX: - attr = ldb_casefold(module->ldb, mem_ctx, t->u.equality.attr); + attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr); if (attr == NULL) return NULL; h = ldb_attrib_handler(module->ldb, attr); @@ -1058,7 +1058,7 @@ static int lsqlite3_add(struct ldb_module *module, const struct ldb_message *msg int j; /* Get a case-folded copy of the attribute name */ - attr = ldb_casefold(module->ldb, local_ctx, el->name); + attr = ldb_attr_casefold(module->ldb, local_ctx, el->name); if (attr == NULL) { ret = LDB_ERR_OTHER; goto failed; @@ -1157,7 +1157,7 @@ static int lsqlite3_modify(struct ldb_module *module, const struct ldb_message * int j; /* Get a case-folded copy of the attribute name */ - attr = ldb_casefold(module->ldb, local_ctx, el->name); + attr = ldb_attr_casefold(module->ldb, local_ctx, el->name); if (attr == NULL) { ret = LDB_ERR_OTHER; goto failed; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index fb29a9ddbf..ac3063ef28 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -106,7 +106,7 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, const struct ldb_attrib_handler *h; char *attr_folded; - attr_folded = ldb_casefold(ldb, ldb, attr); + attr_folded = ldb_attr_casefold(ldb, ldb, attr); if (!attr_folded) { return NULL; } diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index 232cfcbb16..446923f282 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -204,7 +204,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { goto failed; } - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); + ldb_set_utf8_fns(ldb, NULL, wrap_caseless_cmp, wrap_casefold); #endif if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) { fprintf(stderr, "Failed to connect to %s - %s\n", -- cgit