diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-01-02 07:49:29 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:55 -0500 |
commit | 1a988ec9af7960616fb4661b20d86ff05146d836 (patch) | |
tree | 725eb92b6b97133b23972215f5c69117e29c339c /source4/lib/ldb/ldb_tdb | |
parent | 65f96eba32b93ced0717c2639007bba59da55fa4 (diff) | |
download | samba-1a988ec9af7960616fb4661b20d86ff05146d836.tar.gz samba-1a988ec9af7960616fb4661b20d86ff05146d836.tar.bz2 samba-1a988ec9af7960616fb4661b20d86ff05146d836.zip |
r4474: - converted ldb to use talloc internally
- added gcov flags to Makefile.ldb
- expanded ldb test suite to get more coverage
(This used to be commit 0ab98f50a7e0fe15347a99e5c29a6590a87729a0)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb')
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_cache.c | 164 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_index.c | 327 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_match.c | 9 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_pack.c | 26 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_search.c | 185 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 200 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.h | 14 |
7 files changed, 471 insertions, 454 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index a8eb9ae916..e7420c5f7a 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -42,9 +42,8 @@ */ static int ltdb_baseinfo_init(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_message msg; + struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; int ret; @@ -55,60 +54,61 @@ static int ltdb_baseinfo_init(struct ldb_module *module) ltdb->sequence_number = atof(initial_sequence_number); - msg.num_elements = 1; - msg.elements = ⪙ - msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); - if (!msg.dn) { - errno = ENOMEM; - return -1; + msg = talloc_p(ltdb, struct ldb_message); + if (msg == NULL) { + goto failed; } - el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + if (!msg->dn) { + goto failed; + } + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); if (!el.name) { - ldb_free(ldb, msg.dn); - errno = ENOMEM; - return -1; + goto failed; } el.values = &val; el.num_values = 1; el.flags = 0; - val.data = ldb_strdup(ldb, initial_sequence_number); + val.data = talloc_strdup(msg, initial_sequence_number); if (!val.data) { - ldb_free(ldb, el.name); - ldb_free(ldb, msg.dn); - errno = ENOMEM; - return -1; + goto failed; } val.length = 1; - ret = ltdb_store(module, &msg, TDB_INSERT); + ret = ltdb_store(module, msg, TDB_INSERT); - ldb_free(ldb, msg.dn); - ldb_free(ldb, el.name); - ldb_free(ldb, val.data); + talloc_free(msg); return ret; + +failed: + talloc_free(msg); + errno = ENOMEM; + return -1; } /* free any cache records */ -void ltdb_cache_free(struct ldb_module *module) +static void ltdb_cache_free(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - ldb->alloc_ops.alloc = NULL; ltdb->sequence_number = 0; - ltdb_search_dn1_free(module, <db->cache.baseinfo); - ltdb_search_dn1_free(module, <db->cache.indexlist); - ltdb_search_dn1_free(module, <db->cache.subclasses); - ltdb_search_dn1_free(module, <db->cache.attributes); - - ldb_free(ldb, ltdb->cache.last_attribute.name); - memset(<db->cache, 0, sizeof(ltdb->cache)); + talloc_free(ltdb->cache); + ltdb->cache = NULL; +} - ldb->alloc_ops = alloc; +/* + force a cache reload +*/ +int ltdb_cache_reload(struct ldb_module *module) +{ + ltdb_cache_free(module); + return ltdb_cache_load(module); } /* @@ -116,60 +116,78 @@ void ltdb_cache_free(struct ldb_module *module) */ int ltdb_cache_load(struct ldb_module *module) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; double seq; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - ldb->alloc_ops.alloc = NULL; + if (ltdb->cache == NULL) { + ltdb->cache = talloc_zero_p(ltdb, struct ltdb_cache); + if (ltdb->cache == NULL) goto failed; + ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + } - ltdb_search_dn1_free(module, <db->cache.baseinfo); + talloc_free(ltdb->cache->baseinfo); + ltdb->cache->baseinfo = talloc_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->baseinfo == NULL) goto failed; - if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) == -1) { + if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) { goto failed; } /* possibly initialise the baseinfo */ - if (!ltdb->cache.baseinfo.dn) { + if (!ltdb->cache->baseinfo->dn) { if (ltdb_baseinfo_init(module) != 0) { goto failed; } - if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) != 1) { + if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) { goto failed; } } /* if the current internal sequence number is the same as the one in the database then assume the rest of the cache is OK */ - seq = ldb_msg_find_double(<db->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0); + seq = ldb_msg_find_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); if (seq == ltdb->sequence_number) { goto done; } ltdb->sequence_number = seq; - ldb_free(ldb, ltdb->cache.last_attribute.name); - memset(<db->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute)); + talloc_free(ltdb->cache->last_attribute.name); + memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); - ltdb_search_dn1_free(module, <db->cache.indexlist); - ltdb_search_dn1_free(module, <db->cache.subclasses); - ltdb_search_dn1_free(module, <db->cache.attributes); + talloc_free(ltdb->cache->indexlist); + talloc_free(ltdb->cache->subclasses); + talloc_free(ltdb->cache->attributes); - if (ltdb_search_dn1(module, LTDB_INDEXLIST, <db->cache.indexlist) == -1) { + ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { goto failed; } - if (ltdb_search_dn1(module, LTDB_SUBCLASSES, <db->cache.subclasses) == -1) { + + if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) { goto failed; } - if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, <db->cache.attributes) == -1) { + if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) { + goto failed; + } + if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) { goto failed; } done: - ldb->alloc_ops = alloc; return 0; failed: - ldb->alloc_ops = alloc; return -1; } @@ -181,33 +199,37 @@ int ltdb_increase_sequence_number(struct ldb_module *module) { struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct ldb_message msg; + struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; char *s = NULL; int ret; - ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1); + s = talloc_asprintf(ldb, "%.0f", ltdb->sequence_number+1); if (!s) { errno = ENOMEM; return -1; } - msg.num_elements = 1; - msg.elements = ⪙ - msg.dn = ldb_strdup(ldb, LTDB_BASEINFO); - el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER); + msg = talloc_p(ltdb, struct ldb_message); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); el.values = &val; el.num_values = 1; el.flags = LDB_FLAG_MOD_REPLACE; val.data = s; val.length = strlen(s); - ret = ltdb_modify_internal(module, &msg); + ret = ltdb_modify_internal(module, msg); - ldb_free(ldb, s); - ldb_free(ldb, msg.dn); - ldb_free(ldb, el.name); + talloc_free(msg); if (ret == 0) { ltdb->sequence_number += 1; @@ -223,7 +245,6 @@ int ltdb_increase_sequence_number(struct ldb_module *module) */ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; const char *attrs; const struct { @@ -238,11 +259,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) }; size_t len; int i, ret=0; - struct ldb_alloc_ops alloc = ldb->alloc_ops; - if (ltdb->cache.last_attribute.name && - ldb_attr_cmp(ltdb->cache.last_attribute.name, attr_name) == 0) { - return ltdb->cache.last_attribute.flags; + if (ltdb->cache->last_attribute.name && + ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) { + return ltdb->cache->last_attribute.flags; } /* objectclass is a special default case */ @@ -250,7 +270,7 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE; } - attrs = ldb_msg_find_string(<db->cache.attributes, attr_name, NULL); + attrs = ldb_msg_find_string(ltdb->cache->attributes, attr_name, NULL); if (!attrs) { return ret; @@ -270,14 +290,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) attrs += strspn(attrs, " ,"); } - ldb->alloc_ops.alloc = NULL; + talloc_free(ltdb->cache->last_attribute.name); - ldb_free(ldb, ltdb->cache.last_attribute.name); + ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name); + ltdb->cache->last_attribute.flags = ret; - ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name); - ltdb->cache.last_attribute.flags = ret; - - ldb->alloc_ops = alloc; - return ret; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index eaf699be62..ff0cabb0d6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -44,18 +44,6 @@ struct dn_list { }; /* - free a struct dn_list -*/ -static void dn_list_free(struct ldb_context *ldb, struct dn_list *list) -{ - unsigned int i; - for (i=0;i<list->count;i++) { - ldb_free(ldb, list->dn[i]); - } - ldb_free(ldb, list->dn); -} - -/* return the dn key to be used for an index caller frees */ @@ -67,13 +55,13 @@ static char *ldb_dn_key(struct ldb_context *ldb, if (ldb_should_b64_encode(value)) { char *vstr = ldb_base64_encode(ldb, value->data, value->length); if (!vstr) return NULL; - ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr); - ldb_free(ldb, vstr); + ret = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr, vstr); + talloc_free(vstr); return ret; } - ldb_asprintf(ldb, &ret, "%s:%s:%.*s", LTDB_INDEX, attr, value->length, (char *)value->data); - return ret; + return talloc_asprintf(ldb, "%s:%s:%.*s", + LTDB_INDEX, attr, value->length, (char *)value->data); } /* @@ -118,7 +106,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, char *dn = NULL; int ret; unsigned int i, j; - struct ldb_message msg; + struct ldb_message *msg; list->count = 0; list->dn = NULL; @@ -141,39 +129,43 @@ static int ltdb_index_dn_simple(struct ldb_module *module, dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value); if (!dn) return -1; - ret = ltdb_search_dn1(module, dn, &msg); - ldb_free(ldb, dn); + msg = talloc_p(list, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn, msg); + talloc_free(dn); if (ret == 0 || ret == -1) { return ret; } - for (i=0;i<msg.num_elements;i++) { + for (i=0;i<msg->num_elements;i++) { struct ldb_message_element *el; - if (strcmp(msg.elements[i].name, LTDB_IDX) != 0) { + if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { continue; } - el = &msg.elements[i]; + el = &msg->elements[i]; - list->dn = ldb_malloc_array_p(ldb, char *, el->num_values); + list->dn = talloc_array_p(list, char *, el->num_values); if (!list->dn) { break; } for (j=0;j<el->num_values;j++) { list->dn[list->count] = - ldb_strdup(ldb, (char *)el->values[j].data); + talloc_strdup(list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { - dn_list_free(ldb, list); - ltdb_search_dn1_free(module, &msg); + talloc_free(list); return -1; } list->count++; } } - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); @@ -203,30 +195,34 @@ static int ltdb_index_dn_objectclass(struct ldb_module *module, ret = ltdb_index_dn_simple(module, tree, index_list, list); - for (i=0;i<ltdb->cache.subclasses.num_elements;i++) { - struct ldb_message_element *el = <db->cache.subclasses.elements[i]; + for (i=0;i<ltdb->cache->subclasses->num_elements;i++) { + struct ldb_message_element *el = <db->cache->subclasses->elements[i]; if (ldb_attr_cmp(el->name, target) == 0) { unsigned int j; for (j=0;j<el->num_values;j++) { struct ldb_parse_tree tree2; - struct dn_list list2; + struct dn_list *list2; tree2.operation = LDB_OP_SIMPLE; - tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS); + tree2.u.simple.attr = talloc_strdup(list, LTDB_OBJECTCLASS); if (!tree2.u.simple.attr) { return -1; } tree2.u.simple.value = el->values[j]; + list2 = talloc_p(list, struct dn_list); + if (list2 == NULL) { + return -1; + } if (ltdb_index_dn_objectclass(module, &tree2, - index_list, &list2) == 1) { + index_list, list2) == 1) { if (list->count == 0) { - *list = list2; + *list = *list2; ret = 1; } else { - list_union(ldb, list, &list2); - dn_list_free(ldb, &list2); + list_union(ldb, list, list2); + talloc_free(list2); } } - ldb_free(ldb, tree2.u.simple.attr); + talloc_free(tree2.u.simple.attr); } } } @@ -257,35 +253,42 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, static int list_intersect(struct ldb_context *ldb, struct dn_list *list, const struct dn_list *list2) { - struct dn_list list3; + struct dn_list *list3; unsigned int i; if (list->count == 0 || list2->count == 0) { /* 0 & X == 0 */ - dn_list_free(ldb, list); + talloc_free(list); return 0; } - list3.dn = ldb_malloc_array_p(ldb, char *, list->count); - if (!list3.dn) { - dn_list_free(ldb, list); + list3 = talloc_p(ldb, struct dn_list); + if (list3 == NULL) { return -1; } - list3.count = 0; + + list3->dn = talloc_array_p(list3, char *, list->count); + if (!list3->dn) { + talloc_free(list); + talloc_free(list3); + return -1; + } + list3->count = 0; for (i=0;i<list->count;i++) { if (ldb_list_find(list->dn[i], list2->dn, list2->count, sizeof(char *), (comparison_fn_t)strcmp) != -1) { - list3.dn[list3.count] = list->dn[i]; - list3.count++; + list3->dn[list3->count] = talloc_steal(list3->dn, list->dn[i]); + list3->count++; } else { - ldb_free(ldb, list->dn[i]); + talloc_free(list->dn[i]); } } - ldb_free(ldb, list->dn); - list->dn = list3.dn; - list->count = list3.count; + talloc_free(list->dn); + list->dn = talloc_steal(list, list3->dn); + list->count = list3->count; + talloc_free(list3); return 0; } @@ -305,13 +308,13 @@ static int list_union(struct ldb_context *ldb, if (list->count == 0 && list2->count == 0) { /* 0 | 0 == 0 */ - dn_list_free(ldb, list); + talloc_free(list); return 0; } - d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count); + d = talloc_realloc_p(list, list->dn, char *, list->count + list2->count); if (!d) { - dn_list_free(ldb, list); + talloc_free(list); return -1; } list->dn = d; @@ -319,9 +322,9 @@ static int list_union(struct ldb_context *ldb, for (i=0;i<list2->count;i++) { if (ldb_list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]); + list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); if (!list->dn[list->count]) { - dn_list_free(ldb, list); + talloc_free(list); return -1; } list->count++; @@ -358,39 +361,48 @@ static int ltdb_index_dn_or(struct ldb_module *module, list->count = 0; for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list list2; + struct dn_list *list2; int v; - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2); + + list2 = talloc_p(module, struct dn_list); + if (list2 == NULL) { + return -1; + } + + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 || X == X */ if (ret == -1) { ret = 0; } + talloc_free(list2); continue; } if (v == -1) { /* 1 || X == 1 */ - dn_list_free(ldb, list); + talloc_free(list->dn); + talloc_free(list2); return -1; } if (ret == -1) { ret = 1; - *list = list2; + list->dn = talloc_steal(list, list2->dn); + list->count = list2->count; } else { - if (list_union(ldb, list, &list2) == -1) { - dn_list_free(ldb, &list2); + if (list_union(ldb, list, list2) == -1) { + talloc_free(list2); return -1; } - dn_list_free(ldb, &list2); ret = 1; } + talloc_free(list2); } if (list->count == 0) { - dn_list_free(ldb, list); + talloc_free(list); return 0; } @@ -434,33 +446,44 @@ static int ltdb_index_dn_and(struct ldb_module *module, list->count = 0; for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list list2; + struct dn_list *list2; int v; - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2); + + list2 = talloc_p(module, struct dn_list); + if (list2 == NULL) { + return -1; + } + + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 && X == 0 */ - dn_list_free(ldb, list); + talloc_free(list->dn); + talloc_free(list2); return 0; } if (v == -1) { + talloc_free(list2); continue; } if (ret == -1) { ret = 1; - *list = list2; + talloc_free(list->dn); + list->dn = talloc_steal(list, list2->dn); + list->count = list2->count; } else { - if (list_intersect(ldb, list, &list2) == -1) { - dn_list_free(ldb, &list2); + if (list_intersect(ldb, list, list2) == -1) { + talloc_free(list2); return -1; } - dn_list_free(ldb, &list2); } + talloc_free(list2); + if (list->count == 0) { - if (list->dn) ldb_free(ldb, list->dn); + talloc_free(list->dn); return 0; } } @@ -514,24 +537,32 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr int count = 0; for (i=0;i<dn_list->count;i++) { - struct ldb_message msg; + struct ldb_message *msg; int ret; - ret = ltdb_search_dn1(module, dn_list->dn[i], &msg); + + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn_list->dn[i], msg); if (ret == 0) { /* the record has disappeared? yes, this can happen */ + talloc_free(msg); continue; } if (ret == -1) { /* an internal error */ + talloc_free(msg); return -1; } ret = 0; - if (ltdb_message_match(module, &msg, tree, base, scope) == 1) { - ret = ltdb_add_attr_results(module, &msg, attrs, &count, res); + if (ltdb_message_match(module, msg, tree, base, scope) == 1) { + ret = ltdb_add_attr_results(module, msg, attrs, &count, res); } - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); if (ret != 0) { return -1; } @@ -551,26 +582,31 @@ int ltdb_search_indexed(struct ldb_module *module, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - struct dn_list dn_list; + struct dn_list *dn_list; int ret; - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no index list? must do full search */ return -1; } - ret = ltdb_index_dn(module, tree, <db->cache.indexlist, &dn_list); + dn_list = talloc_p(module, struct dn_list); + if (dn_list == NULL) { + return -1; + } + + ret = ltdb_index_dn(module, tree, ltdb->cache->indexlist, dn_list); if (ret == 1) { /* we've got a candidate list - now filter by the full tree and extract the needed attributes */ - ret = ldb_index_filter(module, tree, base, scope, &dn_list, + ret = ldb_index_filter(module, tree, base, scope, dn_list, attrs, res); - dn_list_free(ldb, &dn_list); } + talloc_free(dn_list); + return ret; } @@ -585,19 +621,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, struct ldb_message_element *el2; /* add another entry */ - el2 = ldb_realloc_p(ldb, msg->elements, - struct ldb_message_element, msg->num_elements+1); + el2 = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!el2) { return -1; } msg->elements = el2; - msg->elements[msg->num_elements].name = ldb_strdup(ldb, LTDB_IDX); + msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX); if (!msg->elements[msg->num_elements].name) { return -1; } msg->elements[msg->num_elements].num_values = 0; - msg->elements[msg->num_elements].values = ldb_malloc_p(ldb, struct ldb_val); + msg->elements[msg->num_elements].values = talloc_p(msg->elements, struct ldb_val); if (!msg->elements[msg->num_elements].values) { return -1; } @@ -630,9 +666,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } } - v2 = ldb_realloc_p(ldb, msg->elements[idx].values, - struct ldb_val, - msg->elements[idx].num_values+1); + v2 = talloc_realloc_p(msg->elements, msg->elements[idx].values, + struct ldb_val, + msg->elements[idx].num_values+1); if (!v2) { return -1; } @@ -652,9 +688,9 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; - struct ldb_message msg; + struct ldb_message *msg; char *dn_key; - int ret, added=0, added_dn=0; + int ret; unsigned int i; dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); @@ -662,52 +698,45 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, return -1; } - ret = ltdb_search_dn1(module, dn_key, &msg); + msg = talloc_p(dn_key, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_search_dn1(module, dn_key, msg); if (ret == -1) { - ldb_free(ldb, dn_key); + talloc_free(dn_key); return -1; } if (ret == 0) { - added_dn = 1; - msg.dn = ldb_strdup(ldb, dn_key); - if (!msg.dn) { - ldb_free(ldb, dn_key); + msg->dn = talloc_strdup(msg, dn_key); + if (!msg->dn) { + talloc_free(dn_key); errno = ENOMEM; return -1; } - msg.num_elements = 0; - msg.elements = NULL; - msg.private_data = NULL; + msg->num_elements = 0; + msg->elements = NULL; } - ldb_free(ldb, dn_key); - - for (i=0;i<msg.num_elements;i++) { - if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) { + for (i=0;i<msg->num_elements;i++) { + if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) { break; } } - if (i == msg.num_elements) { - added = 1; - ret = ltdb_index_add1_new(ldb, &msg, el, dn); + if (i == msg->num_elements) { + ret = ltdb_index_add1_new(ldb, msg, el, dn); } else { - ret = ltdb_index_add1_add(ldb, &msg, el, i, dn); + ret = ltdb_index_add1_add(ldb, msg, el, i, dn); } if (ret == 0) { - ret = ltdb_store(module, &msg, TDB_REPLACE); + ret = ltdb_store(module, msg, TDB_REPLACE); } - if (added) { - ldb_free(ldb, msg.elements[i].name); - } - if (added_dn) { - ldb_free(ldb, msg.dn); - } - - ltdb_search_dn1_free(module, &msg); + talloc_free(dn_key); return ret; } @@ -722,13 +751,13 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) int ret; unsigned int i, j; - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no indexed fields */ return 0; } for (i=0;i<msg->num_elements;i++) { - ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name, + ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; @@ -752,7 +781,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; - struct ldb_message msg; + struct ldb_message *msg; char *dn_key; int ret, i; unsigned int j; @@ -762,44 +791,48 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, return -1; } - ret = ltdb_search_dn1(module, dn_key, &msg); + msg = talloc_p(dn_key, struct ldb_message); + if (msg == NULL) { + talloc_free(dn_key); + return -1; + } + + ret = ltdb_search_dn1(module, dn_key, msg); if (ret == -1) { - ldb_free(ldb, dn_key); + talloc_free(dn_key); return -1; } if (ret == 0) { /* it wasn't indexed. Did we have an earlier error? If we did then its gone now */ - ldb_free(ldb, dn_key); + talloc_free(dn_key); return 0; } - i = ldb_msg_find_idx(&msg, dn, &j, LTDB_IDX); + i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); if (i == -1) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: dn %s not found in %s\n", dn, dn_key); /* it ain't there. hmmm */ - ltdb_search_dn1_free(module, &msg); - ldb_free(ldb, dn_key); + talloc_free(dn_key); return 0; } - if (j != msg.elements[i].num_values - 1) { - memmove(&msg.elements[i].values[j], - &msg.elements[i].values[j+1], - (msg.elements[i].num_values-(j+1)) * - sizeof(msg.elements[i].values[0])); + if (j != msg->elements[i].num_values - 1) { + memmove(&msg->elements[i].values[j], + &msg->elements[i].values[j+1], + (msg->elements[i].num_values-(j+1)) * + sizeof(msg->elements[i].values[0])); } - msg.elements[i].num_values--; + msg->elements[i].num_values--; - if (msg.elements[i].num_values == 0) { + if (msg->elements[i].num_values == 0) { ret = ltdb_delete_noindex(module, dn_key); } else { - ret = ltdb_store(module, &msg, TDB_REPLACE); + ret = ltdb_store(module, msg, TDB_REPLACE); } - ltdb_search_dn1_free(module, &msg); - ldb_free(ldb, dn_key); + talloc_free(dn_key); return ret; } @@ -815,13 +848,13 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) unsigned int i, j; /* find the list of indexed fields */ - if (ltdb->cache.indexlist.num_elements == 0) { + if (ltdb->cache->indexlist->num_elements == 0) { /* no indexed fields */ return 0; } for (i=0;i<msg->num_elements;i++) { - ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name, + ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; @@ -856,7 +889,7 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, vo static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ldb_module *module = state; - struct ldb_message msg; + struct ldb_message *msg; int ret; if (strncmp(key.dptr, "DN=@", 4) == 0 || @@ -864,18 +897,24 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * return 0; } - ret = ltdb_unpack_data(module, &data, &msg); + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_unpack_data(module, &data, msg); if (ret != 0) { + talloc_free(msg); return -1; } - if (!msg.dn) { - msg.dn = key.dptr+3; + if (!msg->dn) { + msg->dn = key.dptr+3; } - ret = ltdb_index_add(module, &msg); + ret = ltdb_index_add(module, msg); - ltdb_unpack_data_free(module, &msg); + talloc_free(msg); return ret; } @@ -888,9 +927,7 @@ int ltdb_reindex(struct ldb_module *module) struct ltdb_private *ltdb = module->private_data; int ret; - ltdb_cache_free(module); - - if (ltdb_cache_load(module) != 0) { + if (ltdb_cache_reload(module) != 0) { return -1; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c index 4a51cfddf0..3bb63e2b5b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_match.c +++ b/source4/lib/ldb/ldb_tdb/ldb_match.c @@ -93,13 +93,14 @@ static int ltdb_val_equal_wildcard_ci(struct ldb_module *module, s2 = ldb_casefold(ldb, v2->data); if (!s2) { + talloc_free(s1); return -1; } ret = fnmatch(s2, s1, 0); - ldb_free(ldb, s1); - ldb_free(ldb, s2); + talloc_free(s1); + talloc_free(s2); if (ret == 0) { return 1; @@ -149,8 +150,8 @@ static int ltdb_val_equal_objectclass(struct ldb_module *module, return 1; } - for (i=0;i<ltdb->cache.subclasses.num_elements;i++) { - struct ldb_message_element *el = <db->cache.subclasses.elements[i]; + for (i=0;i<ltdb->cache->subclasses->num_elements;i++) { + struct ldb_message_element *el = <db->cache->subclasses->elements[i]; if (ldb_attr_cmp(el->name, v2->data) == 0) { unsigned int j; for (j=0;j<el->num_values;j++) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 9515beeaa7..a548a4189b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -99,7 +99,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = ldb_malloc(ldb, size); + data->dptr = talloc_array_p(ldb, char, size); if (!data->dptr) { errno = ENOMEM; return -1; @@ -144,25 +144,14 @@ int ltdb_pack_data(struct ldb_module *module, void ltdb_unpack_data_free(struct ldb_module *module, struct ldb_message *message) { - struct ldb_context *ldb = module->ldb; - unsigned int i; - - for (i=0;i<message->num_elements;i++) { - if (message->elements[i].values) ldb_free(ldb, message->elements[i].values); - } - if (message->elements) ldb_free(ldb, message->elements); + talloc_free(message->elements); } /* unpack a ldb message from a linear buffer in TDB_DATA - note that this does not fill in the class and key elements - - caller frees. Memory for the elements[] and values[] arrays are - malloced, but the memory for the elements is re-used from the - TDB_DATA data. This means the caller only has to free the elements - and values arrays. This can be done with ltdb_unpack_data_free() + Free with ltdb_unpack_data_free() */ int ltdb_unpack_data(struct ldb_module *module, const struct TDB_DATA *data, @@ -220,8 +209,7 @@ int ltdb_unpack_data(struct ldb_module *module, goto failed; } - message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, - message->num_elements); + message->elements = talloc_array_p(ldb, struct ldb_message_element, message->num_elements); if (!message->elements) { errno = ENOMEM; goto failed; @@ -247,9 +235,9 @@ int ltdb_unpack_data(struct ldb_module *module, message->elements[i].num_values = pull_uint32(p, 0); message->elements[i].values = NULL; if (message->elements[i].num_values != 0) { - message->elements[i].values = ldb_malloc_array_p(ldb, - struct ldb_val, - message->elements[i].num_values); + message->elements[i].values = talloc_array_p(message->elements, + struct ldb_val, + message->elements[i].num_values); if (!message->elements[i].values) { errno = ENOMEM; goto failed; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 27718a4c86..720188b74c 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -39,25 +39,6 @@ #include "ldb/include/ldb_parse.h" /* - free a message that has all parts separately allocated -*/ -static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg) -{ - unsigned int i, j; - ldb_free(ldb, msg->dn); - for (i=0;i<msg->num_elements;i++) { - ldb_free(ldb, msg->elements[i].name); - for (j=0;j<msg->elements[i].num_values;j++) { - ldb_free(ldb, msg->elements[i].values[j].data); - } - ldb_free(ldb, msg->elements[i].values); - } - ldb_free(ldb, msg->elements); - ldb_free(ldb, msg); -} - - -/* add one element to a message */ static int msg_add_element(struct ldb_context *ldb, @@ -66,7 +47,7 @@ static int msg_add_element(struct ldb_context *ldb, unsigned int i; struct ldb_message_element *e2, *elnew; - e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1); + e2 = talloc_realloc_p(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); if (!e2) { return -1; } @@ -74,13 +55,13 @@ static int msg_add_element(struct ldb_context *ldb, elnew = &e2[ret->num_elements]; - elnew->name = ldb_strdup(ldb, el->name); + elnew->name = talloc_strdup(ret->elements, el->name); if (!elnew->name) { return -1; } if (el->num_values) { - elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); + elnew->values = talloc_array_p(ret->elements, struct ldb_val, el->num_values); if (!elnew->values) { return -1; } @@ -89,7 +70,7 @@ static int msg_add_element(struct ldb_context *ldb, } for (i=0;i<el->num_values;i++) { - elnew->values[i] = ldb_val_dup(ldb, &el->values[i]); + elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); if (elnew->values[i].length != el->values[i].length) { return -1; } @@ -136,24 +117,23 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, struct ldb_message *ret; int i; - ret = ldb_malloc_p(ldb, struct ldb_message); + ret = talloc_p(ldb, struct ldb_message); if (!ret) { return NULL; } - ret->dn = ldb_strdup(ldb, msg->dn); + ret->dn = talloc_strdup(ret, msg->dn); if (!ret->dn) { - ldb_free(ldb, ret); + talloc_free(ret); return NULL; } ret->num_elements = 0; ret->elements = NULL; - ret->private_data = NULL; if (!attrs) { if (msg_add_all_elements(module, ret, msg) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } return ret; @@ -164,7 +144,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, if (strcmp(attrs[i], "*") == 0) { if (msg_add_all_elements(module, ret, msg) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } continue; @@ -175,10 +155,9 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, struct ldb_val val; el2.flags = 0; - el2.name = ldb_strdup(ldb, "dn"); + el2.name = talloc_strdup(ret, "dn"); if (!el2.name) { - msg_free_all_parts(ldb, ret); - ldb_free(ldb, el2.name); + talloc_free(ret); return NULL; } el2.num_values = 1; @@ -187,11 +166,10 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, val.length = strlen(ret->dn); if (msg_add_element(ldb, ret, &el2) != 0) { - msg_free_all_parts(ldb, ret); - ldb_free(ldb, el2.name); + talloc_free(ret); return NULL; } - ldb_free(ldb, el2.name); + talloc_free(el2.name); continue; } @@ -200,7 +178,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, continue; } if (msg_add_element(ldb, ret, el) != 0) { - msg_free_all_parts(ldb, ret); + talloc_free(ret); return NULL; } } @@ -238,22 +216,6 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, /* - free the results of a ltdb_search_dn1 search -*/ -void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - ldb_free(ldb, msg->private_data); - for (i=0;i<msg->num_elements;i++) { - ldb_free(ldb, msg->elements[i].values); - } - ldb_free(ldb, msg->elements); - memset(msg, 0, sizeof(*msg)); -} - - -/* search the database for a single simple dn, returning all attributes in a single message @@ -261,7 +223,6 @@ void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg) */ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_message *msg) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; int ret; TDB_DATA tdb_key, tdb_data, tdb_data2; @@ -275,35 +236,32 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag } tdb_data = tdb_fetch(ltdb->tdb, tdb_key); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); if (!tdb_data.dptr) { return 0; } - tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize); + tdb_data2.dptr = talloc_memdup(msg, tdb_data.dptr, tdb_data.dsize); + free(tdb_data.dptr); if (!tdb_data2.dptr) { - free(tdb_data.dptr); return -1; } - memcpy(tdb_data2.dptr, tdb_data.dptr, tdb_data.dsize); - free(tdb_data.dptr); tdb_data2.dsize = tdb_data.dsize; - msg->private_data = tdb_data2.dptr; msg->num_elements = 0; msg->elements = NULL; ret = ltdb_unpack_data(module, &tdb_data2, msg); if (ret == -1) { - ldb_free(ldb, tdb_data2.dptr); + talloc_free(tdb_data2.dptr); return -1; } if (!msg->dn) { - msg->dn = ldb_strdup(ldb, dn); + msg->dn = talloc_strdup(tdb_data2.dptr, dn); } if (!msg->dn) { - ldb_free(ldb, tdb_data2.dptr); + talloc_free(tdb_data2.dptr); return -1; } @@ -319,27 +277,35 @@ int ltdb_search_dn(struct ldb_module *module, char *dn, { struct ldb_context *ldb = module->ldb; int ret; - struct ldb_message msg, *msg2; + struct ldb_message *msg, *msg2; + + *res = talloc_array_p(ldb, struct ldb_message *, 2); + if (! *res) { + return -1; + } - ret = ltdb_search_dn1(module, dn, &msg); + msg = talloc_p(*res, struct ldb_message); + if (msg == NULL) { + talloc_free(*res); + *res = NULL; + return -1; + } + + ret = ltdb_search_dn1(module, dn, msg); if (ret != 1) { + talloc_free(*res); + *res = NULL; return ret; } - msg2 = ltdb_pull_attrs(module, &msg, attrs); + msg2 = ltdb_pull_attrs(module, msg, attrs); - ltdb_search_dn1_free(module, &msg); + talloc_free(msg); if (!msg2) { return -1; } - *res = ldb_malloc_array_p(ldb, struct ldb_message *, 2); - if (! *res) { - msg_free_all_parts(ldb, msg2); - return -1; - } - (*res)[0] = msg2; (*res)[1] = NULL; @@ -367,9 +333,9 @@ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, } /* add to the results list */ - res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2); + res2 = talloc_realloc_p(ldb, *res, struct ldb_message *, (*count)+2); if (!res2) { - msg_free_all_parts(ldb, msg2); + talloc_free(msg2); return -1; } @@ -404,7 +370,7 @@ struct ltdb_search_info { static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ltdb_search_info *sinfo = state; - struct ldb_message msg; + struct ldb_message *msg; int ret; if (key.dsize < 4 || @@ -412,31 +378,37 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi return 0; } + msg = talloc_p(sinfo, struct ldb_message); + if (msg == NULL) { + return -1; + } + /* unpack the record */ - ret = ltdb_unpack_data(sinfo->module, &data, &msg); + ret = ltdb_unpack_data(sinfo->module, &data, msg); if (ret == -1) { sinfo->failures++; + talloc_free(msg); return 0; } - if (!msg.dn) { - msg.dn = key.dptr + 3; + if (!msg->dn) { + msg->dn = key.dptr + 3; } /* see if it matches the given expression */ - if (!ltdb_message_match(sinfo->module, &msg, sinfo->tree, - sinfo->base, sinfo->scope)) { - ltdb_unpack_data_free(sinfo->module, &msg); + if (!ltdb_message_match(sinfo->module, msg, sinfo->tree, + sinfo->base, sinfo->scope)) { + talloc_free(msg); return 0; } - ret = ltdb_add_attr_results(sinfo->module, &msg, sinfo->attrs, &sinfo->count, &sinfo->msgs); + ret = ltdb_add_attr_results(sinfo->module, msg, sinfo->attrs, &sinfo->count, &sinfo->msgs); if (ret == -1) { sinfo->failures++; } - ltdb_unpack_data_free(sinfo->module, &msg); + talloc_free(msg); return ret; } @@ -447,19 +419,11 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi */ int ltdb_search_free(struct ldb_module *module, struct ldb_message **msgs) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; - int i; ltdb->last_err_string = NULL; - if (!msgs) return 0; - - for (i=0;msgs[i];i++) { - msg_free_all_parts(ldb, msgs[i]); - } - - ldb_free(ldb, msgs); + talloc_free(msgs); return 0; } @@ -475,27 +439,36 @@ static int ltdb_search_full(struct ldb_module *module, const char * const attrs[], struct ldb_message ***res) { struct ltdb_private *ltdb = module->private_data; - int ret; - struct ltdb_search_info sinfo; + int ret, count; + struct ltdb_search_info *sinfo; + + sinfo = talloc_p(ltdb, struct ltdb_search_info); + if (sinfo == NULL) { + return -1; + } - sinfo.tree = tree; - sinfo.module = module; - sinfo.scope = scope; - sinfo.base = base; - sinfo.attrs = attrs; - sinfo.msgs = NULL; - sinfo.count = 0; - sinfo.failures = 0; + sinfo->tree = tree; + sinfo->module = module; + sinfo->scope = scope; + sinfo->base = base; + sinfo->attrs = attrs; + sinfo->msgs = NULL; + sinfo->count = 0; + sinfo->failures = 0; - ret = tdb_traverse(ltdb->tdb, search_func, &sinfo); + ret = tdb_traverse(ltdb->tdb, search_func, sinfo); if (ret == -1) { - ltdb_search_free(module, sinfo.msgs); + talloc_free(sinfo); return -1; } - *res = sinfo.msgs; - return sinfo.count; + *res = talloc_steal(ltdb, sinfo->msgs); + count = sinfo->count; + + talloc_free(sinfo); + + return count; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 179b205097..288633cb01 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -75,7 +75,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) if (strncmp(dn, prefix, strlen(prefix)) == 0 && (s = strchr(dn+strlen(prefix), ':'))) { char *attr_name, *attr_name_folded; - attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix)))); + attr_name = talloc_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix)))); if (!attr_name) { goto failed; } @@ -88,12 +88,12 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) if (!attr_name_folded) { goto failed; } - ldb_asprintf(ldb, &dn_folded, "%s:%s:%s", - prefix, attr_name_folded, - s+1); - ldb_free(ldb, attr_name_folded); + dn_folded = talloc_asprintf(ldb, "%s:%s:%s", + prefix, attr_name_folded, + s+1); + talloc_free(attr_name_folded); } - ldb_free(ldb, attr_name); + talloc_free(attr_name); } else { dn_folded = ldb_casefold(ldb, dn); } @@ -102,8 +102,8 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) goto failed; } - ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded); - ldb_free(ldb, dn_folded); + key_str = talloc_asprintf(ldb, "DN=%s", dn_folded); + talloc_free(dn_folded); if (!key_str) { goto failed; @@ -126,7 +126,6 @@ failed: */ static int ltdb_lock(struct ldb_module *module, const char *lockname) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA key; int ret; @@ -142,7 +141,7 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) ret = tdb_chainlock(ltdb->tdb, key); - ldb_free(ldb, key.dptr); + talloc_free(key.dptr); return ret; } @@ -152,7 +151,6 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) */ static int ltdb_unlock(struct ldb_module *module, const char *lockname) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA key; @@ -167,7 +165,7 @@ static int ltdb_unlock(struct ldb_module *module, const char *lockname) tdb_chainunlock(ltdb->tdb, key); - ldb_free(ldb, key.dptr); + talloc_free(key.dptr); return 0; } @@ -199,7 +197,6 @@ static int ltdb_modified(struct ldb_module *module, const char *dn) */ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key, tdb_data; int ret; @@ -211,7 +208,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg ret = ltdb_pack_data(module, msg, &tdb_data); if (ret == -1) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); return -1; } @@ -226,8 +223,8 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg } done: - ldb_free(ldb, tdb_key.dptr); - ldb_free(ldb, tdb_data.dptr); + talloc_free(tdb_key.dptr); + talloc_free(tdb_data.dptr); return ret; } @@ -269,7 +266,6 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg) */ int ltdb_delete_noindex(struct ldb_module *module, const char *dn) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key; int ret; @@ -280,7 +276,7 @@ int ltdb_delete_noindex(struct ldb_module *module, const char *dn) } ret = tdb_delete(ltdb->tdb, tdb_key); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); return ret; } @@ -292,7 +288,7 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) { struct ltdb_private *ltdb = module->private_data; int ret; - struct ldb_message msg; + struct ldb_message *msg = NULL; ltdb->last_err_string = NULL; @@ -301,13 +297,17 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) } if (ltdb_cache_load(module) != 0) { - ltdb_unlock(module, LDBLOCK); - return -1; + goto failed; + } + + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + goto failed; } /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, dn, &msg); + ret = ltdb_search_dn1(module, dn, msg); if (ret != 1) { /* not finding the old record is an error */ goto failed; @@ -315,23 +315,22 @@ static int ltdb_delete(struct ldb_module *module, const char *dn) ret = ltdb_delete_noindex(module, dn); if (ret == -1) { - ltdb_search_dn1_free(module, &msg); goto failed; } /* remove any indexed attributes */ - ret = ltdb_index_del(module, &msg); - - ltdb_search_dn1_free(module, &msg); + ret = ltdb_index_del(module, msg); if (ret == 0) { ltdb_modified(module, dn); } + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return ret; failed: + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return -1; } @@ -369,8 +368,8 @@ static int msg_add_element(struct ldb_context *ldb, struct ldb_message_element *e2; unsigned int i; - e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element, - msg->num_elements+1); + e2 = talloc_realloc_p(msg, msg->elements, struct ldb_message_element, + msg->num_elements+1); if (!e2) { errno = ENOMEM; return -1; @@ -384,7 +383,7 @@ static int msg_add_element(struct ldb_context *ldb, e2->flags = el->flags; e2->values = NULL; if (el->num_values != 0) { - e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values); + e2->values = talloc_array_p(msg->elements, struct ldb_val, el->num_values); if (!e2->values) { errno = ENOMEM; return -1; @@ -407,30 +406,28 @@ static int msg_delete_attribute(struct ldb_module *module, struct ldb_context *ldb, struct ldb_message *msg, const char *name) { - unsigned int i, j, count=0; - struct ldb_message_element *el2; - - el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements); - if (!el2) { - errno = ENOMEM; - return -1; - } + unsigned int i, j; for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) != 0) { - el2[count++] = msg->elements[i]; - } else { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { for (j=0;j<msg->elements[i].num_values;j++) { ltdb_index_del_value(module, msg->dn, &msg->elements[i], j); } - ldb_free(ldb, msg->elements[i].values); + talloc_free(msg->elements[i].values); + if (msg->num_elements > (i+1)) { + memmove(&msg->elements[i], + &msg->elements[i+1], + sizeof(struct ldb_message_element)* + (msg->num_elements - (i+1))); + } + msg->num_elements--; + i--; + msg->elements = talloc_realloc_p(msg, msg->elements, + struct ldb_message_element, + msg->num_elements); } } - msg->num_elements = count; - ldb_free(ldb, msg->elements); - msg->elements = el2; - return 0; } @@ -486,7 +483,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key, tdb_data; - struct ldb_message msg2; + struct ldb_message *msg2; unsigned i, j; int ret; @@ -497,19 +494,25 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms tdb_data = tdb_fetch(ltdb->tdb, tdb_key); if (!tdb_data.dptr) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); + return -1; + } + + msg2 = talloc_p(tdb_key.dptr, struct ldb_message); + if (msg2 == NULL) { + talloc_free(tdb_key.dptr); return -1; } - ret = ltdb_unpack_data(module, &tdb_data, &msg2); + ret = ltdb_unpack_data(module, &tdb_data, msg2); if (ret == -1) { - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); return -1; } - if (!msg2.dn) { - msg2.dn = msg->dn; + if (!msg2->dn) { + msg2->dn = msg->dn; } for (i=0;i<msg->num_elements;i++) { @@ -522,16 +525,16 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms case LDB_FLAG_MOD_ADD: /* add this element to the message. fail if it already exists */ - ret = find_element(&msg2, el->name); + ret = find_element(msg2, el->name); if (ret == -1) { - if (msg_add_element(ldb, &msg2, el) != 0) { + if (msg_add_element(ldb, msg2, el) != 0) { goto failed; } continue; } - el2 = &msg2.elements[ret]; + el2 = &msg2->elements[ret]; /* An attribute with this name already exists, add all * values if they don't already exist. */ @@ -544,15 +547,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } } - vals = ldb_realloc_p(ldb, el2->values, struct ldb_val, - el2->num_values + el->num_values); + vals = talloc_realloc_p(msg2->elements, el2->values, struct ldb_val, + el2->num_values + el->num_values); if (vals == NULL) goto failed; for (j=0;j<el->num_values;j++) { vals[el2->num_values + j] = - ldb_val_dup(ldb, &el->values[j]); + ldb_val_dup(vals, &el->values[j]); } el2->values = vals; @@ -563,11 +566,11 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms case LDB_FLAG_MOD_REPLACE: /* replace all elements of this attribute name with the elements listed. The attribute not existing is not an error */ - msg_delete_attribute(module, ldb, &msg2, msg->elements[i].name); + msg_delete_attribute(module, ldb, msg2, msg->elements[i].name); /* add the replacement element, if not empty */ if (msg->elements[i].num_values != 0 && - msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { + msg_add_element(ldb, msg2, &msg->elements[i]) != 0) { goto failed; } break; @@ -576,7 +579,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms /* we could be being asked to delete all values or just some values */ if (msg->elements[i].num_values == 0) { - if (msg_delete_attribute(module, ldb, &msg2, + if (msg_delete_attribute(module, ldb, msg2, msg->elements[i].name) != 0) { ltdb->last_err_string = "No such attribute"; goto failed; @@ -585,7 +588,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } for (j=0;j<msg->elements[i].num_values;j++) { if (msg_delete_element(module, - &msg2, + msg2, msg->elements[i].name, &msg->elements[i].values[j]) != 0) { ltdb->last_err_string = "No such attribute"; @@ -600,17 +603,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } /* we've made all the mods - save the modified record back into the database */ - ret = ltdb_store(module, &msg2, TDB_MODIFY); + ret = ltdb_store(module, msg2, TDB_MODIFY); - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(module, &msg2); return ret; failed: - ldb_free(ldb, tdb_key.dptr); + talloc_free(tdb_key.dptr); free(tdb_data.dptr); - ltdb_unpack_data_free(module, &msg2); return -1; } @@ -649,10 +650,9 @@ static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg) */ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn) { - struct ldb_context *ldb = module->ldb; struct ltdb_private *ltdb = module->private_data; int ret; - struct ldb_message msg; + struct ldb_message *msg; const char *error_str; ltdb->last_err_string = NULL; @@ -661,28 +661,28 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char return -1; } + msg = talloc_p(module, struct ldb_message); + if (msg == NULL) { + goto failed; + } + /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, olddn, &msg); + ret = ltdb_search_dn1(module, olddn, msg); if (ret != 1) { /* not finding the old record is an error */ goto failed; } - msg.dn = ldb_strdup(ldb,newdn); - if (!msg.dn) { - ltdb_search_dn1_free(module, &msg); + msg->dn = talloc_strdup(msg, newdn); + if (!msg->dn) { goto failed; } - ret = ltdb_add(module, &msg); + ret = ltdb_add(module, msg); if (ret == -1) { - ldb_free(ldb, msg.dn); - ltdb_search_dn1_free(module, &msg); goto failed; } - ldb_free(ldb, msg.dn); - ltdb_search_dn1_free(module, &msg); ret = ltdb_delete(module, olddn); error_str = ltdb->last_err_string; @@ -692,10 +692,13 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char ltdb->last_err_string = error_str; + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return ret; + failed: + talloc_free(msg); ltdb_unlock(module, LDBLOCK); return -1; } @@ -706,18 +709,8 @@ failed: static int ltdb_close(struct ldb_module *module) { struct ldb_context *ldb = module->ldb; - struct ltdb_private *ltdb = module->private_data; - int ret; - - ltdb->last_err_string = NULL; - - ltdb_cache_free(module); - ldb_set_alloc(ldb, NULL, NULL); - - ret = tdb_close(ltdb->tdb); - ldb_free(ldb, ltdb); - free(ldb); - return ret; + talloc_free(ldb); + return 0; } @@ -745,12 +738,21 @@ static const struct ldb_module_ops ltdb_ops = { ltdb_rename, ltdb_lock, ltdb_unlock, - ltdb_errstring, - ltdb_cache_free + ltdb_errstring }; /* + destroy the ltdb context +*/ +static int ltdb_destructor(void *p) +{ + struct ltdb_private *ltdb = p; + tdb_close(ltdb->tdb); + return 0; +} + +/* connect to the database */ struct ldb_context *ltdb_connect(const char *url, @@ -763,7 +765,7 @@ struct ldb_context *ltdb_connect(const char *url, TDB_CONTEXT *tdb; struct ldb_context *ldb; - ldb = calloc(1, sizeof(struct ldb_context)); + ldb = talloc_zero_p(NULL, struct ldb_context); if (!ldb) { errno = ENOMEM; return NULL; @@ -773,6 +775,7 @@ struct ldb_context *ltdb_connect(const char *url, if (strchr(url, ':')) { if (strncmp(url, "tdb://", 6) != 0) { errno = EINVAL; + talloc_free(ldb); return NULL; } path = url+6; @@ -791,14 +794,14 @@ struct ldb_context *ltdb_connect(const char *url, /* note that we use quite a large default hash size */ tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666); if (!tdb) { - free(ldb); + talloc_free(ldb); return NULL; } - ltdb = ldb_malloc_p(ldb, struct ltdb_private); + ltdb = talloc_zero_p(ldb, struct ltdb_private); if (!ltdb) { tdb_close(tdb); - free(ldb); + talloc_free(ldb); errno = ENOMEM; return NULL; } @@ -806,12 +809,11 @@ struct ldb_context *ltdb_connect(const char *url, ltdb->tdb = tdb; ltdb->sequence_number = 0; - memset(<db->cache, 0, sizeof(ltdb->cache)); + talloc_set_destructor(ltdb, ltdb_destructor); - ldb->modules = ldb_malloc_p(ldb, struct ldb_module); + ldb->modules = talloc_p(ldb, struct ldb_module); if (!ldb->modules) { - tdb_close(tdb); - free(ldb); + talloc_free(ldb); errno = ENOMEM; return NULL; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 7d6f35dc79..49052550d0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -13,17 +13,17 @@ struct ltdb_private { handling. It has plenty of digits of precision */ double sequence_number; - struct { - struct ldb_message baseinfo; - struct ldb_message indexlist; - struct ldb_message attributes; - struct ldb_message subclasses; + struct ltdb_cache { + struct ldb_message *baseinfo; + struct ldb_message *indexlist; + struct ldb_message *attributes; + struct ldb_message *subclasses; struct { char *name; int flags; } last_attribute; - } cache; + } *cache; /* error if an internal ldb+tdb error */ const char *last_err_string; @@ -51,7 +51,7 @@ struct ltdb_private { /* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ -void ltdb_cache_free(struct ldb_module *module); +int ltdb_cache_reload(struct ldb_module *module); int ltdb_cache_load(struct ldb_module *module); int ltdb_increase_sequence_number(struct ldb_module *module); int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name); |