summaryrefslogtreecommitdiff
path: root/source4/lib/ldb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r--source4/lib/ldb/Makefile.in2
-rw-r--r--source4/lib/ldb/common/ldb.c2
-rw-r--r--source4/lib/ldb/common/ldb_dn.c26
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c36
-rw-r--r--source4/lib/ldb/common/ldb_msg.c5
-rw-r--r--source4/lib/ldb/common/ldb_utf8.c81
-rw-r--r--source4/lib/ldb/include/ldb.h36
-rw-r--r--source4/lib/ldb/include/ldb_private.h7
-rw-r--r--source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c38
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c2
-rw-r--r--source4/lib/ldb/tools/ldbtest.c2
11 files changed, 139 insertions, 98 deletions
diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in
index 320b9c281f..43d1674d08 100644
--- a/source4/lib/ldb/Makefile.in
+++ b/source4/lib/ldb/Makefile.in
@@ -188,7 +188,7 @@ endif
test: $(BINS) test-tdb test-ldap test-sqlite3 test-schema
install: all
- cp include/ldb.h $(includedir)
+ cp include/ldb.h include/ldb_errors.h $(includedir)
cp $(LDB_LIB) $(libdir)
cp $(BINS) $(bindir)
cp ldb.pc $(libdir)/pkgconfig
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);
}
/*
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 9139e6d2f5..a8c2d176b5 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -209,6 +209,16 @@ struct ldb_debug_ops {
};
/**
+ The user can optionally supply a custom utf8 functions,
+ to handle comparisons and casefolding.
+*/
+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);
+};
+
+/**
Flag value for database connection mode.
If LDB_FLG_RDONLY is used in ldb_connect, then the database will be
@@ -719,29 +729,47 @@ int ldb_transaction_cancel(struct ldb_context *ldb);
const char *ldb_errstring(struct ldb_context *ldb);
/**
+ setup the default utf8 functions
+ FIXME: these functions do not yet handle utf8
+*/
+void ldb_set_utf8_default(struct ldb_context *ldb);
+
+/**
Casefold a string
+ \param ldb the ldb context
\param mem_ctx the memory context to allocate the result string
memory from.
\param s the string that is to be folded
\return a copy of the string, converted to upper case
- \todo This function should be UTF8 aware, but currently is not.
+ \note The default function is not yet UTF8 aware. Provide your own
+ set of functions through ldb_set_utf8_fns()
*/
-char *ldb_casefold(void *mem_ctx, const char *s);
+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 This function is not UTF8 aware.
+ \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
+
+ \return 1 if the name is ok
*/
-int ldb_caseless_cmp(const char *s1, const char *s2);
+int ldb_valid_attr_name(const char *s);
/*
ldif manipulation functions
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index 6871d8d552..fffda77ff8 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -90,6 +90,9 @@ struct ldb_context {
/* debugging operations */
struct ldb_debug_ops debug_ops;
+ /* custom utf8 functions */
+ struct ldb_utf8_fns utf8_fns;
+
/* backend specific opaque parameters */
struct ldb_opaque {
struct ldb_opaque *next;
@@ -191,4 +194,8 @@ int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx,
struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid);
int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver);
int check_critical_controls(struct ldb_control **controls);
+
+/* The following definitions come from lib/ldb/common/ldb_utf8.c */
+char *ldb_casefold_default(void *context, void *mem_ctx, const char *s);
+int ldb_caseless_cmp_default(void *context, const char *s1, const char *s2);
#endif
diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
index 4c00998fa9..fbbbf037b3 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(mem_ctx, t->u.equality.attr);
+ attr = ldb_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(mem_ctx, t->u.substring.attr);
+ attr = ldb_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(mem_ctx, t->u.equality.attr);
+ attr = ldb_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(mem_ctx, t->u.equality.attr);
+ attr = ldb_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(mem_ctx, t->u.present.attr);
+ attr = ldb_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(mem_ctx, t->u.equality.attr);
+ attr = ldb_casefold(module->ldb, mem_ctx, t->u.equality.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
@@ -715,26 +715,8 @@ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char
if (!found) return 0;
}
- msg->elements = talloc_realloc(msg,
- msg->elements,
- struct ldb_message_element,
- msg->num_elements + 1);
- if (msg->elements == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].flags = 0;
- msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, cols[2]);
- if (msg->elements[msg->num_elements].name == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].num_values = 1;
- msg->elements[msg->num_elements].values = talloc_array(msg->elements,
- struct ldb_val, 1);
- if (msg->elements[msg->num_elements].values == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].values[0].length = strlen(cols[3]);
- msg->elements[msg->num_elements].values[0].data = talloc_strdup(msg->elements, cols[3]);
- if (msg->elements[msg->num_elements].values[0].data == NULL) return SQLITE_ABORT;
-
- msg->num_elements++;
+ if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0)
+ return SQLITE_ABORT;
return SQLITE_OK;
}
@@ -1076,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(local_ctx, el->name);
+ attr = ldb_casefold(module->ldb, local_ctx, el->name);
if (attr == NULL) {
ret = LDB_ERR_OTHER;
goto failed;
@@ -1175,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(local_ctx, el->name);
+ attr = ldb_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 c74ce62fbf..fb29a9ddbf 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, attr);
+ attr_folded = ldb_casefold(ldb, ldb, attr);
if (!attr_folded) {
return NULL;
}
diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c
index f2efd4d22a..69362d0f20 100644
--- a/source4/lib/ldb/tools/ldbtest.c
+++ b/source4/lib/ldb/tools/ldbtest.c
@@ -94,7 +94,7 @@ static void add_records(struct ldb_context *ldb,
el[2].name = talloc_strdup(tmp_ctx, "uid");
el[2].num_values = 1;
el[2].values = vals[2];
- vals[2][0].data = (uint8_t *)ldb_casefold(tmp_ctx, name);
+ vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name);
vals[2][0].length = strlen((char *)vals[2][0].data);
el[3].flags = 0;