diff options
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r-- | source4/lib/ldb/common/attrib_handlers.c | 70 | ||||
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 20 |
2 files changed, 57 insertions, 33 deletions
diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c index 9cb9ff886c..3ea9857d52 100644 --- a/source4/lib/ldb/common/attrib_handlers.c +++ b/source4/lib/ldb/common/attrib_handlers.c @@ -187,13 +187,13 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, { const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; size_t n1 = v1->length, n2 = v2->length; - const char *u1, *u2; char *b1, *b2; + const char *u1, *u2; int ret; - while (*s1 == ' ' && n1) { s1++; n1--; }; - while (*s2 == ' ' && n2) { s2++; n2--; }; - /* TODO: make utf8 safe, possibly with helper function from application */ - while (*s1 && *s2 && n1 && n2) { + while (n1 && *s1 == ' ') { s1++; n1--; }; + while (n2 && *s2 == ' ') { s2++; n2--; }; + + while (n1 && n2 && *s1 && *s2) { /* the first 127 (0x7F) chars are ascii and utf8 guarantes they * never appear in multibyte sequences */ if (((unsigned char)s1[0]) & 0x80) goto utf8str; @@ -201,40 +201,58 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) break; if (*s1 == ' ') { - while (s1[0] == s1[1] && n1) { s1++; n1--; } - while (s2[0] == s2[1] && n2) { s2++; n2--; } + while (n1 && s1[0] == s1[1]) { s1++; n1--; } + while (n2 && s2[0] == s2[1]) { s2++; n2--; } } s1++; s2++; n1--; n2--; } - if (! (*s1 && *s2)) { - /* check for trailing spaces only if one of the pointers - * has reached the end of the strings otherwise we - * can mistakenly match. - * ex. "domain users" <-> "domainUpdates" - */ - while (*s1 == ' ') { s1++; n1--; } - while (*s2 == ' ') { s2++; n2--; } + + /* check for trailing spaces only if the other pointers has + * reached the end of the strings otherwise we can + * mistakenly match. ex. "domain users" <-> + * "domainUpdates" + */ + if (n1 && *s1 == ' ' && (!n2 || !*s2)) { + while (n1 && *s1 == ' ') { s1++; n1--; } + } + if (n2 && *s2 == ' ' && (!n1 || !*s1)) { + while (n2 && *s2 == ' ') { s2++; n2--; } + } + if (n1 == 0 && n2 != 0) { + return -(int)toupper(*s2); + } + if (n2 == 0 && n1 != 0) { + return (int)toupper(*s1); } - return (int)(toupper(*s1)) - (int)(toupper(*s2)); + if (n2 == 0 && n2 == 0) { + return 0; + } + return (int)toupper(*s1) - (int)toupper(*s2); utf8str: /* no need to recheck from the start, just from the first utf8 char found */ b1 = ldb_casefold(ldb, mem_ctx, s1, n1); b2 = ldb_casefold(ldb, mem_ctx, s2, n2); - if (b1 && b2) { - /* Both strings converted correctly */ - - u1 = b1; - u2 = b2; - } else { - /* One of the strings was not UTF8, so we have no options but to do a binary compare */ - - u1 = s1; - u2 = s2; + if (!b1 || !b2) { + /* One of the strings was not UTF8, so we have no + * options but to do a binary compare */ + talloc_free(b1); + talloc_free(b2); + if (memcmp(s1, s2, MIN(n1, n2)) == 0) { + if (n1 == n2) return 0; + if (n1 > n2) { + return (int)toupper(s1[n2]); + } else { + return -(int)toupper(s2[n1]); + } + } } + u1 = b1; + u2 = b2; + while (*u1 & *u2) { if (*u1 != *u2) break; diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index e9f873f073..8b54f52b5e 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -1,8 +1,8 @@ /* ldb database library - Copyright (C) Andrew Bartlet 2005 - Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Andrew Bartlett 2005 + Copyright (C) Simo Sorce 2006-2008 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -23,13 +23,13 @@ */ /* - * Name: rdb_name + * Name: rdn_name * * Component: ldb rdn name module * * Description: keep a consistent name attribute on objects manpulations * - * Author: Andrew Bartlet + * Author: Andrew Bartlett * * Modifications: * - made the module async @@ -156,9 +156,15 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) } } if (i == attribute->num_values) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "RDN mismatch on %s: %s (%s)", - ldb_dn_get_linearized(msg->dn), rdn_name, rdn_val.data); + char *rdn_errstring = talloc_asprintf(ac, "RDN mismatch on %s: %s (%.*s) should match one of:", + ldb_dn_get_linearized(msg->dn), rdn_name, + (int)rdn_val.length, (const char *)rdn_val.data); + for (i = 0; i < attribute->num_values; i++) { + rdn_errstring = talloc_asprintf_append(rdn_errstring, " (%.*s)", + (int)attribute->values[i].length, + (const char *)attribute->values[i].data); + } + ldb_debug_set(ldb, LDB_DEBUG_FATAL, "%s", rdn_errstring); talloc_free(ac); /* Match AD's error here */ return LDB_ERR_INVALID_DN_SYNTAX; |