diff options
25 files changed, 693 insertions, 492 deletions
diff --git a/source4/lib/ldb/Makefile.ldb b/source4/lib/ldb/Makefile.ldb index 0b8fdfe28f..0a0b95f7fe 100644 --- a/source4/lib/ldb/Makefile.ldb +++ b/source4/lib/ldb/Makefile.ldb @@ -22,7 +22,8 @@ LDB_TDB_OBJ=ldb_tdb/ldb_match.o ldb_tdb/ldb_tdb.o \ COMMON_OBJ=common/ldb.o common/ldb_ldif.o common/util.o \ - common/ldb_parse.o common/ldb_msg.o common/ldb_utf8.o + common/ldb_parse.o common/ldb_msg.o common/ldb_utf8.o \ + common/ldb_alloc.o OBJS = $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(LDB_LDAP_OBJ) diff --git a/source4/lib/ldb/common/ldb_alloc.c b/source4/lib/ldb/common/ldb_alloc.c new file mode 100644 index 0000000000..667759e832 --- /dev/null +++ b/source4/lib/ldb/common/ldb_alloc.c @@ -0,0 +1,174 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb alloc + * + * Description: functions for memory allocation + * + * Author: Andrew Tridgell + */ + +#include "includes.h" + + +/* + this allows the user to choose their own allocation function +*/ +int ldb_set_alloc(struct ldb_context *ldb, + void *(*alloc)(void *context, void *ptr, size_t size), + void *context) +{ + ldb->alloc_ops.alloc = alloc; + ldb->alloc_ops.context = context; + return 0; +} + +/* + this is the default memory allocation function +*/ +static void *ldb_default_alloc(void *context, void *ptr, size_t size) +{ + /* by setting LDB_ALLOC_OFS to non-zero the test suite can + catch any places where we incorrectly use the libc alloc + funcitons directly */ +#define LDB_ALLOC_OFS 4 + /* we don't assume a modern realloc function */ + if (ptr == NULL) { + ptr = malloc(size+LDB_ALLOC_OFS); + if (ptr) return ((char *)ptr)+LDB_ALLOC_OFS; + return NULL; + } + if (size == 0) { + free(((char *)ptr)-LDB_ALLOC_OFS); + return NULL; + } + ptr = realloc(((char *)ptr)-LDB_ALLOC_OFS, size+LDB_ALLOC_OFS); + if (ptr) { + return ((char *)ptr)+LDB_ALLOC_OFS; + } + return NULL; +} + +/* + all memory allocation goes via this function +*/ +void *ldb_realloc(struct ldb_context *ldb, void *ptr, size_t size) +{ + if (!ldb->alloc_ops.alloc) { + ldb_set_alloc(ldb, ldb_default_alloc, NULL); + } + return ldb->alloc_ops.alloc(ldb->alloc_ops.context, ptr, size); +} + +void *ldb_malloc(struct ldb_context *ldb, size_t size) +{ + return ldb_realloc(ldb, NULL, size); +} + +void ldb_free(struct ldb_context *ldb, void *ptr) +{ + if (ptr != NULL) { + ldb_realloc(ldb, ptr, 0); + } +} + +void *ldb_strndup(struct ldb_context *ldb, const char *str, size_t maxlen) +{ + size_t len = strnlen(str, maxlen); + void *ret; + ret = ldb_realloc(ldb, NULL, len+1); + if (ret) { + memcpy(ret, str, len); + ((char *)ret)[len] = 0; + } + return ret; +} + +void *ldb_strdup(struct ldb_context *ldb, const char *str) +{ + size_t len = strlen(str); + void *ret; + ret = ldb_realloc(ldb, NULL, len+1); + if (ret) { + memcpy(ret, str, len+1); + } + return ret; +} + +/* + a ldb wrapper for asprintf(), using ldb_malloc() +*/ +int ldb_asprintf(struct ldb_context *ldb, char **strp, const char *fmt, ...) +{ + int len, len2; + va_list ap; + + *strp = NULL; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + if (len < 0) { + return len; + } + + *strp = ldb_malloc(ldb, len+1); + if (! *strp) { + return -1; + } + + va_start(ap, fmt); + len2 = vsnprintf(*strp, len+1, fmt, ap); + va_end(ap); + + if (len2 != len) { + /* buggy (or non-C99) vsnprintf function */ + ldb_free(ldb, *strp); + return -1; + } + + return len; +} + +/* + realloc an array, checking for integer overflow in the array size +*/ +void *ldb_realloc_array(struct ldb_context *ldb, + void *ptr, size_t el_size, unsigned count) +{ +#define MAX_MALLOC_SIZE 0x7fffffff + + if (count == 0 || + count >= MAX_MALLOC_SIZE/el_size) { + return NULL; + } + if (!ptr) { + return ldb_malloc(ldb, el_size * count); + } + return ldb_realloc(ldb, ptr, el_size * count); +} + diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index ef782e90e3..451276c48d 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -86,7 +86,7 @@ static int base64_decode(char *s) encode as base64 caller frees */ -char *ldb_base64_encode(const char *buf, int len) +char *ldb_base64_encode(struct ldb_context *ldb, const char *buf, int len) { const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int bit_offset, byte_offset, idx, i; @@ -94,7 +94,7 @@ char *ldb_base64_encode(const char *buf, int len) int bytes = (len*8 + 5)/6; char *out; - out = malloc(bytes+2); + out = ldb_malloc(ldb, bytes+2); if (!out) return NULL; for (i=0;i<bytes;i++) { @@ -164,10 +164,12 @@ static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *priva /* encode as base64 to a file */ -static int base64_encode_f(int (*fprintf_fn)(void *, const char *, ...), void *private_data, +static int base64_encode_f(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...), + void *private_data, const char *buf, int len, int start_pos) { - char *b = ldb_base64_encode(buf, len); + char *b = ldb_base64_encode(ldb, buf, len); int ret; if (!b) { @@ -176,7 +178,7 @@ static int base64_encode_f(int (*fprintf_fn)(void *, const char *, ...), void *p ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos); - free(b); + ldb_free(ldb, b); return ret; } @@ -194,7 +196,8 @@ static const struct { /* write to ldif, using a caller supplied write method */ -int ldif_write(int (*fprintf_fn)(void *, const char *, ...), +int ldif_write(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...), void *private_data, const struct ldb_ldif *ldif) { @@ -244,7 +247,7 @@ int ldif_write(int (*fprintf_fn)(void *, const char *, ...), ret = fprintf_fn(private_data, "%s:: ", msg->elements[i].name); CHECK_RET; - ret = base64_encode_f(fprintf_fn, private_data, + ret = base64_encode_f(ldb, fprintf_fn, private_data, msg->elements[i].values[j].data, msg->elements[i].values[j].length, strlen(msg->elements[i].name)+3); @@ -282,7 +285,8 @@ int ldif_write(int (*fprintf_fn)(void *, const char *, ...), caller frees */ -static char *next_chunk(int (*fgetc_fn)(void *), void *private_data) +static char *next_chunk(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data) { size_t alloc_size=0, chunk_size = 0; char *chunk = NULL; @@ -293,9 +297,9 @@ static char *next_chunk(int (*fgetc_fn)(void *), void *private_data) if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = realloc_p(chunk, char, alloc_size); + c2 = ldb_realloc_p(ldb, chunk, char, alloc_size); if (!c2) { - free(chunk); + ldb_free(ldb, chunk); errno = ENOMEM; return NULL; } @@ -402,27 +406,29 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) /* free a message from a ldif_read */ -void ldif_read_free(struct ldb_ldif *ldif) +void ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) { struct ldb_message *msg = &ldif->msg; int i; for (i=0;i<msg->num_elements;i++) { - if (msg->elements[i].name) free(msg->elements[i].name); - if (msg->elements[i].values) free(msg->elements[i].values); + if (msg->elements[i].name) ldb_free(ldb, msg->elements[i].name); + if (msg->elements[i].values) ldb_free(ldb, msg->elements[i].values); } - if (msg->elements) free(msg->elements); - if (msg->private_data) free(msg->private_data); - free(ldif); + if (msg->elements) ldb_free(ldb, msg->elements); + if (msg->private_data) ldb_free(ldb, msg->private_data); + ldb_free(ldb, ldif); } /* add an empty element */ -static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned flags) +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 = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1); + el2 = ldb_realloc_p(ldb, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!el2) { errno = ENOMEM; return -1; @@ -432,7 +438,7 @@ static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned fla el = &msg->elements[msg->num_elements]; - el->name = strdup(name); + el->name = ldb_strdup(ldb, name); el->num_values = 0; el->values = NULL; el->flags = flags; @@ -450,7 +456,8 @@ static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned fla /* read from a LDIF source, creating a ldb_message */ -struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) +struct ldb_ldif *ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data) { struct ldb_ldif *ldif; struct ldb_message *msg; @@ -461,7 +468,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) value.data = NULL; - ldif = malloc_p(struct ldb_ldif); + ldif = ldb_malloc_p(ldb, struct ldb_ldif); if (!ldif) return NULL; ldif->changetype = LDB_CHANGETYPE_NONE; @@ -472,7 +479,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) msg->num_elements = 0; msg->private_data = NULL; - chunk = next_chunk(fgetc_fn, private_data); + chunk = next_chunk(ldb, fgetc_fn, private_data); if (!chunk) { goto failed; } @@ -530,7 +537,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) } if (empty) { - if (msg_add_empty(msg, (char *)value.data, flags) != 0) { + if (msg_add_empty(ldb, msg, (char *)value.data, flags) != 0) { goto failed; } continue; @@ -542,7 +549,8 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) flags == el->flags) { /* its a continuation */ el->values = - realloc_p(el->values, struct ldb_val, el->num_values+1); + ldb_realloc_p(ldb, el->values, + struct ldb_val, el->num_values+1); if (!el->values) { goto failed; } @@ -550,16 +558,16 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) el->num_values++; } else { /* its a new attribute */ - msg->elements = realloc_p(msg->elements, - struct ldb_message_element, - msg->num_elements+1); + msg->elements = ldb_realloc_p(ldb, msg->elements, + struct ldb_message_element, + msg->num_elements+1); if (!msg->elements) { goto failed; } el = &msg->elements[msg->num_elements]; el->flags = flags; - el->name = strdup(attr); - el->values = malloc_p(struct ldb_val); + el->name = ldb_strdup(ldb, attr); + el->values = ldb_malloc_p(ldb, struct ldb_val); if (!el->values || !el->name) { goto failed; } @@ -572,7 +580,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data) return ldif; failed: - if (ldif) ldif_read_free(ldif); + if (ldif) ldif_read_free(ldb, ldif); return NULL; } @@ -591,11 +599,11 @@ static int fgetc_file(void *private_data) return fgetc(state->f); } -struct ldb_ldif *ldif_read_file(FILE *f) +struct ldb_ldif *ldif_read_file(struct ldb_context *ldb, FILE *f) { struct ldif_read_file_state state; state.f = f; - return ldif_read(fgetc_file, &state); + return ldif_read(ldb, fgetc_file, &state); } @@ -615,11 +623,11 @@ static int fgetc_string(void *private_data) return EOF; } -struct ldb_ldif *ldif_read_string(const char *s) +struct ldb_ldif *ldif_read_string(struct ldb_context *ldb, const char *s) { struct ldif_read_string_state state; state.s = s; - return ldif_read(fgetc_string, &state); + return ldif_read(ldb, fgetc_string, &state); } @@ -642,9 +650,9 @@ static int fprintf_file(void *private_data, const char *fmt, ...) return ret; } -int ldif_write_file(FILE *f, const struct ldb_ldif *ldif) +int ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) { struct ldif_write_file_state state; state.f = f; - return ldif_write(fprintf_file, &state, ldif); + return ldif_write(ldb, fprintf_file, &state, ldif); } diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 8eb8a8c5ef..5976db81b6 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -87,11 +87,13 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, /* add an empty element to a message */ -int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) +int ldb_msg_add_empty(struct ldb_context *ldb, + struct ldb_message *msg, const char *attr_name, int flags) { struct ldb_message_element *els; - els = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1); + els = ldb_realloc_p(ldb, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!els) { errno = ENOMEM; return -1; @@ -100,7 +102,7 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) els[msg->num_elements].values = NULL; els[msg->num_elements].num_values = 0; els[msg->num_elements].flags = flags; - els[msg->num_elements].name = strdup(attr_name); + els[msg->num_elements].name = ldb_strdup(ldb, attr_name); if (!els[msg->num_elements].name) { return -1; } @@ -114,11 +116,12 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) /* add an empty element to a message */ -int ldb_msg_add(struct ldb_message *msg, +int ldb_msg_add(struct ldb_context *ldb, + struct ldb_message *msg, const struct ldb_message_element *el, int flags) { - if (ldb_msg_add_empty(msg, el->name, flags) != 0) { + if (ldb_msg_add_empty(ldb, msg, el->name, flags) != 0) { return -1; } diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index 4f8d469e6c..75eb44fcc0 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -59,7 +59,7 @@ a filter is defined by: /* return next token element. Caller frees */ -static char *ldb_parse_lex(const char **s) +static char *ldb_parse_lex(struct ldb_context *ldb, const char **s) { const char *p = *s; char *ret; @@ -75,7 +75,7 @@ static char *ldb_parse_lex(const char **s) if (strchr("()&|=!", *p)) { (*s) = p+1; - ret = strndup(p, 1); + ret = ldb_strndup(ldb, p, 1); if (!ret) { errno = ENOMEM; } @@ -90,7 +90,7 @@ static char *ldb_parse_lex(const char **s) return NULL; } - ret = strndup(*s, p - *s); + ret = ldb_strndup(ldb, *s, p - *s); if (!ret) { errno = ENOMEM; } @@ -122,46 +122,42 @@ static const char *match_brace(const char *s) } -static struct ldb_parse_tree *ldb_parse_filter(const char **s); +static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s); /* <simple> ::= <attributetype> <filtertype> <attributevalue> */ -static struct ldb_parse_tree *ldb_parse_simple(const char *s) +static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const char *s) { char *eq, *val, *l; struct ldb_parse_tree *ret; - l = ldb_parse_lex(&s); + l = ldb_parse_lex(ldb, &s); if (!l) { - fprintf(stderr, "Unexpected end of expression\n"); return NULL; } if (strchr("()&|=", *l)) { - fprintf(stderr, "Unexpected token '%s'\n", l); - free(l); + ldb_free(ldb, l); return NULL; } - eq = ldb_parse_lex(&s); + eq = ldb_parse_lex(ldb, &s); if (!eq || strcmp(eq, "=") != 0) { - fprintf(stderr, "Expected '='\n"); - free(l); - if (eq) free(eq); + ldb_free(ldb, l); + if (eq) ldb_free(ldb, eq); return NULL; } - free(eq); + ldb_free(ldb, eq); - val = ldb_parse_lex(&s); + val = ldb_parse_lex(ldb, &s); if (val && strchr("()&|=", *val)) { - fprintf(stderr, "Unexpected token '%s'\n", val); - free(l); - if (val) free(val); + ldb_free(ldb, l); + if (val) ldb_free(ldb, val); return NULL; } - ret = malloc_p(struct ldb_parse_tree); + ret = ldb_malloc_p(ldb, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -182,11 +178,12 @@ static struct ldb_parse_tree *ldb_parse_simple(const char *s) <or> ::= '|' <filterlist> <filterlist> ::= <filter> | <filter> <filterlist> */ -static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const char *s) +static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb, + enum ldb_parse_op op, const char *s) { struct ldb_parse_tree *ret, *next; - ret = malloc_p(struct ldb_parse_tree); + ret = ldb_malloc_p(ldb, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -194,31 +191,31 @@ static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const c ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = malloc_p(struct ldb_parse_tree *); + ret->u.list.elements = ldb_malloc_p(ldb, struct ldb_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; - free(ret); + ldb_free(ldb, ret); return NULL; } - ret->u.list.elements[0] = ldb_parse_filter(&s); + ret->u.list.elements[0] = ldb_parse_filter(ldb, &s); if (!ret->u.list.elements[0]) { - free(ret->u.list.elements); - free(ret); + ldb_free(ldb, ret->u.list.elements); + ldb_free(ldb, ret); return NULL; } while (isspace(*s)) s++; - while (*s && (next = ldb_parse_filter(&s))) { + while (*s && (next = ldb_parse_filter(ldb, &s))) { struct ldb_parse_tree **e; - e = realloc_p(ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); + e = ldb_realloc_p(ldb, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); if (!e) { errno = ENOMEM; - ldb_parse_tree_free(next); - ldb_parse_tree_free(ret); + ldb_parse_tree_free(ldb, next); + ldb_parse_tree_free(ldb, ret); return NULL; } ret->u.list.elements = e; @@ -234,20 +231,20 @@ static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const c /* <not> ::= '!' <filter> */ -static struct ldb_parse_tree *ldb_parse_not(const char *s) +static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char *s) { struct ldb_parse_tree *ret; - ret = malloc_p(struct ldb_parse_tree); + ret = ldb_malloc_p(ldb, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; } ret->operation = LDB_OP_NOT; - ret->u.not.child = ldb_parse_filter(&s); + ret->u.not.child = ldb_parse_filter(ldb, &s); if (!ret->u.not.child) { - free(ret); + ldb_free(ldb, ret); return NULL; } @@ -258,67 +255,64 @@ static struct ldb_parse_tree *ldb_parse_not(const char *s) parse a filtercomp <filtercomp> ::= <and> | <or> | <not> | <simple> */ -static struct ldb_parse_tree *ldb_parse_filtercomp(const char *s) +static struct ldb_parse_tree *ldb_parse_filtercomp(struct ldb_context *ldb, + const char *s) { while (isspace(*s)) s++; switch (*s) { case '&': - return ldb_parse_filterlist(LDB_OP_AND, s+1); + return ldb_parse_filterlist(ldb, LDB_OP_AND, s+1); case '|': - return ldb_parse_filterlist(LDB_OP_OR, s+1); + return ldb_parse_filterlist(ldb, LDB_OP_OR, s+1); case '!': - return ldb_parse_not(s+1); + return ldb_parse_not(ldb, s+1); case '(': case ')': - fprintf(stderr, "Unexpected token '%c'\n", *s); return NULL; } - return ldb_parse_simple(s); + return ldb_parse_simple(ldb, s); } /* <filter> ::= '(' <filtercomp> ')' */ -static struct ldb_parse_tree *ldb_parse_filter(const char **s) +static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s) { char *l, *s2; const char *p, *p2; struct ldb_parse_tree *ret; - l = ldb_parse_lex(s); + l = ldb_parse_lex(ldb, s); if (!l) { - fprintf(stderr, "Unexpected end of expression\n"); return NULL; } if (strcmp(l, "(") != 0) { - free(l); - fprintf(stderr, "Expected '('\n"); + ldb_free(ldb, l); return NULL; } - free(l); + ldb_free(ldb, l); p = match_brace(*s); if (!p) { - fprintf(stderr, "Parse error - mismatched braces\n"); return NULL; } p2 = p + 1; - s2 = strndup(*s, p - *s); + s2 = ldb_strndup(ldb, *s, p - *s); if (!s2) { errno = ENOMEM; return NULL; } - ret = ldb_parse_filtercomp(s2); - free(s2); + ret = ldb_parse_filtercomp(ldb, s2); + ldb_free(ldb, s2); *s = p2; @@ -331,130 +325,43 @@ static struct ldb_parse_tree *ldb_parse_filter(const char **s) expression ::= <simple> | <filter> */ -struct ldb_parse_tree *ldb_parse_tree(const char *s) +struct ldb_parse_tree *ldb_parse_tree(struct ldb_context *ldb, const char *s) { while (isspace(*s)) s++; if (*s == '(') { - return ldb_parse_filter(&s); + return ldb_parse_filter(ldb, &s); } - return ldb_parse_simple(s); + return ldb_parse_simple(ldb, s); } /* free a parse tree returned from ldb_parse_tree() */ -void ldb_parse_tree_free(struct ldb_parse_tree *tree) +void ldb_parse_tree_free(struct ldb_context *ldb, struct ldb_parse_tree *tree) { int i; switch (tree->operation) { case LDB_OP_SIMPLE: - free(tree->u.simple.attr); - if (tree->u.simple.value.data) free(tree->u.simple.value.data); + ldb_free(ldb, tree->u.simple.attr); + if (tree->u.simple.value.data) ldb_free(ldb, tree->u.simple.value.data); break; case LDB_OP_AND: case LDB_OP_OR: for (i=0;i<tree->u.list.num_elements;i++) { - ldb_parse_tree_free(tree->u.list.elements[i]); + ldb_parse_tree_free(ldb, tree->u.list.elements[i]); } - if (tree->u.list.elements) free(tree->u.list.elements); + if (tree->u.list.elements) ldb_free(ldb, tree->u.list.elements); break; case LDB_OP_NOT: - ldb_parse_tree_free(tree->u.not.child); + ldb_parse_tree_free(ldb, tree->u.not.child); break; } - free(tree); + ldb_free(ldb, tree); } -#if TEST_PROGRAM -/* - return a string representation of a parse tree - used for debugging -*/ -static char *tree_string(struct ldb_parse_tree *tree) -{ - char *s = NULL; - char *s1, *s2; - int i; - - switch (tree->operation) { - case LDB_OP_SIMPLE: - asprintf(&s, "( %s = \"%s\" )", tree->u.simple.attr, - (char *)tree->u.simple.value.data); - break; - - case LDB_OP_AND: - case LDB_OP_OR: - asprintf(&s, "( %c", tree->operation==LDB_OP_AND?'&':'|'); - if (!s) return NULL; - - for (i=0;i<tree->u.list.num_elements;i++) { - s1 = tree_string(tree->u.list.elements[i]); - if (!s1) { - free(s); - return NULL; - } - asprintf(&s2, "%s %s", s, s1); - free(s); - free(s1); - s = s2; - } - if (!s) { - return NULL; - } - asprintf(&s2, "%s )", s); - free(s); - s = s2; - break; - - case LDB_OP_NOT: - s1 = tree_string(tree->u.not.child); - asprintf(&s, "( ! %s )", s1); - free(s1); - break; - } - return s; -} - - -/* - print a tree - */ -static void print_tree(struct ldb_parse_tree *tree) -{ - char *s = tree_string(tree); - printf("%s\n", s); - free(s); -} - - - int main(void) -{ - char line[1000]; - int ret = 0; - - while (fgets(line, sizeof(line)-1, stdin)) { - struct ldb_parse_tree *tree; - - if (line[strlen(line)-1] == '\n') { - line[strlen(line)-1] = 0; - } - tree = ldb_parse_tree(line); - if (!tree) { - fprintf(stderr, "Failed to parse\n"); - ret = 1; - continue; - } - print_tree(tree); - ldb_parse_tree_free(tree); - } - - return ret; -} -#endif /* TEST_PROGRAM */ - diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c index 7767b0955e..1e467d23af 100644 --- a/source4/lib/ldb/common/ldb_utf8.c +++ b/source4/lib/ldb/common/ldb_utf8.c @@ -38,10 +38,10 @@ TODO: a simple case folding function - will be replaced by a UTF8 aware function later */ -char *ldb_casefold(const char *s) +char *ldb_casefold(struct ldb_context *ldb, const char *s) { int i; - char *ret = strdup(s); + char *ret = ldb_strdup(ldb, s); if (!s) { errno = ENOMEM; return NULL; diff --git a/source4/lib/ldb/common/util.c b/source4/lib/ldb/common/util.c index 22bbc8334e..68537a7864 100644 --- a/source4/lib/ldb/common/util.c +++ b/source4/lib/ldb/common/util.c @@ -35,24 +35,6 @@ #include "includes.h" -#define MAX_MALLOC_SIZE 0x7fffffff - -/* - realloc an array, checking for integer overflow in the array size -*/ -void *realloc_array(void *ptr, size_t el_size, unsigned count) -{ - if (count == 0 || - count >= MAX_MALLOC_SIZE/el_size) { - return NULL; - } - if (!ptr) { - return malloc(el_size * count); - } - return realloc(ptr, el_size * count); -} - - /* find an element in a list, using the given comparison function and assuming that the list is already sorted using comp_fn diff --git a/source4/lib/ldb/config.m4 b/source4/lib/ldb/config.m4 index 444e65bfab..975da5a4a6 100644 --- a/source4/lib/ldb/config.m4 +++ b/source4/lib/ldb/config.m4 @@ -8,6 +8,7 @@ SMB_SUBSYSTEM(LIBLDB,[lib/ldb/common/ldb.o], lib/ldb/common/ldb_msg.o \ lib/ldb/common/util.o \ lib/ldb/common/ldb_utf8.o \ + lib/ldb/common/ldb_alloc.o \ lib/ldb/ldb_tdb/ldb_search.o \ lib/ldb/ldb_tdb/ldb_tdb.o \ lib/ldb/ldb_tdb/ldb_pack.o \ diff --git a/source4/lib/ldb/include/includes.h b/source4/lib/ldb/include/includes.h index 7ee6876f48..bf61a983e0 100644 --- a/source4/lib/ldb/include/includes.h +++ b/source4/lib/ldb/include/includes.h @@ -18,11 +18,5 @@ #include <sys/time.h> #include <time.h> #include "ldb.h" -#include "ldb_parse.h" - -#define malloc_p(type) (type *)malloc(sizeof(type)) -#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count) -#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count) - #include "tdb/tdb.h" #include "proto.h" diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index cee72c3c21..852389d415 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -32,6 +32,9 @@ * Author: Andrew Tridgell */ +#ifndef _LDB_H_ +#define _LDB_H_ 1 + /* major restrictions as compared to normal LDAP: @@ -46,7 +49,6 @@ */ - /* an individual lump of data in a result comes in this format. The pointer will usually be to a UTF-8 string if the application is @@ -58,6 +60,9 @@ struct ldb_val { void *data; }; +#include "ldb_parse.h" + + /* these flags are used in ldd_message_element.flags fields. The LDA_FLAGS_MOD_* flags are used in ldap_modify() calls to specify whether attributes are being added, deleted or modified */ @@ -130,8 +135,24 @@ struct ldb_backend_ops { int (*modify_record)(struct ldb_context *, const struct ldb_message *); int (*delete_record)(struct ldb_context *, const char *); const char * (*errstring)(struct ldb_context *); + + /* this is called when the alloc ops changes to ensure we + don't have any old allocated data in the context */ + void (*cache_free)(struct ldb_context *); }; + +/* + the user can optionally supply a allocator function. It is presumed + it will act like a modern realloc(), with a context ptr to allow + for pool allocators +*/ +struct ldb_alloc_ops { + void *(*alloc)(void *context, void *ptr, size_t size); + void *context; +}; + + /* every ldb connection is started by establishing a ldb_context */ @@ -141,6 +162,9 @@ struct ldb_context { /* the operations provided by the backend */ const struct ldb_backend_ops *ops; + + /* memory allocation info */ + struct ldb_alloc_ops alloc_ops; }; @@ -209,19 +233,21 @@ const char *ldb_errstring(struct ldb_context *ldb); /* casefold a string (should be UTF8, but at the moment it isn't) */ -char *ldb_casefold(const char *s); +char *ldb_casefold(struct ldb_context *ldb, const char *s); /* ldif manipulation functions */ -int ldif_write(int (*fprintf_fn)(void *, const char *, ...), +int ldif_write(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...), void *private_data, const struct ldb_ldif *ldif); -void ldif_read_free(struct ldb_ldif *); -struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data); -struct ldb_ldif *ldif_read_file(FILE *f); -struct ldb_ldif *ldif_read_string(const char *s); -int ldif_write_file(FILE *f, const struct ldb_ldif *msg); +void ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *); +struct ldb_ldif *ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data); +struct ldb_ldif *ldif_read_file(struct ldb_context *ldb, FILE *f); +struct ldb_ldif *ldif_read_string(struct ldb_context *ldb, const char *s); +int ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); /* useful functions for ldb_message structure manipulation */ @@ -238,10 +264,12 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, struct ldb_val *val); /* add a new empty element to a ldb_message */ -int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags); +int ldb_msg_add_empty(struct ldb_context *ldb, + struct ldb_message *msg, const char *attr_name, int flags); /* add a element to a ldb_message */ -int ldb_msg_add(struct ldb_message *msg, +int ldb_msg_add(struct ldb_context *ldb, + struct ldb_message *msg, const struct ldb_message_element *el, int flags); @@ -264,3 +292,26 @@ double ldb_msg_find_double(const struct ldb_message *msg, const char *ldb_msg_find_string(const struct ldb_message *msg, const char *attr_name, const char *default_value); + + +/* + this allows the user to choose their own allocation function + the allocation function should behave like a modern realloc() + function, which means that: + malloc(size) == alloc(context, NULL, size) + free(ptr) == alloc(context, ptr, 0) + realloc(ptr, size) == alloc(context, ptr, size) + The context argument is provided to allow for pool based allocators, + which often take a context argument +*/ +int ldb_set_alloc(struct ldb_context *ldb, + void *(*alloc)(void *context, void *ptr, size_t size), + void *context); + + +/* these are used as type safe versions of the ldb allocation functions */ +#define ldb_malloc_p(ldb, type) (type *)ldb_malloc(ldb, sizeof(type)) +#define ldb_malloc_array_p(ldb, type, count) (type *)ldb_realloc_array(ldb, NULL, sizeof(type), count) +#define ldb_realloc_p(ldb, p, type, count) (type *)ldb_realloc_array(ldb, p, sizeof(type), count) + +#endif diff --git a/source4/lib/ldb/include/ldb_parse.h b/source4/lib/ldb/include/ldb_parse.h index c0d5806cc9..930799d7b6 100644 --- a/source4/lib/ldb/include/ldb_parse.h +++ b/source4/lib/ldb/include/ldb_parse.h @@ -32,6 +32,8 @@ * Author: Andrew Tridgell */ +#ifndef _LDB_PARSE_H +#define _LDB_PARSE_H 1 enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT}; @@ -51,3 +53,5 @@ struct ldb_parse_tree { } not; } u; }; + +#endif diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 8723beeadc..7e7d047f25 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -77,13 +77,15 @@ static int lldb_close(struct ldb_context *ldb) ret = -1; } + ldb_set_alloc(ldb, NULL, NULL); + if (lldb->options) { for (i=0;lldb->options[i];i++) { - free(lldb->options[i]); + ldb_free(ldb, lldb->options[i]); } - free(lldb->options); + ldb_free(ldb, lldb->options); } - free(lldb); + ldb_free(ldb, lldb); free(ldb); return ret; @@ -116,18 +118,18 @@ static int lldb_delete(struct ldb_context *ldb, const char *dn) static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg) { int i, j; - free(msg->dn); + ldb_free(ldb, msg->dn); for (i=0;i<msg->num_elements;i++) { - free(msg->elements[i].name); + ldb_free(ldb, msg->elements[i].name); for (j=0;j<msg->elements[i].num_values;j++) { if (msg->elements[i].values[j].data) { - free(msg->elements[i].values[j].data); + ldb_free(ldb, msg->elements[i].values[j].data); } } - free(msg->elements[i].values); + ldb_free(ldb, msg->elements[i].values); } - if (msg->elements) free(msg->elements); - free(msg); + if (msg->elements) ldb_free(ldb, msg->elements); + ldb_free(ldb, msg); return 0; } @@ -142,7 +144,7 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res) return -1; } } - free(res); + ldb_free(ldb, res); return 0; } @@ -150,7 +152,8 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res) /* add a single set of ldap message values to a ldb_message */ -static int lldb_add_msg_attr(struct ldb_message *msg, +static int lldb_add_msg_attr(struct ldb_context *ldb, + struct ldb_message *msg, const char *attr, struct berval **bval) { int count, i; @@ -162,8 +165,8 @@ static int lldb_add_msg_attr(struct ldb_message *msg, return -1; } - el = realloc_p(msg->elements, struct ldb_message_element, - msg->num_elements + 1); + el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, + msg->num_elements + 1); if (!el) { errno = ENOMEM; return -1; @@ -173,7 +176,7 @@ static int lldb_add_msg_attr(struct ldb_message *msg, el = &msg->elements[msg->num_elements]; - el->name = strdup(attr); + el->name = ldb_strdup(ldb, attr); if (!el->name) { errno = ENOMEM; return -1; @@ -181,14 +184,14 @@ static int lldb_add_msg_attr(struct ldb_message *msg, el->flags = 0; el->num_values = 0; - el->values = malloc_array_p(struct ldb_val, count); + el->values = ldb_malloc_array_p(ldb, struct ldb_val, count); if (!el->values) { errno = ENOMEM; return -1; } for (i=0;i<count;i++) { - el->values[i].data = malloc(bval[i]->bv_len); + el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len); if (!el->values[i].data) { return -1; } @@ -225,7 +228,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base, return count; } - (*res) = malloc_array_p(struct ldb_message *, count+1); + (*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1); if (! *res) { ldap_msgfree(ldapres); errno = ENOMEM; @@ -249,7 +252,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base, break; } - (*res)[msg_count] = malloc_p(struct ldb_message); + (*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message); if (!(*res)[msg_count]) { goto failed; } @@ -260,7 +263,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base, goto failed; } - (*res)[msg_count]->dn = strdup(dn); + (*res)[msg_count]->dn = ldb_strdup(ldb, dn); ldap_memfree(dn); if (!(*res)[msg_count]->dn) { goto failed; @@ -279,7 +282,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base, bval = ldap_get_values_len(lldb->ldap, msg, attr); if (bval) { - lldb_add_msg_attr((*res)[msg_count], attr, bval); + lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval); ldap_value_free_len(bval); } @@ -303,7 +306,7 @@ failed: /* free a set of mods from lldb_msg_to_mods() */ -static void lldb_mods_free(LDAPMod **mods) +static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods) { int i, j; @@ -312,13 +315,13 @@ static void lldb_mods_free(LDAPMod **mods) for (i=0;mods[i];i++) { if (mods[i]->mod_vals.modv_bvals) { for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) { - free(mods[i]->mod_vals.modv_bvals[j]); + ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]); } - free(mods[i]->mod_vals.modv_bvals); + ldb_free(ldb, mods[i]->mod_vals.modv_bvals); } - free(mods[i]); + ldb_free(ldb, mods[i]); } - free(mods); + ldb_free(ldb, mods); } @@ -326,13 +329,14 @@ static void lldb_mods_free(LDAPMod **mods) convert a ldb_message structure to a list of LDAPMod structures ready for ldap_add() or ldap_modify() */ -static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags) +static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb, + const struct ldb_message *msg, int use_flags) { LDAPMod **mods; int i, j, num_mods = 0; /* allocate maximum number of elements needed */ - mods = malloc_array_p(LDAPMod *, msg->num_elements+1); + mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1); if (!mods) { errno = ENOMEM; return NULL; @@ -342,7 +346,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags) for (i=0;i<msg->num_elements;i++) { const struct ldb_message_element *el = &msg->elements[i]; - mods[num_mods] = malloc_p(LDAPMod); + mods[num_mods] = ldb_malloc_p(ldb, LDAPMod); if (!mods[num_mods]) { goto failed; } @@ -362,14 +366,15 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags) } } mods[num_mods]->mod_type = el->name; - mods[num_mods]->mod_vals.modv_bvals = malloc_array_p(struct berval *, - 1+el->num_values); + mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb, + struct berval *, + 1+el->num_values); if (!mods[num_mods]->mod_vals.modv_bvals) { goto failed; } for (j=0;j<el->num_values;j++) { - mods[num_mods]->mod_vals.modv_bvals[j] = malloc_p(struct berval); + mods[num_mods]->mod_vals.modv_bvals[j] = ldb_malloc_p(ldb, struct berval); if (!mods[num_mods]->mod_vals.modv_bvals[j]) { goto failed; } @@ -383,7 +388,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags) return mods; failed: - lldb_mods_free(mods); + lldb_mods_free(ldb, mods); return NULL; } @@ -402,14 +407,14 @@ static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg) return 0; } - mods = lldb_msg_to_mods(msg, 0); + mods = lldb_msg_to_mods(ldb, msg, 0); lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods); if (lldb->last_rc != LDAP_SUCCESS) { ret = -1; } - lldb_mods_free(mods); + lldb_mods_free(ldb, mods); return ret; } @@ -429,14 +434,14 @@ static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg) return 0; } - mods = lldb_msg_to_mods(msg, 1); + mods = lldb_msg_to_mods(ldb, msg, 1); lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods); if (lldb->last_rc != LDAP_SUCCESS) { ret = -1; } - lldb_mods_free(mods); + lldb_mods_free(ldb, mods); return ret; } @@ -474,15 +479,15 @@ struct ldb_context *lldb_connect(const char *url, struct lldb_private *lldb = NULL; int i; - ldb = malloc_p(struct ldb_context); + ldb = calloc(1, sizeof(struct ldb_context)); if (!ldb) { errno = ENOMEM; goto failed; } - lldb = malloc_p(struct lldb_private); + lldb = ldb_malloc_p(ldb, struct lldb_private); if (!lldb) { - free(ldb); + ldb_free(ldb, ldb); errno = ENOMEM; goto failed; } @@ -503,14 +508,14 @@ struct ldb_context *lldb_connect(const char *url, on the caller keeping it around (it might be dynamic) */ for (i=0;options[i];i++) ; - lldb->options = malloc_array_p(char *, i+1); + lldb->options = ldb_malloc_array_p(ldb, char *, i+1); if (!lldb->options) { goto failed; } for (i=0;options[i];i++) { lldb->options[i+1] = NULL; - lldb->options[i] = strdup(options[i]); + lldb->options[i] = ldb_strdup(ldb, options[i]); if (!lldb->options[i]) { goto failed; } @@ -522,14 +527,14 @@ struct ldb_context *lldb_connect(const char *url, failed: if (lldb && lldb->options) { for (i=0;lldb->options[i];i++) { - free(lldb->options[i]); + ldb_free(ldb, lldb->options[i]); } - free(lldb->options); + ldb_free(ldb, lldb->options); } if (lldb && lldb->ldap) { ldap_unbind(lldb->ldap); } - if (lldb) free(lldb); + ldb_free(ldb, lldb); if (ldb) free(ldb); return NULL; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index 3c6ce63c2b..6734de9fd8 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -50,24 +50,24 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb) msg.num_elements = 1; msg.elements = ⪙ - msg.dn = strdup(LTDB_BASEINFO); + msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); if (!msg.dn) { errno = ENOMEM; return -1; } - el.name = strdup(LTDB_SEQUENCE_NUMBER); + el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); if (!el.name) { - free(msg.dn); + ldb_free(ldb, msg.dn); errno = ENOMEM; return -1; } el.values = &val; el.num_values = 1; el.flags = 0; - val.data = strdup("0"); + val.data = ldb_strdup(ldb, "0"); if (!val.data) { - free(el.name); - free(msg.dn); + ldb_free(ldb, el.name); + ldb_free(ldb, msg.dn); errno = ENOMEM; return -1; } @@ -75,9 +75,9 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb) ret = ltdb_store(ldb, &msg, TDB_INSERT); - free(msg.dn); - free(el.name); - free(val.data); + ldb_free(ldb, msg.dn); + ldb_free(ldb, el.name); + ldb_free(ldb, val.data); return ret; } @@ -88,6 +88,8 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb) void ltdb_cache_free(struct ldb_context *ldb) { struct ltdb_private *ltdb = ldb->private_data; + struct ldb_alloc_ops alloc = ldb->alloc_ops; + ldb->alloc_ops.alloc = NULL; ltdb->sequence_number = 0; ltdb_search_dn1_free(ldb, <db->cache.baseinfo); @@ -95,8 +97,10 @@ void ltdb_cache_free(struct ldb_context *ldb) ltdb_search_dn1_free(ldb, <db->cache.subclasses); ltdb_search_dn1_free(ldb, <db->cache.attributes); - if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name); + ldb_free(ldb, ltdb->cache.last_attribute.name); memset(<db->cache, 0, sizeof(ltdb->cache)); + + ldb->alloc_ops = alloc; } /* @@ -106,20 +110,23 @@ int ltdb_cache_load(struct ldb_context *ldb) { struct ltdb_private *ltdb = ldb->private_data; double seq; + struct ldb_alloc_ops alloc = ldb->alloc_ops; + + ldb->alloc_ops.alloc = NULL; ltdb_search_dn1_free(ldb, <db->cache.baseinfo); if (ltdb_search_dn1(ldb, LTDB_BASEINFO, <db->cache.baseinfo) == -1) { - return -1; + goto failed; } /* possibly initialise the baseinfo */ if (!ltdb->cache.baseinfo.dn) { if (ltdb_baseinfo_init(ldb) != 0) { - return -1; + goto failed; } if (ltdb_search_dn1(ldb, LTDB_BASEINFO, <db->cache.baseinfo) != 1) { - return -1; + goto failed; } } @@ -127,11 +134,11 @@ int ltdb_cache_load(struct ldb_context *ldb) in the database then assume the rest of the cache is OK */ seq = ldb_msg_find_double(<db->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0); if (seq == ltdb->sequence_number) { - return 0; + goto done; } ltdb->sequence_number = seq; - if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name); + ldb_free(ldb, ltdb->cache.last_attribute.name); memset(<db->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute)); ltdb_search_dn1_free(ldb, <db->cache.indexlist); @@ -139,16 +146,22 @@ int ltdb_cache_load(struct ldb_context *ldb) ltdb_search_dn1_free(ldb, <db->cache.attributes); if (ltdb_search_dn1(ldb, LTDB_INDEXLIST, <db->cache.indexlist) == -1) { - return -1; + goto failed; } if (ltdb_search_dn1(ldb, LTDB_SUBCLASSES, <db->cache.subclasses) == -1) { - return -1; + goto failed; } if (ltdb_search_dn1(ldb, LTDB_ATTRIBUTES, <db->cache.attributes) == -1) { - return -1; + goto failed; } +done: + ldb->alloc_ops = alloc; return 0; + +failed: + ldb->alloc_ops = alloc; + return -1; } @@ -164,7 +177,7 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb) char *s = NULL; int ret; - asprintf(&s, "%.0f", ltdb->sequence_number+1); + ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1); if (!s) { errno = ENOMEM; return -1; @@ -172,8 +185,8 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb) msg.num_elements = 1; msg.elements = ⪙ - msg.dn = strdup(LTDB_BASEINFO); - el.name = strdup(LTDB_SEQUENCE_NUMBER); + msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); + el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); el.values = &val; el.num_values = 1; el.flags = LDB_FLAG_MOD_REPLACE; @@ -182,9 +195,9 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb) ret = ltdb_modify_internal(ldb, &msg); - free(s); - free(msg.dn); - free(el.name); + ldb_free(ldb, s); + ldb_free(ldb, msg.dn); + ldb_free(ldb, el.name); if (ret == 0) { ltdb->sequence_number += 1; @@ -244,9 +257,9 @@ int ltdb_attribute_flags(struct ldb_context *ldb, const char *attr_name) attrs += strspn(attrs, " ,"); } - if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name); + if (ltdb->cache.last_attribute.name) ldb_free(ldb, ltdb->cache.last_attribute.name); - ltdb->cache.last_attribute.name = strdup(attr_name); + ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name); ltdb->cache.last_attribute.flags = ret; return ret; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 0b9581e52f..07077281ce 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -43,32 +43,33 @@ struct dn_list { /* free a struct dn_list */ -static void dn_list_free(struct dn_list *list) +static void dn_list_free(struct ldb_context *ldb, struct dn_list *list) { int i; for (i=0;i<list->count;i++) { - free(list->dn[i]); + ldb_free(ldb, list->dn[i]); } - if (list->dn) free(list->dn); + ldb_free(ldb, list->dn); } /* return the dn key to be used for an index caller frees */ -static char *ldb_dn_key(const char *attr, const struct ldb_val *value) +static char *ldb_dn_key(struct ldb_context *ldb, + const char *attr, const struct ldb_val *value) { char *ret = NULL; if (ldb_should_b64_encode(value)) { - char *vstr = ldb_base64_encode(value->data, value->length); + char *vstr = ldb_base64_encode(ldb, value->data, value->length); if (!vstr) return NULL; - asprintf(&ret, "%s:%s::%s", LTDB_INDEX, attr, vstr); - free(vstr); + ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr); + ldb_free(ldb, vstr); return ret; } - asprintf(&ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data); + ldb_asprintf(ldb, &ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data); return ret; } @@ -132,11 +133,11 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb, /* the attribute is indexed. Pull the list of DNs that match the search criterion */ - dn = ldb_dn_key(tree->u.simple.attr, &tree->u.simple.value); + dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value); if (!dn) return -1; ret = ltdb_search_dn1(ldb, dn, &msg); - free(dn); + ldb_free(ldb, dn); if (ret == 0 || ret == -1) { return ret; } @@ -150,16 +151,16 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb, el = &msg.elements[i]; - list->dn = malloc_array_p(char *, el->num_values); + list->dn = ldb_malloc_array_p(ldb, char *, el->num_values); if (!list->dn) { break; } for (j=0;j<el->num_values;j++) { list->dn[list->count] = - strdup((char *)el->values[j].data); + ldb_strdup(ldb, (char *)el->values[j].data); if (!list->dn[list->count]) { - dn_list_free(list); + dn_list_free(ldb, list); ltdb_search_dn1_free(ldb, &msg); return -1; } @@ -202,7 +203,7 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb, struct ldb_parse_tree tree2; struct dn_list list2; tree2.operation = LDB_OP_SIMPLE; - tree2.u.simple.attr = strdup(LTDB_OBJECTCLASS); + tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS); if (!tree2.u.simple.attr) { return -1; } @@ -214,10 +215,10 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb, ret = 1; } else { list_union(list, &list2); - dn_list_free(&list2); + dn_list_free(ldb, &list2); } } - free(tree2.u.simple.attr); + ldb_free(ldb, tree2.u.simple.attr); } } } @@ -245,20 +246,21 @@ static int ltdb_index_dn_leaf(struct ldb_context *ldb, list = list & list2 relies on the lists being sorted */ -static int list_intersect(struct dn_list *list, const struct dn_list *list2) +static int list_intersect(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) { struct dn_list list3; int i; if (list->count == 0 || list2->count == 0) { /* 0 & X == 0 */ - dn_list_free(list); + dn_list_free(ldb, list); return 0; } - list3.dn = malloc_array_p(char *, list->count); + list3.dn = ldb_malloc_array_p(ldb, char *, list->count); if (!list3.dn) { - dn_list_free(list); + dn_list_free(ldb, list); return -1; } list3.count = 0; @@ -269,11 +271,11 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2) list3.dn[list3.count] = list->dn[i]; list3.count++; } else { - free(list->dn[i]); + ldb_free(ldb, list->dn[i]); } } - free(list->dn); + ldb_free(ldb, list->dn); list->dn = list3.dn; list->count = list3.count; @@ -286,7 +288,8 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2) list = list | list2 relies on the lists being sorted */ -static int list_union(struct dn_list *list, const struct dn_list *list2) +static int list_union(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) { int i; char **d; @@ -294,13 +297,13 @@ static int list_union(struct dn_list *list, const struct dn_list *list2) if (list->count == 0 && list2->count == 0) { /* 0 | 0 == 0 */ - dn_list_free(list); + dn_list_free(ldb, list); return 0; } - d = realloc_p(list->dn, char *, list->count + list2->count); + d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count); if (!d) { - dn_list_free(list); + dn_list_free(ldb, list); return -1; } list->dn = d; @@ -308,9 +311,9 @@ static int list_union(struct dn_list *list, const struct dn_list *list2) for (i=0;i<list2->count;i++) { if (list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = strdup(list2->dn[i]); + list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]); if (!list->dn[list->count]) { - dn_list_free(list); + dn_list_free(ldb, list); return -1; } list->count++; @@ -359,7 +362,7 @@ static int ltdb_index_dn_or(struct ldb_context *ldb, if (v == -1) { /* 1 || X == 1 */ - dn_list_free(list); + dn_list_free(ldb, list); return -1; } @@ -367,16 +370,16 @@ static int ltdb_index_dn_or(struct ldb_context *ldb, ret = 1; *list = list2; } else { - if (list_union(list, &list2) == -1) { - dn_list_free(&list2); + if (list_union(ldb, list, &list2) == -1) { + dn_list_free(ldb, &list2); return -1; } - dn_list_free(&list2); + dn_list_free(ldb, &list2); } } if (list->count == 0) { - dn_list_free(list); + dn_list_free(ldb, list); return 0; } @@ -424,7 +427,7 @@ static int ltdb_index_dn_and(struct ldb_context *ldb, if (v == 0) { /* 0 && X == 0 */ - dn_list_free(list); + dn_list_free(ldb, list); return 0; } @@ -436,15 +439,15 @@ static int ltdb_index_dn_and(struct ldb_context *ldb, ret = 1; *list = list2; } else { - if (list_intersect(list, &list2) == -1) { - dn_list_free(&list2); + if (list_intersect(ldb, list, &list2) == -1) { + dn_list_free(ldb, &list2); return -1; } - dn_list_free(&list2); + dn_list_free(ldb, &list2); } if (list->count == 0) { - if (list->dn) free(list->dn); + if (list->dn) ldb_free(ldb, list->dn); return 0; } } @@ -550,7 +553,7 @@ int ltdb_search_indexed(struct ldb_context *ldb, and extract the needed attributes */ ret = ldb_index_filter(ldb, tree, base, scope, &dn_list, attrs, res); - dn_list_free(&dn_list); + dn_list_free(ldb, &dn_list); } return ret; @@ -567,18 +570,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, struct ldb_message_element *el2; /* add another entry */ - el2 = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1); + el2 = ldb_realloc_p(ldb, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!el2) { return -1; } msg->elements = el2; - msg->elements[msg->num_elements].name = strdup(LTDB_IDX); + msg->elements[msg->num_elements].name = ldb_strdup(ldb, LTDB_IDX); if (!msg->elements[msg->num_elements].name) { return -1; } msg->elements[msg->num_elements].num_values = 0; - msg->elements[msg->num_elements].values = malloc_p(struct ldb_val); + msg->elements[msg->num_elements].values = ldb_malloc_p(ldb, struct ldb_val); if (!msg->elements[msg->num_elements].values) { return -1; } @@ -611,9 +615,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } } - v2 = realloc_p(msg->elements[idx].values, - struct ldb_val, - msg->elements[idx].num_values+1); + v2 = ldb_realloc_p(ldb, msg->elements[idx].values, + struct ldb_val, + msg->elements[idx].num_values+1); if (!v2) { return -1; } @@ -634,23 +638,24 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn, { struct ldb_message msg; char *dn_key; - int ret, i, added=0; + int ret, i, added=0, added_dn=0; - dn_key = ldb_dn_key(el->name, &el->values[v_idx]); + dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); if (!dn_key) { return -1; } ret = ltdb_search_dn1(ldb, dn_key, &msg); if (ret == -1) { - free(dn_key); + ldb_free(ldb, dn_key); return -1; } if (ret == 0) { - msg.dn = strdup(dn_key); + added_dn = 1; + msg.dn = ldb_strdup(ldb, dn_key); if (!msg.dn) { - free(dn_key); + ldb_free(ldb, dn_key); errno = ENOMEM; return -1; } @@ -659,7 +664,7 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn, msg.private_data = NULL; } - free(dn_key); + ldb_free(ldb, dn_key); for (i=0;i<msg.num_elements;i++) { if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) { @@ -679,7 +684,10 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn, } if (added) { - free(msg.elements[i].name); + ldb_free(ldb, msg.elements[i].name); + } + if (added_dn) { + ldb_free(ldb, msg.dn); } ltdb_search_dn1_free(ldb, &msg); @@ -728,14 +736,14 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn, char *dn_key; int ret, i, j; - dn_key = ldb_dn_key(el->name, &el->values[v_idx]); + dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); if (!dn_key) { return -1; } ret = ltdb_search_dn1(ldb, dn_key, &msg); if (ret == -1) { - free(dn_key); + ldb_free(ldb, dn_key); return -1; } @@ -743,6 +751,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn, /* it wasn't indexed. Did we have an earlier error? If we did then its gone now */ ltdb_search_dn1_free(ldb, &msg); + ldb_free(ldb, dn_key); return 0; } @@ -750,6 +759,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn, if (i == -1) { /* it ain't there. hmmm */ ltdb_search_dn1_free(ldb, &msg); + ldb_free(ldb, dn_key); return 0; } @@ -768,6 +778,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn, } ltdb_search_dn1_free(ldb, &msg); + ldb_free(ldb, dn_key); return ret; } @@ -841,7 +852,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * ret = ltdb_index_add(ldb, &msg); - ltdb_unpack_data_free(&msg); + ltdb_unpack_data_free(ldb, &msg); return ret; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c index 26e0eebfe7..80d147cb43 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_match.c +++ b/source4/lib/ldb/ldb_tdb/ldb_match.c @@ -71,7 +71,8 @@ static int ldb_val_equal_case_insensitive(const struct ldb_val *v1, and case insensitive return 1 for a match, 0 for a mis-match */ -static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1, +static int ldb_val_equal_wildcard_ci(struct ldb_context *ldb, + const struct ldb_val *v1, const struct ldb_val *v2) { char *s1, *s2; @@ -81,20 +82,20 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1, return v1->data == v2->data; } - s1 = ldb_casefold(v1->data); + s1 = ldb_casefold(ldb, v1->data); if (!s1) { return -1; } - s2 = ldb_casefold(v2->data); + s2 = ldb_casefold(ldb, v2->data); if (!s2) { return -1; } ret = fnmatch(s2, s1, 0); - free(s1); - free(s2); + ldb_free(ldb, s1); + ldb_free(ldb, s2); if (ret == 0) { return 1; @@ -107,12 +108,13 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1, see if two ldb_val structures contain the same data with wildcards return 1 for a match, 0 for a mis-match */ -static int ldb_val_equal_wildcard(const struct ldb_val *v1, +static int ldb_val_equal_wildcard(struct ldb_context *ldb, + const struct ldb_val *v1, const struct ldb_val *v2, int flags) { if (flags & LTDB_FLAG_CASE_INSENSITIVE) { - return ldb_val_equal_wildcard_ci(v1, v2); + return ldb_val_equal_wildcard_ci(ldb, v1, v2); } if (!v1->data || !v2->data) { return v1->data == v2->data; @@ -182,7 +184,7 @@ int ldb_val_equal(struct ldb_context *ldb, } if (flags & LTDB_FLAG_WILDCARD) { - return ldb_val_equal_wildcard(v1, v2, flags); + return ldb_val_equal_wildcard(ldb, v1, v2, flags); } if (flags & LTDB_FLAG_CASE_INSENSITIVE) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 3ded595259..a32197e2cf 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -49,7 +49,7 @@ caller frees the data buffer after use */ -int ltdb_pack_data(struct ldb_context *ctx, +int ltdb_pack_data(struct ldb_context *ldb, const struct ldb_message *message, struct TDB_DATA *data) { @@ -74,7 +74,7 @@ int ltdb_pack_data(struct ldb_context *ctx, } /* allocate it */ - data->dptr = malloc(size); + data->dptr = ldb_malloc(ldb, size); if (!data->dptr) { errno = ENOMEM; return -1; @@ -116,14 +116,15 @@ int ltdb_pack_data(struct ldb_context *ctx, /* free the memory allocated from a ltdb_unpack_data() */ -void ltdb_unpack_data_free(struct ldb_message *message) +void ltdb_unpack_data_free(struct ldb_context *ldb, + struct ldb_message *message) { int i; for (i=0;i<message->num_elements;i++) { - if (message->elements[i].values) free(message->elements[i].values); + if (message->elements[i].values) ldb_free(ldb, message->elements[i].values); } - if (message->elements) free(message->elements); + if (message->elements) ldb_free(ldb, message->elements); } @@ -137,7 +138,7 @@ void ltdb_unpack_data_free(struct ldb_message *message) TDB_DATA data. This means the caller only has to free the elements and values arrays. This can be done with ltdb_unpack_data_free() */ -int ltdb_unpack_data(struct ldb_context *ctx, +int ltdb_unpack_data(struct ldb_context *ldb, const struct TDB_DATA *data, struct ldb_message *message) { @@ -192,8 +193,8 @@ int ltdb_unpack_data(struct ldb_context *ctx, goto failed; } - message->elements = malloc_array_p(struct ldb_message_element, - message->num_elements); + message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, + message->num_elements); if (!message->elements) { errno = ENOMEM; @@ -217,8 +218,9 @@ int ltdb_unpack_data(struct ldb_context *ctx, message->elements[i].num_values = IVAL(p, 0); message->elements[i].values = NULL; if (message->elements[i].num_values != 0) { - message->elements[i].values = malloc_array_p(struct ldb_val, - message->elements[i].num_values); + message->elements[i].values = ldb_malloc_array_p(ldb, + struct ldb_val, + message->elements[i].num_values); if (!message->elements[i].values) { errno = ENOMEM; goto failed; @@ -242,7 +244,7 @@ int ltdb_unpack_data(struct ldb_context *ctx, return 0; failed: - ltdb_unpack_data_free(message); + ltdb_unpack_data_free(ldb, message); return -1; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 1dce8f83a2..5ee4449dee 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -38,27 +38,27 @@ /* free a message that has all parts separately allocated */ -static void msg_free_all_parts(struct ldb_message *msg) +static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg) { int i, j; - if (msg->dn) free(msg->dn); + ldb_free(ldb, msg->dn); for (i=0;i<msg->num_elements;i++) { - if (msg->elements[i].name) free(msg->elements[i].name); + ldb_free(ldb, msg->elements[i].name); for (j=0;j<msg->elements[i].num_values;j++) { - if (msg->elements[i].values[j].data) - free(msg->elements[i].values[j].data); + ldb_free(ldb, msg->elements[i].values[j].data); } - if (msg->elements[i].values) free(msg->elements[i].values); + ldb_free(ldb, msg->elements[i].values); } - free(msg->elements); - free(msg); + ldb_free(ldb, msg->elements); + ldb_free(ldb, msg); } /* duplicate a ldb_val structure */ -struct ldb_val ldb_val_dup(const struct ldb_val *v) +struct ldb_val ldb_val_dup(struct ldb_context *ldb, + const struct ldb_val *v) { struct ldb_val v2; v2.length = v->length; @@ -69,7 +69,7 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v) /* the +1 is to cope with buggy C library routines like strndup that look one byte beyond */ - v2.data = malloc(v->length+1); + v2.data = ldb_malloc(ldb, v->length+1); if (!v2.data) { v2.length = 0; return v2; @@ -85,12 +85,13 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v) /* add one element to a message */ -static int msg_add_element(struct ldb_message *ret, const struct ldb_message_element *el) +static int msg_add_element(struct ldb_context *ldb, + struct ldb_message *ret, const struct ldb_message_element *el) { int i; struct ldb_message_element *e2, *elnew; - e2 = realloc_p(ret->elements, struct ldb_message_element, ret->num_elements+1); + e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1); if (!e2) { return -1; } @@ -98,13 +99,13 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele elnew = &e2[ret->num_elements]; - elnew->name = strdup(el->name); + elnew->name = ldb_strdup(ldb, el->name); if (!elnew->name) { return -1; } if (el->num_values) { - elnew->values = malloc_array_p(struct ldb_val, el->num_values); + elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); if (!elnew->values) { return -1; } @@ -113,7 +114,7 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele } for (i=0;i<el->num_values;i++) { - elnew->values[i] = ldb_val_dup(&el->values[i]); + elnew->values[i] = ldb_val_dup(ldb, &el->values[i]); if (elnew->values[i].length != el->values[i].length) { return -1; } @@ -129,12 +130,12 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele /* add all elements from one message into another */ -static int msg_add_all_elements(struct ldb_message *ret, +static int msg_add_all_elements(struct ldb_context *ldb, struct ldb_message *ret, const struct ldb_message *msg) { int i; for (i=0;i<msg->num_elements;i++) { - if (msg_add_element(ret, &msg->elements[i]) != 0) { + if (msg_add_element(ldb, ret, &msg->elements[i]) != 0) { return -1; } } @@ -153,14 +154,14 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb, struct ldb_message *ret; int i; - ret = malloc_p(struct ldb_message); + ret = ldb_malloc_p(ldb, struct ldb_message); if (!ret) { return NULL; } - ret->dn = strdup(msg->dn); + ret->dn = ldb_strdup(ldb, msg->dn); if (!ret->dn) { - free(ret); + ldb_free(ldb, ret); return NULL; } @@ -169,8 +170,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb, ret->private_data = NULL; if (!attrs) { - if (msg_add_all_elements(ret, msg) != 0) { - msg_free_all_parts(ret); + if (msg_add_all_elements(ldb, ret, msg) != 0) { + msg_free_all_parts(ldb, ret); return NULL; } return ret; @@ -180,8 +181,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb, struct ldb_message_element *el; if (strcmp(attrs[i], "*") == 0) { - if (msg_add_all_elements(ret, msg) != 0) { - msg_free_all_parts(ret); + if (msg_add_all_elements(ldb, ret, msg) != 0) { + msg_free_all_parts(ldb, ret); return NULL; } continue; @@ -191,8 +192,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb, if (!el) { continue; } - if (msg_add_element(ret, el) != 0) { - msg_free_all_parts(ret); + if (msg_add_element(ldb, ret, el) != 0) { + msg_free_all_parts(ldb, ret); return NULL; } } @@ -235,11 +236,11 @@ int ltdb_has_wildcard(struct ldb_context *ldb, const char *attr_name, void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg) { int i; - if (msg->private_data) free(msg->private_data); + ldb_free(ldb, msg->private_data); for (i=0;i<msg->num_elements;i++) { - if (msg->elements[i].values) free(msg->elements[i].values); + ldb_free(ldb, msg->elements[i].values); } - if (msg->elements) free(msg->elements); + ldb_free(ldb, msg->elements); memset(msg, 0, sizeof(*msg)); } @@ -254,7 +255,7 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message { struct ltdb_private *ltdb = ldb->private_data; int ret; - TDB_DATA tdb_key, tdb_data; + TDB_DATA tdb_key, tdb_data, tdb_data2; /* form the key */ tdb_key = ltdb_key(ldb, dn); @@ -263,26 +264,35 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message } tdb_data = tdb_fetch(ltdb->tdb, tdb_key); - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); if (!tdb_data.dptr) { return 0; } - msg->private_data = tdb_data.dptr; + tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize); + if (!tdb_data2.dptr) { + free(tdb_data.dptr); + return -1; + } + memcpy(tdb_data2.dptr, tdb_data.dptr, tdb_data.dsize); + free(tdb_data.dptr); + tdb_data2.dsize = tdb_data.dsize; + + msg->private_data = tdb_data2.dptr; msg->num_elements = 0; msg->elements = NULL; - ret = ltdb_unpack_data(ldb, &tdb_data, msg); + ret = ltdb_unpack_data(ldb, &tdb_data2, msg); if (ret == -1) { - free(tdb_data.dptr); + free(tdb_data2.dptr); return -1; } if (!msg->dn) { - msg->dn = strdup(dn); + msg->dn = ldb_strdup(ldb, dn); } if (!msg->dn) { - free(tdb_data.dptr); + ldb_free(ldb, tdb_data2.dptr); return -1; } @@ -312,9 +322,9 @@ int ltdb_search_dn(struct ldb_context *ldb, char *dn, return -1; } - *res = malloc_array_p(struct ldb_message *, 2); + *res = ldb_malloc_array_p(ldb, struct ldb_message *, 2); if (! *res) { - msg_free_all_parts(msg2); + msg_free_all_parts(ldb, msg2); return -1; } @@ -344,9 +354,9 @@ int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg, } /* add to the results list */ - res2 = realloc_p(*res, struct ldb_message *, (*count)+2); + res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2); if (!res2) { - msg_free_all_parts(msg2); + msg_free_all_parts(ldb, msg2); return -1; } @@ -403,7 +413,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi /* see if it matches the given expression */ if (!ldb_message_match(sinfo->ldb, &msg, sinfo->tree, sinfo->base, sinfo->scope)) { - ltdb_unpack_data_free(&msg); + ltdb_unpack_data_free(sinfo->ldb, &msg); return 0; } @@ -413,7 +423,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi sinfo->failures++; } - ltdb_unpack_data_free(&msg); + ltdb_unpack_data_free(sinfo->ldb, &msg); return ret; } @@ -424,15 +434,18 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi */ int ltdb_search_free(struct ldb_context *ldb, struct ldb_message **msgs) { + struct ltdb_private *ltdb = ldb->private_data; int i; + ltdb->last_err_string = NULL; + if (!msgs) return 0; for (i=0;msgs[i];i++) { - msg_free_all_parts(msgs[i]); + msg_free_all_parts(ldb, msgs[i]); } - free(msgs); + ldb_free(ldb, msgs); return 0; } @@ -480,9 +493,12 @@ int ltdb_search(struct ldb_context *ldb, const char *base, enum ldb_scope scope, const char *expression, char * const attrs[], struct ldb_message ***res) { + struct ltdb_private *ltdb = ldb->private_data; struct ldb_parse_tree *tree; int ret; + ltdb->last_err_string = NULL; + if (ltdb_cache_load(ldb) != 0) { return -1; } @@ -490,8 +506,9 @@ int ltdb_search(struct ldb_context *ldb, const char *base, *res = NULL; /* form a parse tree for the expression */ - tree = ldb_parse_tree(expression); + tree = ldb_parse_tree(ldb, expression); if (!tree) { + ltdb->last_err_string = "expression parse failed"; return -1; } @@ -507,7 +524,7 @@ int ltdb_search(struct ldb_context *ldb, const char *base, } } - ldb_parse_tree_free(tree); + ldb_parse_tree_free(ldb, tree); return ret; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index c674f0c27e..eb28bc4938 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -67,35 +67,35 @@ struct TDB_DATA ltdb_key(struct ldb_context *ldb, const char *dn) if (strncmp(dn, prefix, strlen(prefix)) == 0 && (s = strchr(dn+strlen(prefix), ':'))) { char *attr_name, *attr_name_folded; - attr_name = strndup(dn+strlen(prefix), (s-(dn+strlen(prefix)))); + attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix)))); if (!attr_name) { goto failed; } flags = ltdb_attribute_flags(ldb, attr_name); if (flags & LTDB_FLAG_CASE_INSENSITIVE) { - dn_folded = ldb_casefold(dn); + dn_folded = ldb_casefold(ldb, dn); } else { - attr_name_folded = ldb_casefold(attr_name); + attr_name_folded = ldb_casefold(ldb, attr_name); if (!attr_name_folded) { goto failed; } - asprintf(&dn_folded, "%s:%s:%s", + ldb_asprintf(ldb, &dn_folded, "%s:%s:%s", prefix, attr_name_folded, s+1); - free(attr_name_folded); + ldb_free(ldb, attr_name_folded); } - free(attr_name); + ldb_free(ldb, attr_name); } else { - dn_folded = ldb_casefold(dn); + dn_folded = ldb_casefold(ldb, dn); } if (!dn_folded) { goto failed; } - asprintf(&key_str, "DN=%s", dn_folded); - free(dn_folded); + ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded); + ldb_free(ldb, dn_folded); if (!key_str) { goto failed; @@ -129,7 +129,7 @@ static int ltdb_lock(struct ldb_context *ldb) ret = tdb_chainlock(ltdb->tdb, key); - free(key.dptr); + ldb_free(ldb, key.dptr); return ret; } @@ -149,7 +149,7 @@ static void ltdb_unlock(struct ldb_context *ldb) tdb_chainunlock(ltdb->tdb, key); - free(key.dptr); + ldb_free(ldb, key.dptr); } @@ -190,7 +190,7 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs) ret = ltdb_pack_data(ldb, msg, &tdb_data); if (ret == -1) { - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); return -1; } @@ -205,8 +205,8 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs) } done: - free(tdb_key.dptr); - free(tdb_data.dptr); + ldb_free(ldb, tdb_key.dptr); + ldb_free(ldb, tdb_data.dptr); return ret; } @@ -217,8 +217,11 @@ done: */ static int ltdb_add(struct ldb_context *ldb, const struct ldb_message *msg) { + struct ltdb_private *ltdb = ldb->private_data; int ret; + ltdb->last_err_string = NULL; + if (ltdb_lock(ldb) != 0) { return -1; } @@ -255,7 +258,7 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn) } ret = tdb_delete(ltdb->tdb, tdb_key); - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); return ret; } @@ -265,9 +268,12 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn) */ static int ltdb_delete(struct ldb_context *ldb, const char *dn) { + struct ltdb_private *ltdb = ldb->private_data; int ret; struct ldb_message msg; + ltdb->last_err_string = NULL; + if (ltdb_lock(ldb) != 0) { return -1; } @@ -335,12 +341,13 @@ static int find_element(const struct ldb_message *msg, const char *name) returns 0 on success, -1 on failure (and sets errno) */ -static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *el) +static int msg_add_element(struct ldb_context *ldb, + struct ldb_message *msg, struct ldb_message_element *el) { struct ldb_message_element *e2; int i; - e2 = realloc_p(msg->elements, struct ldb_message_element, + e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, msg->num_elements+1); if (!e2) { errno = ENOMEM; @@ -355,7 +362,7 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element * e2->flags = el->flags; e2->values = NULL; if (el->num_values != 0) { - e2->values = malloc_array_p(struct ldb_val, el->num_values); + e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); if (!e2->values) { free(e2->name); errno = ENOMEM; @@ -375,12 +382,13 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element * /* delete all elements having a specified attribute name */ -static int msg_delete_attribute(struct ldb_message *msg, const char *name) +static int msg_delete_attribute(struct ldb_context *ldb, + struct ldb_message *msg, const char *name) { int i, count=0; struct ldb_message_element *el2; - el2 = malloc_array_p(struct ldb_message_element, msg->num_elements); + el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements); if (!el2) { errno = ENOMEM; return -1; @@ -390,12 +398,12 @@ static int msg_delete_attribute(struct ldb_message *msg, const char *name) if (ldb_attr_cmp(msg->elements[i].name, name) != 0) { el2[count++] = msg->elements[i]; } else { - if (msg->elements[i].values) free(msg->elements[i].values); + ldb_free(ldb, msg->elements[i].values); } } msg->num_elements = count; - if (msg->elements) free(msg->elements); + ldb_free(ldb, msg->elements); msg->elements = el2; return 0; @@ -425,7 +433,7 @@ static int msg_delete_element(struct ldb_context *ldb, if (ldb_val_equal(ldb, msg->elements[i].name, &el->values[i], val)) { if (i<el->num_values-1) { memmove(&el->values[i], &el->values[i+1], - sizeof(el->values[i])*el->num_values-(i+1)); + sizeof(el->values[i])*(el->num_values-(i+1))); } el->num_values--; return 0; @@ -463,7 +471,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) ret = ltdb_unpack_data(ldb, &tdb_data, &msg2); if (ret == -1) { - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); free(tdb_data.dptr); return -1; } @@ -483,7 +491,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) errno = EEXIST; goto failed; } - if (msg_add_element(&msg2, &msg->elements[i]) != 0) { + if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { goto failed; } break; @@ -491,11 +499,11 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) case LDB_FLAG_MOD_REPLACE: /* replace all elements of this attribute name with the elements listed */ - if (msg_delete_attribute(&msg2, msg->elements[i].name) != 0) { + if (msg_delete_attribute(ldb, &msg2, msg->elements[i].name) != 0) { goto failed; } /* add the replacement element */ - if (msg_add_element(&msg2, &msg->elements[i]) != 0) { + if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { goto failed; } break; @@ -504,8 +512,8 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) /* we could be being asked to delete all values or just some values */ if (msg->elements[i].num_values == 0) { - if (msg_delete_attribute(&msg2, - msg->elements[i].name) != 0) { + if (msg_delete_attribute(ldb, &msg2, + msg->elements[i].name) != 0) { goto failed; } break; @@ -525,15 +533,15 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) /* we've made all the mods - save the modified record back into the database */ ret = ltdb_store(ldb, &msg2, TDB_MODIFY); - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(&msg2); + ltdb_unpack_data_free(ldb, &msg2); return ret; failed: - free(tdb_key.dptr); + ldb_free(ldb, tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(&msg2); + ltdb_unpack_data_free(ldb, &msg2); return -1; } @@ -542,8 +550,11 @@ failed: */ static int ltdb_modify(struct ldb_context *ldb, const struct ldb_message *msg) { + struct ltdb_private *ltdb = ldb->private_data; int ret; + ltdb->last_err_string = NULL; + if (ltdb_lock(ldb) != 0) { return -1; } @@ -572,10 +583,13 @@ static int ltdb_close(struct ldb_context *ldb) struct ltdb_private *ltdb = ldb->private_data; int ret; + ltdb->last_err_string = NULL; + ltdb_cache_free(ldb); + ldb_set_alloc(ldb, NULL, NULL); ret = tdb_close(ltdb->tdb); - free(ltdb); + ldb_free(ldb, ltdb); free(ldb); return ret; } @@ -587,6 +601,9 @@ static int ltdb_close(struct ldb_context *ldb) static const char *ltdb_errstring(struct ldb_context *ldb) { struct ltdb_private *ltdb = ldb->private_data; + if (ltdb->last_err_string) { + return ltdb->last_err_string; + } return tdb_errorstr(ltdb->tdb); } @@ -598,7 +615,8 @@ static const struct ldb_backend_ops ltdb_ops = { ltdb_add, ltdb_modify, ltdb_delete, - ltdb_errstring + ltdb_errstring, + ltdb_cache_free }; @@ -615,6 +633,12 @@ struct ldb_context *ltdb_connect(const char *url, TDB_CONTEXT *tdb; struct ldb_context *ldb; + ldb = calloc(1, sizeof(struct ldb_context)); + if (!ldb) { + errno = ENOMEM; + return NULL; + } + /* parse the url */ if (strchr(url, ':')) { if (strncmp(url, "tdb://", 6) != 0) { @@ -637,12 +661,14 @@ struct ldb_context *ltdb_connect(const char *url, /* note that we use quite a large default hash size */ tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666); if (!tdb) { + free(ldb); return NULL; } - ltdb = malloc_p(struct ltdb_private); + ltdb = ldb_malloc_p(ldb, struct ltdb_private); if (!ltdb) { tdb_close(tdb); + free(ldb); errno = ENOMEM; return NULL; } @@ -652,14 +678,6 @@ struct ldb_context *ltdb_connect(const char *url, memset(<db->cache, 0, sizeof(ltdb->cache)); - ldb = malloc_p(struct ldb_context); - if (!ldb) { - tdb_close(tdb); - free(ltdb); - errno = ENOMEM; - return NULL; - } - ldb->private_data = ltdb; ldb->ops = <db_ops; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index e87027db63..c791cbe201 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -19,6 +19,9 @@ struct ltdb_private { int flags; } last_attribute; } cache; + + /* error if an internal ldb+tdb error */ + const char *last_err_string; }; /* special record types */ diff --git a/source4/lib/ldb/tests/test-generic.sh b/source4/lib/ldb/tests/test-generic.sh index 794b451074..6db57967df 100755 --- a/source4/lib/ldb/tests/test-generic.sh +++ b/source4/lib/ldb/tests/test-generic.sh @@ -1,17 +1,17 @@ echo "Adding base elements" -bin/ldbadd tests/test.ldif || exit 1 +$VALGRIND bin/ldbadd tests/test.ldif || exit 1 echo "Modifying elements" -bin/ldbmodify tests/test-modify.ldif || exit 1 +$VALGRIND bin/ldbmodify tests/test-modify.ldif || exit 1 echo "Showing modified record" -bin/ldbsearch '(uid=uham)' || exit 1 +$VALGRIND bin/ldbsearch '(uid=uham)' || exit 1 echo "Starting ldbtest" -time bin/ldbtest -r 1000 -s 100 || exit 1 +time $VALGRIND bin/ldbtest -r 1000 -s 10 || exit 1 echo "Adding index" -bin/ldbadd tests/test-index.ldif || exit 1 +$VALGRIND bin/ldbadd tests/test-index.ldif || exit 1 echo "Starting ldbtest indexed" -time bin/ldbtest -r 1000 -s 5000 || exit 1 +time $VALGRIND bin/ldbtest -r 1000 -s 5000 || exit 1 diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c index 15febb76e7..6d89f67e0f 100644 --- a/source4/lib/ldb/tools/ldbadd.c +++ b/source4/lib/ldb/tools/ldbadd.c @@ -55,7 +55,7 @@ static int process_file(struct ldb_context *ldb, FILE *f) struct ldb_ldif *ldif; int ret, count=0; - while ((ldif = ldif_read_file(f))) { + while ((ldif = ldif_read_file(ldb, f))) { if (ldif->changetype != LDB_CHANGETYPE_ADD && ldif->changetype != LDB_CHANGETYPE_NONE) { fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); @@ -70,7 +70,7 @@ static int process_file(struct ldb_context *ldb, FILE *f) } else { count++; } - ldif_read_free(ldif); + ldif_read_free(ldb, ldif); } return count; diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index eb95ed3267..57c54cad40 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -60,7 +60,7 @@ static int modify_record(struct ldb_context *ldb, continue; } - if (ldb_msg_add(&mod, + if (ldb_msg_add(ldb, &mod, &msg2->elements[i], el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { return -1; @@ -72,7 +72,7 @@ static int modify_record(struct ldb_context *ldb, for (i=0;i<msg1->num_elements;i++) { el = ldb_msg_find_element(msg2, msg1->elements[i].name); if (!el) { - if (ldb_msg_add_empty(&mod, + if (ldb_msg_add_empty(ldb, &mod, msg1->elements[i].name, LDB_FLAG_MOD_DELETE) != 0) { return -1; @@ -159,7 +159,8 @@ static int merge_edits(struct ldb_context *ldb, /* save a set of messages as ldif to a file */ -static int save_ldif(FILE *f, struct ldb_message **msgs, int count) +static int save_ldif(struct ldb_context *ldb, + FILE *f, struct ldb_message **msgs, int count) { int i; @@ -172,7 +173,7 @@ static int save_ldif(FILE *f, struct ldb_message **msgs, int count) ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = *msgs[i]; - ldif_write_file(f, &ldif); + ldif_write_file(ldb, f, &ldif); } return 0; @@ -211,13 +212,13 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun return -1; } - if (save_ldif(f, msgs1, count1) != 0) { + if (save_ldif(ldb, f, msgs1, count1) != 0) { return -1; } fclose(f); - asprintf(&cmd, "%s %s", editor, template); + ldb_asprintf(ldb, &cmd, "%s %s", editor, template); if (!cmd) { unlink(template); @@ -242,8 +243,8 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun return -1; } - while ((ldif = ldif_read_file(f))) { - msgs2 = realloc_p(msgs2, struct ldb_message *, count2+1); + while ((ldif = ldif_read_file(ldb, f))) { + msgs2 = ldb_realloc_p(ldb, msgs2, struct ldb_message *, count2+1); if (!msgs2) { fprintf(stderr, "out of memory"); return -1; diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index bc29369a5c..6ac8e366c7 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -54,7 +54,7 @@ static int process_file(struct ldb_context *ldb, FILE *f) struct ldb_ldif *ldif; int ret = -1, count = 0; - while ((ldif = ldif_read_file(f))) { + while ((ldif = ldif_read_file(ldb, f))) { switch (ldif->changetype) { case LDB_CHANGETYPE_NONE: case LDB_CHANGETYPE_ADD: @@ -74,7 +74,7 @@ static int process_file(struct ldb_context *ldb, FILE *f) } else { count++; } - ldif_read_free(ldif); + ldif_read_free(ldb, ldif); } return count; diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index 541024dd2d..edda31b793 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -45,11 +45,11 @@ static void usage(void) exit(1); } -static void do_search(struct ldb_context *ldb, - const char *basedn, - int scope, - const char *expression, - char * const *attrs) +static int do_search(struct ldb_context *ldb, + const char *basedn, + int scope, + const char *expression, + char * const *attrs) { int ret, i; struct ldb_message **msgs; @@ -57,7 +57,7 @@ static void do_search(struct ldb_context *ldb, ret = ldb_search(ldb, basedn, scope, expression, attrs, &msgs); if (ret == -1) { printf("search failed - %s\n", ldb_errstring(ldb)); - return; + return -1; } printf("# returned %d records\n", ret); @@ -69,7 +69,7 @@ static void do_search(struct ldb_context *ldb, ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = *msgs[i]; - ldif_write_file(stdout, &ldif); + ldif_write_file(ldb, stdout, &ldif); } if (ret > 0) { @@ -79,6 +79,8 @@ static void do_search(struct ldb_context *ldb, exit(1); } } + + return 0; } int main(int argc, char * const argv[]) @@ -89,7 +91,7 @@ static void do_search(struct ldb_context *ldb, const char *basedn = NULL; int opt; enum ldb_scope scope = LDB_SCOPE_SUBTREE; - int interactive = 0; + int interactive = 0, ret=0; ldb_url = getenv("LDB_URL"); @@ -150,12 +152,14 @@ static void do_search(struct ldb_context *ldb, if (interactive) { char line[1024]; while (fgets(line, sizeof(line), stdin)) { - do_search(ldb, basedn, scope, line, attrs); + if (do_search(ldb, basedn, scope, line, attrs) == -1) { + ret = -1; + } } } else { - do_search(ldb, basedn, scope, argv[0], attrs); + ret = do_search(ldb, basedn, scope, argv[0], attrs); } ldb_close(ldb); - return 0; + return ret; } diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index bcb8bdcb16..e7db767387 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -84,7 +84,7 @@ static void add_records(struct ldb_context *ldb, el[2].name = "uid"; el[2].num_values = 1; el[2].values = vals[2]; - vals[2][0].data = ldb_casefold(name); + vals[2][0].data = ldb_casefold(ldb, name); vals[2][0].length = strlen(vals[2][0].data); el[3].flags = 0; @@ -121,7 +121,7 @@ static void add_records(struct ldb_context *ldb, free(name); free(msg.dn); free(vals[1][0].data); - free(vals[2][0].data); + ldb_free(ldb, vals[2][0].data); free(vals[3][0].data); } |