summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-05-06 04:40:15 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:51:45 -0500
commitd8ce7c6a2acbf371509a23775470e7614bcb6027 (patch)
tree3b0d2157dc855a17a6e7f0ace37cddfb60dfdb04 /source4/lib/ldb/ldb_tdb
parent3aa278b873c5d06a279e0e65a96d6e6b42b64583 (diff)
downloadsamba-d8ce7c6a2acbf371509a23775470e7614bcb6027.tar.gz
samba-d8ce7c6a2acbf371509a23775470e7614bcb6027.tar.bz2
samba-d8ce7c6a2acbf371509a23775470e7614bcb6027.zip
r502: modified ldb to allow the use of an external pool memory
allocator. The way to use this is to call ldb_set_alloc() with a function pointer to whatever memory allocator you like. It includes a context pointer to allow for pool based allocators. (This used to be commit 3955c482e6c2c9e975a4bb809ec8cb6068e48e34)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c65
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c121
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_match.c18
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_pack.c24
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c109
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c106
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h3
7 files changed, 256 insertions, 190 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index 3c6ce63c2b..6734de9fd8 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -50,24 +50,24 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
msg.num_elements = 1;
msg.elements = &el;
- msg.dn = strdup(LTDB_BASEINFO);
+ msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
if (!msg.dn) {
errno = ENOMEM;
return -1;
}
- el.name = strdup(LTDB_SEQUENCE_NUMBER);
+ el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
if (!el.name) {
- free(msg.dn);
+ ldb_free(ldb, msg.dn);
errno = ENOMEM;
return -1;
}
el.values = &val;
el.num_values = 1;
el.flags = 0;
- val.data = strdup("0");
+ val.data = ldb_strdup(ldb, "0");
if (!val.data) {
- free(el.name);
- free(msg.dn);
+ ldb_free(ldb, el.name);
+ ldb_free(ldb, msg.dn);
errno = ENOMEM;
return -1;
}
@@ -75,9 +75,9 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
ret = ltdb_store(ldb, &msg, TDB_INSERT);
- free(msg.dn);
- free(el.name);
- free(val.data);
+ ldb_free(ldb, msg.dn);
+ ldb_free(ldb, el.name);
+ ldb_free(ldb, val.data);
return ret;
}
@@ -88,6 +88,8 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
void ltdb_cache_free(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
+ struct ldb_alloc_ops alloc = ldb->alloc_ops;
+ ldb->alloc_ops.alloc = NULL;
ltdb->sequence_number = 0;
ltdb_search_dn1_free(ldb, &ltdb->cache.baseinfo);
@@ -95,8 +97,10 @@ void ltdb_cache_free(struct ldb_context *ldb)
ltdb_search_dn1_free(ldb, &ltdb->cache.subclasses);
ltdb_search_dn1_free(ldb, &ltdb->cache.attributes);
- if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
+ ldb_free(ldb, ltdb->cache.last_attribute.name);
memset(&ltdb->cache, 0, sizeof(ltdb->cache));
+
+ ldb->alloc_ops = alloc;
}
/*
@@ -106,20 +110,23 @@ int ltdb_cache_load(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
double seq;
+ struct ldb_alloc_ops alloc = ldb->alloc_ops;
+
+ ldb->alloc_ops.alloc = NULL;
ltdb_search_dn1_free(ldb, &ltdb->cache.baseinfo);
if (ltdb_search_dn1(ldb, LTDB_BASEINFO, &ltdb->cache.baseinfo) == -1) {
- return -1;
+ goto failed;
}
/* possibly initialise the baseinfo */
if (!ltdb->cache.baseinfo.dn) {
if (ltdb_baseinfo_init(ldb) != 0) {
- return -1;
+ goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_BASEINFO, &ltdb->cache.baseinfo) != 1) {
- return -1;
+ goto failed;
}
}
@@ -127,11 +134,11 @@ int ltdb_cache_load(struct ldb_context *ldb)
in the database then assume the rest of the cache is OK */
seq = ldb_msg_find_double(&ltdb->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0);
if (seq == ltdb->sequence_number) {
- return 0;
+ goto done;
}
ltdb->sequence_number = seq;
- if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
+ ldb_free(ldb, ltdb->cache.last_attribute.name);
memset(&ltdb->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute));
ltdb_search_dn1_free(ldb, &ltdb->cache.indexlist);
@@ -139,16 +146,22 @@ int ltdb_cache_load(struct ldb_context *ldb)
ltdb_search_dn1_free(ldb, &ltdb->cache.attributes);
if (ltdb_search_dn1(ldb, LTDB_INDEXLIST, &ltdb->cache.indexlist) == -1) {
- return -1;
+ goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_SUBCLASSES, &ltdb->cache.subclasses) == -1) {
- return -1;
+ goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_ATTRIBUTES, &ltdb->cache.attributes) == -1) {
- return -1;
+ goto failed;
}
+done:
+ ldb->alloc_ops = alloc;
return 0;
+
+failed:
+ ldb->alloc_ops = alloc;
+ return -1;
}
@@ -164,7 +177,7 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
char *s = NULL;
int ret;
- asprintf(&s, "%.0f", ltdb->sequence_number+1);
+ ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1);
if (!s) {
errno = ENOMEM;
return -1;
@@ -172,8 +185,8 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
msg.num_elements = 1;
msg.elements = &el;
- msg.dn = strdup(LTDB_BASEINFO);
- el.name = strdup(LTDB_SEQUENCE_NUMBER);
+ msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
+ el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
el.values = &val;
el.num_values = 1;
el.flags = LDB_FLAG_MOD_REPLACE;
@@ -182,9 +195,9 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
ret = ltdb_modify_internal(ldb, &msg);
- free(s);
- free(msg.dn);
- free(el.name);
+ ldb_free(ldb, s);
+ ldb_free(ldb, msg.dn);
+ ldb_free(ldb, el.name);
if (ret == 0) {
ltdb->sequence_number += 1;
@@ -244,9 +257,9 @@ int ltdb_attribute_flags(struct ldb_context *ldb, const char *attr_name)
attrs += strspn(attrs, " ,");
}
- if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
+ if (ltdb->cache.last_attribute.name) ldb_free(ldb, ltdb->cache.last_attribute.name);
- ltdb->cache.last_attribute.name = strdup(attr_name);
+ ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name);
ltdb->cache.last_attribute.flags = ret;
return ret;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 0b9581e52f..07077281ce 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -43,32 +43,33 @@ struct dn_list {
/*
free a struct dn_list
*/
-static void dn_list_free(struct dn_list *list)
+static void dn_list_free(struct ldb_context *ldb, struct dn_list *list)
{
int i;
for (i=0;i<list->count;i++) {
- free(list->dn[i]);
+ ldb_free(ldb, list->dn[i]);
}
- if (list->dn) free(list->dn);
+ ldb_free(ldb, list->dn);
}
/*
return the dn key to be used for an index
caller frees
*/
-static char *ldb_dn_key(const char *attr, const struct ldb_val *value)
+static char *ldb_dn_key(struct ldb_context *ldb,
+ const char *attr, const struct ldb_val *value)
{
char *ret = NULL;
if (ldb_should_b64_encode(value)) {
- char *vstr = ldb_base64_encode(value->data, value->length);
+ char *vstr = ldb_base64_encode(ldb, value->data, value->length);
if (!vstr) return NULL;
- asprintf(&ret, "%s:%s::%s", LTDB_INDEX, attr, vstr);
- free(vstr);
+ ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr);
+ ldb_free(ldb, vstr);
return ret;
}
- asprintf(&ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data);
+ ldb_asprintf(ldb, &ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data);
return ret;
}
@@ -132,11 +133,11 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb,
/* the attribute is indexed. Pull the list of DNs that match the
search criterion */
- dn = ldb_dn_key(tree->u.simple.attr, &tree->u.simple.value);
+ dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value);
if (!dn) return -1;
ret = ltdb_search_dn1(ldb, dn, &msg);
- free(dn);
+ ldb_free(ldb, dn);
if (ret == 0 || ret == -1) {
return ret;
}
@@ -150,16 +151,16 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb,
el = &msg.elements[i];
- list->dn = malloc_array_p(char *, el->num_values);
+ list->dn = ldb_malloc_array_p(ldb, char *, el->num_values);
if (!list->dn) {
break;
}
for (j=0;j<el->num_values;j++) {
list->dn[list->count] =
- strdup((char *)el->values[j].data);
+ ldb_strdup(ldb, (char *)el->values[j].data);
if (!list->dn[list->count]) {
- dn_list_free(list);
+ dn_list_free(ldb, list);
ltdb_search_dn1_free(ldb, &msg);
return -1;
}
@@ -202,7 +203,7 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb,
struct ldb_parse_tree tree2;
struct dn_list list2;
tree2.operation = LDB_OP_SIMPLE;
- tree2.u.simple.attr = strdup(LTDB_OBJECTCLASS);
+ tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS);
if (!tree2.u.simple.attr) {
return -1;
}
@@ -214,10 +215,10 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb,
ret = 1;
} else {
list_union(list, &list2);
- dn_list_free(&list2);
+ dn_list_free(ldb, &list2);
}
}
- free(tree2.u.simple.attr);
+ ldb_free(ldb, tree2.u.simple.attr);
}
}
}
@@ -245,20 +246,21 @@ static int ltdb_index_dn_leaf(struct ldb_context *ldb,
list = list & list2
relies on the lists being sorted
*/
-static int list_intersect(struct dn_list *list, const struct dn_list *list2)
+static int list_intersect(struct ldb_context *ldb,
+ struct dn_list *list, const struct dn_list *list2)
{
struct dn_list list3;
int i;
if (list->count == 0 || list2->count == 0) {
/* 0 & X == 0 */
- dn_list_free(list);
+ dn_list_free(ldb, list);
return 0;
}
- list3.dn = malloc_array_p(char *, list->count);
+ list3.dn = ldb_malloc_array_p(ldb, char *, list->count);
if (!list3.dn) {
- dn_list_free(list);
+ dn_list_free(ldb, list);
return -1;
}
list3.count = 0;
@@ -269,11 +271,11 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
list3.dn[list3.count] = list->dn[i];
list3.count++;
} else {
- free(list->dn[i]);
+ ldb_free(ldb, list->dn[i]);
}
}
- free(list->dn);
+ ldb_free(ldb, list->dn);
list->dn = list3.dn;
list->count = list3.count;
@@ -286,7 +288,8 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
list = list | list2
relies on the lists being sorted
*/
-static int list_union(struct dn_list *list, const struct dn_list *list2)
+static int list_union(struct ldb_context *ldb,
+ struct dn_list *list, const struct dn_list *list2)
{
int i;
char **d;
@@ -294,13 +297,13 @@ static int list_union(struct dn_list *list, const struct dn_list *list2)
if (list->count == 0 && list2->count == 0) {
/* 0 | 0 == 0 */
- dn_list_free(list);
+ dn_list_free(ldb, list);
return 0;
}
- d = realloc_p(list->dn, char *, list->count + list2->count);
+ d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count);
if (!d) {
- dn_list_free(list);
+ dn_list_free(ldb, list);
return -1;
}
list->dn = d;
@@ -308,9 +311,9 @@ static int list_union(struct dn_list *list, const struct dn_list *list2)
for (i=0;i<list2->count;i++) {
if (list_find(list2->dn[i], list->dn, count,
sizeof(char *), (comparison_fn_t)strcmp) == -1) {
- list->dn[list->count] = strdup(list2->dn[i]);
+ list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]);
if (!list->dn[list->count]) {
- dn_list_free(list);
+ dn_list_free(ldb, list);
return -1;
}
list->count++;
@@ -359,7 +362,7 @@ static int ltdb_index_dn_or(struct ldb_context *ldb,
if (v == -1) {
/* 1 || X == 1 */
- dn_list_free(list);
+ dn_list_free(ldb, list);
return -1;
}
@@ -367,16 +370,16 @@ static int ltdb_index_dn_or(struct ldb_context *ldb,
ret = 1;
*list = list2;
} else {
- if (list_union(list, &list2) == -1) {
- dn_list_free(&list2);
+ if (list_union(ldb, list, &list2) == -1) {
+ dn_list_free(ldb, &list2);
return -1;
}
- dn_list_free(&list2);
+ dn_list_free(ldb, &list2);
}
}
if (list->count == 0) {
- dn_list_free(list);
+ dn_list_free(ldb, list);
return 0;
}
@@ -424,7 +427,7 @@ static int ltdb_index_dn_and(struct ldb_context *ldb,
if (v == 0) {
/* 0 && X == 0 */
- dn_list_free(list);
+ dn_list_free(ldb, list);
return 0;
}
@@ -436,15 +439,15 @@ static int ltdb_index_dn_and(struct ldb_context *ldb,
ret = 1;
*list = list2;
} else {
- if (list_intersect(list, &list2) == -1) {
- dn_list_free(&list2);
+ if (list_intersect(ldb, list, &list2) == -1) {
+ dn_list_free(ldb, &list2);
return -1;
}
- dn_list_free(&list2);
+ dn_list_free(ldb, &list2);
}
if (list->count == 0) {
- if (list->dn) free(list->dn);
+ if (list->dn) ldb_free(ldb, list->dn);
return 0;
}
}
@@ -550,7 +553,7 @@ int ltdb_search_indexed(struct ldb_context *ldb,
and extract the needed attributes */
ret = ldb_index_filter(ldb, tree, base, scope, &dn_list,
attrs, res);
- dn_list_free(&dn_list);
+ dn_list_free(ldb, &dn_list);
}
return ret;
@@ -567,18 +570,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
struct ldb_message_element *el2;
/* add another entry */
- el2 = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1);
+ el2 = ldb_realloc_p(ldb, msg->elements,
+ struct ldb_message_element, msg->num_elements+1);
if (!el2) {
return -1;
}
msg->elements = el2;
- msg->elements[msg->num_elements].name = strdup(LTDB_IDX);
+ msg->elements[msg->num_elements].name = ldb_strdup(ldb, LTDB_IDX);
if (!msg->elements[msg->num_elements].name) {
return -1;
}
msg->elements[msg->num_elements].num_values = 0;
- msg->elements[msg->num_elements].values = malloc_p(struct ldb_val);
+ msg->elements[msg->num_elements].values = ldb_malloc_p(ldb, struct ldb_val);
if (!msg->elements[msg->num_elements].values) {
return -1;
}
@@ -611,9 +615,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
}
}
- v2 = realloc_p(msg->elements[idx].values,
- struct ldb_val,
- msg->elements[idx].num_values+1);
+ v2 = ldb_realloc_p(ldb, msg->elements[idx].values,
+ struct ldb_val,
+ msg->elements[idx].num_values+1);
if (!v2) {
return -1;
}
@@ -634,23 +638,24 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
{
struct ldb_message msg;
char *dn_key;
- int ret, i, added=0;
+ int ret, i, added=0, added_dn=0;
- dn_key = ldb_dn_key(el->name, &el->values[v_idx]);
+ dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]);
if (!dn_key) {
return -1;
}
ret = ltdb_search_dn1(ldb, dn_key, &msg);
if (ret == -1) {
- free(dn_key);
+ ldb_free(ldb, dn_key);
return -1;
}
if (ret == 0) {
- msg.dn = strdup(dn_key);
+ added_dn = 1;
+ msg.dn = ldb_strdup(ldb, dn_key);
if (!msg.dn) {
- free(dn_key);
+ ldb_free(ldb, dn_key);
errno = ENOMEM;
return -1;
}
@@ -659,7 +664,7 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
msg.private_data = NULL;
}
- free(dn_key);
+ ldb_free(ldb, dn_key);
for (i=0;i<msg.num_elements;i++) {
if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) {
@@ -679,7 +684,10 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
}
if (added) {
- free(msg.elements[i].name);
+ ldb_free(ldb, msg.elements[i].name);
+ }
+ if (added_dn) {
+ ldb_free(ldb, msg.dn);
}
ltdb_search_dn1_free(ldb, &msg);
@@ -728,14 +736,14 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
char *dn_key;
int ret, i, j;
- dn_key = ldb_dn_key(el->name, &el->values[v_idx]);
+ dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]);
if (!dn_key) {
return -1;
}
ret = ltdb_search_dn1(ldb, dn_key, &msg);
if (ret == -1) {
- free(dn_key);
+ ldb_free(ldb, dn_key);
return -1;
}
@@ -743,6 +751,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
/* it wasn't indexed. Did we have an earlier error? If we did then
its gone now */
ltdb_search_dn1_free(ldb, &msg);
+ ldb_free(ldb, dn_key);
return 0;
}
@@ -750,6 +759,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
if (i == -1) {
/* it ain't there. hmmm */
ltdb_search_dn1_free(ldb, &msg);
+ ldb_free(ldb, dn_key);
return 0;
}
@@ -768,6 +778,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
}
ltdb_search_dn1_free(ldb, &msg);
+ ldb_free(ldb, dn_key);
return ret;
}
@@ -841,7 +852,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
ret = ltdb_index_add(ldb, &msg);
- ltdb_unpack_data_free(&msg);
+ ltdb_unpack_data_free(ldb, &msg);
return ret;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c
index 26e0eebfe7..80d147cb43 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_match.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_match.c
@@ -71,7 +71,8 @@ static int ldb_val_equal_case_insensitive(const struct ldb_val *v1,
and case insensitive
return 1 for a match, 0 for a mis-match
*/
-static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
+static int ldb_val_equal_wildcard_ci(struct ldb_context *ldb,
+ const struct ldb_val *v1,
const struct ldb_val *v2)
{
char *s1, *s2;
@@ -81,20 +82,20 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
return v1->data == v2->data;
}
- s1 = ldb_casefold(v1->data);
+ s1 = ldb_casefold(ldb, v1->data);
if (!s1) {
return -1;
}
- s2 = ldb_casefold(v2->data);
+ s2 = ldb_casefold(ldb, v2->data);
if (!s2) {
return -1;
}
ret = fnmatch(s2, s1, 0);
- free(s1);
- free(s2);
+ ldb_free(ldb, s1);
+ ldb_free(ldb, s2);
if (ret == 0) {
return 1;
@@ -107,12 +108,13 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
see if two ldb_val structures contain the same data with wildcards
return 1 for a match, 0 for a mis-match
*/
-static int ldb_val_equal_wildcard(const struct ldb_val *v1,
+static int ldb_val_equal_wildcard(struct ldb_context *ldb,
+ const struct ldb_val *v1,
const struct ldb_val *v2,
int flags)
{
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
- return ldb_val_equal_wildcard_ci(v1, v2);
+ return ldb_val_equal_wildcard_ci(ldb, v1, v2);
}
if (!v1->data || !v2->data) {
return v1->data == v2->data;
@@ -182,7 +184,7 @@ int ldb_val_equal(struct ldb_context *ldb,
}
if (flags & LTDB_FLAG_WILDCARD) {
- return ldb_val_equal_wildcard(v1, v2, flags);
+ return ldb_val_equal_wildcard(ldb, v1, v2, flags);
}
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c
index 3ded595259..a32197e2cf 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -49,7 +49,7 @@
caller frees the data buffer after use
*/
-int ltdb_pack_data(struct ldb_context *ctx,
+int ltdb_pack_data(struct ldb_context *ldb,
const struct ldb_message *message,
struct TDB_DATA *data)
{
@@ -74,7 +74,7 @@ int ltdb_pack_data(struct ldb_context *ctx,
}
/* allocate it */
- data->dptr = malloc(size);
+ data->dptr = ldb_malloc(ldb, size);
if (!data->dptr) {
errno = ENOMEM;
return -1;
@@ -116,14 +116,15 @@ int ltdb_pack_data(struct ldb_context *ctx,
/*
free the memory allocated from a ltdb_unpack_data()
*/
-void ltdb_unpack_data_free(struct ldb_message *message)
+void ltdb_unpack_data_free(struct ldb_context *ldb,
+ struct ldb_message *message)
{
int i;
for (i=0;i<message->num_elements;i++) {
- if (message->elements[i].values) free(message->elements[i].values);
+ if (message->elements[i].values) ldb_free(ldb, message->elements[i].values);
}
- if (message->elements) free(message->elements);
+ if (message->elements) ldb_free(ldb, message->elements);
}
@@ -137,7 +138,7 @@ void ltdb_unpack_data_free(struct ldb_message *message)
TDB_DATA data. This means the caller only has to free the elements
and values arrays. This can be done with ltdb_unpack_data_free()
*/
-int ltdb_unpack_data(struct ldb_context *ctx,
+int ltdb_unpack_data(struct ldb_context *ldb,
const struct TDB_DATA *data,
struct ldb_message *message)
{
@@ -192,8 +193,8 @@ int ltdb_unpack_data(struct ldb_context *ctx,
goto failed;
}
- message->elements = malloc_array_p(struct ldb_message_element,
- message->num_elements);
+ message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element,
+ message->num_elements);
if (!message->elements) {
errno = ENOMEM;
@@ -217,8 +218,9 @@ int ltdb_unpack_data(struct ldb_context *ctx,
message->elements[i].num_values = IVAL(p, 0);
message->elements[i].values = NULL;
if (message->elements[i].num_values != 0) {
- message->elements[i].values = malloc_array_p(struct ldb_val,
- message->elements[i].num_values);
+ message->elements[i].values = ldb_malloc_array_p(ldb,
+ struct ldb_val,
+ message->elements[i].num_values);
if (!message->elements[i].values) {
errno = ENOMEM;
goto failed;
@@ -242,7 +244,7 @@ int ltdb_unpack_data(struct ldb_context *ctx,
return 0;
failed:
- ltdb_unpack_data_free(message);
+ ltdb_unpack_data_free(ldb, message);
return -1;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index 1dce8f83a2..5ee4449dee 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -38,27 +38,27 @@
/*
free a message that has all parts separately allocated
*/
-static void msg_free_all_parts(struct ldb_message *msg)
+static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg)
{
int i, j;
- if (msg->dn) free(msg->dn);
+ ldb_free(ldb, msg->dn);
for (i=0;i<msg->num_elements;i++) {
- if (msg->elements[i].name) free(msg->elements[i].name);
+ ldb_free(ldb, msg->elements[i].name);
for (j=0;j<msg->elements[i].num_values;j++) {
- if (msg->elements[i].values[j].data)
- free(msg->elements[i].values[j].data);
+ ldb_free(ldb, msg->elements[i].values[j].data);
}
- if (msg->elements[i].values) free(msg->elements[i].values);
+ ldb_free(ldb, msg->elements[i].values);
}
- free(msg->elements);
- free(msg);
+ ldb_free(ldb, msg->elements);
+ ldb_free(ldb, msg);
}
/*
duplicate a ldb_val structure
*/
-struct ldb_val ldb_val_dup(const struct ldb_val *v)
+struct ldb_val ldb_val_dup(struct ldb_context *ldb,
+ const struct ldb_val *v)
{
struct ldb_val v2;
v2.length = v->length;
@@ -69,7 +69,7 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v)
/* the +1 is to cope with buggy C library routines like strndup
that look one byte beyond */
- v2.data = malloc(v->length+1);
+ v2.data = ldb_malloc(ldb, v->length+1);
if (!v2.data) {
v2.length = 0;
return v2;
@@ -85,12 +85,13 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v)
/*
add one element to a message
*/
-static int msg_add_element(struct ldb_message *ret, const struct ldb_message_element *el)
+static int msg_add_element(struct ldb_context *ldb,
+ struct ldb_message *ret, const struct ldb_message_element *el)
{
int i;
struct ldb_message_element *e2, *elnew;
- e2 = realloc_p(ret->elements, struct ldb_message_element, ret->num_elements+1);
+ e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1);
if (!e2) {
return -1;
}
@@ -98,13 +99,13 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
elnew = &e2[ret->num_elements];
- elnew->name = strdup(el->name);
+ elnew->name = ldb_strdup(ldb, el->name);
if (!elnew->name) {
return -1;
}
if (el->num_values) {
- elnew->values = malloc_array_p(struct ldb_val, el->num_values);
+ elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
if (!elnew->values) {
return -1;
}
@@ -113,7 +114,7 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
}
for (i=0;i<el->num_values;i++) {
- elnew->values[i] = ldb_val_dup(&el->values[i]);
+ elnew->values[i] = ldb_val_dup(ldb, &el->values[i]);
if (elnew->values[i].length != el->values[i].length) {
return -1;
}
@@ -129,12 +130,12 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
/*
add all elements from one message into another
*/
-static int msg_add_all_elements(struct ldb_message *ret,
+static int msg_add_all_elements(struct ldb_context *ldb, struct ldb_message *ret,
const struct ldb_message *msg)
{
int i;
for (i=0;i<msg->num_elements;i++) {
- if (msg_add_element(ret, &msg->elements[i]) != 0) {
+ if (msg_add_element(ldb, ret, &msg->elements[i]) != 0) {
return -1;
}
}
@@ -153,14 +154,14 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
struct ldb_message *ret;
int i;
- ret = malloc_p(struct ldb_message);
+ ret = ldb_malloc_p(ldb, struct ldb_message);
if (!ret) {
return NULL;
}
- ret->dn = strdup(msg->dn);
+ ret->dn = ldb_strdup(ldb, msg->dn);
if (!ret->dn) {
- free(ret);
+ ldb_free(ldb, ret);
return NULL;
}
@@ -169,8 +170,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
ret->private_data = NULL;
if (!attrs) {
- if (msg_add_all_elements(ret, msg) != 0) {
- msg_free_all_parts(ret);
+ if (msg_add_all_elements(ldb, ret, msg) != 0) {
+ msg_free_all_parts(ldb, ret);
return NULL;
}
return ret;
@@ -180,8 +181,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
struct ldb_message_element *el;
if (strcmp(attrs[i], "*") == 0) {
- if (msg_add_all_elements(ret, msg) != 0) {
- msg_free_all_parts(ret);
+ if (msg_add_all_elements(ldb, ret, msg) != 0) {
+ msg_free_all_parts(ldb, ret);
return NULL;
}
continue;
@@ -191,8 +192,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
if (!el) {
continue;
}
- if (msg_add_element(ret, el) != 0) {
- msg_free_all_parts(ret);
+ if (msg_add_element(ldb, ret, el) != 0) {
+ msg_free_all_parts(ldb, ret);
return NULL;
}
}
@@ -235,11 +236,11 @@ int ltdb_has_wildcard(struct ldb_context *ldb, const char *attr_name,
void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg)
{
int i;
- if (msg->private_data) free(msg->private_data);
+ ldb_free(ldb, msg->private_data);
for (i=0;i<msg->num_elements;i++) {
- if (msg->elements[i].values) free(msg->elements[i].values);
+ ldb_free(ldb, msg->elements[i].values);
}
- if (msg->elements) free(msg->elements);
+ ldb_free(ldb, msg->elements);
memset(msg, 0, sizeof(*msg));
}
@@ -254,7 +255,7 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message
{
struct ltdb_private *ltdb = ldb->private_data;
int ret;
- TDB_DATA tdb_key, tdb_data;
+ TDB_DATA tdb_key, tdb_data, tdb_data2;
/* form the key */
tdb_key = ltdb_key(ldb, dn);
@@ -263,26 +264,35 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message
}
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
if (!tdb_data.dptr) {
return 0;
}
- msg->private_data = tdb_data.dptr;
+ tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize);
+ if (!tdb_data2.dptr) {
+ free(tdb_data.dptr);
+ return -1;
+ }
+ memcpy(tdb_data2.dptr, tdb_data.dptr, tdb_data.dsize);
+ free(tdb_data.dptr);
+ tdb_data2.dsize = tdb_data.dsize;
+
+ msg->private_data = tdb_data2.dptr;
msg->num_elements = 0;
msg->elements = NULL;
- ret = ltdb_unpack_data(ldb, &tdb_data, msg);
+ ret = ltdb_unpack_data(ldb, &tdb_data2, msg);
if (ret == -1) {
- free(tdb_data.dptr);
+ free(tdb_data2.dptr);
return -1;
}
if (!msg->dn) {
- msg->dn = strdup(dn);
+ msg->dn = ldb_strdup(ldb, dn);
}
if (!msg->dn) {
- free(tdb_data.dptr);
+ ldb_free(ldb, tdb_data2.dptr);
return -1;
}
@@ -312,9 +322,9 @@ int ltdb_search_dn(struct ldb_context *ldb, char *dn,
return -1;
}
- *res = malloc_array_p(struct ldb_message *, 2);
+ *res = ldb_malloc_array_p(ldb, struct ldb_message *, 2);
if (! *res) {
- msg_free_all_parts(msg2);
+ msg_free_all_parts(ldb, msg2);
return -1;
}
@@ -344,9 +354,9 @@ int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg,
}
/* add to the results list */
- res2 = realloc_p(*res, struct ldb_message *, (*count)+2);
+ res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2);
if (!res2) {
- msg_free_all_parts(msg2);
+ msg_free_all_parts(ldb, msg2);
return -1;
}
@@ -403,7 +413,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
/* see if it matches the given expression */
if (!ldb_message_match(sinfo->ldb, &msg, sinfo->tree,
sinfo->base, sinfo->scope)) {
- ltdb_unpack_data_free(&msg);
+ ltdb_unpack_data_free(sinfo->ldb, &msg);
return 0;
}
@@ -413,7 +423,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
sinfo->failures++;
}
- ltdb_unpack_data_free(&msg);
+ ltdb_unpack_data_free(sinfo->ldb, &msg);
return ret;
}
@@ -424,15 +434,18 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
*/
int ltdb_search_free(struct ldb_context *ldb, struct ldb_message **msgs)
{
+ struct ltdb_private *ltdb = ldb->private_data;
int i;
+ ltdb->last_err_string = NULL;
+
if (!msgs) return 0;
for (i=0;msgs[i];i++) {
- msg_free_all_parts(msgs[i]);
+ msg_free_all_parts(ldb, msgs[i]);
}
- free(msgs);
+ ldb_free(ldb, msgs);
return 0;
}
@@ -480,9 +493,12 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
enum ldb_scope scope, const char *expression,
char * const attrs[], struct ldb_message ***res)
{
+ struct ltdb_private *ltdb = ldb->private_data;
struct ldb_parse_tree *tree;
int ret;
+ ltdb->last_err_string = NULL;
+
if (ltdb_cache_load(ldb) != 0) {
return -1;
}
@@ -490,8 +506,9 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
*res = NULL;
/* form a parse tree for the expression */
- tree = ldb_parse_tree(expression);
+ tree = ldb_parse_tree(ldb, expression);
if (!tree) {
+ ltdb->last_err_string = "expression parse failed";
return -1;
}
@@ -507,7 +524,7 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
}
}
- ldb_parse_tree_free(tree);
+ ldb_parse_tree_free(ldb, tree);
return ret;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index c674f0c27e..eb28bc4938 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -67,35 +67,35 @@ struct TDB_DATA ltdb_key(struct ldb_context *ldb, const char *dn)
if (strncmp(dn, prefix, strlen(prefix)) == 0 &&
(s = strchr(dn+strlen(prefix), ':'))) {
char *attr_name, *attr_name_folded;
- attr_name = strndup(dn+strlen(prefix), (s-(dn+strlen(prefix))));
+ attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
if (!attr_name) {
goto failed;
}
flags = ltdb_attribute_flags(ldb, attr_name);
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
- dn_folded = ldb_casefold(dn);
+ dn_folded = ldb_casefold(ldb, dn);
} else {
- attr_name_folded = ldb_casefold(attr_name);
+ attr_name_folded = ldb_casefold(ldb, attr_name);
if (!attr_name_folded) {
goto failed;
}
- asprintf(&dn_folded, "%s:%s:%s",
+ ldb_asprintf(ldb, &dn_folded, "%s:%s:%s",
prefix, attr_name_folded,
s+1);
- free(attr_name_folded);
+ ldb_free(ldb, attr_name_folded);
}
- free(attr_name);
+ ldb_free(ldb, attr_name);
} else {
- dn_folded = ldb_casefold(dn);
+ dn_folded = ldb_casefold(ldb, dn);
}
if (!dn_folded) {
goto failed;
}
- asprintf(&key_str, "DN=%s", dn_folded);
- free(dn_folded);
+ ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded);
+ ldb_free(ldb, dn_folded);
if (!key_str) {
goto failed;
@@ -129,7 +129,7 @@ static int ltdb_lock(struct ldb_context *ldb)
ret = tdb_chainlock(ltdb->tdb, key);
- free(key.dptr);
+ ldb_free(ldb, key.dptr);
return ret;
}
@@ -149,7 +149,7 @@ static void ltdb_unlock(struct ldb_context *ldb)
tdb_chainunlock(ltdb->tdb, key);
- free(key.dptr);
+ ldb_free(ldb, key.dptr);
}
@@ -190,7 +190,7 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs)
ret = ltdb_pack_data(ldb, msg, &tdb_data);
if (ret == -1) {
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
return -1;
}
@@ -205,8 +205,8 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs)
}
done:
- free(tdb_key.dptr);
- free(tdb_data.dptr);
+ ldb_free(ldb, tdb_key.dptr);
+ ldb_free(ldb, tdb_data.dptr);
return ret;
}
@@ -217,8 +217,11 @@ done:
*/
static int ltdb_add(struct ldb_context *ldb, const struct ldb_message *msg)
{
+ struct ltdb_private *ltdb = ldb->private_data;
int ret;
+ ltdb->last_err_string = NULL;
+
if (ltdb_lock(ldb) != 0) {
return -1;
}
@@ -255,7 +258,7 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn)
}
ret = tdb_delete(ltdb->tdb, tdb_key);
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
return ret;
}
@@ -265,9 +268,12 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn)
*/
static int ltdb_delete(struct ldb_context *ldb, const char *dn)
{
+ struct ltdb_private *ltdb = ldb->private_data;
int ret;
struct ldb_message msg;
+ ltdb->last_err_string = NULL;
+
if (ltdb_lock(ldb) != 0) {
return -1;
}
@@ -335,12 +341,13 @@ static int find_element(const struct ldb_message *msg, const char *name)
returns 0 on success, -1 on failure (and sets errno)
*/
-static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *el)
+static int msg_add_element(struct ldb_context *ldb,
+ struct ldb_message *msg, struct ldb_message_element *el)
{
struct ldb_message_element *e2;
int i;
- e2 = realloc_p(msg->elements, struct ldb_message_element,
+ e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
msg->num_elements+1);
if (!e2) {
errno = ENOMEM;
@@ -355,7 +362,7 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *
e2->flags = el->flags;
e2->values = NULL;
if (el->num_values != 0) {
- e2->values = malloc_array_p(struct ldb_val, el->num_values);
+ e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
if (!e2->values) {
free(e2->name);
errno = ENOMEM;
@@ -375,12 +382,13 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *
/*
delete all elements having a specified attribute name
*/
-static int msg_delete_attribute(struct ldb_message *msg, const char *name)
+static int msg_delete_attribute(struct ldb_context *ldb,
+ struct ldb_message *msg, const char *name)
{
int i, count=0;
struct ldb_message_element *el2;
- el2 = malloc_array_p(struct ldb_message_element, msg->num_elements);
+ el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
if (!el2) {
errno = ENOMEM;
return -1;
@@ -390,12 +398,12 @@ static int msg_delete_attribute(struct ldb_message *msg, const char *name)
if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
el2[count++] = msg->elements[i];
} else {
- if (msg->elements[i].values) free(msg->elements[i].values);
+ ldb_free(ldb, msg->elements[i].values);
}
}
msg->num_elements = count;
- if (msg->elements) free(msg->elements);
+ ldb_free(ldb, msg->elements);
msg->elements = el2;
return 0;
@@ -425,7 +433,7 @@ static int msg_delete_element(struct ldb_context *ldb,
if (ldb_val_equal(ldb, msg->elements[i].name, &el->values[i], val)) {
if (i<el->num_values-1) {
memmove(&el->values[i], &el->values[i+1],
- sizeof(el->values[i])*el->num_values-(i+1));
+ sizeof(el->values[i])*(el->num_values-(i+1)));
}
el->num_values--;
return 0;
@@ -463,7 +471,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
ret = ltdb_unpack_data(ldb, &tdb_data, &msg2);
if (ret == -1) {
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
return -1;
}
@@ -483,7 +491,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
errno = EEXIST;
goto failed;
}
- if (msg_add_element(&msg2, &msg->elements[i]) != 0) {
+ if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
goto failed;
}
break;
@@ -491,11 +499,11 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
case LDB_FLAG_MOD_REPLACE:
/* replace all elements of this attribute name with the elements
listed */
- if (msg_delete_attribute(&msg2, msg->elements[i].name) != 0) {
+ if (msg_delete_attribute(ldb, &msg2, msg->elements[i].name) != 0) {
goto failed;
}
/* add the replacement element */
- if (msg_add_element(&msg2, &msg->elements[i]) != 0) {
+ if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
goto failed;
}
break;
@@ -504,8 +512,8 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
/* we could be being asked to delete all
values or just some values */
if (msg->elements[i].num_values == 0) {
- if (msg_delete_attribute(&msg2,
- msg->elements[i].name) != 0) {
+ if (msg_delete_attribute(ldb, &msg2,
+ msg->elements[i].name) != 0) {
goto failed;
}
break;
@@ -525,15 +533,15 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
/* we've made all the mods - save the modified record back into the database */
ret = ltdb_store(ldb, &msg2, TDB_MODIFY);
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
- ltdb_unpack_data_free(&msg2);
+ ltdb_unpack_data_free(ldb, &msg2);
return ret;
failed:
- free(tdb_key.dptr);
+ ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
- ltdb_unpack_data_free(&msg2);
+ ltdb_unpack_data_free(ldb, &msg2);
return -1;
}
@@ -542,8 +550,11 @@ failed:
*/
static int ltdb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
{
+ struct ltdb_private *ltdb = ldb->private_data;
int ret;
+ ltdb->last_err_string = NULL;
+
if (ltdb_lock(ldb) != 0) {
return -1;
}
@@ -572,10 +583,13 @@ static int ltdb_close(struct ldb_context *ldb)
struct ltdb_private *ltdb = ldb->private_data;
int ret;
+ ltdb->last_err_string = NULL;
+
ltdb_cache_free(ldb);
+ ldb_set_alloc(ldb, NULL, NULL);
ret = tdb_close(ltdb->tdb);
- free(ltdb);
+ ldb_free(ldb, ltdb);
free(ldb);
return ret;
}
@@ -587,6 +601,9 @@ static int ltdb_close(struct ldb_context *ldb)
static const char *ltdb_errstring(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
+ if (ltdb->last_err_string) {
+ return ltdb->last_err_string;
+ }
return tdb_errorstr(ltdb->tdb);
}
@@ -598,7 +615,8 @@ static const struct ldb_backend_ops ltdb_ops = {
ltdb_add,
ltdb_modify,
ltdb_delete,
- ltdb_errstring
+ ltdb_errstring,
+ ltdb_cache_free
};
@@ -615,6 +633,12 @@ struct ldb_context *ltdb_connect(const char *url,
TDB_CONTEXT *tdb;
struct ldb_context *ldb;
+ ldb = calloc(1, sizeof(struct ldb_context));
+ if (!ldb) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
/* parse the url */
if (strchr(url, ':')) {
if (strncmp(url, "tdb://", 6) != 0) {
@@ -637,12 +661,14 @@ struct ldb_context *ltdb_connect(const char *url,
/* note that we use quite a large default hash size */
tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
if (!tdb) {
+ free(ldb);
return NULL;
}
- ltdb = malloc_p(struct ltdb_private);
+ ltdb = ldb_malloc_p(ldb, struct ltdb_private);
if (!ltdb) {
tdb_close(tdb);
+ free(ldb);
errno = ENOMEM;
return NULL;
}
@@ -652,14 +678,6 @@ struct ldb_context *ltdb_connect(const char *url,
memset(&ltdb->cache, 0, sizeof(ltdb->cache));
- ldb = malloc_p(struct ldb_context);
- if (!ldb) {
- tdb_close(tdb);
- free(ltdb);
- errno = ENOMEM;
- return NULL;
- }
-
ldb->private_data = ltdb;
ldb->ops = &ltdb_ops;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index e87027db63..c791cbe201 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -19,6 +19,9 @@ struct ltdb_private {
int flags;
} last_attribute;
} cache;
+
+ /* error if an internal ldb+tdb error */
+ const char *last_err_string;
};
/* special record types */