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:
parent
a83bb07016
commit
cc43037f19
@ -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);
|
||||
|
@ -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.
|
||||
**/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user