diff options
Diffstat (limited to 'source4/lib/ldb')
28 files changed, 729 insertions, 1140 deletions
diff --git a/source4/lib/ldb/Makefile.ldb b/source4/lib/ldb/Makefile.ldb index 721ba5f407..a472f949af 100644 --- a/source4/lib/ldb/Makefile.ldb +++ b/source4/lib/ldb/Makefile.ldb @@ -10,24 +10,33 @@ LDB_LDAP_OBJ=ldb_ldap/ldb_ldap.o endif TDBDIR=../tdb +TALLOCDIR=../talloc -CFLAGS=-Wall -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -g -Iinclude -I. -I.. -I$(TDBDIR)/include -DUSE_MMAP=1 $(LDAP_FLAGS) -LIB_FLAGS=-Llib -lldb $(LDAP_LIBS) +CFLAGS1=-Wall -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith \ + -Wcast-qual -Wcast-align -Wwrite-strings -g -Iinclude -I. -I.. \ + -I$(TDBDIR)/include -I$(TALLOCDIR) -DUSE_MMAP=1 $(LDAP_FLAGS) +#GCOV_FLAGS = -ftest-coverage -fprofile-arcs +#GCOV_LIBS = -lgcov + +CFLAGS = $(CFLAGS1) $(GCOV_FLAGS) + +LIB_FLAGS=-Llib -lldb $(LDAP_LIBS) $(GCOV_LIBS) TDB_OBJ=$(TDBDIR)/common/tdb.o $(TDBDIR)/common/spinlock.o +TALLOC_OBJ=$(TALLOCDIR)/talloc.o LDB_TDB_OBJ=ldb_tdb/ldb_match.o ldb_tdb/ldb_tdb.o \ ldb_tdb/ldb_pack.o ldb_tdb/ldb_search.o ldb_tdb/ldb_index.o \ ldb_tdb/ldb_cache.o -COMMON_OBJ=common/ldb.o common/ldb_ldif.o common/util.o common/talloc.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_alloc.o common/ldb_debug.o common/ldb_modules.o + common/ldb_debug.o common/ldb_modules.o MODULES_OBJ=modules/timestamps.o -OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(LDB_LDAP_OBJ) +OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LDAP_OBJ) LDB_LIB = lib/libldb.a @@ -72,7 +81,7 @@ manpages: -man/build_manpages.sh clean: - rm -f */*.o *~ */*~ $(BINS) $(LDB_LIB) man/man?/*.[13] + rm -f */*.o *.gcov */*.gc?? *~ */*~ $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LIB) man/man?/*.[13] etags: etags */*.[ch] @@ -86,3 +95,10 @@ test-ldap: tests/test-ldap.sh test: test-tdb test-ldap + +gcov: + gcov -po ldb_ldap ldb_ldap/*.c 2| tee ldb_ldap.report.gcov + gcov -po ldb_tdb ldb_tdb/*.c 2| tee ldb_tdb.report.gcov + gcov -po common common/*.c 2| tee ldb_common.report.gcov + gcov -po modules modules/*.c 2| tee ldb_modules.report.gcov + gcov -po tools tools/*.c 2| tee ldb_tools.report.gcov diff --git a/source4/lib/ldb/common/ldb_alloc.c b/source4/lib/ldb/common/ldb_alloc.c deleted file mode 100644 index 7dc12b142e..0000000000 --- a/source4/lib/ldb/common/ldb_alloc.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - 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" -#include "ldb/include/ldb.h" -#include "ldb/include/ldb_private.h" - - -/* - this allows the user to choose their own allocation function -*/ -int ldb_set_alloc(struct ldb_context *ldb, - void *(*alloc)(const 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(const 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 94e15805a6..d20a2a3553 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -97,7 +97,7 @@ char *ldb_base64_encode(struct ldb_context *ldb, const char *buf, int len) int bytes = (len*8 + 5)/6; char *out; - out = ldb_malloc(ldb, bytes+2); + out = talloc_array_p(ldb, char, bytes+2); if (!out) return NULL; for (i=0;i<bytes;i++) { @@ -185,7 +185,7 @@ static int base64_encode_f(struct ldb_context *ldb, ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos); - ldb_free(ldb, b); + talloc_free(b); return ret; } @@ -212,7 +212,7 @@ int ldb_ldif_write(struct ldb_context *ldb, int total=0, ret; const struct ldb_message *msg; - msg = &ldif->msg; + msg = ldif->msg; ret = fprintf_fn(private_data, "dn: %s\n", msg->dn); CHECK_RET; @@ -305,9 +305,9 @@ static char *next_chunk(struct ldb_context *ldb, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = ldb_realloc_p(ldb, chunk, char, alloc_size); + c2 = talloc_realloc_p(ldb, chunk, char, alloc_size); if (!c2) { - ldb_free(ldb, chunk); + talloc_free(chunk); errno = ENOMEM; return NULL; } @@ -416,15 +416,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) */ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) { - struct ldb_message *msg = &ldif->msg; - unsigned int i; - for (i=0;i<msg->num_elements;i++) { - 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) ldb_free(ldb, msg->elements); - if (msg->private_data) ldb_free(ldb, msg->private_data); - ldb_free(ldb, ldif); + talloc_free(ldif); } /* @@ -435,8 +427,8 @@ static int msg_add_empty(struct ldb_context *ldb, { struct ldb_message_element *el2, *el; - el2 = ldb_realloc_p(ldb, msg->elements, - struct ldb_message_element, msg->num_elements+1); + el2 = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!el2) { errno = ENOMEM; return -1; @@ -446,7 +438,7 @@ static int msg_add_empty(struct ldb_context *ldb, el = &msg->elements[msg->num_elements]; - el->name = ldb_strdup(ldb, name); + el->name = talloc_strdup(msg->elements, name); el->num_values = 0; el->values = NULL; el->flags = flags; @@ -476,11 +468,17 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, value.data = NULL; - ldif = ldb_malloc_p(ldb, struct ldb_ldif); + ldif = talloc_p(ldb, struct ldb_ldif); if (!ldif) return NULL; + ldif->msg = talloc_p(ldif, struct ldb_message); + if (ldif->msg == NULL) { + talloc_free(ldif); + return NULL; + } + ldif->changetype = LDB_CHANGETYPE_NONE; - msg = &ldif->msg; + msg = ldif->msg; msg->dn = NULL; msg->elements = NULL; @@ -558,8 +556,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, flags == el->flags) { /* its a continuation */ el->values = - ldb_realloc_p(ldb, el->values, - struct ldb_val, el->num_values+1); + talloc_realloc_p(msg->elements, el->values, + struct ldb_val, el->num_values+1); if (!el->values) { goto failed; } @@ -567,16 +565,16 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, el->num_values++; } else { /* its a new attribute */ - msg->elements = ldb_realloc_p(ldb, msg->elements, - struct ldb_message_element, - msg->num_elements+1); + msg->elements = talloc_realloc_p(ldif, 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 = ldb_strdup(ldb, attr); - el->values = ldb_malloc_p(ldb, struct ldb_val); + el->name = talloc_strdup(msg->elements, attr); + el->values = talloc_p(msg->elements, struct ldb_val); if (!el->values || !el->name) { goto failed; } @@ -589,7 +587,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, return ldif; failed: - if (ldif) ldb_ldif_read_free(ldb, ldif); + talloc_free(ldif); return NULL; } diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 71ec3fdc00..4f53535bc4 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -57,21 +57,19 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) pn = 0; if (options) { - for (i = 0; options[i] != NULL; i++) { - - if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) { - - p = q = ldb_strdup(ldb, &options[i][LDB_MODULE_PREFIX_LEN]); + if (strncmp(options[i], LDB_MODULE_PREFIX, + LDB_MODULE_PREFIX_LEN) == 0) { + p = q = talloc_strdup(ldb, &options[i][LDB_MODULE_PREFIX_LEN]); if (*q != ':') { - ldb_free(ldb, q); + talloc_free(q); return -1; } do { *p = '\0'; q = p + 1; pn++; - modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn); + modules = talloc_realloc_p(ldb, modules, char *, pn); if (!modules) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n"); return -1; @@ -82,10 +80,12 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) } } - if (!modules && strcmp("ldap", ldb->modules->ops->name)) { /* no modules in the options, look for @MODULES in the db (not for ldap) */ + if (!modules && strcmp("ldap", ldb->modules->ops->name)) { + /* no modules in the options, look for @MODULES in the + db (not for ldap) */ int ret, j, k; const char * const attrs[] = { "@MODULE" , NULL}; - struct ldb_message **msg; + struct ldb_message **msg = NULL; ret = ldb_search(ldb, "", LDB_SCOPE_BASE, "dn=@MODULES", attrs, &msg); if (ret == 0) { @@ -103,12 +103,12 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) for (j = 0; j < msg[0]->num_elements; j++) { for (k = 0; k < msg[0]->elements[j].num_values; k++) { pn++; - modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn); + modules = talloc_realloc_p(ldb, modules, char *, pn); if (!modules) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n"); return -1; } - modules[pn - 1] = ldb_strndup(ldb, msg[0]->elements[j].values[k].data, msg[0]->elements[j].values[k].length); + modules[pn - 1] = talloc_strndup(modules, msg[0]->elements[j].values[k].data, msg[0]->elements[j].values[k].length); if (!modules[pn - 1]) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n"); return -1; @@ -116,13 +116,11 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) } } } - ldb_search_free(ldb, msg); + talloc_free(msg); } if (modules) { - for (i = 0; i < pn; i++) { - if (strcmp(modules[i], "timestamps") == 0) { current = timestamps_module_init(ldb, options); if (!current) { @@ -274,10 +272,3 @@ const char *ldb_next_errstring(struct ldb_module *module) return module->next->ops->errstring(module->next); } -void ldb_next_cache_free(struct ldb_module *module) -{ - if (!module->next) { - return; - } - module->next->ops->cache_free(module->next); -} diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 3865e7afa9..89f8feb3c0 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -36,6 +36,13 @@ #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" +/* + create a new ldb_message in a given memory context (NULL for top level) +*/ +struct ldb_message *ldb_msg_new(void *mem_ctx) +{ + return talloc_zero_p(mem_ctx, struct ldb_message); +} /* find an element in a message by attribute name @@ -88,7 +95,7 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, /* duplicate a ldb_val structure */ -struct ldb_val ldb_val_dup(struct ldb_context *ldb, +struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) { struct ldb_val v2; @@ -100,7 +107,7 @@ struct ldb_val ldb_val_dup(struct ldb_context *ldb, /* the +1 is to cope with buggy C library routines like strndup that look one byte beyond */ - v2.data = ldb_malloc(ldb, v->length+1); + v2.data = talloc_array_p(mem_ctx, char, v->length+1); if (!v2.data) { v2.length = 0; return v2; @@ -119,8 +126,8 @@ int ldb_msg_add_empty(struct ldb_context *ldb, { struct ldb_message_element *els; - els = ldb_realloc_p(ldb, msg->elements, - struct ldb_message_element, msg->num_elements+1); + els = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!els) { errno = ENOMEM; return -1; @@ -129,7 +136,7 @@ int ldb_msg_add_empty(struct ldb_context *ldb, els[msg->num_elements].values = NULL; els[msg->num_elements].num_values = 0; els[msg->num_elements].flags = flags; - els[msg->num_elements].name = ldb_strdup(ldb, attr_name); + els[msg->num_elements].name = talloc_strdup(els, attr_name); if (!els[msg->num_elements].name) { return -1; } @@ -178,7 +185,7 @@ int ldb_msg_add_value(struct ldb_context *ldb, return -1; } - vals = ldb_realloc_p(ldb, el->values, struct ldb_val, el->num_values+1); + vals = talloc_realloc_p(msg, el->values, struct ldb_val, el->num_values+1); if (!vals) { errno = ENOMEM; return -1; @@ -332,19 +339,7 @@ void ldb_msg_sort_elements(struct ldb_message *msg) */ void ldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg) { - int i, j; - - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - for (j=0;j<el->num_values;j++) { - ldb_free(ldb, el->values[j].data); - } - if (el->values) ldb_free(ldb, el->values); - ldb_free(ldb, el->name); - } - if (msg->elements) ldb_free(ldb, msg->elements); - ldb_free(ldb, msg->dn); - ldb_free(ldb, msg); + talloc_free(msg); } /* @@ -356,17 +351,17 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb, struct ldb_message *msg2; int i, j; - msg2 = ldb_malloc_p(ldb, struct ldb_message); + msg2 = talloc_p(ldb, struct ldb_message); if (msg2 == NULL) return NULL; msg2->elements = NULL; msg2->num_elements = 0; msg2->private_data = NULL; - msg2->dn = ldb_strdup(ldb, msg->dn); + msg2->dn = talloc_strdup(msg2, msg->dn); if (msg2->dn == NULL) goto failed; - msg2->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements); + msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg->num_elements); if (msg2->elements == NULL) goto failed; for (i=0;i<msg->num_elements;i++) { @@ -376,15 +371,16 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb, el2->flags = el1->flags; el2->num_values = 0; el2->values = NULL; - el2->name = ldb_strdup(ldb, el1->name); + el2->name = talloc_strdup(msg2->elements, el1->name); if (el2->name == NULL) goto failed; - el2->values = ldb_malloc_array_p(ldb, struct ldb_val, el1->num_values); + el2->values = talloc_array_p(msg2->elements, struct ldb_val, el1->num_values); for (j=0;j<el1->num_values;j++) { el2->values[j] = ldb_val_dup(ldb, &el1->values[j]); if (el2->values[j].data == NULL && el1->values[j].length != 0) { goto failed; } + el2->values[j].data = talloc_steal(el2->values, el2->values[j].data); el2->num_values++; } @@ -394,7 +390,7 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb, return msg2; failed: - ldb_msg_free(ldb, msg2); + talloc_free(msg2); return NULL; } @@ -417,8 +413,8 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, struct ldb_message_element *el1 = &msg2->elements[i-1]; struct ldb_message_element *el2 = &msg2->elements[i]; if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = ldb_realloc_p(ldb, el1->values, struct ldb_val, - el1->num_values + el2->num_values); + el1->values = talloc_realloc_p(msg2->elements, el1->values, struct ldb_val, + el1->num_values + el2->num_values); if (el1->values == NULL) { return NULL; } @@ -426,8 +422,8 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, el2->values, sizeof(struct ldb_val) * el2->num_values); el1->num_values += el2->num_values; - ldb_free(ldb, el2->name); - ldb_free(ldb, el2->values); + talloc_free(el2->name); + talloc_free(el2->values); if (i+1<msg2->num_elements) { memmove(el2, el2+1, sizeof(struct ldb_message_element) * (msg2->num_elements - (i+1))); diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index 1e00a05d55..6ee6f99253 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -65,7 +65,7 @@ a filter is defined by: /* return next token element. Caller frees */ -static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char *sep) +static char *ldb_parse_lex(TALLOC_CTX *ctx, const char **s, const char *sep) { const char *p = *s; char *ret; @@ -81,7 +81,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char * if (strchr(sep, *p)) { (*s) = p+1; - ret = ldb_strndup(ldb, p, 1); + ret = talloc_strndup(ctx, p, 1); if (!ret) { errno = ENOMEM; } @@ -96,7 +96,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char * return NULL; } - ret = ldb_strndup(ldb, *s, p - *s); + ret = talloc_strndup(ctx, *s, p - *s); if (!ret) { errno = ENOMEM; } @@ -128,47 +128,46 @@ static const char *match_brace(const char *s) } -static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s); +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s); /* <simple> ::= <attributetype> <filtertype> <attributevalue> */ -static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const char *s) +static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *ctx, const char *s) { char *eq, *val, *l; struct ldb_parse_tree *ret; - l = ldb_parse_lex(ldb, &s, LDB_ALL_SEP); + ret = talloc_p(ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + l = ldb_parse_lex(ret, &s, LDB_ALL_SEP); if (!l) { + talloc_free(ret); return NULL; } if (strchr("()&|=", *l)) { - ldb_free(ldb, l); + talloc_free(ret); return NULL; } - eq = ldb_parse_lex(ldb, &s, LDB_ALL_SEP); + eq = ldb_parse_lex(ret, &s, LDB_ALL_SEP); if (!eq || strcmp(eq, "=") != 0) { - ldb_free(ldb, l); - if (eq) ldb_free(ldb, eq); + talloc_free(ret); return NULL; } - ldb_free(ldb, eq); + talloc_free(eq); - val = ldb_parse_lex(ldb, &s, ")"); + val = ldb_parse_lex(ret, &s, ")"); if (val && strchr("()&|", *val)) { - ldb_free(ldb, l); - if (val) ldb_free(ldb, val); + talloc_free(ret); return NULL; } - ret = ldb_malloc_p(ldb, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - ret->operation = LDB_OP_SIMPLE; ret->u.simple.attr = l; ret->u.simple.value.data = val; @@ -184,12 +183,12 @@ static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const ch <or> ::= '|' <filterlist> <filterlist> ::= <filter> | <filter> <filterlist> */ -static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb, +static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *ctx, enum ldb_parse_op op, const char *s) { struct ldb_parse_tree *ret, *next; - ret = ldb_malloc_p(ldb, struct ldb_parse_tree); + ret = talloc_p(ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -197,31 +196,29 @@ static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb, ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = ldb_malloc_p(ldb, struct ldb_parse_tree *); + ret->u.list.elements = talloc_p(ret, struct ldb_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; - ldb_free(ldb, ret); + talloc_free(ret); return NULL; } - ret->u.list.elements[0] = ldb_parse_filter(ldb, &s); + ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &s); if (!ret->u.list.elements[0]) { - ldb_free(ldb, ret->u.list.elements); - ldb_free(ldb, ret); + talloc_free(ret); return NULL; } while (isspace(*s)) s++; - while (*s && (next = ldb_parse_filter(ldb, &s))) { + while (*s && (next = ldb_parse_filter(ret->u.list.elements, &s))) { struct ldb_parse_tree **e; - e = ldb_realloc_p(ldb, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); + e = talloc_realloc_p(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); if (!e) { errno = ENOMEM; - ldb_parse_tree_free(ldb, next); - ldb_parse_tree_free(ldb, ret); + talloc_free(ret); return NULL; } ret->u.list.elements = e; @@ -237,20 +234,20 @@ static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb, /* <not> ::= '!' <filter> */ -static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char *s) +static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *ctx, const char *s) { struct ldb_parse_tree *ret; - ret = ldb_malloc_p(ldb, struct ldb_parse_tree); + ret = talloc_p(ctx, struct ldb_parse_tree); if (!ret) { errno = ENOMEM; return NULL; } ret->operation = LDB_OP_NOT; - ret->u.not.child = ldb_parse_filter(ldb, &s); + ret->u.not.child = ldb_parse_filter(ret, &s); if (!ret->u.not.child) { - ldb_free(ldb, ret); + talloc_free(ret); return NULL; } @@ -261,49 +258,48 @@ static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char parse a filtercomp <filtercomp> ::= <and> | <or> | <not> | <simple> */ -static struct ldb_parse_tree *ldb_parse_filtercomp(struct ldb_context *ldb, - const char *s) +static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *ctx, const char *s) { while (isspace(*s)) s++; switch (*s) { case '&': - return ldb_parse_filterlist(ldb, LDB_OP_AND, s+1); + return ldb_parse_filterlist(ctx, LDB_OP_AND, s+1); case '|': - return ldb_parse_filterlist(ldb, LDB_OP_OR, s+1); + return ldb_parse_filterlist(ctx, LDB_OP_OR, s+1); case '!': - return ldb_parse_not(ldb, s+1); + return ldb_parse_not(ctx, s+1); case '(': case ')': return NULL; } - return ldb_parse_simple(ldb, s); + return ldb_parse_simple(ctx, s); } /* <filter> ::= '(' <filtercomp> ')' */ -static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s) +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s) { char *l, *s2; const char *p, *p2; struct ldb_parse_tree *ret; - l = ldb_parse_lex(ldb, s, LDB_ALL_SEP); + l = ldb_parse_lex(ctx, s, LDB_ALL_SEP); if (!l) { return NULL; } if (strcmp(l, "(") != 0) { - ldb_free(ldb, l); + talloc_free(l); return NULL; } - ldb_free(ldb, l); + talloc_free(l); p = match_brace(*s); if (!p) { @@ -311,14 +307,14 @@ static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const ch } p2 = p + 1; - s2 = ldb_strndup(ldb, *s, p - *s); + s2 = talloc_strndup(ctx, *s, p - *s); if (!s2) { errno = ENOMEM; return NULL; } - ret = ldb_parse_filtercomp(ldb, s2); - ldb_free(ldb, s2); + ret = ldb_parse_filtercomp(ctx, s2); + talloc_free(s2); *s = p2; @@ -347,27 +343,6 @@ struct ldb_parse_tree *ldb_parse_tree(struct ldb_context *ldb, const char *s) */ void ldb_parse_tree_free(struct ldb_context *ldb, struct ldb_parse_tree *tree) { - unsigned int i; - - switch (tree->operation) { - case LDB_OP_SIMPLE: - 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(ldb, tree->u.list.elements[i]); - } - if (tree->u.list.elements) ldb_free(ldb, tree->u.list.elements); - break; - - case LDB_OP_NOT: - ldb_parse_tree_free(ldb, tree->u.not.child); - break; - } - - ldb_free(ldb, tree); + talloc_free(tree); } diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c index 01bd8eb9ac..577766d9f7 100644 --- a/source4/lib/ldb/common/ldb_utf8.c +++ b/source4/lib/ldb/common/ldb_utf8.c @@ -44,7 +44,7 @@ char *ldb_casefold(struct ldb_context *ldb, const char *s) { int i; - char *ret = ldb_strdup(ldb, s); + char *ret = talloc_strdup(ldb, s); if (!s) { errno = ENOMEM; return NULL; diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk index a026ae1229..8a7a34f05b 100644 --- a/source4/lib/ldb/config.mk +++ b/source4/lib/ldb/config.mk @@ -48,11 +48,10 @@ ADD_OBJ_FILES = \ 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/common/ldb_debug.o \ lib/ldb/common/ldb_modules.o REQUIRED_SUBSYSTEMS = \ - LIBREPLACE + LIBREPLACE LIBTALLOC NOPROTO = YES # # End SUBSYSTEM LIBLDB diff --git a/source4/lib/ldb/include/includes.h b/source4/lib/ldb/include/includes.h index 4926e1524a..66b984a87d 100644 --- a/source4/lib/ldb/include/includes.h +++ b/source4/lib/ldb/include/includes.h @@ -18,15 +18,15 @@ #include <fnmatch.h> #include <sys/time.h> #include <time.h> +#include <stdint.h> #include "ldb.h" #include "ldb_private.h" +#include "talloc.h" -#ifdef HAVE_INTPTR_T +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) #define discard_const(ptr) ((void *)((intptr_t)(ptr))) #else #define discard_const(ptr) ((void *)(ptr)) #endif #define discard_const_p(type, ptr) ((type *)discard_const(ptr)) - - diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 9dff510417..7aa2b6f4cd 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -105,7 +105,7 @@ enum ldb_changetype { */ struct ldb_ldif { enum ldb_changetype changetype; - struct ldb_message msg; + struct ldb_message *msg; }; enum ldb_scope {LDB_SCOPE_DEFAULT=-1, @@ -123,16 +123,6 @@ typedef int (*ldb_traverse_fn)(struct ldb_context *, const struct ldb_message *) struct ldb_module; -/* - 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)(const void *context, void *ptr, size_t size); - void *context; -}; - /* debugging uses one of the following levels */ enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; @@ -240,6 +230,9 @@ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif int ldb_dn_cmp(const char *dn1, const char *dn2); int ldb_attr_cmp(const char *dn1, const char *dn2); +/* create an empty message */ +struct ldb_message *ldb_msg_new(void *mem_ctx); + /* find an element within an message */ struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, const char *attr_name); @@ -305,40 +298,11 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg); -struct ldb_val ldb_val_dup(struct ldb_context *ldb, - const struct ldb_val *v); - -/* - 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)(const 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) - -void *ldb_realloc(struct ldb_context *ldb, void *ptr, size_t size); -void *ldb_malloc(struct ldb_context *ldb, size_t size); -void ldb_free(struct ldb_context *ldb, void *ptr); -void *ldb_strndup(struct ldb_context *ldb, const char *str, size_t maxlen); -void *ldb_strdup(struct ldb_context *ldb, const char *str); -void *ldb_realloc_array(struct ldb_context *ldb, - void *ptr, size_t el_size, unsigned count); +struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v); #ifndef PRINTF_ATTRIBUTE #define PRINTF_ATTRIBUTE(a,b) #endif -int ldb_asprintf(struct ldb_context *ldb, char **strp, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); /* this allows the user to set a debug function for error reporting diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index a2171162ad..3d3b1ec0eb 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -66,10 +66,6 @@ struct ldb_module_ops { int (*named_lock)(struct ldb_module *, const char *); int (*named_unlock)(struct ldb_module *, const char *); const char * (*errstring)(struct ldb_module *); - - /* 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_module *); }; /* the modules init function */ @@ -82,10 +78,7 @@ struct ldb_context { /* the operations provided by the backend */ struct ldb_module *modules; - /* memory allocation info */ - struct ldb_alloc_ops alloc_ops; - - /* memory allocation info */ + /* debugging operations */ struct ldb_debug_ops debug_ops; }; @@ -106,7 +99,6 @@ int ldb_next_rename_record(struct ldb_module *module, const char *olddn, const c int ldb_next_named_lock(struct ldb_module *module, const char *lockname); int ldb_next_named_unlock(struct ldb_module *module, const char *lockname); const char *ldb_next_errstring(struct ldb_module *module); -void ldb_next_cache_free(struct ldb_module *module); /* The following definitions come from lib/ldb/common/util.c */ int ldb_list_find(const void *needle, diff --git a/source4/lib/ldb/include/talloc.h b/source4/lib/ldb/include/talloc.h deleted file mode 100644 index ffb4c9f252..0000000000 --- a/source4/lib/ldb/include/talloc.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _TALLOC_H_ -#define _TALLOC_H_ -/* - Unix SMB/CIFS implementation. - Samba temporary memory allocation functions - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* this is only needed for compatibility with the old talloc */ -typedef void TALLOC_CTX; - -/* - this uses a little trick to allow __LINE__ to be stringified -*/ -#define _STRING_LINE_(s) #s -#define _STRING_LINE2_(s) _STRING_LINE_(s) -#define __LINESTR__ _STRING_LINE2_(__LINE__) -#define __location__ __FILE__ ":" __LINESTR__ - -/* useful macros for creating type checked pointers */ -#define talloc(ctx, size) talloc_named_const(ctx, size, __location__) -#define talloc_zero(ctx, size) _talloc_zero(ctx, size, __location__) -#define talloc_realloc(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) -#define talloc_p(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) -#define talloc_zero_p(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) -#define talloc_zero_array_p(ctx, type, count) (type *)talloc_zero_array(ctx, sizeof(type), count, __location__) -#define talloc_array_p(ctx, type, count) (type *)talloc_array(ctx, sizeof(type), count, __location__) -#define talloc_realloc_p(ctx, p, type, count) (type *)talloc_realloc_array(ctx, p, sizeof(type), count, __location__) -#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) - -#define talloc_destroy(ctx) talloc_free(ctx) - -#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) - -#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: "__location__) -#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: "__location__) - -#ifndef PRINTF_ATTRIBUTE -#define PRINTF_ATTRIBUTE(a1, a2) -#endif - - -/* The following definitions come from lib/talloc.c */ -void *_talloc(const void *context, size_t size); -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); -void talloc_increase_ref_count(const void *ptr); -void *talloc_reference(const void *context, const void *ptr); -int talloc_unlink(const void *context, void *ptr); -void talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -void talloc_set_name_const(const void *ptr, const char *name); -void *talloc_named(const void *context, size_t size, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); -void *talloc_named_const(const void *context, size_t size, const char *name); -const char *talloc_get_name(const void *ptr); -void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); -int talloc_free(void *ptr); -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); -void *talloc_steal(const void *new_ctx, const void *ptr); -off_t talloc_total_size(const void *ptr); -off_t talloc_total_blocks(const void *ptr); -void talloc_report_full(const void *ptr, FILE *f); -void talloc_report(const void *ptr, FILE *f); -void talloc_enable_leak_report(void); -void talloc_enable_leak_report_full(void); -void *_talloc_zero(const void *ctx, size_t size, const char *name); -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -char *talloc_strdup(const void *t, const char *p); -char *talloc_strndup(const void *t, const char *p, size_t n); -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append(char *s, - const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); -void *talloc_ldb_alloc(void *context, void *ptr, size_t size); - -#endif - diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index b9c3865acc..fee02da32f 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -72,26 +72,9 @@ static const char *lldb_option_find(const struct lldb_private *lldb, const char */ static int lldb_close(struct ldb_module *module) { - int i, ret = 0; struct ldb_context *ldb = module->ldb; - struct lldb_private *lldb = module->private_data; - - if (ldap_unbind(lldb->ldap) != LDAP_SUCCESS) { - ret = -1; - } - - ldb_set_alloc(ldb, NULL, NULL); - - if (lldb->options) { - for (i=0;lldb->options[i];i++) { - ldb_free(ldb, lldb->options[i]); - } - ldb_free(ldb, lldb->options); - } - ldb_free(ldb, lldb); - free(ldb); - - return ret; + talloc_free(ldb); + return 0; } /* @@ -99,18 +82,18 @@ static int lldb_close(struct ldb_module *module) */ static int lldb_rename(struct ldb_module *module, const char *olddn, const char *newdn) { - struct ldb_context *ldb = module->ldb; struct lldb_private *lldb = module->private_data; int ret = 0; char *newrdn, *p; const char *parentdn = ""; + TALLOC_CTX *mem_ctx = talloc(lldb, 0); /* ignore ltdb specials */ if (olddn[0] == '@' ||newdn[0] == '@') { return 0; } - newrdn = ldb_strdup(ldb, newdn); + newrdn = talloc_strdup(mem_ctx, newdn); if (!newrdn) { return -1; } @@ -122,11 +105,12 @@ static int lldb_rename(struct ldb_module *module, const char *olddn, const char } lldb->last_rc = ldap_rename_s(lldb->ldap, olddn, newrdn, parentdn, 1, NULL, NULL); - ldb_free(ldb, newrdn); if (lldb->last_rc != LDAP_SUCCESS) { ret = -1; } + talloc_free(mem_ctx); + return ret; } @@ -152,39 +136,11 @@ static int lldb_delete(struct ldb_module *module, const char *dn) } /* - free a search message -*/ -static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg) -{ - unsigned int i, j; - ldb_free(ldb, msg->dn); - for (i=0;i<msg->num_elements;i++) { - ldb_free(ldb, msg->elements[i].name); - for (j=0;j<msg->elements[i].num_values;j++) { - if (msg->elements[i].values[j].data) { - ldb_free(ldb, msg->elements[i].values[j].data); - } - } - ldb_free(ldb, msg->elements[i].values); - } - if (msg->elements) ldb_free(ldb, msg->elements); - ldb_free(ldb, msg); - return 0; -} - -/* free a search result */ static int lldb_search_free(struct ldb_module *module, struct ldb_message **res) { - struct ldb_context *ldb = module->ldb; - int i; - for (i=0;res[i];i++) { - if (lldb_msg_free(ldb, res[i]) != 0) { - return -1; - } - } - ldb_free(ldb, res); + talloc_free(res); return 0; } @@ -205,8 +161,8 @@ static int lldb_add_msg_attr(struct ldb_context *ldb, return -1; } - el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, - msg->num_elements + 1); + el = talloc_realloc_p(msg, msg->elements, struct ldb_message_element, + msg->num_elements + 1); if (!el) { errno = ENOMEM; return -1; @@ -216,7 +172,7 @@ static int lldb_add_msg_attr(struct ldb_context *ldb, el = &msg->elements[msg->num_elements]; - el->name = ldb_strdup(ldb, attr); + el->name = talloc_strdup(msg->elements, attr); if (!el->name) { errno = ENOMEM; return -1; @@ -224,18 +180,17 @@ static int lldb_add_msg_attr(struct ldb_context *ldb, el->flags = 0; el->num_values = 0; - el->values = ldb_malloc_array_p(ldb, struct ldb_val, count); + el->values = talloc_array_p(msg->elements, struct ldb_val, count); if (!el->values) { errno = ENOMEM; return -1; } for (i=0;i<count;i++) { - el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len); + el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len); if (!el->values[i].data) { return -1; } - memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); el->values[i].length = bval[i]->bv_len; el->num_values++; } @@ -275,7 +230,7 @@ static int lldb_search(struct ldb_module *module, const char *base, return count; } - (*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1); + (*res) = talloc_array_p(lldb, struct ldb_message *, count+1); if (! *res) { ldap_msgfree(ldapres); errno = ENOMEM; @@ -299,7 +254,7 @@ static int lldb_search(struct ldb_module *module, const char *base, break; } - (*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message); + (*res)[msg_count] = talloc_p(*res, struct ldb_message); if (!(*res)[msg_count]) { goto failed; } @@ -310,7 +265,7 @@ static int lldb_search(struct ldb_module *module, const char *base, goto failed; } - (*res)[msg_count]->dn = ldb_strdup(ldb, dn); + (*res)[msg_count]->dn = talloc_strdup((*res)[msg_count], dn); ldap_memfree(dn); if (!(*res)[msg_count]->dn) { goto failed; @@ -351,28 +306,6 @@ failed: /* - free a set of mods from lldb_msg_to_mods() -*/ -static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods) -{ - int i, j; - - if (!mods) return; - - for (i=0;mods[i];i++) { - if (mods[i]->mod_vals.modv_bvals) { - for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) { - ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]); - } - ldb_free(ldb, mods[i]->mod_vals.modv_bvals); - } - ldb_free(ldb, mods[i]); - } - ldb_free(ldb, mods); -} - - -/* convert a ldb_message structure to a list of LDAPMod structures ready for ldap_add() or ldap_modify() */ @@ -384,7 +317,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb, int num_mods = 0; /* allocate maximum number of elements needed */ - mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1); + mods = talloc_array_p(ldb, LDAPMod *, msg->num_elements+1); if (!mods) { errno = ENOMEM; return NULL; @@ -394,7 +327,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb, for (i=0;i<msg->num_elements;i++) { const struct ldb_message_element *el = &msg->elements[i]; - mods[num_mods] = ldb_malloc_p(ldb, LDAPMod); + mods[num_mods] = talloc_p(ldb, LDAPMod); if (!mods[num_mods]) { goto failed; } @@ -414,15 +347,16 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb, } } mods[num_mods]->mod_type = el->name; - mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb, - struct berval *, - 1+el->num_values); + mods[num_mods]->mod_vals.modv_bvals = talloc_array_p(mods[num_mods], + 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] = ldb_malloc_p(ldb, struct berval); + mods[num_mods]->mod_vals.modv_bvals[j] = talloc_p(mods[num_mods]->mod_vals.modv_bvals, + struct berval); if (!mods[num_mods]->mod_vals.modv_bvals[j]) { goto failed; } @@ -436,7 +370,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb, return mods; failed: - lldb_mods_free(ldb, mods); + talloc_free(mods); return NULL; } @@ -463,7 +397,7 @@ static int lldb_add(struct ldb_module *module, const struct ldb_message *msg) ret = -1; } - lldb_mods_free(ldb, mods); + talloc_free(mods); return ret; } @@ -491,7 +425,7 @@ static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg) ret = -1; } - lldb_mods_free(ldb, mods); + talloc_free(mods); return ret; } @@ -547,6 +481,13 @@ static const struct ldb_module_ops lldb_ops = { }; +static int lldb_destructor(void *p) +{ + struct lldb_private *lldb = p; + ldap_unbind(lldb->ldap); + return 0; +} + /* connect to the database */ @@ -558,15 +499,14 @@ struct ldb_context *lldb_connect(const char *url, struct lldb_private *lldb = NULL; int i, version = 3; - ldb = calloc(1, sizeof(struct ldb_context)); + ldb = talloc_p(NULL, struct ldb_context); if (!ldb) { errno = ENOMEM; goto failed; } - lldb = ldb_malloc_p(ldb, struct lldb_private); + lldb = talloc_p(ldb, struct lldb_private); if (!lldb) { - ldb_free(ldb, ldb); errno = ENOMEM; goto failed; } @@ -579,14 +519,15 @@ struct ldb_context *lldb_connect(const char *url, goto failed; } + talloc_set_destructor(lldb, lldb_destructor); + lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); if (lldb->last_rc != LDAP_SUCCESS) { goto failed; } - ldb->modules = ldb_malloc_p(ldb, struct ldb_module); + ldb->modules = talloc_p(ldb, struct ldb_module); if (!ldb->modules) { - ldb_free(ldb, ldb); errno = ENOMEM; goto failed; } @@ -600,14 +541,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 = ldb_malloc_array_p(ldb, char *, i+1); + lldb->options = talloc_array_p(lldb, char *, i+1); if (!lldb->options) { goto failed; } for (i=0;options[i];i++) { lldb->options[i+1] = NULL; - lldb->options[i] = ldb_strdup(ldb, options[i]); + lldb->options[i] = talloc_strdup(lldb->options, options[i]); if (!lldb->options[i]) { goto failed; } @@ -617,17 +558,7 @@ struct ldb_context *lldb_connect(const char *url, return ldb; failed: - if (lldb && lldb->options) { - for (i=0;lldb->options[i];i++) { - ldb_free(ldb, lldb->options[i]); - } - ldb_free(ldb, lldb->options); - } - if (lldb && lldb->ldap) { - ldap_unbind(lldb->ldap); - } - ldb_free(ldb, lldb); - if (ldb) free(ldb); + talloc_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 a8eb9ae916..e7420c5f7a 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -42,9 +42,8 @@ */ static int ltdb_baseinfo_init(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_message msg; + struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; int ret; @@ -55,60 +54,61 @@ static int ltdb_baseinfo_init(struct ldb_module *module) ltdb->sequence_number = atof(initial_sequence_number); - msg.num_elements = 1; - msg.elements = ⪙ - msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); - if (!msg.dn) { - errno = ENOMEM; - return -1; + msg = talloc_p(ltdb, struct ldb_message); + if (msg == NULL) { + goto failed; } - el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + if (!msg->dn) { + goto failed; + } + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); if (!el.name) { - ldb_free(ldb, msg.dn); - errno = ENOMEM; - return -1; + goto failed; } el.values = &val; el.num_values = 1; el.flags = 0; - val.data = ldb_strdup(ldb, initial_sequence_number); + val.data = talloc_strdup(msg, initial_sequence_number); if (!val.data) { - ldb_free(ldb, el.name); - ldb_free(ldb, msg.dn); - errno = ENOMEM; - return -1; + goto failed; } val.length = 1; - ret = ltdb_store(module, &msg, TDB_INSERT); + ret = ltdb_store(module, msg, TDB_INSERT); - ldb_free(ldb, msg.dn); - ldb_free(ldb, el.name); - ldb_free(ldb, val.data); + talloc_free(msg); return ret; + +failed: + talloc_free(msg); + errno = ENOMEM; + return -1; } /* free any cache records */ -void ltdb_cache_free(struct ldb_module *module) +static void ltdb_cache_free(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - ldb->alloc_ops.alloc = NULL; ltdb->sequence_number = 0; - ltdb_search_dn1_free(module, <db->cache.baseinfo); - ltdb_search_dn1_free(module, <db->cache.indexlist); - ltdb_search_dn1_free(module, <db->cache.subclasses); - ltdb_search_dn1_free(module, <db->cache.attributes); - - ldb_free(ldb, ltdb->cache.last_attribute.name); - memset(<db->cache, 0, sizeof(ltdb->cache)); + talloc_free(ltdb->cache); + ltdb->cache = NULL; +} - ldb->alloc_ops = alloc; +/* + force a cache reload +*/ +int ltdb_cache_reload(struct ldb_module *module) +{ + ltdb_cache_free(module); + return ltdb_cache_load(module); } /* @@ -116,60 +116,78 @@ void ltdb_cache_free(struct ldb_module *module) */ int ltdb_cache_load(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; double seq; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - ldb->alloc_ops.alloc = NULL; + if (ltdb->cache == NULL) { + ltdb->cache = talloc_zero_p(ltdb, struct ltdb_cache); + if (ltdb->cache == NULL) goto failed; + ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + } - ltdb_search_dn1_free(module, <db->cache.baseinfo); + talloc_free(ltdb->cache->baseinfo); + ltdb->cache->baseinfo = talloc_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->baseinfo == NULL) goto failed; - if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) == -1) { + if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) { goto failed; } /* possibly initialise the baseinfo */ - if (!ltdb->cache.baseinfo.dn) { + if (!ltdb->cache->baseinfo->dn) { if (ltdb_baseinfo_init(module) != 0) { goto failed; } - if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) != 1) { + if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) { goto failed; } } /* if the current internal sequence number is the same as the one in the database then assume the rest of the cache is OK */ - seq = ldb_msg_find_double(<db->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0); + seq = ldb_msg_find_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); if (seq == ltdb->sequence_number) { goto done; } ltdb->sequence_number = seq; - ldb_free(ldb, ltdb->cache.last_attribute.name); - memset(<db->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute)); + talloc_free(ltdb->cache->last_attribute.name); + memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); - ltdb_search_dn1_free(module, <db->cache.indexlist); - ltdb_search_dn1_free(module, <db->cache.subclasses); - ltdb_search_dn1_free(module, <db->cache.attributes); + talloc_free(ltdb->cache->indexlist); + talloc_free(ltdb->cache->subclasses); + talloc_free(ltdb->cache->attributes); - if (ltdb_search_dn1(module, LTDB_INDEXLIST, <db->cache.indexlist) == -1) { + ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { goto failed; } - if (ltdb_search_dn1(module, LTDB_SUBCLASSES, <db->cache.subclasses) == -1) { + + if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) { goto failed; } - if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, <db->cache.attributes) == -1) { + if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) { + goto failed; + } + if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) { goto failed; } done: - ldb->alloc_ops = alloc; return 0; failed: - ldb->alloc_ops = alloc; return -1; } @@ -181,33 +199,37 @@ int ltdb_increase_sequence_number(struct ldb_module *module) { struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_message msg; + struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; char *s = NULL; int ret; - ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1); + s = talloc_asprintf(ldb, "%.0f", ltdb->sequence_number+1); if (!s) { errno = ENOMEM; return -1; } - msg.num_elements = 1; - msg.elements = ⪙ - msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); - el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); + msg = talloc_p(ltdb, struct ldb_message); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); el.values = &val; el.num_values = 1; el.flags = LDB_FLAG_MOD_REPLACE; val.data = s; val.length = strlen(s); - ret = ltdb_modify_internal(module, &msg); + ret = ltdb_modify_internal(module, msg); - ldb_free(ldb, s); - ldb_free(ldb, msg.dn); - ldb_free(ldb, el.name); + talloc_free(msg); if (ret == 0) { ltdb->sequence_number += 1; @@ -223,7 +245,6 @@ int ltdb_increase_sequence_number(struct ldb_module *module) */ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; const char *attrs; const struct { @@ -238,11 +259,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) }; size_t len; int i, ret=0; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - if (ltdb->cache.last_attribute.name && - ldb_attr_cmp(ltdb->cache.last_attribute.name, attr_name) == 0) { - return ltdb->cache.last_attribute.flags; + if (ltdb->cache->last_attribute.name && + ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) { + return ltdb->cache->last_attribute.flags; } /* objectclass is a special default case */ @@ -250,7 +270,7 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE; } - attrs = ldb_msg_find_string(<db->cache.attributes, attr_name, NULL); + attrs = ldb_msg_find_string(ltdb->cache->attributes, attr_name, NULL); if (!attrs) { return ret; @@ -270,14 +290,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) attrs += strspn(attrs, " ,"); } - ldb->alloc_ops.alloc = NULL; + talloc_free(ltdb->cache->last_attribute.name); - ldb_free(ldb, ltdb->cache.last_attribute.name); + ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name); + ltdb->cache->last_attribute.flags = ret; - ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name); - ltdb->cache.last_attribute.flags = ret; - - ldb->alloc_ops = alloc; - return ret; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index eaf699be62..ff0cabb0d6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -44,18 +44,6 @@ struct dn_list { }; /* - free a struct dn_list -*/ -static void dn_list_free(struct ldb_context *ldb, struct dn_list *list) -{ - unsigned int i; - for (i=0;i<list->count;i++) { - ldb_free(ldb, list->dn[i]); - } - ldb_free(ldb, list->dn); -} - -/* return the dn key to be used for an index caller frees */ @@ -67,13 +55,13 @@ static char *ldb_dn_key(struct ldb_context *ldb, if (ldb_should_b64_encode(value)) { char *vstr = ldb_base64_encode(ldb, value->data, value->length); if (!vstr) return NULL; - ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr); - ldb_free(ldb, vstr); + ret = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr, vstr); + talloc_free(vstr); return ret; } - ldb_asprintf(ldb, &ret, "%s:%s:%.*s", LTDB_INDEX, attr, value->length, (char *)value->data); - return ret; + return talloc_asprintf(ldb, "%s:%s:%.*s", + LTDB_INDEX, attr, value->length, (char *)value->data); } /* @@ -118,7 +106,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, char *dn = NULL; int ret; unsigned int i, j; - struct ldb_message msg; + struct ldb_message *msg; list->count = 0; list->dn = NULL; @@ -141,39 +129,43 @@ static int ltdb_index_dn_simple(struct ldb_module *module, dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value); if (!dn) return -1; - ret = ltdb_search_dn1(module, dn, &msg); - ldb_free(ldb, dn); + msg = talloc_p(list, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn, msg); + talloc_free(dn); if (ret == 0 || ret == -1) { return ret; } - for (i=0;i<msg.num_elements;i++) { + for (i=0;i<msg->num_elements;i++) { struct ldb_message_element *el; - if (strcmp(msg.elements[i].name, LTDB_IDX) != 0) { + if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { continue; } - el = &msg.elements[i]; + el = &msg->elements[i]; - list->dn = ldb_malloc_array_p(ldb, char *, el->num_values); + list->dn = talloc_array_p(list, char *, el->num_values); if (!list->dn) { break; } for (j=0;j<el->num_values;j++) { list->dn[list->count] = - ldb_strdup(ldb, (char *)el->values[j].data); + talloc_strdup(list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { - dn_list_free(ldb, list); - ltdb_search_dn1_free(module, &msg); + talloc_free(list); return -1; } list->count++; } } - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); @@ -203,30 +195,34 @@ static int ltdb_index_dn_objectclass(struct ldb_module *module, ret = ltdb_index_dn_simple(module, tree, index_list, list); - for (i=0;i<ltdb->cache.subclasses.num_elements;i++) { - struct ldb_message_element *el = <db->cache.subclasses.elements[i]; + for (i=0;i<ltdb->cache->subclasses->num_elements;i++) { + struct ldb_message_element *el = <db->cache->subclasses->elements[i]; if (ldb_attr_cmp(el->name, target) == 0) { unsigned int j; for (j=0;j<el->num_values;j++) { struct ldb_parse_tree tree2; - struct dn_list list2; + struct dn_list *list2; tree2.operation = LDB_OP_SIMPLE; - tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS); + tree2.u.simple.attr = talloc_strdup(list, LTDB_OBJECTCLASS); if (!tree2.u.simple.attr) { return -1; } tree2.u.simple.value = el->values[j]; + list2 = talloc_p(list, struct dn_list); + if (list2 == NULL) { + return -1; + } if (ltdb_index_dn_objectclass(module, &tree2, - index_list, &list2) == 1) { + index_list, list2) == 1) { if (list->count == 0) { - *list = list2; + *list = *list2; ret = 1; } else { - list_union(ldb, list, &list2); - dn_list_free(ldb, &list2); + list_union(ldb, list, list2); + talloc_free(list2); } } - ldb_free(ldb, tree2.u.simple.attr); + talloc_free(tree2.u.simple.attr); } } } @@ -257,35 +253,42 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, static int list_intersect(struct ldb_context *ldb, struct dn_list *list, const struct dn_list *list2) { - struct dn_list list3; + struct dn_list *list3; unsigned int i; if (list->count == 0 || list2->count == 0) { /* 0 & X == 0 */ - dn_list_free(ldb, list); + talloc_free(list); return 0; } - list3.dn = ldb_malloc_array_p(ldb, char *, list->count); - if (!list3.dn) { - dn_list_free(ldb, list); + list3 = talloc_p(ldb, struct dn_list); + if (list3 == NULL) { return -1; } - list3.count = 0; + + list3->dn = talloc_array_p(list3, char *, list->count); + if (!list3->dn) { + talloc_free(list); + talloc_free(list3); + return -1; + } + list3->count = 0; for (i=0;i<list->count;i++) { if (ldb_list_find(list->dn[i], list2->dn, list2->count, sizeof(char *), (comparison_fn_t)strcmp) != -1) { - list3.dn[list3.count] = list->dn[i]; - list3.count++; + list3->dn[list3->count] = talloc_steal(list3->dn, list->dn[i]); + list3->count++; } else { - ldb_free(ldb, list->dn[i]); + talloc_free(list->dn[i]); } } - ldb_free(ldb, list->dn); - list->dn = list3.dn; - list->count = list3.count; + talloc_free(list->dn); + list->dn = talloc_steal(list, list3->dn); + list->count = list3->count; + talloc_free(list3); return 0; } @@ -305,13 +308,13 @@ static int list_union(struct ldb_context *ldb, if (list->count == 0 && list2->count == 0) { /* 0 | 0 == 0 */ - dn_list_free(ldb, list); + talloc_free(list); return 0; } - d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count); + d = talloc_realloc_p(list, list->dn, char *, list->count + list2->count); if (!d) { - dn_list_free(ldb, list); + talloc_free(list); return -1; } list->dn = d; @@ -319,9 +322,9 @@ static int list_union(struct ldb_context *ldb, for (i=0;i<list2->count;i++) { if (ldb_list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]); + list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); if (!list->dn[list->count]) { - dn_list_free(ldb, list); + talloc_free(list); return -1; } list->count++; @@ -358,39 +361,48 @@ static int ltdb_index_dn_or(struct ldb_module *module, list->count = 0; for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list list2; + struct dn_list *list2; int v; - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2); + + list2 = talloc_p(module, struct dn_list); + if (list2 == NULL) { + return -1; + } + + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 || X == X */ if (ret == -1) { ret = 0; } + talloc_free(list2); continue; } if (v == -1) { /* 1 || X == 1 */ - dn_list_free(ldb, list); + talloc_free(list->dn); + talloc_free(list2); return -1; } if (ret == -1) { ret = 1; - *list = list2; + list->dn = talloc_steal(list, list2->dn); + list->count = list2->count; } else { - if (list_union(ldb, list, &list2) == -1) { - dn_list_free(ldb, &list2); + if (list_union(ldb, list, list2) == -1) { + talloc_free(list2); return -1; } - dn_list_free(ldb, &list2); ret = 1; } + talloc_free(list2); } if (list->count == 0) { - dn_list_free(ldb, list); + talloc_free(list); return 0; } @@ -434,33 +446,44 @@ static int ltdb_index_dn_and(struct ldb_module *module, list->count = 0; for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list list2; + struct dn_list *list2; int v; - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2); + + list2 = talloc_p(module, struct dn_list); + if (list2 == NULL) { + return -1; + } + + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 && X == 0 */ - dn_list_free(ldb, list); + talloc_free(list->dn); + talloc_free(list2); return 0; } if (v == -1) { + talloc_free(list2); continue; } if (ret == -1) { ret = 1; - *list = list2; + talloc_free(list->dn); + list->dn = talloc_steal(list, list2->dn); + list->count = list2->count; } else { - if (list_intersect(ldb, list, &list2) == -1) { - dn_list_free(ldb, &list2); + if (list_intersect(ldb, list, list2) == -1) { + talloc_free(list2); return -1; } - dn_list_free(ldb, &list2); } + talloc_free(list2); + if (list->count == 0) { - if (list->dn) ldb_free(ldb, list->dn); + talloc_free(list->dn); return 0; } } @@ -514,24 +537,32 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr int count = 0; for (i=0;i<dn_list->count;i++) { - struct ldb_message msg; + struct ldb_message *msg; int ret; - ret = ltdb_search_dn1(module, dn_list->dn[i], &msg); + + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn_list->dn[i], msg); if (ret == 0) { /* the record has disappeared? yes, this can happen */ + talloc_free(msg); continue; } if (ret == -1) { /* an internal error */ + talloc_free(msg); return -1; } ret = 0; - if (ltdb_message_match(module, &msg, tree, base, scope) == 1) { - ret = ltdb_add_attr_results(module, &msg, attrs, &count, res); + if (ltdb_message_match(module, msg, tree, base, scope) == 1) { + ret = ltdb_add_attr_results(module, msg, attrs, &count, res); } - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); if (ret != 0) { return -1; } @@ -551,26 +582,31 @@ int ltdb_search_indexed(struct ldb_module *module, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct dn_list dn_list; + struct dn_list *dn_list; int ret; - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no index list? must do full search */ return -1; } - ret = ltdb_index_dn(module, tree, <db->cache.indexlist, &dn_list); + dn_list = talloc_p(module, struct dn_list); + if (dn_list == NULL) { + return -1; + } + + ret = ltdb_index_dn(module, tree, ltdb->cache->indexlist, dn_list); if (ret == 1) { /* we've got a candidate list - now filter by the full tree and extract the needed attributes */ - ret = ldb_index_filter(module, tree, base, scope, &dn_list, + ret = ldb_index_filter(module, tree, base, scope, dn_list, attrs, res); - dn_list_free(ldb, &dn_list); } + talloc_free(dn_list); + return ret; } @@ -585,19 +621,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, struct ldb_message_element *el2; /* add another entry */ - el2 = ldb_realloc_p(ldb, msg->elements, - struct ldb_message_element, msg->num_elements+1); + el2 = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!el2) { return -1; } msg->elements = el2; - msg->elements[msg->num_elements].name = ldb_strdup(ldb, LTDB_IDX); + msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, 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 = ldb_malloc_p(ldb, struct ldb_val); + msg->elements[msg->num_elements].values = talloc_p(msg->elements, struct ldb_val); if (!msg->elements[msg->num_elements].values) { return -1; } @@ -630,9 +666,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } } - v2 = ldb_realloc_p(ldb, msg->elements[idx].values, - struct ldb_val, - msg->elements[idx].num_values+1); + v2 = talloc_realloc_p(msg->elements, msg->elements[idx].values, + struct ldb_val, + msg->elements[idx].num_values+1); if (!v2) { return -1; } @@ -652,9 +688,9 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; - struct ldb_message msg; + struct ldb_message *msg; char *dn_key; - int ret, added=0, added_dn=0; + int ret; unsigned int i; dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); @@ -662,52 +698,45 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, return -1; } - ret = ltdb_search_dn1(module, dn_key, &msg); + msg = talloc_p(dn_key, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn_key, msg); if (ret == -1) { - ldb_free(ldb, dn_key); + talloc_free(dn_key); return -1; } if (ret == 0) { - added_dn = 1; - msg.dn = ldb_strdup(ldb, dn_key); - if (!msg.dn) { - ldb_free(ldb, dn_key); + msg->dn = talloc_strdup(msg, dn_key); + if (!msg->dn) { + talloc_free(dn_key); errno = ENOMEM; return -1; } - msg.num_elements = 0; - msg.elements = NULL; - msg.private_data = NULL; + msg->num_elements = 0; + msg->elements = NULL; } - ldb_free(ldb, dn_key); - - for (i=0;i<msg.num_elements;i++) { - if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) { + for (i=0;i<msg->num_elements;i++) { + if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) { break; } } - if (i == msg.num_elements) { - added = 1; - ret = ltdb_index_add1_new(ldb, &msg, el, dn); + if (i == msg->num_elements) { + ret = ltdb_index_add1_new(ldb, msg, el, dn); } else { - ret = ltdb_index_add1_add(ldb, &msg, el, i, dn); + ret = ltdb_index_add1_add(ldb, msg, el, i, dn); } if (ret == 0) { - ret = ltdb_store(module, &msg, TDB_REPLACE); + ret = ltdb_store(module, msg, TDB_REPLACE); } - if (added) { - ldb_free(ldb, msg.elements[i].name); - } - if (added_dn) { - ldb_free(ldb, msg.dn); - } - - ltdb_search_dn1_free(module, &msg); + talloc_free(dn_key); return ret; } @@ -722,13 +751,13 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) int ret; unsigned int i, j; - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no indexed fields */ return 0; } for (i=0;i<msg->num_elements;i++) { - ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name, + ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; @@ -752,7 +781,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; - struct ldb_message msg; + struct ldb_message *msg; char *dn_key; int ret, i; unsigned int j; @@ -762,44 +791,48 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, return -1; } - ret = ltdb_search_dn1(module, dn_key, &msg); + msg = talloc_p(dn_key, struct ldb_message); + if (msg == NULL) { + talloc_free(dn_key); + return -1; + } + + ret = ltdb_search_dn1(module, dn_key, msg); if (ret == -1) { - ldb_free(ldb, dn_key); + talloc_free(dn_key); return -1; } if (ret == 0) { /* it wasn't indexed. Did we have an earlier error? If we did then its gone now */ - ldb_free(ldb, dn_key); + talloc_free(dn_key); return 0; } - i = ldb_msg_find_idx(&msg, dn, &j, LTDB_IDX); + i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); if (i == -1) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: dn %s not found in %s\n", dn, dn_key); /* it ain't there. hmmm */ - ltdb_search_dn1_free(module, &msg); - ldb_free(ldb, dn_key); + talloc_free(dn_key); return 0; } - if (j != msg.elements[i].num_values - 1) { - memmove(&msg.elements[i].values[j], - &msg.elements[i].values[j+1], - (msg.elements[i].num_values-(j+1)) * - sizeof(msg.elements[i].values[0])); + if (j != msg->elements[i].num_values - 1) { + memmove(&msg->elements[i].values[j], + &msg->elements[i].values[j+1], + (msg->elements[i].num_values-(j+1)) * + sizeof(msg->elements[i].values[0])); } - msg.elements[i].num_values--; + msg->elements[i].num_values--; - if (msg.elements[i].num_values == 0) { + if (msg->elements[i].num_values == 0) { ret = ltdb_delete_noindex(module, dn_key); } else { - ret = ltdb_store(module, &msg, TDB_REPLACE); + ret = ltdb_store(module, msg, TDB_REPLACE); } - ltdb_search_dn1_free(module, &msg); - ldb_free(ldb, dn_key); + talloc_free(dn_key); return ret; } @@ -815,13 +848,13 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) unsigned int i, j; /* find the list of indexed fields */ - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no indexed fields */ return 0; } for (i=0;i<msg->num_elements;i++) { - ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name, + ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; @@ -856,7 +889,7 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, vo static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ldb_module *module = state; - struct ldb_message msg; + struct ldb_message *msg; int ret; if (strncmp(key.dptr, "DN=@", 4) == 0 || @@ -864,18 +897,24 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * return 0; } - ret = ltdb_unpack_data(module, &data, &msg); + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_unpack_data(module, &data, msg); if (ret != 0) { + talloc_free(msg); return -1; } - if (!msg.dn) { - msg.dn = key.dptr+3; + if (!msg->dn) { + msg->dn = key.dptr+3; } - ret = ltdb_index_add(module, &msg); + ret = ltdb_index_add(module, msg); - ltdb_unpack_data_free(module, &msg); + talloc_free(msg); return ret; } @@ -888,9 +927,7 @@ int ltdb_reindex(struct ldb_module *module) struct ltdb_private *ltdb = module->private_data; int ret; - ltdb_cache_free(module); - - if (ltdb_cache_load(module) != 0) { + if (ltdb_cache_reload(module) != 0) { return -1; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c index 4a51cfddf0..3bb63e2b5b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_match.c +++ b/source4/lib/ldb/ldb_tdb/ldb_match.c @@ -93,13 +93,14 @@ static int ltdb_val_equal_wildcard_ci(struct ldb_module *module, s2 = ldb_casefold(ldb, v2->data); if (!s2) { + talloc_free(s1); return -1; } ret = fnmatch(s2, s1, 0); - ldb_free(ldb, s1); - ldb_free(ldb, s2); + talloc_free(s1); + talloc_free(s2); if (ret == 0) { return 1; @@ -149,8 +150,8 @@ static int ltdb_val_equal_objectclass(struct ldb_module *module, return 1; } - for (i=0;i<ltdb->cache.subclasses.num_elements;i++) { - struct ldb_message_element *el = <db->cache.subclasses.elements[i]; + for (i=0;i<ltdb->cache->subclasses->num_elements;i++) { + struct ldb_message_element *el = <db->cache->subclasses->elements[i]; if (ldb_attr_cmp(el->name, v2->data) == 0) { unsigned int j; for (j=0;j<el->num_values;j++) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 9515beeaa7..a548a4189b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -99,7 +99,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = ldb_malloc(ldb, size); + data->dptr = talloc_array_p(ldb, char, size); if (!data->dptr) { errno = ENOMEM; return -1; @@ -144,25 +144,14 @@ int ltdb_pack_data(struct ldb_module *module, void ltdb_unpack_data_free(struct ldb_module *module, struct ldb_message *message) { - struct ldb_context *ldb = module->ldb; - unsigned int i; - - for (i=0;i<message->num_elements;i++) { - if (message->elements[i].values) ldb_free(ldb, message->elements[i].values); - } - if (message->elements) ldb_free(ldb, message->elements); + talloc_free(message->elements); } /* unpack a ldb message from a linear buffer in TDB_DATA - note that this does not fill in the class and key elements - - caller frees. Memory for the elements[] and values[] arrays are - malloced, but the memory for the elements is re-used from the - 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() + Free with ltdb_unpack_data_free() */ int ltdb_unpack_data(struct ldb_module *module, const struct TDB_DATA *data, @@ -220,8 +209,7 @@ int ltdb_unpack_data(struct ldb_module *module, goto failed; } - message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, - message->num_elements); + message->elements = talloc_array_p(ldb, struct ldb_message_element, message->num_elements); if (!message->elements) { errno = ENOMEM; goto failed; @@ -247,9 +235,9 @@ int ltdb_unpack_data(struct ldb_module *module, message->elements[i].num_values = pull_uint32(p, 0); message->elements[i].values = NULL; if (message->elements[i].num_values != 0) { - message->elements[i].values = ldb_malloc_array_p(ldb, - struct ldb_val, - message->elements[i].num_values); + message->elements[i].values = talloc_array_p(message->elements, + struct ldb_val, + message->elements[i].num_values); if (!message->elements[i].values) { errno = ENOMEM; goto failed; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 27718a4c86..720188b74c 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -39,25 +39,6 @@ #include "ldb/include/ldb_parse.h" /* - free a message that has all parts separately allocated -*/ -static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg) -{ - unsigned int i, j; - ldb_free(ldb, msg->dn); - for (i=0;i<msg->num_elements;i++) { - ldb_free(ldb, msg->elements[i].name); - for (j=0;j<msg->elements[i].num_values;j++) { - ldb_free(ldb, msg->elements[i].values[j].data); - } - ldb_free(ldb, msg->elements[i].values); - } - ldb_free(ldb, msg->elements); - ldb_free(ldb, msg); -} - - -/* add one element to a message */ static int msg_add_element(struct ldb_context *ldb, @@ -66,7 +47,7 @@ static int msg_add_element(struct ldb_context *ldb, unsigned int i; struct ldb_message_element *e2, *elnew; - e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1); + e2 = talloc_realloc_p(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); if (!e2) { return -1; } @@ -74,13 +55,13 @@ static int msg_add_element(struct ldb_context *ldb, elnew = &e2[ret->num_elements]; - elnew->name = ldb_strdup(ldb, el->name); + elnew->name = talloc_strdup(ret->elements, el->name); if (!elnew->name) { return -1; } if (el->num_values) { - elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); + elnew->values = talloc_array_p(ret->elements, struct ldb_val, el->num_values); if (!elnew->values) { return -1; } @@ -89,7 +70,7 @@ static int msg_add_element(struct ldb_context *ldb, } for (i=0;i<el->num_values;i++) { - elnew->values[i] = ldb_val_dup(ldb, &el->values[i]); + elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); if (elnew->values[i].length != el->values[i].length) { return -1; } @@ -136,24 +117,23 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, struct ldb_message *ret; int i; - ret = ldb_malloc_p(ldb, struct ldb_message); + ret = talloc_p(ldb, struct ldb_message); if (!ret) { return NULL; } - ret->dn = ldb_strdup(ldb, msg->dn); + ret->dn = talloc_strdup(ret, msg->dn); if (!ret->dn) { - ldb_free(ldb, ret); + talloc_free(ret); return NULL; } ret->num_elements = 0; ret->elements = NULL; - ret->private_data = NULL; if (!attrs) { if (msg_add_all_elements(module, ret, msg) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } return ret; @@ -164,7 +144,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, if (strcmp(attrs[i], "*") == 0) { if (msg_add_all_elements(module, ret, msg) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } continue; @@ -175,10 +155,9 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, struct ldb_val val; el2.flags = 0; - el2.name = ldb_strdup(ldb, "dn"); + el2.name = talloc_strdup(ret, "dn"); if (!el2.name) { - msg_free_all_parts(ldb, ret); - ldb_free(ldb, el2.name); + talloc_free(ret); return NULL; } el2.num_values = 1; @@ -187,11 +166,10 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, val.length = strlen(ret->dn); if (msg_add_element(ldb, ret, &el2) != 0) { - msg_free_all_parts(ldb, ret); - ldb_free(ldb, el2.name); + talloc_free(ret); return NULL; } - ldb_free(ldb, el2.name); + talloc_free(el2.name); continue; } @@ -200,7 +178,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, continue; } if (msg_add_element(ldb, ret, el) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } } @@ -238,22 +216,6 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, /* - free the results of a ltdb_search_dn1 search -*/ -void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - ldb_free(ldb, msg->private_data); - for (i=0;i<msg->num_elements;i++) { - ldb_free(ldb, msg->elements[i].values); - } - ldb_free(ldb, msg->elements); - memset(msg, 0, sizeof(*msg)); -} - - -/* search the database for a single simple dn, returning all attributes in a single message @@ -261,7 +223,6 @@ void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg) */ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_message *msg) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; int ret; TDB_DATA tdb_key, tdb_data, tdb_data2; @@ -275,35 +236,32 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag } tdb_data = tdb_fetch(ltdb->tdb, tdb_key); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); if (!tdb_data.dptr) { return 0; } - tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize); + tdb_data2.dptr = talloc_memdup(msg, tdb_data.dptr, tdb_data.dsize); + free(tdb_data.dptr); 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(module, &tdb_data2, msg); if (ret == -1) { - ldb_free(ldb, tdb_data2.dptr); + talloc_free(tdb_data2.dptr); return -1; } if (!msg->dn) { - msg->dn = ldb_strdup(ldb, dn); + msg->dn = talloc_strdup(tdb_data2.dptr, dn); } if (!msg->dn) { - ldb_free(ldb, tdb_data2.dptr); + talloc_free(tdb_data2.dptr); return -1; } @@ -319,27 +277,35 @@ int ltdb_search_dn(struct ldb_module *module, char *dn, { struct ldb_context *ldb = module->ldb; int ret; - struct ldb_message msg, *msg2; + struct ldb_message *msg, *msg2; + + *res = talloc_array_p(ldb, struct ldb_message *, 2); + if (! *res) { + return -1; + } - ret = ltdb_search_dn1(module, dn, &msg); + msg = talloc_p(*res, struct ldb_message); + if (msg == NULL) { + talloc_free(*res); + *res = NULL; + return -1; + } + + ret = ltdb_search_dn1(module, dn, msg); if (ret != 1) { + talloc_free(*res); + *res = NULL; return ret; } - msg2 = ltdb_pull_attrs(module, &msg, attrs); + msg2 = ltdb_pull_attrs(module, msg, attrs); - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); if (!msg2) { return -1; } - *res = ldb_malloc_array_p(ldb, struct ldb_message *, 2); - if (! *res) { - msg_free_all_parts(ldb, msg2); - return -1; - } - (*res)[0] = msg2; (*res)[1] = NULL; @@ -367,9 +333,9 @@ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, } /* add to the results list */ - res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2); + res2 = talloc_realloc_p(ldb, *res, struct ldb_message *, (*count)+2); if (!res2) { - msg_free_all_parts(ldb, msg2); + talloc_free(msg2); return -1; } @@ -404,7 +370,7 @@ struct ltdb_search_info { static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ltdb_search_info *sinfo = state; - struct ldb_message msg; + struct ldb_message *msg; int ret; if (key.dsize < 4 || @@ -412,31 +378,37 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi return 0; } + msg = talloc_p(sinfo, struct ldb_message); + if (msg == NULL) { + return -1; + } + /* unpack the record */ - ret = ltdb_unpack_data(sinfo->module, &data, &msg); + ret = ltdb_unpack_data(sinfo->module, &data, msg); if (ret == -1) { sinfo->failures++; + talloc_free(msg); return 0; } - if (!msg.dn) { - msg.dn = key.dptr + 3; + if (!msg->dn) { + msg->dn = key.dptr + 3; } /* see if it matches the given expression */ - if (!ltdb_message_match(sinfo->module, &msg, sinfo->tree, - sinfo->base, sinfo->scope)) { - ltdb_unpack_data_free(sinfo->module, &msg); + if (!ltdb_message_match(sinfo->module, msg, sinfo->tree, + sinfo->base, sinfo->scope)) { + talloc_free(msg); return 0; } - ret = ltdb_add_attr_results(sinfo->module, &msg, sinfo->attrs, &sinfo->count, &sinfo->msgs); + ret = ltdb_add_attr_results(sinfo->module, msg, sinfo->attrs, &sinfo->count, &sinfo->msgs); if (ret == -1) { sinfo->failures++; } - ltdb_unpack_data_free(sinfo->module, &msg); + talloc_free(msg); return ret; } @@ -447,19 +419,11 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi */ int ltdb_search_free(struct ldb_module *module, struct ldb_message **msgs) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - int i; ltdb->last_err_string = NULL; - if (!msgs) return 0; - - for (i=0;msgs[i];i++) { - msg_free_all_parts(ldb, msgs[i]); - } - - ldb_free(ldb, msgs); + talloc_free(msgs); return 0; } @@ -475,27 +439,36 @@ static int ltdb_search_full(struct ldb_module *module, const char * const attrs[], struct ldb_message ***res) { struct ltdb_private *ltdb = module->private_data; - int ret; - struct ltdb_search_info sinfo; + int ret, count; + struct ltdb_search_info *sinfo; + + sinfo = talloc_p(ltdb, struct ltdb_search_info); + if (sinfo == NULL) { + return -1; + } - sinfo.tree = tree; - sinfo.module = module; - sinfo.scope = scope; - sinfo.base = base; - sinfo.attrs = attrs; - sinfo.msgs = NULL; - sinfo.count = 0; - sinfo.failures = 0; + sinfo->tree = tree; + sinfo->module = module; + sinfo->scope = scope; + sinfo->base = base; + sinfo->attrs = attrs; + sinfo->msgs = NULL; + sinfo->count = 0; + sinfo->failures = 0; - ret = tdb_traverse(ltdb->tdb, search_func, &sinfo); + ret = tdb_traverse(ltdb->tdb, search_func, sinfo); if (ret == -1) { - ltdb_search_free(module, sinfo.msgs); + talloc_free(sinfo); return -1; } - *res = sinfo.msgs; - return sinfo.count; + *res = talloc_steal(ltdb, sinfo->msgs); + count = sinfo->count; + + talloc_free(sinfo); + + return count; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 179b205097..288633cb01 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -75,7 +75,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) if (strncmp(dn, prefix, strlen(prefix)) == 0 && (s = strchr(dn+strlen(prefix), ':'))) { char *attr_name, *attr_name_folded; - attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix)))); + attr_name = talloc_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix)))); if (!attr_name) { goto failed; } @@ -88,12 +88,12 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) if (!attr_name_folded) { goto failed; } - ldb_asprintf(ldb, &dn_folded, "%s:%s:%s", - prefix, attr_name_folded, - s+1); - ldb_free(ldb, attr_name_folded); + dn_folded = talloc_asprintf(ldb, "%s:%s:%s", + prefix, attr_name_folded, + s+1); + talloc_free(attr_name_folded); } - ldb_free(ldb, attr_name); + talloc_free(attr_name); } else { dn_folded = ldb_casefold(ldb, dn); } @@ -102,8 +102,8 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) goto failed; } - ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded); - ldb_free(ldb, dn_folded); + key_str = talloc_asprintf(ldb, "DN=%s", dn_folded); + talloc_free(dn_folded); if (!key_str) { goto failed; @@ -126,7 +126,6 @@ failed: */ static int ltdb_lock(struct ldb_module *module, const char *lockname) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA key; int ret; @@ -142,7 +141,7 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) ret = tdb_chainlock(ltdb->tdb, key); - ldb_free(ldb, key.dptr); + talloc_free(key.dptr); return ret; } @@ -152,7 +151,6 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) */ static int ltdb_unlock(struct ldb_module *module, const char *lockname) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA key; @@ -167,7 +165,7 @@ static int ltdb_unlock(struct ldb_module *module, const char *lockname) tdb_chainunlock(ltdb->tdb, key); - ldb_free(ldb, key.dptr); + talloc_free(key.dptr); return 0; } @@ -199,7 +197,6 @@ static int ltdb_modified(struct ldb_module *module, const char *dn) */ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key, tdb_data; int ret; @@ -211,7 +208,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg ret = ltdb_pack_data(module, msg, &tdb_data); if (ret == -1) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); return -1; } @@ -226,8 +223,8 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg } done: - ldb_free(ldb, tdb_key.dptr); - ldb_free(ldb, tdb_data.dptr); + talloc_free(tdb_key.dptr); + talloc_free(tdb_data.dptr); return ret; } @@ -269,7 +266,6 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg) */ int ltdb_delete_noindex(struct ldb_module *module, const char *dn) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key; int ret; @@ -280,7 +276,7 @@ int ltdb_delete_noindex(struct ldb_module *module, const char *dn) } ret = tdb_delete(ltdb->tdb, tdb_key); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); return ret; } @@ -292,7 +288,7 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) { struct ltdb_private *ltdb = module->private_data; int ret; - struct ldb_message msg; + struct ldb_message *msg = NULL; ltdb->last_err_string = NULL; @@ -301,13 +297,17 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) } if (ltdb_cache_load(module) != 0) { - ltdb_unlock(module, LDBLOCK); - return -1; + goto failed; + } + + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + goto failed; } /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, dn, &msg); + ret = ltdb_search_dn1(module, dn, msg); if (ret != 1) { /* not finding the old record is an error */ goto failed; @@ -315,23 +315,22 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) ret = ltdb_delete_noindex(module, dn); if (ret == -1) { - ltdb_search_dn1_free(module, &msg); goto failed; } /* remove any indexed attributes */ - ret = ltdb_index_del(module, &msg); - - ltdb_search_dn1_free(module, &msg); + ret = ltdb_index_del(module, msg); if (ret == 0) { ltdb_modified(module, dn); } + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return ret; failed: + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return -1; } @@ -369,8 +368,8 @@ static int msg_add_element(struct ldb_context *ldb, struct ldb_message_element *e2; unsigned int i; - e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, - msg->num_elements+1); + e2 = talloc_realloc_p(msg, msg->elements, struct ldb_message_element, + msg->num_elements+1); if (!e2) { errno = ENOMEM; return -1; @@ -384,7 +383,7 @@ static int msg_add_element(struct ldb_context *ldb, e2->flags = el->flags; e2->values = NULL; if (el->num_values != 0) { - e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); + e2->values = talloc_array_p(msg->elements, struct ldb_val, el->num_values); if (!e2->values) { errno = ENOMEM; return -1; @@ -407,30 +406,28 @@ static int msg_delete_attribute(struct ldb_module *module, struct ldb_context *ldb, struct ldb_message *msg, const char *name) { - unsigned int i, j, count=0; - struct ldb_message_element *el2; - - el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements); - if (!el2) { - errno = ENOMEM; - return -1; - } + unsigned int i, j; for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) != 0) { - el2[count++] = msg->elements[i]; - } else { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { for (j=0;j<msg->elements[i].num_values;j++) { ltdb_index_del_value(module, msg->dn, &msg->elements[i], j); } - ldb_free(ldb, msg->elements[i].values); + talloc_free(msg->elements[i].values); + if (msg->num_elements > (i+1)) { + memmove(&msg->elements[i], + &msg->elements[i+1], + sizeof(struct ldb_message_element)* + (msg->num_elements - (i+1))); + } + msg->num_elements--; + i--; + msg->elements = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, + msg->num_elements); } } - msg->num_elements = count; - ldb_free(ldb, msg->elements); - msg->elements = el2; - return 0; } @@ -486,7 +483,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key, tdb_data; - struct ldb_message msg2; + struct ldb_message *msg2; unsigned i, j; int ret; @@ -497,19 +494,25 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms tdb_data = tdb_fetch(ltdb->tdb, tdb_key); if (!tdb_data.dptr) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); + return -1; + } + + msg2 = talloc_p(tdb_key.dptr, struct ldb_message); + if (msg2 == NULL) { + talloc_free(tdb_key.dptr); return -1; } - ret = ltdb_unpack_data(module, &tdb_data, &msg2); + ret = ltdb_unpack_data(module, &tdb_data, msg2); if (ret == -1) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); return -1; } - if (!msg2.dn) { - msg2.dn = msg->dn; + if (!msg2->dn) { + msg2->dn = msg->dn; } for (i=0;i<msg->num_elements;i++) { @@ -522,16 +525,16 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms case LDB_FLAG_MOD_ADD: /* add this element to the message. fail if it already exists */ - ret = find_element(&msg2, el->name); + ret = find_element(msg2, el->name); if (ret == -1) { - if (msg_add_element(ldb, &msg2, el) != 0) { + if (msg_add_element(ldb, msg2, el) != 0) { goto failed; } continue; } - el2 = &msg2.elements[ret]; + el2 = &msg2->elements[ret]; /* An attribute with this name already exists, add all * values if they don't already exist. */ @@ -544,15 +547,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } } - vals = ldb_realloc_p(ldb, el2->values, struct ldb_val, - el2->num_values + el->num_values); + vals = talloc_realloc_p(msg2->elements, el2->values, struct ldb_val, + el2->num_values + el->num_values); if (vals == NULL) goto failed; for (j=0;j<el->num_values;j++) { vals[el2->num_values + j] = - ldb_val_dup(ldb, &el->values[j]); + ldb_val_dup(vals, &el->values[j]); } el2->values = vals; @@ -563,11 +566,11 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms case LDB_FLAG_MOD_REPLACE: /* replace all elements of this attribute name with the elements listed. The attribute not existing is not an error */ - msg_delete_attribute(module, ldb, &msg2, msg->elements[i].name); + msg_delete_attribute(module, ldb, msg2, msg->elements[i].name); /* add the replacement element, if not empty */ if (msg->elements[i].num_values != 0 && - msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { + msg_add_element(ldb, msg2, &msg->elements[i]) != 0) { goto failed; } break; @@ -576,7 +579,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms /* we could be being asked to delete all values or just some values */ if (msg->elements[i].num_values == 0) { - if (msg_delete_attribute(module, ldb, &msg2, + if (msg_delete_attribute(module, ldb, msg2, msg->elements[i].name) != 0) { ltdb->last_err_string = "No such attribute"; goto failed; @@ -585,7 +588,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } for (j=0;j<msg->elements[i].num_values;j++) { if (msg_delete_element(module, - &msg2, + msg2, msg->elements[i].name, &msg->elements[i].values[j]) != 0) { ltdb->last_err_string = "No such attribute"; @@ -600,17 +603,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } /* we've made all the mods - save the modified record back into the database */ - ret = ltdb_store(module, &msg2, TDB_MODIFY); + ret = ltdb_store(module, msg2, TDB_MODIFY); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(module, &msg2); return ret; failed: - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(module, &msg2); return -1; } @@ -649,10 +650,9 @@ static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg) */ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; int ret; - struct ldb_message msg; + struct ldb_message *msg; const char *error_str; ltdb->last_err_string = NULL; @@ -661,28 +661,28 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char return -1; } + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + goto failed; + } + /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, olddn, &msg); + ret = ltdb_search_dn1(module, olddn, msg); if (ret != 1) { /* not finding the old record is an error */ goto failed; } - msg.dn = ldb_strdup(ldb,newdn); - if (!msg.dn) { - ltdb_search_dn1_free(module, &msg); + msg->dn = talloc_strdup(msg, newdn); + if (!msg->dn) { goto failed; } - ret = ltdb_add(module, &msg); + ret = ltdb_add(module, msg); if (ret == -1) { - ldb_free(ldb, msg.dn); - ltdb_search_dn1_free(module, &msg); goto failed; } - ldb_free(ldb, msg.dn); - ltdb_search_dn1_free(module, &msg); ret = ltdb_delete(module, olddn); error_str = ltdb->last_err_string; @@ -692,10 +692,13 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char ltdb->last_err_string = error_str; + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return ret; + failed: + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return -1; } @@ -706,18 +709,8 @@ failed: static int ltdb_close(struct ldb_module *module) { struct ldb_context *ldb = module->ldb; - struct ltdb_private *ltdb = module->private_data; - int ret; - - ltdb->last_err_string = NULL; - - ltdb_cache_free(module); - ldb_set_alloc(ldb, NULL, NULL); - - ret = tdb_close(ltdb->tdb); - ldb_free(ldb, ltdb); - free(ldb); - return ret; + talloc_free(ldb); + return 0; } @@ -745,12 +738,21 @@ static const struct ldb_module_ops ltdb_ops = { ltdb_rename, ltdb_lock, ltdb_unlock, - ltdb_errstring, - ltdb_cache_free + ltdb_errstring }; /* + destroy the ltdb context +*/ +static int ltdb_destructor(void *p) +{ + struct ltdb_private *ltdb = p; + tdb_close(ltdb->tdb); + return 0; +} + +/* connect to the database */ struct ldb_context *ltdb_connect(const char *url, @@ -763,7 +765,7 @@ struct ldb_context *ltdb_connect(const char *url, TDB_CONTEXT *tdb; struct ldb_context *ldb; - ldb = calloc(1, sizeof(struct ldb_context)); + ldb = talloc_zero_p(NULL, struct ldb_context); if (!ldb) { errno = ENOMEM; return NULL; @@ -773,6 +775,7 @@ struct ldb_context *ltdb_connect(const char *url, if (strchr(url, ':')) { if (strncmp(url, "tdb://", 6) != 0) { errno = EINVAL; + talloc_free(ldb); return NULL; } path = url+6; @@ -791,14 +794,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); + talloc_free(ldb); return NULL; } - ltdb = ldb_malloc_p(ldb, struct ltdb_private); + ltdb = talloc_zero_p(ldb, struct ltdb_private); if (!ltdb) { tdb_close(tdb); - free(ldb); + talloc_free(ldb); errno = ENOMEM; return NULL; } @@ -806,12 +809,11 @@ struct ldb_context *ltdb_connect(const char *url, ltdb->tdb = tdb; ltdb->sequence_number = 0; - memset(<db->cache, 0, sizeof(ltdb->cache)); + talloc_set_destructor(ltdb, ltdb_destructor); - ldb->modules = ldb_malloc_p(ldb, struct ldb_module); + ldb->modules = talloc_p(ldb, struct ldb_module); if (!ldb->modules) { - tdb_close(tdb); - free(ldb); + talloc_free(ldb); errno = ENOMEM; return NULL; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 7d6f35dc79..49052550d0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -13,17 +13,17 @@ struct ltdb_private { handling. It has plenty of digits of precision */ double sequence_number; - struct { - struct ldb_message baseinfo; - struct ldb_message indexlist; - struct ldb_message attributes; - struct ldb_message subclasses; + struct ltdb_cache { + struct ldb_message *baseinfo; + struct ldb_message *indexlist; + struct ldb_message *attributes; + struct ldb_message *subclasses; struct { char *name; int flags; } last_attribute; - } cache; + } *cache; /* error if an internal ldb+tdb error */ const char *last_err_string; @@ -51,7 +51,7 @@ struct ltdb_private { /* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ -void ltdb_cache_free(struct ldb_module *module); +int ltdb_cache_reload(struct ldb_module *module); int ltdb_cache_load(struct ldb_module *module); int ltdb_increase_sequence_number(struct ldb_module *module); int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name); diff --git a/source4/lib/ldb/modules/skel.c b/source4/lib/ldb/modules/skel.c index 3581969c18..afafe1bbd9 100644 --- a/source4/lib/ldb/modules/skel.c +++ b/source4/lib/ldb/modules/skel.c @@ -98,11 +98,6 @@ static const char *skel_errstring(struct ldb_module *module) return ldb_next_errstring(module); } -static void skel_cache_free(struct ldb_module *module) -{ - ldb_next_cache_free(module); -} - static const struct ldb_module_ops skel_ops = { "skel", skel_close, @@ -114,8 +109,7 @@ static const struct ldb_module_ops skel_ops = { skel_rename_record, skel_named_lock, skel_named_unlock, - skel_errstring, - skel_cache_free + skel_errstring }; #ifdef HAVE_DLOPEN diff --git a/source4/lib/ldb/modules/timestamps.c b/source4/lib/ldb/modules/timestamps.c index fde87ef4a6..53c39e751e 100644 --- a/source4/lib/ldb/modules/timestamps.c +++ b/source4/lib/ldb/modules/timestamps.c @@ -57,7 +57,8 @@ static int timestamps_search_free(struct ldb_module *module, struct ldb_message return ldb_next_search_free(module, res); } -static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, const char *attr_name, const char *time_string, unsigned int flags) +static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, + const char *attr_name, const char *time_string, unsigned int flags) { struct ldb_val *values; char *name, *timestr; @@ -69,10 +70,11 @@ static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, co } } - msg->elements = ldb_realloc_array(ldb, msg->elements, sizeof(struct ldb_message_element), msg->num_elements + 1); - name = ldb_strdup(ldb, attr_name); - timestr = ldb_strdup(ldb, time_string); - values = ldb_malloc(ldb, sizeof(struct ldb_val)); + msg->elements = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, msg->num_elements + 1); + name = talloc_strdup(msg->elements, attr_name); + timestr = talloc_strdup(msg->elements, time_string); + values = talloc_p(msg->elements, struct ldb_val); if (!msg->elements || !name || !timestr || !values) { return -1; } @@ -89,19 +91,6 @@ static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, co return 0; } -static void free_elements(struct ldb_context *ldb, struct ldb_message *msg, int real_el_num) -{ - int i; - - for (i = real_el_num; i < msg->num_elements; i++) { - ldb_free(ldb, msg->elements[i].name); - ldb_free(ldb, msg->elements[i].values[0].data); - ldb_free(ldb, msg->elements[i].values); - } - ldb_free(ldb, msg->elements); - ldb_free(ldb, msg); -} - /* add_record: add crateTimestamp/modifyTimestamp attributes */ static int timestamps_add_record(struct ldb_module *module, const struct ldb_message *msg) { @@ -120,25 +109,24 @@ static int timestamps_add_record(struct ldb_module *module, const struct ldb_mes return -1; } - /* formatted like: 20040408072012.0Z */ - ldb_asprintf(module->ldb, ×tr, - "%04u%02u%02u%02u%02u%02u.0Z", - tm->tm_year+1900, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - if (!timestr) { + msg2 = talloc_p(module, struct ldb_message); + if (!msg2) { return -1; } - msg2 = ldb_malloc_p(module->ldb, struct ldb_message); - if (!msg2) { + /* formatted like: 20040408072012.0Z */ + timestr = talloc_asprintf(msg2, "%04u%02u%02u%02u%02u%02u.0Z", + tm->tm_year+1900, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + if (!timestr) { return -1; } + msg2->dn = msg->dn; msg2->num_elements = msg->num_elements; msg2->private_data = msg->private_data; - msg2->elements = ldb_malloc_array_p(module->ldb, struct ldb_message_element, msg2->num_elements); + msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg2->num_elements); for (i = 0; i < msg2->num_elements; i++) { msg2->elements[i] = msg->elements[i]; } @@ -147,13 +135,11 @@ static int timestamps_add_record(struct ldb_module *module, const struct ldb_mes add_time_element(module->ldb, msg2, "modifyTimestamp", timestr, LDB_FLAG_MOD_ADD); add_time_element(module->ldb, msg2, "whenCreated", timestr, LDB_FLAG_MOD_ADD); add_time_element(module->ldb, msg2, "whenChanged", timestr, LDB_FLAG_MOD_ADD); - - ldb_free(module->ldb, timestr); } if (msg2) { ret = ldb_next_add_record(module, msg2); - free_elements(module->ldb, msg2, msg->num_elements); + talloc_free(msg2); } else { ret = ldb_next_add_record(module, msg); } @@ -179,38 +165,36 @@ static int timestamps_modify_record(struct ldb_module *module, const struct ldb_ return -1; } + msg2 = talloc_p(module, struct ldb_message); + if (!msg2) { + return -1; + } + /* formatted like: 20040408072012.0Z */ - ldb_asprintf(module->ldb, ×tr, + timestr = talloc_asprintf(msg2, "%04u%02u%02u%02u%02u%02u.0Z", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - if (!timestr) { return -1; } - msg2 = ldb_malloc_p(module->ldb, struct ldb_message); - if (!msg2) { - return -1; - } msg2->dn = msg->dn; msg2->num_elements = msg->num_elements; msg2->private_data = msg->private_data; - msg2->elements = ldb_malloc_array_p(module->ldb, struct ldb_message_element, msg2->num_elements); + msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg2->num_elements); for (i = 0; i < msg2->num_elements; i++) { msg2->elements[i] = msg->elements[i]; } add_time_element(module->ldb, msg2, "modifyTimestamp", timestr, LDB_FLAG_MOD_REPLACE); add_time_element(module->ldb, msg2, "whenChanged", timestr, LDB_FLAG_MOD_REPLACE); - - ldb_free(module->ldb, timestr); } if (msg2) { ret = ldb_next_modify_record(module, msg2); - free_elements(module->ldb, msg2, msg->num_elements); + talloc_free(msg2); } else { ret = ldb_next_modify_record(module, msg); } @@ -249,12 +233,6 @@ static const char *timestamps_errstring(struct ldb_module *module) return ldb_next_errstring(module); } -static void timestamps_cache_free(struct ldb_module *module) -{ - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "timestamps_cache_free\n"); - ldb_next_cache_free(module); -} - static const struct ldb_module_ops timestamps_ops = { "timestamps", timestamps_close, @@ -266,8 +244,7 @@ static const struct ldb_module_ops timestamps_ops = { timestamps_rename_record, timestamps_lock, timestamps_unlock, - timestamps_errstring, - timestamps_cache_free + timestamps_errstring }; @@ -280,7 +257,7 @@ struct ldb_module *timestamps_module_init(struct ldb_context *ldb, const char *o { struct ldb_module *ctx; - ctx = (struct ldb_module *)malloc(sizeof(struct ldb_module)); + ctx = talloc_p(ldb, struct ldb_module); if (!ctx) return NULL; diff --git a/source4/lib/ldb/tests/test-generic.sh b/source4/lib/ldb/tests/test-generic.sh index c4647a7ba3..4fb54b6c3b 100755 --- a/source4/lib/ldb/tests/test-generic.sh +++ b/source4/lib/ldb/tests/test-generic.sh @@ -25,6 +25,14 @@ time $VALGRIND bin/ldbtest -r 1000 -s 10 || exit 1 echo "Adding index" $VALGRIND bin/ldbadd tests/test-index.ldif || exit 1 +echo "testing indexed search" +$VALGRIND bin/ldbsearch '(uid=uham)' || exit 1 +$VALGRIND bin/ldbsearch '(&(uid=uham)(uid=uham))' || exit 1 +$VALGRIND bin/ldbsearch '(|(uid=uham)(uid=uham))' || exit 1 +$VALGRIND bin/ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 +$VALGRIND bin/ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 +$VALGRIND bin/ldbsearch '(&(uid=uham)(!(uid=uhamxx)))' || exit 1 + echo "Starting ldbtest indexed" 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 9d19a1db0a..d95036497a 100644 --- a/source4/lib/ldb/tools/ldbadd.c +++ b/source4/lib/ldb/tools/ldbadd.c @@ -66,10 +66,10 @@ static int process_file(struct ldb_context *ldb, FILE *f) break; } - ret = ldb_add(ldb, &ldif->msg); + ret = ldb_add(ldb, ldif->msg); if (ret != 0) { fprintf(stderr, "ERR: \"%s\" on DN %s\n", - ldb_errstring(ldb), ldif->msg.dn); + ldb_errstring(ldb), ldif->msg->dn); failures++; } else { count++; diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 6cd6ef041b..66b684f4d5 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -48,7 +48,7 @@ static void ldif_write_msg(struct ldb_context *ldb, { struct ldb_ldif ldif; ldif.changetype = changetype; - ldif.msg = *msg; + ldif.msg = msg; ldb_ldif_write_file(ldb, f, &ldif); } @@ -60,14 +60,16 @@ static int modify_record(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2) { - struct ldb_message mod; + struct ldb_message *mod; struct ldb_message_element *el; unsigned int i; int count = 0; - mod.dn = msg1->dn; - mod.num_elements = 0; - mod.elements = NULL; + mod = ldb_msg_new(ldb); + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; msg2 = ldb_msg_canonicalize(ldb, msg2); if (msg2 == NULL) { @@ -84,7 +86,7 @@ static int modify_record(struct ldb_context *ldb, continue; } - if (ldb_msg_add(ldb, &mod, + if (ldb_msg_add(ldb, mod, &msg2->elements[i], el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { return -1; @@ -96,7 +98,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(ldb, &mod, + if (ldb_msg_add_empty(ldb, mod, msg1->elements[i].name, LDB_FLAG_MOD_DELETE) != 0) { return -1; @@ -105,18 +107,18 @@ static int modify_record(struct ldb_context *ldb, } } - if (mod.num_elements == 0) { + if (mod->num_elements == 0) { return 0; } - if (ldb_modify(ldb, &mod) != 0) { + if (ldb_modify(ldb, mod) != 0) { fprintf(stderr, "failed to modify %s - %s\n", msg1->dn, ldb_errstring(ldb)); return -1; } if (verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, &mod); + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); } return count; @@ -205,7 +207,7 @@ static int save_ldif(struct ldb_context *ldb, fprintf(f, "# record %d\n", i+1); ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = *msgs[i]; + ldif.msg = msgs[i]; ldb_ldif_write_file(ldb, f, &ldif); } @@ -278,12 +280,12 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun } while ((ldif = ldb_ldif_read_file(ldb, f))) { - msgs2 = ldb_realloc_p(ldb, msgs2, struct ldb_message *, count2+1); + msgs2 = talloc_realloc_p(ldb, msgs2, struct ldb_message *, count2+1); if (!msgs2) { fprintf(stderr, "out of memory"); return -1; } - msgs2[count2++] = &ldif->msg; + msgs2[count2++] = ldif->msg; } fclose(f); diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index 5fabba57b7..3bdb946897 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -62,18 +62,18 @@ static int process_file(struct ldb_context *ldb, FILE *f) switch (ldif->changetype) { case LDB_CHANGETYPE_NONE: case LDB_CHANGETYPE_ADD: - ret = ldb_add(ldb, &ldif->msg); + ret = ldb_add(ldb, ldif->msg); break; case LDB_CHANGETYPE_DELETE: - ret = ldb_delete(ldb, ldif->msg.dn); + ret = ldb_delete(ldb, ldif->msg->dn); break; case LDB_CHANGETYPE_MODIFY: - ret = ldb_modify(ldb, &ldif->msg); + ret = ldb_modify(ldb, ldif->msg); break; } if (ret != 0) { fprintf(stderr, "ERR: \"%s\" on DN %s\n", - ldb_errstring(ldb), ldif->msg.dn); + ldb_errstring(ldb), ldif->msg->dn); failures++; } else { count++; diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index fced589572..9041231faf 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -71,7 +71,7 @@ static int do_search(struct ldb_context *ldb, printf("# record %d\n", i+1); ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = *msgs[i]; + ldif.msg = msgs[i]; ldb_ldif_write_file(ldb, stdout, &ldif); } diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index 645bc93fd3..01fa1b8ed7 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -130,7 +130,7 @@ static void add_records(struct ldb_context *ldb, free(name); free(msg.dn); free(vals[1][0].data); - ldb_free(ldb, vals[2][0].data); + talloc_free(vals[2][0].data); free(vals[3][0].data); free(vals[4][0].data); } @@ -288,7 +288,7 @@ be indexed */ static void start_test_index(struct ldb_context **ldb) { - struct ldb_message msg; + struct ldb_message *msg; struct ldb_message **res; int ret; @@ -296,24 +296,25 @@ static void start_test_index(struct ldb_context **ldb) ldb_delete(*ldb, "@INDEXLIST"); - memset(&msg, 0, sizeof(msg)); - msg.dn = strdup("@INDEXLIST"); - ldb_msg_add_string(*ldb, &msg, "@IDXATTR", strdup("uid")); + msg = ldb_msg_new(NULL); + + msg->dn = strdup("@INDEXLIST"); + ldb_msg_add_string(*ldb, msg, "@IDXATTR", strdup("uid")); - if (ldb_add(*ldb, &msg) != 0) { - printf("Add of %s failed - %s\n", msg.dn, ldb_errstring(*ldb)); + if (ldb_add(*ldb, msg) != 0) { + printf("Add of %s failed - %s\n", msg->dn, ldb_errstring(*ldb)); exit(1); } - memset(&msg, 0, sizeof(msg)); - asprintf(&msg.dn, "cn=%s,%s", "test", base_dn); - ldb_msg_add_string(*ldb, &msg, "cn", strdup("test")); - ldb_msg_add_string(*ldb, &msg, "sn", strdup("test")); - ldb_msg_add_string(*ldb, &msg, "uid", strdup("test")); - ldb_msg_add_string(*ldb, &msg, "objectClass", strdup("OpenLDAPperson")); + memset(msg, 0, sizeof(*msg)); + asprintf(&msg->dn, "cn=%s,%s", "test", base_dn); + ldb_msg_add_string(*ldb, msg, "cn", strdup("test")); + ldb_msg_add_string(*ldb, msg, "sn", strdup("test")); + ldb_msg_add_string(*ldb, msg, "uid", strdup("test")); + ldb_msg_add_string(*ldb, msg, "objectClass", strdup("OpenLDAPperson")); - if (ldb_add(*ldb, &msg) != 0) { - printf("Add of %s failed - %s\n", msg.dn, ldb_errstring(*ldb)); + if (ldb_add(*ldb, msg) != 0) { + printf("Add of %s failed - %s\n", msg->dn, ldb_errstring(*ldb)); exit(1); } @@ -335,7 +336,7 @@ static void start_test_index(struct ldb_context **ldb) exit(1); } - if (ldb_delete(*ldb, msg.dn) != 0 || + if (ldb_delete(*ldb, msg->dn) != 0 || ldb_delete(*ldb, "@INDEXLIST") != 0) { printf("cleanup failed - %s\n", ldb_errstring(*ldb)); exit(1); |