r502: modified ldb to allow the use of an external pool memory
authorAndrew Tridgell <tridge@samba.org>
Thu, 6 May 2004 04:40:15 +0000 (04:40 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:51:45 +0000 (12:51 -0500)
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.

25 files changed:
source/lib/ldb/Makefile.ldb
source/lib/ldb/common/ldb_alloc.c [new file with mode: 0644]
source/lib/ldb/common/ldb_ldif.c
source/lib/ldb/common/ldb_msg.c
source/lib/ldb/common/ldb_parse.c
source/lib/ldb/common/ldb_utf8.c
source/lib/ldb/common/util.c
source/lib/ldb/config.m4
source/lib/ldb/include/includes.h
source/lib/ldb/include/ldb.h
source/lib/ldb/include/ldb_parse.h
source/lib/ldb/ldb_ldap/ldb_ldap.c
source/lib/ldb/ldb_tdb/ldb_cache.c
source/lib/ldb/ldb_tdb/ldb_index.c
source/lib/ldb/ldb_tdb/ldb_match.c
source/lib/ldb/ldb_tdb/ldb_pack.c
source/lib/ldb/ldb_tdb/ldb_search.c
source/lib/ldb/ldb_tdb/ldb_tdb.c
source/lib/ldb/ldb_tdb/ldb_tdb.h
source/lib/ldb/tests/test-generic.sh
source/lib/ldb/tools/ldbadd.c
source/lib/ldb/tools/ldbedit.c
source/lib/ldb/tools/ldbmodify.c
source/lib/ldb/tools/ldbsearch.c
source/lib/ldb/tools/ldbtest.c

index 0b8fdfe28f3d095fd9810c1c7860dcb62c7dcd81..0a0b95f7fe0b650fe4922195fed7585c170ce044 100644 (file)
@@ -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/source/lib/ldb/common/ldb_alloc.c b/source/lib/ldb/common/ldb_alloc.c
new file mode 100644 (file)
index 0000000..667759e
--- /dev/null
@@ -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);
+}
+
index ef782e90e3127cc7847a47b54591566c6202cfee..451276c48d72e30b396c93fd55c2520675cee225 100644 (file)
@@ -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);
 }
index 8eb8a8c5efeff1b0a89d5c4c02295aa4643e812f..5976db81b6a5a66a3ad1f64139206e32be2a8040 100644 (file)
@@ -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;
        }
 
index 4f8d469e6c6f2a2dfc3d38bd7c5adc8afddd8a22..75eb44fcc0e867fe1397169fd9bce78b7cf8a377 100644 (file)
@@ -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 */
-
index 7767b0955e49e1775eddffd7a12f6f2d5625d54d..1e467d23afc3030082797d42eed71b75923766b2 100644 (file)
   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;
index 22bbc8334e2e4c34636de3d46cbc1cf0dea4d931..68537a78640aa9cc3aa0d960bcd1f7fd16ce7854 100644 (file)
 #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
index 444e65bfabffcd4cb93ddd086baab7cdc25e2eb9..975da5a4a625a730c8a90f67c398a2cec0ce9dab 100644 (file)
@@ -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 \
index 7ee6876f485f5532013283c156a4c5fef3dbce43..bf61a983e0e5cc1e59689965c9a09c018a26ce6c 100644 (file)
 #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"
index cee72c3c212c79d3d87a3c8274c6a2c76b6c4f7d..852389d415b043b678cefb18011e3383fe3cd648 100644 (file)
@@ -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
index c0d5806cc9af2803bc72c933128ba3803fe007e3..930799d7b6f3a69dd3e4ca1b14637b1ec1b4c709 100644 (file)
@@ -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
index 8723beeadc7e7d78eb1153205dbe00a8498e0540..7e7d047f2518d6edc18f0bee5244c5c2f3c70ab9 100644 (file)
@@ -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;
 }
index 3c6ce63c2bf565ee101a0df5263d1d652447c61d..6734de9fd896f2ce8b1cc2a24702fe640d13864e 100644 (file)
@@ -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;
index 0b9581e52fffee95ff47b396be23cd2d024b3000..07077281ced9a3e6a368c2d2378a8984f47b84d3 100644 (file)
@@ -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;
 }
index 26e0eebfe7218ddbc513781649f6f40a872009c7..80d147cb436677cf2f7fe85d2290b01812192a02 100644 (file)
@@ -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) {
index 3ded59525943d8e541be42911189c60082857fe7..a32197e2cf0832bf4ffdb3cf20b90768f754b061 100644 (file)
@@ -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;
 }
index 1dce8f83a29d88eb42fe02828f4a76328d439975..5ee4449deeb69029b66d2104bec50b293b71c724 100644 (file)
 /*
   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;
 }
index c674f0c27e6efb4dbf40daf5154aa86f3a91240c..eb28bc4938b1678354b8167b2ca1bf7aa7dc7f8c 100644 (file)
@@ -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;
 
index e87027db63eed62e718a174e9317b78735fe42bd..c791cbe201c159c7a7d2f39692e15617ad6628e3 100644 (file)
@@ -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 */
index 794b451074ece24a650f25bb24e4f72ea9c4092e..6db57967df613f574dd5f5f1d2f28a81af9168e2 100755 (executable)
@@ -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
index 15febb76e787db9401dda6bb9807def0bb6ada7c..6d89f67e0fed96af921e0b9c1f0004c811ab23cb 100644 (file)
@@ -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;
index eb95ed326759a12365f5767e3106df448c98edb7..57c54cad405b81b1b69f271e304b83ca3ef53624 100644 (file)
@@ -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;
index bc29369a5c1a7fcbb532c7e91e6c41c432a63c37..6ac8e366c779278472f6719233f58da2625c886c 100644 (file)
@@ -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;
index 541024dd2ddad892a3374275e10250eaa2d3de9f..edda31b7937e9d244336a5a964b485e0777e50fd 100644 (file)
@@ -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;
 }
index bcb8bdcb163af4eb7533a2a1dca1d0237c557b58..e7db7673875df16e08b0caf82608cd528fb6a7a2 100644 (file)
@@ -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);
        }