1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-09 09:57:48 +03:00

r13324: From now on check attribute names obey rfc2251

Also add a way to provide utf8 compliant functions
by registering them with ldb_set_utf8_fns()

Next comes code to register samba internal utf8 functions.

Simo.
This commit is contained in:
Simo Sorce 2006-02-04 00:38:48 +00:00 committed by Gerald (Jerry) Carter
parent c170079184
commit ac9b8a41ff
11 changed files with 139 additions and 98 deletions

View File

@ -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

View File

@ -50,6 +50,8 @@ struct ldb_context *ldb_init(void *mem_ctx)
return NULL;
}
ldb_set_utf8_default(ldb);
return ldb;
}

View File

@ -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) {

View File

@ -498,40 +498,6 @@ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif)
talloc_free(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
*/
@ -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;

View File

@ -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;
}

View File

@ -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);
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)
{
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);
}
/*

View File

@ -208,6 +208,16 @@ struct ldb_debug_ops {
void *context;
};
/**
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.
@ -718,30 +728,48 @@ 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(const char *s1, const char *s2);
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_valid_attr_name(const char *s);
/*
ldif manipulation functions

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;