diff options
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r-- | source4/lib/ldb/common/ldb.c | 2 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_dn.c | 26 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_ldif.c | 36 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_msg.c | 5 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_utf8.c | 81 |
5 files changed, 87 insertions, 63 deletions
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 41b1a3efb7..0857c07ad4 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -50,6 +50,8 @@ struct ldb_context *ldb_init(void *mem_ctx) return NULL; } + ldb_set_utf8_default(ldb); + return ldb; } diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index e0c6f4a103..c2212fd6fe 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -55,23 +55,6 @@ int ldb_dn_check_special(const struct ldb_dn *dn, const char *check) return ! strcmp((char *)dn->components[0].value.data, check); } -static int ldb_dn_is_valid_attribute_name(const char *name) -{ - if (name == NULL) return 0; - - while (*name) { - if (! isascii(*name)) { - return 0; - } - if (! (isalnum((unsigned char)*name) || *name == '-')) { - return 0; - } - name++; - } - - return 1; -} - char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value) { const char *p, *s, *src; @@ -301,7 +284,7 @@ static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw if (!dc.name) return dc; - if (! ldb_dn_is_valid_attribute_name(dc.name)) { + if (! ldb_valid_attr_name(dc.name)) { goto failed; } @@ -519,7 +502,8 @@ int ldb_dn_compare_base(struct ldb_context *ldb, const struct ldb_attrib_handler *h; /* compare names (attribute names are guaranteed to be ASCII only) */ - ret = ldb_caseless_cmp(base->components[n0].name, + ret = ldb_caseless_cmp(ldb, + base->components[n0].name, dn->components[n1].name); if (ret) { return ret; @@ -598,7 +582,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(cedn, edn->components[i].name); + dc.name = ldb_casefold(ldb, cedn, edn->components[i].name); LDB_DN_NULL_FAILED(dc.name); h = ldb_attrib_handler(ldb, dc.name); @@ -761,7 +745,7 @@ struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr, const struct ldb_dn *base) { struct ldb_dn *new; - if (! ldb_dn_is_valid_attribute_name(attr)) return NULL; + if (! ldb_valid_attr_name(attr)) return NULL; if (value == NULL || value == '\0') return NULL; if (base != NULL) { diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index 53dadcc6fe..7501e89222 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -499,40 +499,6 @@ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) } /* - add an empty element -*/ -static int msg_add_empty(struct ldb_context *ldb, - struct ldb_message *msg, const char *name, unsigned flags) -{ - struct ldb_message_element *el2, *el; - - el2 = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); - if (!el2) { - errno = ENOMEM; - return -1; - } - - msg->elements = el2; - - el = &msg->elements[msg->num_elements]; - - el->name = talloc_strdup(msg->elements, name); - el->num_values = 0; - el->values = NULL; - el->flags = flags; - - if (!el->name) { - errno = ENOMEM; - return -1; - } - - msg->num_elements++; - - return 0; -} - -/* read from a LDIF source, creating a ldb_message */ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, @@ -630,7 +596,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, } if (empty) { - if (msg_add_empty(ldb, msg, (char *)value.data, flags) != 0) { + if (ldb_msg_add_empty(msg, (char *)value.data, flags) != 0) { goto failed; } continue; diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 513a4de1f8..497d2cb0d5 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -123,6 +123,10 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) { struct ldb_message_element *els; + if (! ldb_valid_attr_name(attr_name)) { + return -1; + } + els = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements+1); if (!els) { @@ -135,6 +139,7 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) els[msg->num_elements].flags = flags; els[msg->num_elements].name = talloc_strdup(els, attr_name); if (!els[msg->num_elements].name) { + errno = ENOMEM; return -1; } diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c index c2d31d440b..4735b35af6 100644 --- a/source4/lib/ldb/common/ldb_utf8.c +++ b/source4/lib/ldb/common/ldb_utf8.c @@ -35,11 +35,29 @@ #include "includes.h" #include "ldb/include/includes.h" + /* - TODO: - a simple case folding function - will be replaced by a UTF8 aware function later + this allow the user to pass in a caseless comparison + function to handle utf8 caseless comparisons + */ +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; +} + +/* + a simple case folding function + NOTE: does not handle UTF8 */ -char *ldb_casefold(void *mem_ctx, const char *s) +char *ldb_casefold_default(void *context, void *mem_ctx, const char *s) { int i; char *ret = talloc_strdup(mem_ctx, s); @@ -55,20 +73,69 @@ char *ldb_casefold(void *mem_ctx, const char *s) /* a caseless compare, optimised for 7 bit - TODO: doesn't yet handle UTF8 + NOTE: doesn't handle UTF8 */ -int ldb_caseless_cmp(const char *s1, const char *s2) + +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_caseless_cmp_default, ldb_casefold_default); +} + +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 + */ + +int ldb_valid_attr_name(const char *s) { - return strcasecmp(s1, s2); + int i; + + if (!s || !s[0]) + return 0; + + /* handle special ldb_tdb wildcard */ + if (strcmp(s, "*") == 0) return 1; + + for (i = 0; s[i]; i++) { + if (! isascii(s[i])) { + return 0; + } + if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ + if (! (isalpha(s[i]) || (s[i] == '@'))) { + return 0; + } + } else { + if (! (isalnum(s[i]) || (s[i] == '-'))) { + return 0; + } + } + } + return 1; } /* compare two attribute names + attribute names are restricted by rfc2251 so using strcasecmp here is ok. return 0 for match */ int ldb_attr_cmp(const char *attr1, const char *attr2) { - return ldb_caseless_cmp(attr1, attr2); + return strcasecmp(attr1, attr2); } /* |