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