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