1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-09 08:58:35 +03:00

fixed a problem with length limited ldap values

The core ldb code for string matching assumed NULL terminated strings,
whereas the anr module used data_blob_const() to effectively truncate
a ldb_val by changing its length. The ldb code is supposed to be based
around length limited blobs, not NULL terminated strings, so the
correct fix was to change the string comparison functions to be length
limited
(This used to be commit 26c6aa5a80ffaf06fc33f30a6533f8f16ef538bc)
This commit is contained in:
Andrew Tridgell 2008-08-22 17:36:56 +10:00
parent a83bb07016
commit cc43037f19
10 changed files with 48 additions and 29 deletions

View File

@ -97,6 +97,7 @@ size_t count_chars_w(const char *s, char c);
void strupper_m(char *s);
void strlower_m(char *s);
char *strupper_talloc(TALLOC_CTX *ctx, const char *src);
char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n);
char *strlower_talloc(TALLOC_CTX *ctx, const char *src);
bool strhasupper(const char *string);
bool strhaslower(const char *string);

View File

@ -518,8 +518,9 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
/**
Convert a string to UPPER case, allocated with talloc
source length limited to n bytes
**/
_PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
_PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n)
{
size_t size=0;
char *dest;
@ -531,12 +532,12 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
/* this takes advantage of the fact that upper/lower can't
change the length of a character by more than 1 byte */
dest = talloc_array(ctx, char, 2*(strlen(src))+1);
dest = talloc_array(ctx, char, 2*(n+1));
if (dest == NULL) {
return NULL;
}
while (*src) {
while (*src && n--) {
size_t c_size;
codepoint_t c = next_codepoint(iconv_convenience, src, &c_size);
src += c_size;
@ -561,6 +562,16 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
return dest;
}
/**
Convert a string to UPPER case, allocated with talloc
**/
_PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
{
return strupper_talloc_n(ctx, src, src?strlen(src):0);
}
/**
Convert a string to lower case.
**/

View File

@ -55,11 +55,12 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
{
char *s, *t;
int l;
if (!in || !out || !(in->data)) {
return -1;
}
out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data));
out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length);
if (out->data == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%s]", in->data);
return -1;
@ -153,13 +154,14 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *v1, const struct ldb_val *v2)
{
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;
int ret;
while (*s1 == ' ') s1++;
while (*s2 == ' ') s2++;
while (*s1 == ' ' && n1) { s1++; n1--; };
while (*s2 == ' ' && n2) { s2++; n2--; };
/* TODO: make utf8 safe, possibly with helper function from application */
while (*s1 && *s2) {
while (*s1 && *s2 && n1 && n2) {
/* the first 127 (0x7F) chars are ascii and utf8 guarantes they
* never appear in multibyte sequences */
if (((unsigned char)s1[0]) & 0x80) goto utf8str;
@ -167,10 +169,11 @@ 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]) s1++;
while (s2[0] == s2[1]) s2++;
while (s1[0] == s1[1] && n1) { s1++; n1--; }
while (s2[0] == s2[1] && n2) { s2++; n2--; }
}
s1++; s2++;
n1--; n2--;
}
if (! (*s1 && *s2)) {
/* check for trailing spaces only if one of the pointers
@ -178,15 +181,18 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
* can mistakenly match.
* ex. "domain users" <-> "domainUpdates"
*/
while (*s1 == ' ') s1++;
while (*s2 == ' ') s2++;
while (*s1 == ' ') { s1++; n1--; }
while (*s2 == ' ') { s2++; n2--; }
}
if (n1 != n2) {
return n1 - n2;
}
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);
b2 = ldb_casefold(ldb, mem_ctx, s2);
b1 = ldb_casefold(ldb, mem_ctx, s1, n1);
b2 = ldb_casefold(ldb, mem_ctx, s2, n2);
if (b1 && b2) {
/* Both strings converted correctly */
@ -221,6 +227,7 @@ utf8str:
return ret;
}
/*
canonicalise a attribute in DN format
*/

View File

@ -40,8 +40,8 @@
function to handle utf8 caseless comparisons
*/
void ldb_set_utf8_fns(struct ldb_context *ldb,
void *context,
char *(*casefold)(void *, void *, const char *))
void *context,
char *(*casefold)(void *, void *, const char *, size_t))
{
if (context)
ldb->utf8_fns.context = context;
@ -53,10 +53,10 @@ void ldb_set_utf8_fns(struct ldb_context *ldb,
a simple case folding function
NOTE: does not handle UTF8
*/
char *ldb_casefold_default(void *context, void *mem_ctx, const char *s)
char *ldb_casefold_default(void *context, void *mem_ctx, const char *s, size_t n)
{
int i;
char *ret = talloc_strdup(mem_ctx, s);
char *ret = talloc_strndup(mem_ctx, s, n);
if (!s) {
errno = ENOMEM;
return NULL;
@ -72,9 +72,9 @@ void ldb_set_utf8_default(struct ldb_context *ldb)
ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default);
}
char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s)
char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s, size_t n)
{
return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s);
return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n);
}
/*

View File

@ -203,7 +203,7 @@ struct ldb_debug_ops {
*/
struct ldb_utf8_fns {
void *context;
char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s);
char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n);
};
/**
@ -1216,7 +1216,7 @@ void ldb_set_utf8_default(struct ldb_context *ldb);
\note The default function is not yet UTF8 aware. Provide your own
set of functions through ldb_set_utf8_fns()
*/
char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s);
char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n);
/**
Check the attribute name is valid according to rfc2251
@ -1603,8 +1603,8 @@ int ldb_set_debug(struct ldb_context *ldb,
this allows the user to set custom utf8 function for error reporting
*/
void ldb_set_utf8_fns(struct ldb_context *ldb,
void *context,
char *(*casefold)(void *, void *, const char *));
void *context,
char *(*casefold)(void *, void *, const char *, size_t n));
/**
this sets up debug to print messages on stderr

View File

@ -235,7 +235,7 @@ int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct l
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);
char *ldb_casefold_default(void *context, void *mem_ctx, const char *s, size_t n);
void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el);

View File

@ -93,7 +93,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(ldb, tmp_ctx, name);
vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name, strlen(name));
vals[2][0].length = strlen((char *)vals[2][0].data);
el[3].flags = 0;

View File

@ -29,7 +29,7 @@ struct cli_credentials;
struct loadparm_context;
struct event_context;
char *wrap_casefold(void *context, void *mem_ctx, const char *s);
char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n);
struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
struct event_context *ev,

View File

@ -125,9 +125,9 @@ int gendb_add_ldif(struct ldb_context *ldb, const char *ldif_string)
return ret;
}
char *wrap_casefold(void *context, void *mem_ctx, const char *s)
char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n)
{
return strupper_talloc(mem_ctx, s);
return strupper_talloc_n(mem_ctx, s, n);
}

View File

@ -22,6 +22,6 @@ int gendb_search_dn(struct ldb_context *ldb,
struct ldb_message ***res,
const char * const *attrs);
int gendb_add_ldif(struct ldb_context *ldb, const char *ldif_string);
char *wrap_casefold(void *context, void *mem_ctx, const char *s);
char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n);
#endif /* __LIB_UTIL_UTIL_LDB_H__ */