From 3e2c696e45b24b0192ab7b1ddaf1dd4d79571609 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Sep 2006 02:49:04 +0000 Subject: r18866: Jeremy and Volker have given the go-ahead on the group mapping ldb code. Yay! This first commit copies lib/ldb/ from Samba4. A huge congratulations should go to Simo on this - he has put an enormous amount of work into ldb, and it's great to see it go into the Samba3 tree. (This used to be commit bbedf2e34315f5c420a3a05dfe22b1d5cf79f042) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 545 +++++++++++++++ source3/lib/ldb/ldb_tdb/ldb_index.c | 1159 ++++++++++++++++++++++++++++++++ source3/lib/ldb/ldb_tdb/ldb_pack.c | 294 ++++++++ source3/lib/ldb/ldb_tdb/ldb_search.c | 543 +++++++++++++++ source3/lib/ldb/ldb_tdb/ldb_tdb.c | 1065 +++++++++++++++++++++++++++++ source3/lib/ldb/ldb_tdb/ldb_tdb.h | 127 ++++ source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 174 +++++ 7 files changed, 3907 insertions(+) create mode 100644 source3/lib/ldb/ldb_tdb/ldb_cache.c create mode 100644 source3/lib/ldb/ldb_tdb/ldb_index.c create mode 100644 source3/lib/ldb/ldb_tdb/ldb_pack.c create mode 100644 source3/lib/ldb/ldb_tdb/ldb_search.c create mode 100644 source3/lib/ldb/ldb_tdb/ldb_tdb.c create mode 100644 source3/lib/ldb/ldb_tdb/ldb_tdb.h create mode 100644 source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c new file mode 100644 index 0000000000..d6d66dd37f --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -0,0 +1,545 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb tdb cache functions + * + * Description: cache special records in a ldb/tdb + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +#define LTDB_FLAG_CASE_INSENSITIVE (1<<0) +#define LTDB_FLAG_INTEGER (1<<1) +#define LTDB_FLAG_HIDDEN (1<<2) +#define LTDB_FLAG_OBJECTCLASS (1<<3) + +/* valid attribute flags */ +static const struct { + const char *name; + int value; +} ltdb_valid_attr_flags[] = { + { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE }, + { "INTEGER", LTDB_FLAG_INTEGER }, + { "HIDDEN", LTDB_FLAG_HIDDEN }, + { "NONE", 0 }, + { NULL, 0 } +}; + + +/* + de-register any special handlers for @ATTRIBUTES +*/ +static void ltdb_attributes_unload(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg; + int i; + + if (ltdb->cache->attributes == NULL) { + /* no previously loaded attributes */ + return; + } + + msg = ltdb->cache->attributes; + for (i=0;inum_elements;i++) { + const struct ldb_attrib_handler *h; + /* this is rather ugly - a consequence of const handling */ + h = ldb_attrib_handler(module->ldb, msg->elements[i].name); + ldb_remove_attrib_handler(module->ldb, msg->elements[i].name); + if (strcmp(h->attr, msg->elements[i].name) == 0) { + talloc_steal(msg, h->attr); + } + } + + talloc_free(ltdb->cache->attributes); + ltdb->cache->attributes = NULL; +} + +/* + add up the attrib flags for a @ATTRIBUTES element +*/ +static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) +{ + int i; + unsigned value = 0; + for (i=0;inum_values;i++) { + int j; + for (j=0;ltdb_valid_attr_flags[j].name;j++) { + if (strcmp(ltdb_valid_attr_flags[j].name, + (char *)el->values[i].data) == 0) { + value |= ltdb_valid_attr_flags[j].value; + break; + } + } + if (ltdb_valid_attr_flags[j].name == NULL) { + return -1; + } + } + *v = value; + return 0; +} + +/* + register any special handlers from @ATTRIBUTES +*/ +static int ltdb_attributes_load(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg = ltdb->cache->attributes; + struct ldb_dn *dn; + int i; + + dn = ldb_dn_explode(module->ldb, LTDB_ATTRIBUTES); + if (dn == NULL) goto failed; + + if (ltdb_search_dn1(module, dn, msg) == -1) { + talloc_free(dn); + goto failed; + } + talloc_free(dn); + /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, + but its close enough for now */ + for (i=0;inum_elements;i++) { + unsigned flags; + const char *syntax; + const struct ldb_attrib_handler *h; + struct ldb_attrib_handler h2; + + if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) { + ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name); + goto failed; + } + switch (flags & ~LTDB_FLAG_HIDDEN) { + case 0: + syntax = LDB_SYNTAX_OCTET_STRING; + break; + case LTDB_FLAG_CASE_INSENSITIVE: + syntax = LDB_SYNTAX_DIRECTORY_STRING; + break; + case LTDB_FLAG_INTEGER: + syntax = LDB_SYNTAX_INTEGER; + break; + default: + ldb_debug(module->ldb, LDB_DEBUG_ERROR, + "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n", + flags, msg->elements[i].name); + goto failed; + } + + h = ldb_attrib_handler_syntax(module->ldb, syntax); + if (h == NULL) { + ldb_debug(module->ldb, LDB_DEBUG_ERROR, + "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n", + syntax, msg->elements[i].name); + goto failed; + } + h2 = *h; + h2.attr = talloc_strdup(module, msg->elements[i].name); + if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) { + goto failed; + } + } + + return 0; +failed: + return -1; +} + + +/* + register any subclasses from @SUBCLASSES +*/ +static int ltdb_subclasses_load(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg = ltdb->cache->subclasses; + struct ldb_dn *dn; + int i, j; + + dn = ldb_dn_explode(module->ldb, LTDB_SUBCLASSES); + if (dn == NULL) goto failed; + + if (ltdb_search_dn1(module, dn, msg) == -1) { + talloc_free(dn); + goto failed; + } + talloc_free(dn); + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + for (j=0;jnum_values;j++) { + if (ldb_subclass_add(module->ldb, el->name, + (char *)el->values[j].data) != 0) { + goto failed; + } + } + } + + return 0; +failed: + return -1; +} + + +/* + de-register any @SUBCLASSES +*/ +static void ltdb_subclasses_unload(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg; + int i; + + if (ltdb->cache->subclasses == NULL) { + /* no previously loaded subclasses */ + return; + } + + msg = ltdb->cache->subclasses; + for (i=0;inum_elements;i++) { + ldb_subclass_remove(module->ldb, msg->elements[i].name); + } + + talloc_free(ltdb->cache->subclasses); + ltdb->cache->subclasses = NULL; +} + + +/* + initialise the baseinfo record +*/ +static int ltdb_baseinfo_init(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg; + struct ldb_message_element el; + struct ldb_val val; + int ret; + /* the initial sequence number must be different from the one + set in ltdb_cache_free(). Thanks to Jon for pointing this + out. */ + const char *initial_sequence_number = "1"; + + ltdb->sequence_number = atof(initial_sequence_number); + + msg = talloc(ltdb, struct ldb_message); + if (msg == NULL) { + goto failed; + } + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); + if (!msg->dn) { + goto failed; + } + el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); + if (!el.name) { + goto failed; + } + el.values = &val; + el.num_values = 1; + el.flags = 0; + val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); + if (!val.data) { + goto failed; + } + val.length = 1; + + ret = ltdb_store(module, msg, TDB_INSERT); + + talloc_free(msg); + + return ret; + +failed: + talloc_free(msg); + errno = ENOMEM; + return -1; +} + +/* + free any cache records + */ +static void ltdb_cache_free(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + + ltdb->sequence_number = 0; + talloc_free(ltdb->cache); + ltdb->cache = NULL; +} + +/* + force a cache reload +*/ +int ltdb_cache_reload(struct ldb_module *module) +{ + ltdb_attributes_unload(module); + ltdb_subclasses_unload(module); + ltdb_cache_free(module); + return ltdb_cache_load(module); +} + +/* + load the cache records +*/ +int ltdb_cache_load(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_dn *baseinfo_dn = NULL; + struct ldb_dn *indexlist_dn = NULL; + double seq; + + if (ltdb->cache == NULL) { + ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); + if (ltdb->cache == NULL) goto failed; + ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + } + + talloc_free(ltdb->cache->baseinfo); + ltdb->cache->baseinfo = talloc(ltdb->cache, struct ldb_message); + if (ltdb->cache->baseinfo == NULL) goto failed; + + baseinfo_dn = ldb_dn_explode(module->ldb, LTDB_BASEINFO); + if (baseinfo_dn == NULL) goto failed; + + if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) == -1) { + goto failed; + } + + /* possibly initialise the baseinfo */ + if (!ltdb->cache->baseinfo->dn) { + if (ltdb_baseinfo_init(module) != 0) { + goto failed; + } + if (ltdb_search_dn1(module, baseinfo_dn, 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_attr_as_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); + if (seq == ltdb->sequence_number) { + goto done; + } + ltdb->sequence_number = seq; + + talloc_free(ltdb->cache->last_attribute.name); + memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); + + ltdb_attributes_unload(module); + ltdb_subclasses_unload(module); + + talloc_free(ltdb->cache->indexlist); + talloc_free(ltdb->cache->subclasses); + + ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); + ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); + ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); + if (ltdb->cache->indexlist == NULL || + ltdb->cache->subclasses == NULL || + ltdb->cache->attributes == NULL) { + goto failed; + } + + indexlist_dn = ldb_dn_explode(module->ldb, LTDB_INDEXLIST); + if (indexlist_dn == NULL) goto failed; + + if (ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist) == -1) { + goto failed; + } + + if (ltdb_attributes_load(module) == -1) { + goto failed; + } + if (ltdb_subclasses_load(module) == -1) { + goto failed; + } + +done: + talloc_free(baseinfo_dn); + talloc_free(indexlist_dn); + return 0; + +failed: + talloc_free(baseinfo_dn); + talloc_free(indexlist_dn); + return -1; +} + + +/* + increase the sequence number to indicate a database change +*/ +int ltdb_increase_sequence_number(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + struct ldb_message *msg; + struct ldb_message_element el[2]; + struct ldb_val val; + struct ldb_val val_time; + time_t t = time(NULL); + char *s = NULL; + int ret; + + msg = talloc(ltdb, struct ldb_message); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1); + if (!s) { + errno = ENOMEM; + return -1; + } + + msg->num_elements = ARRAY_SIZE(el); + msg->elements = el; + msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); + if (msg->dn == NULL) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } + el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); + if (el[0].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } + el[0].values = &val; + el[0].num_values = 1; + el[0].flags = LDB_FLAG_MOD_REPLACE; + val.data = (uint8_t *)s; + val.length = strlen(s); + + el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP); + if (el[1].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } + el[1].values = &val_time; + el[1].num_values = 1; + el[1].flags = LDB_FLAG_MOD_REPLACE; + + s = ldb_timestring(msg, t); + if (s == NULL) { + return -1; + } + + val_time.data = (uint8_t *)s; + val_time.length = strlen(s); + + ret = ltdb_modify_internal(module, msg); + + talloc_free(msg); + + if (ret == 0) { + ltdb->sequence_number += 1; + } + + return ret; +} + + +/* + return the attribute flags from the @ATTRIBUTES record + for the given attribute +*/ +int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) +{ + struct ltdb_private *ltdb = module->private_data; + const struct ldb_message_element *attr_el; + int i, j, ret=0; + + 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 */ + if (ldb_attr_cmp(attr_name, LTDB_OBJECTCLASS) == 0) { + ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE; + } + + attr_el = ldb_msg_find_element(ltdb->cache->attributes, attr_name); + + if (!attr_el) { + /* check if theres a wildcard attribute */ + attr_el = ldb_msg_find_element(ltdb->cache->attributes, "*"); + + if (!attr_el) { + return ret; + } + } + + for (i = 0; i < attr_el->num_values; i++) { + for (j=0; ltdb_valid_attr_flags[j].name; j++) { + if (strcmp(ltdb_valid_attr_flags[j].name, + (char *)attr_el->values[i].data) == 0) { + ret |= ltdb_valid_attr_flags[j].value; + } + } + } + + talloc_free(ltdb->cache->last_attribute.name); + + ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name); + ltdb->cache->last_attribute.flags = ret; + + return ret; +} + +int ltdb_check_at_attributes_values(const struct ldb_val *value) +{ + int i; + + for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) { + if ((strcmp(ltdb_valid_attr_flags[i].name, (char *)value->data) == 0)) { + return 0; + } + } + + return -1; +} + diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c new file mode 100644 index 0000000000..59c1645ba8 --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -0,0 +1,1159 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb tdb backend - indexing + * + * Description: indexing routines for ldb tdb backend + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* + find an element in a list, using the given comparison function and + assuming that the list is already sorted using comp_fn + + return -1 if not found, or the index of the first occurance of needle if found +*/ +static int ldb_list_find(const void *needle, + const void *base, size_t nmemb, size_t size, + comparison_fn_t comp_fn) +{ + const char *base_p = base; + size_t min_i, max_i, test_i; + + if (nmemb == 0) { + return -1; + } + + min_i = 0; + max_i = nmemb-1; + + while (min_i < max_i) { + int r; + + test_i = (min_i + max_i) / 2; + /* the following cast looks strange, but is + correct. The key to understanding it is that base_p + is a pointer to an array of pointers, so we have to + dereference it after casting to void **. The strange + const in the middle gives us the right type of pointer + after the dereference (tridge) */ + r = comp_fn(needle, *(void * const *)(base_p + (size * test_i))); + if (r == 0) { + /* scan back for first element */ + while (test_i > 0 && + comp_fn(needle, *(void * const *)(base_p + (size * (test_i-1)))) == 0) { + test_i--; + } + return test_i; + } + if (r < 0) { + if (test_i == 0) { + return -1; + } + max_i = test_i - 1; + } + if (r > 0) { + min_i = test_i + 1; + } + } + + if (comp_fn(needle, *(void * const *)(base_p + (size * min_i))) == 0) { + return min_i; + } + + return -1; +} + +struct dn_list { + unsigned int count; + char **dn; +}; + +/* + return the dn key to be used for an index + caller frees +*/ +static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, + const char *attr, const struct ldb_val *value) +{ + struct ldb_dn *ret; + char *dn; + struct ldb_val v; + const struct ldb_attrib_handler *h; + char *attr_folded; + + attr_folded = ldb_attr_casefold(ldb, attr); + if (!attr_folded) { + return NULL; + } + + h = ldb_attrib_handler(ldb, attr); + if (h->canonicalise_fn(ldb, ldb, value, &v) != 0) { + /* canonicalisation can be refused. For example, + a attribute that takes wildcards will refuse to canonicalise + if the value contains a wildcard */ + talloc_free(attr_folded); + return NULL; + } + if (ldb_should_b64_encode(&v)) { + char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); + if (!vstr) return NULL; + dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); + talloc_free(vstr); + if (v.data != value->data) { + talloc_free(v.data); + } + talloc_free(attr_folded); + if (dn == NULL) return NULL; + goto done; + } + + dn = talloc_asprintf(ldb, "%s:%s:%.*s", + LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); + + if (v.data != value->data) { + talloc_free(v.data); + } + talloc_free(attr_folded); + +done: + ret = ldb_dn_explode(ldb, dn); + talloc_free(dn); + return ret; +} + +/* + see if a attribute value is in the list of indexed attributes +*/ +static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr, + unsigned int *v_idx, const char *key) +{ + unsigned int i, j; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, key) == 0) { + const struct ldb_message_element *el = + &msg->elements[i]; + for (j=0;jnum_values;j++) { + if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) { + if (v_idx) { + *v_idx = j; + } + return i; + } + } + } + } + return -1; +} + +/* used in sorting dn lists */ +static int list_cmp(const char **s1, const char **s2) +{ + return strcmp(*s1, *s2); +} + +/* + return a list of dn's that might match a simple indexed search or + */ +static int ltdb_index_dn_simple(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb = module->ldb; + struct ldb_dn *dn; + int ret; + unsigned int i, j; + struct ldb_message *msg; + + list->count = 0; + list->dn = NULL; + + /* if the attribute isn't in the list of indexed attributes then + this node needs a full search */ + if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) { + return -1; + } + + /* the attribute is indexed. Pull the list of DNs that match the + search criterion */ + dn = ldb_dn_key(ldb, tree->u.equality.attr, &tree->u.equality.value); + if (!dn) return -1; + + msg = talloc(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;inum_elements;i++) { + struct ldb_message_element *el; + + if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { + continue; + } + + el = &msg->elements[i]; + + list->dn = talloc_array(list, char *, el->num_values); + if (!list->dn) { + break; + } + + for (j=0;jnum_values;j++) { + list->dn[list->count] = + talloc_strdup(list->dn, (char *)el->values[j].data); + if (!list->dn[list->count]) { + return -1; + } + list->count++; + } + } + + talloc_free(msg); + + if (list->count > 1) { + qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); + } + + return 1; +} + + +static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); + +/* + return a list of dn's that might match a simple indexed search on + the special objectclass attribute + */ +static int ltdb_index_dn_objectclass(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i; + int ret; + const char *target = (const char *)tree->u.equality.value.data; + const char **subclasses; + + list->count = 0; + list->dn = NULL; + + ret = ltdb_index_dn_simple(module, tree, index_list, list); + + subclasses = ldb_subclass_list(module->ldb, target); + + if (subclasses == NULL) { + return ret; + } + + for (i=0;subclasses[i];i++) { + struct ldb_parse_tree tree2; + struct dn_list *list2; + tree2.operation = LDB_OP_EQUALITY; + tree2.u.equality.attr = LTDB_OBJECTCLASS; + if (!tree2.u.equality.attr) { + return -1; + } + tree2.u.equality.value.data = + (uint8_t *)talloc_strdup(list, subclasses[i]); + if (tree2.u.equality.value.data == NULL) { + return -1; + } + tree2.u.equality.value.length = strlen(subclasses[i]); + list2 = talloc(list, struct dn_list); + if (list2 == NULL) { + talloc_free(tree2.u.equality.value.data); + return -1; + } + if (ltdb_index_dn_objectclass(module, &tree2, + index_list, list2) == 1) { + if (list->count == 0) { + *list = *list2; + ret = 1; + } else { + list_union(ldb, list, list2); + talloc_free(list2); + } + } + talloc_free(tree2.u.equality.value.data); + } + + return ret; +} + +/* + return a list of dn's that might match a leaf indexed search + */ +static int ltdb_index_dn_leaf(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + if (ldb_attr_cmp(tree->u.equality.attr, LTDB_OBJECTCLASS) == 0) { + return ltdb_index_dn_objectclass(module, tree, index_list, list); + } + if (ldb_attr_dn(tree->u.equality.attr) == 0) { + list->dn = talloc_array(list, char *, 1); + if (list->dn == NULL) { + ldb_oom(module->ldb); + return -1; + } + list->dn[0] = talloc_strdup(list, (char *)tree->u.equality.value.data); + if (list->dn[0] == NULL) { + ldb_oom(module->ldb); + return -1; + } + list->count = 1; + return 1; + } + return ltdb_index_dn_simple(module, tree, index_list, list); +} + + +/* + list intersection + list = list & list2 + relies on the lists being sorted +*/ +static int list_intersect(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) +{ + struct dn_list *list3; + unsigned int i; + + if (list->count == 0 || list2->count == 0) { + /* 0 & X == 0 */ + return 0; + } + + list3 = talloc(ldb, struct dn_list); + if (list3 == NULL) { + return -1; + } + + list3->dn = talloc_array(list3, char *, list->count); + if (!list3->dn) { + talloc_free(list3); + return -1; + } + list3->count = 0; + + for (i=0;icount;i++) { + if (ldb_list_find(list->dn[i], list2->dn, list2->count, + sizeof(char *), (comparison_fn_t)strcmp) != -1) { + list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); + list3->count++; + } else { + talloc_free(list->dn[i]); + } + } + + talloc_free(list->dn); + list->dn = talloc_move(list, &list3->dn); + list->count = list3->count; + talloc_free(list3); + + return 0; +} + + +/* + list union + list = list | list2 + relies on the lists being sorted +*/ +static int list_union(struct ldb_context *ldb, + struct dn_list *list, const struct dn_list *list2) +{ + unsigned int i; + char **d; + unsigned int count = list->count; + + if (list->count == 0 && list2->count == 0) { + /* 0 | 0 == 0 */ + return 0; + } + + d = talloc_realloc(list, list->dn, char *, list->count + list2->count); + if (!d) { + return -1; + } + list->dn = d; + + for (i=0;icount;i++) { + if (ldb_list_find(list2->dn[i], list->dn, count, + sizeof(char *), (comparison_fn_t)strcmp) == -1) { + list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); + if (!list->dn[list->count]) { + return -1; + } + list->count++; + } + } + + if (list->count != count) { + qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp); + } + + return 0; +} + +static int ltdb_index_dn(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list); + + +/* + OR two index results + */ +static int ltdb_index_dn_or(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i; + int ret; + + ret = -1; + list->dn = NULL; + list->count = 0; + + for (i=0;iu.list.num_elements;i++) { + struct dn_list *list2; + int v; + + list2 = talloc(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 */ + talloc_free(list->dn); + talloc_free(list2); + return -1; + } + + if (ret == -1) { + ret = 1; + list->dn = talloc_move(list, &list2->dn); + list->count = list2->count; + } else { + if (list_union(ldb, list, list2) == -1) { + talloc_free(list2); + return -1; + } + ret = 1; + } + talloc_free(list2); + } + + if (list->count == 0) { + return 0; + } + + return ret; +} + + +/* + NOT an index results + */ +static int ltdb_index_dn_not(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + /* the only way to do an indexed not would be if we could + negate the not via another not or if we knew the total + number of database elements so we could know that the + existing expression covered the whole database. + + instead, we just give up, and rely on a full index scan + (unless an outer & manages to reduce the list) + */ + return -1; +} + +/* + AND two index results + */ +static int ltdb_index_dn_and(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i; + int ret; + + ret = -1; + list->dn = NULL; + list->count = 0; + + for (i=0;iu.list.num_elements;i++) { + struct dn_list *list2; + int v; + + list2 = talloc(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 */ + talloc_free(list->dn); + talloc_free(list2); + return 0; + } + + if (v == -1) { + talloc_free(list2); + continue; + } + + if (ret == -1) { + ret = 1; + talloc_free(list->dn); + list->dn = talloc_move(list, &list2->dn); + list->count = list2->count; + } else { + if (list_intersect(ldb, list, list2) == -1) { + talloc_free(list2); + return -1; + } + } + + talloc_free(list2); + + if (list->count == 0) { + talloc_free(list->dn); + return 0; + } + } + + return ret; +} + +/* + return a list of dn's that might match a indexed search or + -1 if an error. return 0 for no matches, or 1 for matches + */ +static int ltdb_index_dn(struct ldb_module *module, + const struct ldb_parse_tree *tree, + const struct ldb_message *index_list, + struct dn_list *list) +{ + int ret = -1; + + switch (tree->operation) { + case LDB_OP_AND: + ret = ltdb_index_dn_and(module, tree, index_list, list); + break; + + case LDB_OP_OR: + ret = ltdb_index_dn_or(module, tree, index_list, list); + break; + + case LDB_OP_NOT: + ret = ltdb_index_dn_not(module, tree, index_list, list); + break; + + case LDB_OP_EQUALITY: + ret = ltdb_index_dn_leaf(module, tree, index_list, list); + break; + + case LDB_OP_SUBSTRING: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_PRESENT: + case LDB_OP_APPROX: + case LDB_OP_EXTENDED: + /* we can't index with fancy bitops yet */ + ret = -1; + break; + } + + return ret; +} + +/* + filter a candidate dn_list from an indexed search into a set of results + extracting just the given attributes +*/ +static int ltdb_index_filter(const struct dn_list *dn_list, + struct ldb_handle *handle) +{ + struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); + struct ldb_reply *ares = NULL; + unsigned int i; + + for (i = 0; i < dn_list->count; i++) { + struct ldb_dn *dn; + int ret; + + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->message = ldb_msg_new(ares); + if (!ares->message) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; + } + + + dn = ldb_dn_explode(ares->message, dn_list->dn[i]); + if (dn == NULL) { + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_search_dn1(ac->module, dn, ares->message); + talloc_free(dn); + if (ret == 0) { + /* the record has disappeared? yes, this can happen */ + talloc_free(ares); + continue; + } + + if (ret == -1) { + /* an internal error */ + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, ac->base, ac->scope)) { + talloc_free(ares); + continue; + } + + /* filter the attributes that the user wants */ + ret = ltdb_filter_attrs(ares->message, ac->attrs); + + if (ret == -1) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_ENTRY; + handle->state = LDB_ASYNC_PENDING; + handle->status = ac->callback(ac->module->ldb, ac->context, ares); + + if (handle->status != LDB_SUCCESS) { + handle->state = LDB_ASYNC_DONE; + return handle->status; + } + } + + return LDB_SUCCESS; +} + +/* + search the database with a LDAP-like expression using indexes + returns -1 if an indexed search is not possible, in which + case the caller should call ltdb_search_full() +*/ +int ltdb_search_indexed(struct ldb_handle *handle) +{ + struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); + struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); + struct dn_list *dn_list; + int ret; + + if (ltdb->cache->indexlist->num_elements == 0 && + ac->scope != LDB_SCOPE_BASE) { + /* no index list? must do full search */ + return -1; + } + + dn_list = talloc(handle, struct dn_list); + if (dn_list == NULL) { + return -1; + } + + if (ac->scope == LDB_SCOPE_BASE) { + /* with BASE searches only one DN can match */ + dn_list->dn = talloc_array(dn_list, char *, 1); + if (dn_list->dn == NULL) { + ldb_oom(ac->module->ldb); + return -1; + } + dn_list->dn[0] = ldb_dn_linearize(dn_list, ac->base); + if (dn_list->dn[0] == NULL) { + ldb_oom(ac->module->ldb); + return -1; + } + dn_list->count = 1; + ret = 1; + } else { + ret = ltdb_index_dn(ac->module, ac->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 = ltdb_index_filter(dn_list, handle); + handle->status = ret; + handle->state = LDB_ASYNC_DONE; + } + + talloc_free(dn_list); + + return ret; +} + +/* + add a index element where this is the first indexed DN for this value +*/ +static int ltdb_index_add1_new(struct ldb_context *ldb, + struct ldb_message *msg, + struct ldb_message_element *el, + const char *dn) +{ + struct ldb_message_element *el2; + + /* add another entry */ + el2 = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); + if (!el2) { + return -1; + } + + msg->elements = el2; + 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 = talloc(msg->elements, struct ldb_val); + if (!msg->elements[msg->num_elements].values) { + return -1; + } + msg->elements[msg->num_elements].values[0].length = strlen(dn); + msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn); + msg->elements[msg->num_elements].num_values = 1; + msg->num_elements++; + + return 0; +} + + +/* + add a index element where this is not the first indexed DN for this + value +*/ +static int ltdb_index_add1_add(struct ldb_context *ldb, + struct ldb_message *msg, + struct ldb_message_element *el, + int idx, + const char *dn) +{ + struct ldb_val *v2; + unsigned int i; + + /* for multi-valued attributes we can end up with repeats */ + for (i=0;ielements[idx].num_values;i++) { + if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) { + return 0; + } + } + + v2 = talloc_realloc(msg->elements, msg->elements[idx].values, + struct ldb_val, + msg->elements[idx].num_values+1); + if (!v2) { + return -1; + } + msg->elements[idx].values = v2; + + msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn); + msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn); + msg->elements[idx].num_values++; + + return 0; +} + +/* + add an index entry for one message element +*/ +static int ltdb_index_add1(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_dn *dn_key; + int ret; + unsigned int i; + + msg = talloc(module, struct ldb_message); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); + if (!dn_key) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } + talloc_steal(msg, dn_key); + + ret = ltdb_search_dn1(module, dn_key, msg); + if (ret == -1) { + talloc_free(msg); + return -1; + } + + if (ret == 0) { + msg->dn = dn_key; + msg->num_elements = 0; + msg->elements = NULL; + } + + for (i=0;inum_elements;i++) { + if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) { + break; + } + } + + 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); + } + + if (ret == 0) { + ret = ltdb_store(module, msg, TDB_REPLACE); + } + + talloc_free(msg); + + return ret; +} + +static int ltdb_index_add0(struct ldb_module *module, const char *dn, + struct ldb_message_element *elements, int num_el) +{ + struct ltdb_private *ltdb = module->private_data; + int ret; + unsigned int i, j; + + if (dn[0] == '@') { + return 0; + } + + if (ltdb->cache->indexlist->num_elements == 0) { + /* no indexed fields */ + return 0; + } + + for (i = 0; i < num_el; i++) { + ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, + NULL, LTDB_IDXATTR); + if (ret == -1) { + continue; + } + for (j = 0; j < elements[i].num_values; j++) { + ret = ltdb_index_add1(module, dn, &elements[i], j); + if (ret == -1) { + return -1; + } + } + } + + return 0; +} + +/* + add the index entries for a new record + return -1 on failure +*/ +int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) +{ + struct ltdb_private *ltdb = module->private_data; + char *dn; + int ret; + + dn = ldb_dn_linearize(ltdb, msg->dn); + if (dn == NULL) { + return -1; + } + + ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); + + talloc_free(dn); + + return ret; +} + + +/* + delete an index entry for one message element +*/ +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_dn *dn_key; + int ret, i; + unsigned int j; + + if (dn[0] == '@') { + return 0; + } + + dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); + if (!dn_key) { + return -1; + } + + msg = talloc(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) { + 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 */ + talloc_free(dn_key); + return 0; + } + + 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, + ldb_dn_linearize(dn_key, dn_key)); + /* it ain't there. hmmm */ + 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])); + } + msg->elements[i].num_values--; + + if (msg->elements[i].num_values == 0) { + ret = ltdb_delete_noindex(module, dn_key); + } else { + ret = ltdb_store(module, msg, TDB_REPLACE); + } + + talloc_free(dn_key); + + return ret; +} + +/* + delete the index entries for a record + return -1 on failure +*/ +int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) +{ + struct ltdb_private *ltdb = module->private_data; + int ret; + char *dn; + unsigned int i, j; + + if (ldb_dn_is_special(msg->dn)) { + return 0; + } + + dn = ldb_dn_linearize(ltdb, msg->dn); + if (dn == NULL) { + return -1; + } + + /* find the list of indexed fields */ + 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(ltdb->cache->indexlist, msg->elements[i].name, + NULL, LTDB_IDXATTR); + if (ret == -1) { + continue; + } + for (j = 0; j < msg->elements[i].num_values; j++) { + ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); + if (ret == -1) { + talloc_free(dn); + return -1; + } + } + } + + talloc_free(dn); + return 0; +} + + +/* + traversal function that deletes all @INDEX records +*/ +static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + const char *dn = "DN=" LTDB_INDEX ":"; + if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) { + return tdb_delete(tdb, key); + } + return 0; +} + +/* + traversal function that adds @INDEX records during a re index +*/ +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; + char *dn = NULL; + int ret; + TDB_DATA key2; + + if (strncmp((char *)key.dptr, "DN=@", 4) == 0 || + strncmp((char *)key.dptr, "DN=", 3) != 0) { + return 0; + } + + msg = talloc(module, struct ldb_message); + if (msg == NULL) { + return -1; + } + + ret = ltdb_unpack_data(module, &data, msg); + if (ret != 0) { + talloc_free(msg); + return -1; + } + + /* check if the DN key has changed, perhaps due to the + case insensitivity of an element changing */ + key2 = ltdb_key(module, msg->dn); + if (key2.dptr == NULL) { + /* probably a corrupt record ... darn */ + ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n", + ldb_dn_linearize(msg, msg->dn)); + talloc_free(msg); + return 0; + } + if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) { + tdb_delete(tdb, key); + tdb_store(tdb, key2, data, 0); + } + talloc_free(key2.dptr); + + if (msg->dn == NULL) { + dn = (char *)key.dptr + 3; + } else { + dn = ldb_dn_linearize(msg->dn, msg->dn); + } + + ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); + + talloc_free(msg); + + return ret; +} + +/* + force a complete reindex of the database +*/ +int ltdb_reindex(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + int ret; + + if (ltdb_cache_reload(module) != 0) { + return -1; + } + + /* first traverse the database deleting any @INDEX records */ + ret = tdb_traverse(ltdb->tdb, delete_index, NULL); + if (ret == -1) { + return -1; + } + + /* now traverse adding any indexes for normal LDB records */ + ret = tdb_traverse(ltdb->tdb, re_index, module); + if (ret == -1) { + return -1; + } + + return 0; +} diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c new file mode 100644 index 0000000000..c6edf663ae --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -0,0 +1,294 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb pack/unpack + * + * Description: pack/unpack routines for ldb messages as key/value blobs + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* change this if the data format ever changes */ +#define LTDB_PACKING_FORMAT 0x26011967 + +/* old packing formats */ +#define LTDB_PACKING_FORMAT_NODN 0x26011966 + +/* use a portable integer format */ +static void put_uint32(uint8_t *p, int ofs, unsigned int val) +{ + p += ofs; + p[0] = val&0xFF; + p[1] = (val>>8) & 0xFF; + p[2] = (val>>16) & 0xFF; + p[3] = (val>>24) & 0xFF; +} + +static unsigned int pull_uint32(uint8_t *p, int ofs) +{ + p += ofs; + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + +static int attribute_storable_values(const struct ldb_message_element *el) +{ + if (el->num_values == 0) return 0; + + if (ldb_attr_cmp(el->name, "dn") == 0) return 0; + + if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; + + return el->num_values; +} + +/* + pack a ldb message into a linear buffer in a TDB_DATA + + note that this routine avoids saving elements with zero values, + as these are equivalent to having no element + + caller frees the data buffer after use +*/ +int ltdb_pack_data(struct ldb_module *module, + const struct ldb_message *message, + struct TDB_DATA *data) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i, j, real_elements=0; + size_t size; + char *dn; + uint8_t *p; + size_t len; + + dn = ldb_dn_linearize(ldb, message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + /* work out how big it needs to be */ + size = 8; + + size += 1 + strlen(dn); + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + size += 1 + strlen(message->elements[i].name) + 4; + for (j=0;jelements[i].num_values;j++) { + size += 4 + message->elements[i].values[j].length + 1; + } + } + + /* allocate it */ + data->dptr = talloc_array(ldb, uint8_t, size); + if (!data->dptr) { + talloc_free(dn); + errno = ENOMEM; + return -1; + } + data->dsize = size; + + p = data->dptr; + put_uint32(p, 0, LTDB_PACKING_FORMAT); + put_uint32(p, 4, real_elements); + p += 8; + + /* the dn needs to be packed so we can be case preserving + while hashing on a case folded dn */ + len = strlen(dn); + memcpy(p, dn, len+1); + p += len + 1; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + len = strlen(message->elements[i].name); + memcpy(p, message->elements[i].name, len+1); + p += len + 1; + put_uint32(p, 0, message->elements[i].num_values); + p += 4; + for (j=0;jelements[i].num_values;j++) { + put_uint32(p, 0, message->elements[i].values[j].length); + memcpy(p+4, message->elements[i].values[j].data, + message->elements[i].values[j].length); + p[4+message->elements[i].values[j].length] = 0; + p += 4 + message->elements[i].values[j].length + 1; + } + } + + talloc_free(dn); + return 0; +} + +/* + unpack a ldb message from a linear buffer in TDB_DATA + + Free with ltdb_unpack_data_free() +*/ +int ltdb_unpack_data(struct ldb_module *module, + const struct TDB_DATA *data, + struct ldb_message *message) +{ + struct ldb_context *ldb = module->ldb; + uint8_t *p; + unsigned int remaining; + unsigned int i, j; + unsigned format; + size_t len; + + message->elements = NULL; + + p = data->dptr; + if (data->dsize < 8) { + errno = EIO; + goto failed; + } + + format = pull_uint32(p, 0); + message->num_elements = pull_uint32(p, 4); + p += 8; + + remaining = data->dsize - 8; + + switch (format) { + case LTDB_PACKING_FORMAT_NODN: + message->dn = NULL; + break; + + case LTDB_PACKING_FORMAT: + len = strnlen((char *)p, remaining); + if (len == remaining) { + errno = EIO; + goto failed; + } + message->dn = ldb_dn_explode(message, (char *)p); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + break; + + default: + errno = EIO; + goto failed; + } + + if (message->num_elements == 0) { + message->elements = NULL; + return 0; + } + + if (message->num_elements > remaining / 6) { + errno = EIO; + goto failed; + } + + message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + memset(message->elements, 0, + message->num_elements * sizeof(struct ldb_message_element)); + + for (i=0;inum_elements;i++) { + if (remaining < 10) { + errno = EIO; + goto failed; + } + len = strnlen((char *)p, remaining-6); + if (len == remaining-6) { + errno = EIO; + goto failed; + } + message->elements[i].flags = 0; + message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); + if (message->elements[i].name == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + 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 = talloc_array(message->elements, + struct ldb_val, + message->elements[i].num_values); + if (!message->elements[i].values) { + errno = ENOMEM; + goto failed; + } + } + p += 4; + remaining -= 4; + for (j=0;jelements[i].num_values;j++) { + len = pull_uint32(p, 0); + if (len > remaining-5) { + errno = EIO; + goto failed; + } + + message->elements[i].values[j].length = len; + message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + if (message->elements[i].values[j].data == NULL) { + errno = ENOMEM; + goto failed; + } + memcpy(message->elements[i].values[j].data, p+4, len); + message->elements[i].values[j].data[len] = 0; + + remaining -= len+4+1; + p += len+4+1; + } + } + + if (remaining != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %d bytes unread in ltdb_unpack_data\n", remaining); + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c new file mode 100644 index 0000000000..7cdb2b672f --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -0,0 +1,543 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb search functions + * + * Description: functions to search ldb+tdb databases + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* + add one element to a message +*/ +static int msg_add_element(struct ldb_message *ret, + const struct ldb_message_element *el, + int check_duplicates) +{ + unsigned int i; + struct ldb_message_element *e2, *elnew; + + if (check_duplicates && ldb_msg_find_element(ret, el->name)) { + /* its already there */ + return 0; + } + + e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); + if (!e2) { + return -1; + } + ret->elements = e2; + + elnew = &e2[ret->num_elements]; + + elnew->name = talloc_strdup(ret->elements, el->name); + if (!elnew->name) { + return -1; + } + + if (el->num_values) { + elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values); + if (!elnew->values) { + return -1; + } + } else { + elnew->values = NULL; + } + + for (i=0;inum_values;i++) { + elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); + if (elnew->values[i].length != el->values[i].length) { + return -1; + } + } + + elnew->num_values = el->num_values; + + ret->num_elements++; + + return 0; +} + +/* + add the special distinguishedName element +*/ +static int msg_add_distinguished_name(struct ldb_message *msg) +{ + struct ldb_message_element el; + struct ldb_val val; + int ret; + + el.flags = 0; + el.name = "distinguishedName"; + el.num_values = 1; + el.values = &val; + val.data = (uint8_t *)ldb_dn_linearize(msg, msg->dn); + val.length = strlen((char *)val.data); + + ret = msg_add_element(msg, &el, 1); + return ret; +} + +/* + add all elements from one message into another + */ +static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *ret, + const struct ldb_message *msg) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i; + int check_duplicates = (ret->num_elements != 0); + + if (msg_add_distinguished_name(ret) != 0) { + return -1; + } + + for (i=0;inum_elements;i++) { + const struct ldb_attrib_handler *h; + h = ldb_attrib_handler(ldb, msg->elements[i].name); + if (h->flags & LDB_ATTR_FLAG_HIDDEN) { + continue; + } + if (msg_add_element(ret, &msg->elements[i], + check_duplicates) != 0) { + return -1; + } + } + + return 0; +} + + +/* + pull the specified list of attributes from a message + */ +static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char * const *attrs) +{ + struct ldb_message *ret; + int i; + + ret = talloc(mem_ctx, struct ldb_message); + if (!ret) { + return NULL; + } + + ret->dn = ldb_dn_copy(ret, msg->dn); + if (!ret->dn) { + talloc_free(ret); + return NULL; + } + + ret->num_elements = 0; + ret->elements = NULL; + + if (!attrs) { + if (msg_add_all_elements(module, ret, msg) != 0) { + talloc_free(ret); + return NULL; + } + return ret; + } + + for (i=0;attrs[i];i++) { + struct ldb_message_element *el; + + if (strcmp(attrs[i], "*") == 0) { + if (msg_add_all_elements(module, ret, msg) != 0) { + talloc_free(ret); + return NULL; + } + continue; + } + + if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { + if (msg_add_distinguished_name(ret) != 0) { + return NULL; + } + continue; + } + + el = ldb_msg_find_element(msg, attrs[i]); + if (!el) { + continue; + } + if (msg_add_element(ret, el, 1) != 0) { + talloc_free(ret); + return NULL; + } + } + + return ret; +} + + +/* + search the database for a single simple dn, returning all attributes + in a single message + + return 1 on success, 0 on record-not-found and -1 on error +*/ +int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg) +{ + struct ltdb_private *ltdb = module->private_data; + int ret; + TDB_DATA tdb_key, tdb_data; + + memset(msg, 0, sizeof(*msg)); + + /* form the key */ + tdb_key = ltdb_key(module, dn); + if (!tdb_key.dptr) { + return -1; + } + + tdb_data = tdb_fetch(ltdb->tdb, tdb_key); + talloc_free(tdb_key.dptr); + if (!tdb_data.dptr) { + return 0; + } + + msg->num_elements = 0; + msg->elements = NULL; + + ret = ltdb_unpack_data(module, &tdb_data, msg); + free(tdb_data.dptr); + if (ret == -1) { + return -1; + } + + if (!msg->dn) { + msg->dn = ldb_dn_copy(msg, dn); + } + if (!msg->dn) { + return -1; + } + + return 1; +} + +/* the lock key for search locking. Note that this is not a DN, its + just an arbitrary key to give to tdb. Also note that as we and + using transactions for all write operations and transactions take + care of their own locks, we don't need to do any locking anywhere + other than in ldb_search() */ +#define LDBLOCK "INT_LDBLOCK" + +/* + lock the database for read - use by ltdb_search +*/ +static int ltdb_lock_read(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + TDB_DATA key; + + key.dptr = discard_const(LDBLOCK); + key.dsize = strlen(LDBLOCK); + + return tdb_chainlock_read(ltdb->tdb, key); +} + +/* + unlock the database after a ltdb_lock_read() +*/ +static int ltdb_unlock_read(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + TDB_DATA key; + + key.dptr = discard_const(LDBLOCK); + key.dsize = strlen(LDBLOCK); + + return tdb_chainunlock_read(ltdb->tdb, key); +} + +/* + add a set of attributes from a record to a set of results + return 0 on success, -1 on failure +*/ +int ltdb_add_attr_results(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + const char * const attrs[], + unsigned int *count, + struct ldb_message ***res) +{ + struct ldb_message *msg2; + struct ldb_message **res2; + + /* pull the attributes that the user wants */ + msg2 = ltdb_pull_attrs(module, mem_ctx, msg, attrs); + if (!msg2) { + return -1; + } + + /* add to the results list */ + res2 = talloc_realloc(mem_ctx, *res, struct ldb_message *, (*count)+2); + if (!res2) { + talloc_free(msg2); + return -1; + } + + (*res) = res2; + + (*res)[*count] = talloc_move(*res, &msg2); + (*res)[(*count)+1] = NULL; + (*count)++; + + return 0; +} + + + +/* + filter the specified list of attributes from a message + removing not requested attrs. + */ +int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs) +{ + int i, keep_all = 0; + + if (attrs) { + /* check for special attrs */ + for (i = 0; attrs[i]; i++) { + if (strcmp(attrs[i], "*") == 0) { + keep_all = 1; + break; + } + + if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { + if (msg_add_distinguished_name(msg) != 0) { + return -1; + } + } + } + } else { + keep_all = 1; + } + + if (keep_all) { + if (msg_add_distinguished_name(msg) != 0) { + return -1; + } + return 0; + } + + for (i = 0; i < msg->num_elements; i++) { + int j, found; + + for (j = 0, found = 0; attrs[j]; j++) { + if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) { + found = 1; + break; + } + } + + if (!found) { + ldb_msg_remove_attr(msg, msg->elements[i].name); + i--; + } + } + + return 0; +} + +/* + search function for a non-indexed search + */ +static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct ldb_handle *handle = talloc_get_type(state, struct ldb_handle); + struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); + struct ldb_reply *ares = NULL; + int ret; + + if (key.dsize < 4 || + strncmp((char *)key.dptr, "DN=", 3) != 0) { + return 0; + } + + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + return -1; + } + + ares->message = ldb_msg_new(ares); + if (!ares->message) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + talloc_free(ares); + return -1; + } + + /* unpack the record */ + ret = ltdb_unpack_data(ac->module, &data, ares->message); + if (ret == -1) { + talloc_free(ares); + return -1; + } + + if (!ares->message->dn) { + ares->message->dn = ldb_dn_explode(ares->message, (char *)key.dptr + 3); + if (ares->message->dn == NULL) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + talloc_free(ares); + return -1; + } + } + + /* see if it matches the given expression */ + if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, + ac->base, ac->scope)) { + talloc_free(ares); + return 0; + } + + /* filter the attributes that the user wants */ + ret = ltdb_filter_attrs(ares->message, ac->attrs); + + if (ret == -1) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + handle->state = LDB_ASYNC_DONE; + talloc_free(ares); + return -1; + } + + ares->type = LDB_REPLY_ENTRY; + handle->state = LDB_ASYNC_PENDING; + handle->status = ac->callback(ac->module->ldb, ac->context, ares); + + if (handle->status != LDB_SUCCESS) { + /* don't try to free ares here, the callback is in charge of that */ + return -1; + } + + return 0; +} + + +/* + search the database with a LDAP-like expression. + this is the "full search" non-indexed variant +*/ +static int ltdb_search_full(struct ldb_handle *handle) +{ + struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); + struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); + int ret; + + ret = tdb_traverse_read(ltdb->tdb, search_func, handle); + + if (ret == -1) { + handle->status = LDB_ERR_OPERATIONS_ERROR; + } + + handle->state = LDB_ASYNC_DONE; + return LDB_SUCCESS; +} + +/* + search the database with a LDAP-like expression. + choses a search method +*/ +int ltdb_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + struct ltdb_context *ltdb_ac; + struct ldb_reply *ares; + int ret; + + if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) && + (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) + return LDB_ERR_OPERATIONS_ERROR; + + if (ltdb_lock_read(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ltdb_cache_load(module) != 0) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + if (req->handle == NULL) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); + + ltdb_ac->tree = req->op.search.tree; + ltdb_ac->scope = req->op.search.scope; + ltdb_ac->base = req->op.search.base; + ltdb_ac->attrs = req->op.search.attrs; + + ret = ltdb_search_indexed(req->handle); + if (ret == -1) { + ret = ltdb_search_full(req->handle); + } + if (ret != LDB_SUCCESS) { + ldb_set_errstring(module->ldb, "Indexed and full searches both failed!\n"); + req->handle->state = LDB_ASYNC_DONE; + req->handle->status = ret; + } + + /* Finally send an LDB_REPLY_DONE packet when searching is finished */ + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ltdb_unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->handle->state = LDB_ASYNC_DONE; + ares->type = LDB_REPLY_DONE; + + ret = req->callback(module->ldb, req->context, ares); + req->handle->status = ret; + + ltdb_unlock_read(module); + + return LDB_SUCCESS; +} + diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c new file mode 100644 index 0000000000..8f676654a6 --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -0,0 +1,1065 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006 + + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb_tdb + * + * Component: ldb tdb backend + * + * Description: core functions for tdb backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asyncronous calls + * date: Feb 2006 + * Author: Simo Sorce + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + + +/* + map a tdb error code to a ldb error code +*/ +static int ltdb_err_map(enum TDB_ERROR tdb_code) +{ + switch (tdb_code) { + case TDB_SUCCESS: + return LDB_SUCCESS; + case TDB_ERR_CORRUPT: + case TDB_ERR_OOM: + case TDB_ERR_EINVAL: + return LDB_ERR_OPERATIONS_ERROR; + case TDB_ERR_IO: + return LDB_ERR_PROTOCOL_ERROR; + case TDB_ERR_LOCK: + case TDB_ERR_NOLOCK: + return LDB_ERR_BUSY; + case TDB_ERR_LOCK_TIMEOUT: + return LDB_ERR_TIME_LIMIT_EXCEEDED; + case TDB_ERR_EXISTS: + return LDB_ERR_ENTRY_ALREADY_EXISTS; + case TDB_ERR_NOEXIST: + return LDB_ERR_NO_SUCH_OBJECT; + case TDB_ERR_RDONLY: + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + } + return LDB_ERR_OTHER; +} + + +struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, + void *context, + int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) +{ + struct ltdb_context *ac; + struct ldb_handle *h; + + h = talloc_zero(ltdb, struct ldb_handle); + if (h == NULL) { + ldb_set_errstring(module->ldb, "Out of Memory"); + return NULL; + } + + h->module = module; + + ac = talloc_zero(h, struct ltdb_context); + if (ac == NULL) { + ldb_set_errstring(module->ldb, "Out of Memory"); + talloc_free(h); + return NULL; + } + + h->private_data = (void *)ac; + + h->state = LDB_ASYNC_INIT; + h->status = LDB_SUCCESS; + + ac->module = module; + ac->context = context; + ac->callback = callback; + + return h; +} + +/* + form a TDB_DATA for a record key + caller frees + + note that the key for a record can depend on whether the + dn refers to a case sensitive index record or not +*/ +struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) +{ + struct ldb_context *ldb = module->ldb; + TDB_DATA key; + char *key_str = NULL; + char *dn_folded = NULL; + + /* + most DNs are case insensitive. The exception is index DNs for + case sensitive attributes + + there are 3 cases dealt with in this code: + + 1) if the dn doesn't start with @ then uppercase the attribute + names and the attributes values of case insensitive attributes + 2) if the dn starts with @ then leave it alone - the indexing code handles + the rest + */ + + dn_folded = ldb_dn_linearize_casefold(ldb, dn); + if (!dn_folded) { + goto failed; + } + + key_str = talloc_asprintf(ldb, "DN=%s", dn_folded); + + talloc_free(dn_folded); + + if (!key_str) { + goto failed; + } + + key.dptr = (uint8_t *)key_str; + key.dsize = strlen(key_str) + 1; + + return key; + +failed: + errno = ENOMEM; + key.dptr = NULL; + key.dsize = 0; + return key; +} + +/* + check special dn's have valid attributes + currently only @ATTRIBUTES is checked +*/ +int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg) +{ + int i, j; + + if (! ldb_dn_is_special(msg->dn) || + ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { + return 0; + } + + /* we have @ATTRIBUTES, let's check attributes are fine */ + /* should we check that we deny multivalued attributes ? */ + for (i = 0; i < msg->num_elements; i++) { + for (j = 0; j < msg->elements[i].num_values; j++) { + if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { + ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry"); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return 0; +} + + +/* + we've made a modification to a dn - possibly reindex and + update sequence number +*/ +static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn) +{ + int ret = 0; + + if (ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LTDB_INDEXLIST) || + ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) { + ret = ltdb_reindex(module); + } + + if (ret == 0 && + !(ldb_dn_is_special(dn) && + ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { + ret = ltdb_increase_sequence_number(module); + } + + return ret; +} + +/* + store a record into the db +*/ +int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) +{ + struct ltdb_private *ltdb = module->private_data; + TDB_DATA tdb_key, tdb_data; + int ret; + + tdb_key = ltdb_key(module, msg->dn); + if (!tdb_key.dptr) { + return LDB_ERR_OTHER; + } + + ret = ltdb_pack_data(module, msg, &tdb_data); + if (ret == -1) { + talloc_free(tdb_key.dptr); + return LDB_ERR_OTHER; + } + + ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); + if (ret == -1) { + ret = ltdb_err_map(tdb_error(ltdb->tdb)); + goto done; + } + + ret = ltdb_index_add(module, msg); + if (ret == -1) { + tdb_delete(ltdb->tdb, tdb_key); + } + +done: + talloc_free(tdb_key.dptr); + talloc_free(tdb_data.dptr); + + return ret; +} + + +static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg) +{ + int ret; + + ret = ltdb_check_special_dn(module, msg); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_store(module, msg, TDB_INSERT); + + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + char *dn; + + dn = ldb_dn_linearize(module, msg->dn); + if (!dn) { + return ret; + } + ldb_asprintf_errstring(module->ldb, "Entry %s already exists", dn); + talloc_free(dn); + return ret; + } + + if (ret == LDB_SUCCESS) { + ret = ltdb_modified(module, msg->dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return ret; +} + +/* + add a record to the database +*/ +static int ltdb_add(struct ldb_module *module, struct ldb_request *req) +{ + struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + struct ltdb_context *ltdb_ac; + int tret, ret = LDB_SUCCESS; + + if (req->controls != NULL) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); + if (check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); + + tret = ltdb_add_internal(module, req->op.add.message); + if (tret != LDB_SUCCESS) { + req->handle->status = tret; + goto done; + } + + if (ltdb_ac->callback) { + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + } +done: + req->handle->state = LDB_ASYNC_DONE; + return ret; +} + +/* + delete a record from the database, not updating indexes (used for deleting + index records) +*/ +int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn) +{ + struct ltdb_private *ltdb = module->private_data; + TDB_DATA tdb_key; + int ret; + + tdb_key = ltdb_key(module, dn); + if (!tdb_key.dptr) { + return LDB_ERR_OTHER; + } + + ret = tdb_delete(ltdb->tdb, tdb_key); + talloc_free(tdb_key.dptr); + + if (ret != 0) { + ret = ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return ret; +} + +static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn) +{ + struct ldb_message *msg; + int ret; + + msg = talloc(module, struct ldb_message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* in case any attribute of the message was indexed, we need + to fetch the old record */ + ret = ltdb_search_dn1(module, dn, msg); + if (ret != 1) { + /* not finding the old record is an error */ + talloc_free(msg); + return LDB_ERR_NO_SUCH_OBJECT; + } + + ret = ltdb_delete_noindex(module, dn); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return LDB_ERR_NO_SUCH_OBJECT; + } + + /* remove any indexed attributes */ + ret = ltdb_index_del(module, msg); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ltdb_modified(module, dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + talloc_free(msg); + return LDB_SUCCESS; +} + +/* + delete a record from the database +*/ +static int ltdb_delete(struct ldb_module *module, struct ldb_request *req) +{ + struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + struct ltdb_context *ltdb_ac; + int tret, ret = LDB_SUCCESS; + + if (req->controls != NULL) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); + if (check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + req->handle = NULL; + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); + + tret = ltdb_delete_internal(module, req->op.del.dn); + if (tret != LDB_SUCCESS) { + req->handle->status = tret; + goto done; + } + + if (ltdb_ac->callback) { + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + } +done: + req->handle->state = LDB_ASYNC_DONE; + return ret; +} + +/* + find an element by attribute name. At the moment this does a linear search, it should + be re-coded to use a binary search once all places that modify records guarantee + sorted order + + return the index of the first matching element if found, otherwise -1 +*/ +static int find_element(const struct ldb_message *msg, const char *name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { + return i; + } + } + return -1; +} + + +/* + add an element to an existing record. Assumes a elements array that we + can call re-alloc on, and assumed that we can re-use the data pointers from the + passed in additional values. Use with care! + + returns 0 on success, -1 on failure (and sets errno) +*/ +static int msg_add_element(struct ldb_context *ldb, + struct ldb_message *msg, struct ldb_message_element *el) +{ + struct ldb_message_element *e2; + unsigned int i; + + e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, + msg->num_elements+1); + if (!e2) { + errno = ENOMEM; + return -1; + } + + msg->elements = e2; + + e2 = &msg->elements[msg->num_elements]; + + e2->name = el->name; + e2->flags = el->flags; + e2->values = NULL; + if (el->num_values != 0) { + e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values); + if (!e2->values) { + errno = ENOMEM; + return -1; + } + } + for (i=0;inum_values;i++) { + e2->values[i] = el->values[i]; + } + e2->num_values = el->num_values; + + msg->num_elements++; + + return 0; +} + +/* + delete all elements having a specified attribute name +*/ +static int msg_delete_attribute(struct ldb_module *module, + struct ldb_context *ldb, + struct ldb_message *msg, const char *name) +{ + char *dn; + unsigned int i, j; + + dn = ldb_dn_linearize(ldb, msg->dn); + if (dn == NULL) { + return -1; + } + + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { + for (j=0;jelements[i].num_values;j++) { + ltdb_index_del_value(module, dn, &msg->elements[i], j); + } + 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(msg, msg->elements, + struct ldb_message_element, + msg->num_elements); + } + } + + talloc_free(dn); + return 0; +} + +/* + delete all elements matching an attribute name/value + + return 0 on success, -1 on failure +*/ +static int msg_delete_element(struct ldb_module *module, + struct ldb_message *msg, + const char *name, + const struct ldb_val *val) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i; + int found; + struct ldb_message_element *el; + const struct ldb_attrib_handler *h; + + found = find_element(msg, name); + if (found == -1) { + return -1; + } + + el = &msg->elements[found]; + + h = ldb_attrib_handler(ldb, el->name); + + for (i=0;inum_values;i++) { + if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) { + if (inum_values-1) { + memmove(&el->values[i], &el->values[i+1], + sizeof(el->values[i])*(el->num_values-(i+1))); + } + el->num_values--; + if (el->num_values == 0) { + return msg_delete_attribute(module, ldb, msg, name); + } + return 0; + } + } + + return -1; +} + + +/* + modify a record - internal interface + + yuck - this is O(n^2). Luckily n is usually small so we probably + get away with it, but if we ever have really large attribute lists + then we'll need to look at this again +*/ +int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg) +{ + struct ldb_context *ldb = module->ldb; + struct ltdb_private *ltdb = module->private_data; + TDB_DATA tdb_key, tdb_data; + struct ldb_message *msg2; + unsigned i, j; + int ret; + + tdb_key = ltdb_key(module, msg->dn); + if (!tdb_key.dptr) { + return LDB_ERR_OTHER; + } + + tdb_data = tdb_fetch(ltdb->tdb, tdb_key); + if (!tdb_data.dptr) { + talloc_free(tdb_key.dptr); + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + msg2 = talloc(tdb_key.dptr, struct ldb_message); + if (msg2 == NULL) { + talloc_free(tdb_key.dptr); + return LDB_ERR_OTHER; + } + + ret = ltdb_unpack_data(module, &tdb_data, msg2); + if (ret == -1) { + ret = LDB_ERR_OTHER; + goto failed; + } + + if (!msg2->dn) { + msg2->dn = msg->dn; + } + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + struct ldb_message_element *el2; + struct ldb_val *vals; + char *dn; + + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { + + case LDB_FLAG_MOD_ADD: + /* add this element to the message. fail if it + already exists */ + ret = find_element(msg2, el->name); + + if (ret == -1) { + if (msg_add_element(ldb, msg2, el) != 0) { + ret = LDB_ERR_OTHER; + goto failed; + } + continue; + } + + el2 = &msg2->elements[ret]; + + /* An attribute with this name already exists, add all + * values if they don't already exist. */ + + for (j=0;jnum_values;j++) { + if (ldb_msg_find_val(el2, &el->values[j])) { + ldb_set_errstring(module->ldb, "Type or value exists"); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto failed; + } + } + + vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val, + el2->num_values + el->num_values); + + if (vals == NULL) { + ret = LDB_ERR_OTHER; + goto failed; + } + + for (j=0;jnum_values;j++) { + vals[el2->num_values + j] = + ldb_val_dup(vals, &el->values[j]); + } + + el2->values = vals; + el2->num_values += el->num_values; + + break; + + 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); + + /* add the replacement element, if not empty */ + if (msg->elements[i].num_values != 0 && + msg_add_element(ldb, msg2, &msg->elements[i]) != 0) { + ret = LDB_ERR_OTHER; + goto failed; + } + break; + + case LDB_FLAG_MOD_DELETE: + + dn = ldb_dn_linearize(msg2, msg->dn); + if (dn == NULL) { + ret = LDB_ERR_OTHER; + goto failed; + } + + /* 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, + msg->elements[i].name) != 0) { + ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn); + ret = LDB_ERR_NO_SUCH_ATTRIBUTE; + goto failed; + } + break; + } + for (j=0;jelements[i].num_values;j++) { + if (msg_delete_element(module, + msg2, + msg->elements[i].name, + &msg->elements[i].values[j]) != 0) { + ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn); + ret = LDB_ERR_NO_SUCH_ATTRIBUTE; + goto failed; + } + if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) { + ret = LDB_ERR_OTHER; + goto failed; + } + } + break; + default: + ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x", + msg->elements[i].name, + msg->elements[i].flags & LDB_FLAG_MOD_MASK); + ret = LDB_ERR_PROTOCOL_ERROR; + goto failed; + } + } + + /* we've made all the mods - save the modified record back into the database */ + ret = ltdb_store(module, msg2, TDB_MODIFY); + if (ret != LDB_SUCCESS) { + goto failed; + } + + if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto failed; + } + + talloc_free(tdb_key.dptr); + free(tdb_data.dptr); + return ret; + +failed: + talloc_free(tdb_key.dptr); + free(tdb_data.dptr); + return ret; +} + +/* + modify a record +*/ +static int ltdb_modify(struct ldb_module *module, struct ldb_request *req) +{ + struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + struct ltdb_context *ltdb_ac; + int tret, ret = LDB_SUCCESS; + + if (req->controls != NULL) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); + if (check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + req->handle = NULL; + + req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); + + tret = ltdb_check_special_dn(module, req->op.mod.message); + if (tret != LDB_SUCCESS) { + req->handle->status = tret; + goto done; + } + + if (ltdb_cache_load(module) != 0) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + tret = ltdb_modify_internal(module, req->op.mod.message); + if (tret != LDB_SUCCESS) { + req->handle->status = tret; + goto done; + } + + if (ltdb_ac->callback) { + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + } +done: + req->handle->state = LDB_ASYNC_DONE; + return ret; +} + +/* + rename a record +*/ +static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); + struct ltdb_context *ltdb_ac; + struct ldb_message *msg; + int tret, ret = LDB_SUCCESS; + + if (req->controls != NULL) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); + if (check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + req->handle = NULL; + + if (ltdb_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); + + msg = talloc(ltdb_ac, struct ldb_message); + if (msg == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + /* in case any attribute of the message was indexed, we need + to fetch the old record */ + tret = ltdb_search_dn1(module, req->op.rename.olddn, msg); + if (tret != 1) { + /* not finding the old record is an error */ + req->handle->status = LDB_ERR_NO_SUCH_OBJECT; + goto done; + } + + msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); + if (!msg->dn) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + tret = ltdb_add_internal(module, msg); + if (tret != LDB_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + tret = ltdb_delete_internal(module, req->op.rename.olddn); + if (tret != LDB_SUCCESS) { + ltdb_delete_internal(module, req->op.rename.newdn); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + if (ltdb_ac->callback) { + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + } +done: + req->handle->state = LDB_ASYNC_DONE; + return ret; +} + +static int ltdb_start_trans(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + + if (tdb_transaction_start(ltdb->tdb) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return LDB_SUCCESS; +} + +static int ltdb_end_trans(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + + if (tdb_transaction_commit(ltdb->tdb) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return LDB_SUCCESS; +} + +static int ltdb_del_trans(struct ldb_module *module) +{ + struct ltdb_private *ltdb = module->private_data; + + if (tdb_transaction_cancel(ltdb->tdb) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + + return LDB_SUCCESS; +} + +static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type) +{ + return handle->status; +} + +static int ltdb_request(struct ldb_module *module, struct ldb_request *req) +{ + /* check for oustanding critical controls and return an error if found */ + if (req->controls != NULL) { + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); + if (check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + /* search, add, modify, delete, rename are handled by their own, no other op supported */ + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + return sequenceNumber from @BASEINFO +*/ +static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req) +{ + TALLOC_CTX *tmp_ctx = talloc_new(req); + struct ldb_message *msg = NULL; + struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO); + int tret; + + if (tmp_ctx == NULL) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = talloc(tmp_ctx, struct ldb_message); + if (msg == NULL) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->op.seq_num.flags = 0; + + tret = ltdb_search_dn1(module, dn, msg); + if (tret != 1) { + talloc_free(tmp_ctx); + req->op.seq_num.seq_num = 0; + /* zero is as good as anything when we don't know */ + return LDB_SUCCESS; + } + + switch (req->op.seq_num.type) { + case LDB_SEQ_HIGHEST_SEQ: + req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); + break; + case LDB_SEQ_NEXT: + req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); + req->op.seq_num.seq_num++; + break; + case LDB_SEQ_HIGHEST_TIMESTAMP: + { + const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL); + if (date) { + req->op.seq_num.seq_num = ldb_string_to_time(date); + } else { + req->op.seq_num.seq_num = 0; + /* zero is as good as anything when we don't know */ + } + break; + } + } + talloc_free(tmp_ctx); + return LDB_SUCCESS; +} + +static const struct ldb_module_ops ltdb_ops = { + .name = "tdb", + .search = ltdb_search, + .add = ltdb_add, + .modify = ltdb_modify, + .del = ltdb_delete, + .rename = ltdb_rename, + .request = ltdb_request, + .start_transaction = ltdb_start_trans, + .end_transaction = ltdb_end_trans, + .del_transaction = ltdb_del_trans, + .wait = ltdb_wait, + .sequence_number = ltdb_sequence_number +}; + +/* + connect to the database +*/ +static int ltdb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **module) +{ + const char *path; + int tdb_flags, open_flags; + struct ltdb_private *ltdb; + + /* parse the url */ + if (strchr(url, ':')) { + if (strncmp(url, "tdb://", 6) != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url); + return -1; + } + path = url+6; + } else { + path = url; + } + + tdb_flags = TDB_DEFAULT; + + /* check for the 'nosync' option */ + if (flags & LDB_FLG_NOSYNC) { + tdb_flags |= TDB_NOSYNC; + } + + if (flags & LDB_FLG_RDONLY) { + open_flags = O_RDONLY; + } else { + open_flags = O_CREAT | O_RDWR; + } + + ltdb = talloc_zero(ldb, struct ltdb_private); + if (!ltdb) { + ldb_oom(ldb); + return -1; + } + + /* note that we use quite a large default hash size */ + ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, + tdb_flags, open_flags, 0666, ldb); + if (!ltdb->tdb) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); + talloc_free(ltdb); + return -1; + } + + ltdb->sequence_number = 0; + + *module = talloc(ldb, struct ldb_module); + if (!module) { + ldb_oom(ldb); + talloc_free(ltdb); + return -1; + } + (*module)->ldb = ldb; + (*module)->prev = (*module)->next = NULL; + (*module)->private_data = ltdb; + (*module)->ops = <db_ops; + + return 0; +} + +int ldb_tdb_init(void) +{ + return ldb_register_backend("tdb", ltdb_connect); +} diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.h b/source3/lib/ldb/ldb_tdb/ldb_tdb.h new file mode 100644 index 0000000000..670d3b6801 --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.h @@ -0,0 +1,127 @@ + +#ifdef _SAMBA_BUILD_ +#include "system/filesys.h" +#endif + +#if (_SAMBA_BUILD_ >= 4) +#include "lib/tdb/include/tdb.h" +#elif defined(_SAMBA_BUILD_) +#include "tdb/include/tdb.h" +#else +#include "tdb.h" +#endif + +/* this private structure is used by the ltdb backend in the + ldb_context */ +struct ltdb_private { + TDB_CONTEXT *tdb; + unsigned int connect_flags; + + /* a double is used for portability and ease of string + handling. It has plenty of digits of precision */ + unsigned long long sequence_number; + + 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; +}; + +/* + the async local context + holds also internal search state during a full db search +*/ +struct ltdb_context { + struct ldb_module *module; + + /* search stuff */ + const struct ldb_parse_tree *tree; + const struct ldb_dn *base; + enum ldb_scope scope; + const char * const *attrs; + + /* async stuff */ + void *context; + int (*callback)(struct ldb_context *, void *, struct ldb_reply *); +}; + +/* special record types */ +#define LTDB_INDEX "@INDEX" +#define LTDB_INDEXLIST "@INDEXLIST" +#define LTDB_IDX "@IDX" +#define LTDB_IDXATTR "@IDXATTR" +#define LTDB_BASEINFO "@BASEINFO" +#define LTDB_ATTRIBUTES "@ATTRIBUTES" +#define LTDB_SUBCLASSES "@SUBCLASSES" + +/* special attribute types */ +#define LTDB_SEQUENCE_NUMBER "sequenceNumber" +#define LTDB_MOD_TIMESTAMP "whenChanged" +#define LTDB_OBJECTCLASS "objectClass" + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ + +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_check_at_attributes_values(const struct ldb_val *value); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_index.c */ + +struct ldb_parse_tree; + +int ltdb_search_indexed(struct ldb_handle *handle); +int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); +int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); +int ltdb_reindex(struct ldb_module *module); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */ + +int ltdb_pack_data(struct ldb_module *module, + const struct ldb_message *message, + struct TDB_DATA *data); +void ltdb_unpack_data_free(struct ldb_module *module, + struct ldb_message *message); +int ltdb_unpack_data(struct ldb_module *module, + const struct TDB_DATA *data, + struct ldb_message *message); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_search.c */ + +int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, + const struct ldb_val *val); +void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); +int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg); +int ltdb_add_attr_results(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + const char * const attrs[], + unsigned int *count, + struct ldb_message ***res); +int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs); +int ltdb_search(struct ldb_module *module, struct ldb_request *req); + +/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ +struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, + void *context, + int (*callback)(struct ldb_context *, void *, struct ldb_reply *)); +struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn); +int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); +int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn); +int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg); + +int ltdb_index_del_value(struct ldb_module *module, const char *dn, + struct ldb_message_element *el, int v_idx); + +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb); + diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c new file mode 100644 index 0000000000..b28bf77450 --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -0,0 +1,174 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* + the purpose of this code is to work around the braindead posix locking + rules, to allow us to have a ldb open more than once while allowing + locking to work +*/ + +struct ltdb_wrap { + struct ltdb_wrap *next, *prev; + struct tdb_context *tdb; + dev_t device; + ino_t inode; +}; + +static struct ltdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int ltdb_wrap_destructor(struct ltdb_wrap *w) +{ + tdb_close(w->tdb); + if (w->next) { + w->next->prev = w->prev; + } + if (w->prev) { + w->prev->next = w->next; + } + if (w == tdb_list) { + tdb_list = w->next; + } + return 0; +} + +#if defined(_SAMBA_BUILD_) && (_SAMBA_BUILD_ <= 3) +static void ltdb_log_fn(struct tdb_context *tdb, int level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void ltdb_log_fn(struct tdb_context *tdb, int level, const char *fmt, ...) +{ + /* until we merge the tdb debug changes into samba3, we don't know + how serious the error is, and we can't go via the ldb loggin code */ + va_list ap; + const char *name = tdb_name(tdb); + char *message; + va_start(ap, fmt); + message = talloc_vasprintf(NULL, fmt, ap); + va_end(ap); + DEBUG(3, ("ltdb: tdb(%s): %s", name, message)); + talloc_free(message); +} +#else +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); + enum ldb_debug_level ldb_level; + char *message; + va_start(ap, fmt); + message = talloc_vasprintf(ldb, fmt, ap); + va_end(ap); + + switch (level) { + case TDB_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TDB_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TDB_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TDB_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + default: + ldb_level = LDB_DEBUG_FATAL; + } + + ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); + talloc_free(message); +} +#endif + +/* + wrapped connection to a tdb database. The caller should _not_ free + this as it is not a talloc structure (as tdb does not use talloc + yet). It will auto-close when the caller frees the mem_ctx that is + passed to this call + */ +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, + int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb) +{ + struct ltdb_wrap *w; + struct stat st; +#if defined(_SAMBA_BUILD_) && (_SAMBA_BUILD_ <= 3) + tdb_log_func log_ctx_p = ltdb_log_fn; +#else + struct tdb_logging_context log_ctx; + const struct tdb_logging_context *log_ctx_p = &log_ctx; + log_ctx.log_fn = ltdb_log_fn; + log_ctx.log_private = ldb; +#endif + + if (stat(path, &st) == 0) { + for (w=tdb_list;w;w=w->next) { + if (st.st_dev == w->device && st.st_ino == w->inode) { + talloc_reference(mem_ctx, w); + return w->tdb; + } + } + } + + w = talloc(mem_ctx, struct ltdb_wrap); + if (w == NULL) { + return NULL; + } + + w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, log_ctx_p, NULL); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + if (fstat(tdb_fd(w->tdb), &st) != 0) { + tdb_close(w->tdb); + talloc_free(w); + return NULL; + } + + w->device = st.st_dev; + w->inode = st.st_ino; + + talloc_set_destructor(w, ltdb_wrap_destructor); + + w->next = tdb_list; + w->prev = NULL; + if (tdb_list) { + tdb_list->prev = w; + } + tdb_list = w; + + return w->tdb; +} + -- cgit From 0cc2cee8d5ccd95cd4cd10a060e2b3e703b6fba1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Sep 2006 03:34:50 +0000 Subject: r18939: don't rely on the umask being right in ldb creation. Both Samba3 and Samba4 smbd force the umask to 0, which meant we ended up with ldb being world writable. This isn't really an ideal fix, as it means ldb no longer honors umask (as it should do, like all good libraries). Unfortunately the 'proper' fix is too complex for now this also merges a tiny code style fix from s4 to s3 (This used to be commit dd8ec8725f168f4286bbfc00d69cd56089ba3543) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 8f676654a6..5d43783903 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1036,7 +1036,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, /* note that we use quite a large default hash size */ ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, - tdb_flags, open_flags, 0666, ldb); + tdb_flags, open_flags, 0644, ldb); if (!ltdb->tdb) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); talloc_free(ltdb); -- cgit From a65c6b3914cc1e79501d0613e353ac0398a00cb4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 4 Oct 2006 19:12:01 +0000 Subject: r19071: Backport to SAMBA_3_0 as well (This used to be commit df148a5def06956ecd8392d259f1c408c62100fa) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index d6d66dd37f..a6092c45f9 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -318,7 +318,7 @@ int ltdb_cache_load(struct ldb_module *module) struct ltdb_private *ltdb = module->private_data; struct ldb_dn *baseinfo_dn = NULL; struct ldb_dn *indexlist_dn = NULL; - double seq; + uint64_t seq; if (ltdb->cache == NULL) { ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); @@ -356,7 +356,7 @@ int ltdb_cache_load(struct ldb_module *module) /* 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_attr_as_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); + seq = ldb_msg_find_attr_as_uint64(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); if (seq == ltdb->sequence_number) { goto done; } -- cgit From 695c6fbe007445e8e63c7d820b14322ece3edbf5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 6 Oct 2006 14:50:07 +0000 Subject: r19133: More C++ warnings -- Merge across? (This used to be commit c879ed3d1edffeda629dc1e05031dca91c1a1e30) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 5d43783903..2dbcb7a811 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -219,7 +219,8 @@ static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn) */ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); TDB_DATA tdb_key, tdb_data; int ret; @@ -332,7 +333,8 @@ done: */ int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); TDB_DATA tdb_key; int ret; @@ -589,7 +591,8 @@ static int msg_delete_element(struct ldb_module *module, int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg) { struct ldb_context *ldb = module->ldb; - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); TDB_DATA tdb_key, tdb_data; struct ldb_message *msg2; unsigned i, j; @@ -873,7 +876,8 @@ done: static int ltdb_start_trans(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); if (tdb_transaction_start(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); @@ -884,7 +888,8 @@ static int ltdb_start_trans(struct ldb_module *module) static int ltdb_end_trans(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); if (tdb_transaction_commit(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); @@ -895,7 +900,8 @@ static int ltdb_end_trans(struct ldb_module *module) static int ltdb_del_trans(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); if (tdb_transaction_cancel(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); -- cgit From b61d1e665e4f4bf0b8e2d3bdc8fa1135279a903d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 6 Oct 2006 16:14:41 +0000 Subject: r19145: talloc_reference() can fail! metze (This used to be commit e4f2183684da90a67bc6a635d008b72a6dd3d0dd) --- source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index b28bf77450..c9eac013fc 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -134,7 +134,9 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, if (stat(path, &st) == 0) { for (w=tdb_list;w;w=w->next) { if (st.st_dev == w->device && st.st_ino == w->inode) { - talloc_reference(mem_ctx, w); + if (!talloc_reference(mem_ctx, w)) { + return NULL; + } return w->tdb; } } -- cgit From 628fc4b53a33b604e1c28d38ff5fd91459434814 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 7 Oct 2006 10:24:16 +0000 Subject: r19163: pass always a mem_ctx to functions and a ldb_context where needed It would be nice if someone can merge that to samba4, otherwise I'll merge that to samba4 on monday metze (This used to be commit 6bc42f31ce294f2bd50ffbd536e1ee42607ef799) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 2dbcb7a811..9b502b5911 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -138,7 +138,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) the rest */ - dn_folded = ldb_dn_linearize_casefold(ldb, dn); + dn_folded = ldb_dn_linearize_casefold(ldb, ldb, dn); if (!dn_folded) { goto failed; } -- cgit From 617c39ab5ffbefcd7d0536c72ffbb0c36ce04215 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Oct 2006 07:05:08 +0000 Subject: r19182: merge from samba4: add ldb_set_create_perms() function to set the create_perms after ldb_init() and before ldb_connect() metze (This used to be commit dd9d469eef337954b6aee4c86ac0691f52812456) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 9b502b5911..608120e3a7 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1042,7 +1042,8 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, /* note that we use quite a large default hash size */ ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, - tdb_flags, open_flags, 0644, ldb); + tdb_flags, open_flags, + ldb->create_perms, ldb); if (!ltdb->tdb) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); talloc_free(ltdb); -- cgit From 442f5526a043be624e35c8ab2de60de2630cd619 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Oct 2006 08:32:51 +0000 Subject: r19193: merge from samba4: fixed another checker warning and a possible error on allocation failure metze (This used to be commit d64583a763ffcff27f0bd6761196f7d554d44849) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 59c1645ba8..8a9a82a98c 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -232,13 +232,15 @@ static int ltdb_index_dn_simple(struct ldb_module *module, list->dn = talloc_array(list, char *, el->num_values); if (!list->dn) { - break; + talloc_free(msg); + return -1; } for (j=0;jnum_values;j++) { list->dn[list->count] = talloc_strdup(list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { + talloc_free(msg); return -1; } list->count++; -- cgit From 7a390a0dabcdadb30196662b6cdec512bf81dcb4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Oct 2006 00:10:19 +0000 Subject: r19430: merge recent ldb changes from Samba4. This includes memory leak fixes and significant speedups (This used to be commit bb5c205fef90aa8b89ba400fb9f2f37a111676a8) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 33 +++++++++++++++++++-------------- source3/lib/ldb/ldb_tdb/ldb_index.c | 12 ++++++------ source3/lib/ldb/ldb_tdb/ldb_search.c | 24 +++--------------------- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 27 +++++++++++++++++---------- source3/lib/ldb/ldb_tdb/ldb_tdb.h | 8 +++++--- 5 files changed, 50 insertions(+), 54 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index a6092c45f9..467f1ac34d 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -71,13 +71,7 @@ static void ltdb_attributes_unload(struct ldb_module *module) msg = ltdb->cache->attributes; for (i=0;inum_elements;i++) { - const struct ldb_attrib_handler *h; - /* this is rather ugly - a consequence of const handling */ - h = ldb_attrib_handler(module->ldb, msg->elements[i].name); ldb_remove_attrib_handler(module->ldb, msg->elements[i].name); - if (strcmp(h->attr, msg->elements[i].name) == 0) { - talloc_steal(msg, h->attr); - } } talloc_free(ltdb->cache->attributes); @@ -163,7 +157,8 @@ static int ltdb_attributes_load(struct ldb_module *module) goto failed; } h2 = *h; - h2.attr = talloc_strdup(module, msg->elements[i].name); + h2.attr = msg->elements[i].name; + h2.flags |= LDB_ATTR_FLAG_ALLOCATED; if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) { goto failed; } @@ -319,6 +314,13 @@ int ltdb_cache_load(struct ldb_module *module) struct ldb_dn *baseinfo_dn = NULL; struct ldb_dn *indexlist_dn = NULL; uint64_t seq; + struct ldb_message *baseinfo; + + /* a very fast check to avoid extra database reads */ + if (ltdb->cache != NULL && + tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) { + return 0; + } if (ltdb->cache == NULL) { ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); @@ -333,30 +335,31 @@ int ltdb_cache_load(struct ldb_module *module) } } - talloc_free(ltdb->cache->baseinfo); - ltdb->cache->baseinfo = talloc(ltdb->cache, struct ldb_message); - if (ltdb->cache->baseinfo == NULL) goto failed; + baseinfo = talloc(ltdb->cache, struct ldb_message); + if (baseinfo == NULL) goto failed; baseinfo_dn = ldb_dn_explode(module->ldb, LTDB_BASEINFO); if (baseinfo_dn == NULL) goto failed; - if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) == -1) { + if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) == -1) { goto failed; } /* possibly initialise the baseinfo */ - if (!ltdb->cache->baseinfo->dn) { + if (!baseinfo->dn) { if (ltdb_baseinfo_init(module) != 0) { goto failed; } - if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) != 1) { + if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) != 1) { goto failed; } } + ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); + /* 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_attr_as_uint64(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0); + seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0); if (seq == ltdb->sequence_number) { goto done; } @@ -395,11 +398,13 @@ int ltdb_cache_load(struct ldb_module *module) } done: + talloc_free(baseinfo); talloc_free(baseinfo_dn); talloc_free(indexlist_dn); return 0; failed: + talloc_free(baseinfo); talloc_free(baseinfo_dn); talloc_free(indexlist_dn); return -1; diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 8a9a82a98c..0c9d1f33a1 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -1030,6 +1030,12 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) char *dn; unsigned int i, j; + /* find the list of indexed fields */ + if (ltdb->cache->indexlist->num_elements == 0) { + /* no indexed fields */ + return 0; + } + if (ldb_dn_is_special(msg->dn)) { return 0; } @@ -1039,12 +1045,6 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) return -1; } - /* find the list of indexed fields */ - 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(ltdb->cache->indexlist, msg->elements[i].name, NULL, LTDB_IDXATTR); diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c index 7cdb2b672f..4b76c437b6 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_search.c +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -248,25 +248,13 @@ int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct l return 1; } -/* the lock key for search locking. Note that this is not a DN, its - just an arbitrary key to give to tdb. Also note that as we and - using transactions for all write operations and transactions take - care of their own locks, we don't need to do any locking anywhere - other than in ldb_search() */ -#define LDBLOCK "INT_LDBLOCK" - /* lock the database for read - use by ltdb_search */ static int ltdb_lock_read(struct ldb_module *module) { struct ltdb_private *ltdb = module->private_data; - TDB_DATA key; - - key.dptr = discard_const(LDBLOCK); - key.dsize = strlen(LDBLOCK); - - return tdb_chainlock_read(ltdb->tdb, key); + return tdb_lockall_read(ltdb->tdb); } /* @@ -275,12 +263,7 @@ static int ltdb_lock_read(struct ldb_module *module) static int ltdb_unlock_read(struct ldb_module *module) { struct ltdb_private *ltdb = module->private_data; - TDB_DATA key; - - key.dptr = discard_const(LDBLOCK); - key.dsize = strlen(LDBLOCK); - - return tdb_chainunlock_read(ltdb->tdb, key); + return tdb_unlockall_read(ltdb->tdb); } /* @@ -499,12 +482,11 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + req->handle = init_ltdb_handle(ltdb, module, req); if (req->handle == NULL) { ltdb_unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); ltdb_ac->tree = req->op.search.tree; diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 608120e3a7..3f9db39097 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -79,13 +79,12 @@ static int ltdb_err_map(enum TDB_ERROR tdb_code) struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) + struct ldb_request *req) { struct ltdb_context *ac; struct ldb_handle *h; - h = talloc_zero(ltdb, struct ldb_handle); + h = talloc_zero(req, struct ldb_handle); if (h == NULL) { ldb_set_errstring(module->ldb, "Out of Memory"); return NULL; @@ -106,8 +105,8 @@ struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module h->status = LDB_SUCCESS; ac->module = module; - ac->context = context; - ac->callback = callback; + ac->context = req->context; + ac->callback = req->callback; return h; } @@ -307,7 +306,7 @@ static int ltdb_add(struct ldb_module *module, struct ldb_request *req) } } - req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + req->handle = init_ltdb_handle(ltdb, module, req); if (req->handle == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -387,6 +386,7 @@ static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn * ret = ltdb_modified(module, dn); if (ret != LDB_SUCCESS) { + talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } @@ -416,7 +416,7 @@ static int ltdb_delete(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + req->handle = init_ltdb_handle(ltdb, module, req); if (req->handle == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -772,7 +772,7 @@ static int ltdb_modify(struct ldb_module *module, struct ldb_request *req) req->handle = NULL; - req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + req->handle = init_ltdb_handle(ltdb, module, req); if (req->handle == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -826,7 +826,7 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback); + req->handle = init_ltdb_handle(ltdb, module, req); if (req->handle == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -1021,7 +1021,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, path = url; } - tdb_flags = TDB_DEFAULT; + tdb_flags = TDB_DEFAULT | TDB_SEQNUM; /* check for the 'nosync' option */ if (flags & LDB_FLG_NOSYNC) { @@ -1058,11 +1058,18 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, talloc_free(ltdb); return -1; } + talloc_set_name_const(*module, "ldb_tdb backend"); (*module)->ldb = ldb; (*module)->prev = (*module)->next = NULL; (*module)->private_data = ltdb; (*module)->ops = <db_ops; + if (ltdb_cache_load(*module) != 0) { + talloc_free(*module); + talloc_free(ltdb); + return -1; + } + return 0; } diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.h b/source3/lib/ldb/ldb_tdb/ldb_tdb.h index 670d3b6801..42f3dc2421 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.h @@ -21,8 +21,11 @@ struct ltdb_private { handling. It has plenty of digits of precision */ unsigned long long sequence_number; + /* the low level tdb seqnum - used to avoid loading BASEINFO when + possible */ + int tdb_seqnum; + struct ltdb_cache { - struct ldb_message *baseinfo; struct ldb_message *indexlist; struct ldb_message *attributes; struct ldb_message *subclasses; @@ -110,8 +113,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req); /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)); + struct ldb_request *req); struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn); int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn); -- cgit From 866a3b6e40952193d5bcd812ec7079cf7434e600 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Nov 2006 17:34:20 +0000 Subject: r19725: sync samba3's ldb with samba4 metze (This used to be commit 207643e9c9c75546f38a09f12ea0b574b08086c5) --- source3/lib/ldb/ldb_tdb/ldb_search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c index 4b76c437b6..884eccd362 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_search.c +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -464,7 +464,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req) struct ldb_reply *ares; int ret; - if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) && + if ((req->op.search.base == NULL || ldb_dn_get_comp_num(req->op.search.base) == 0) && (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) return LDB_ERR_OPERATIONS_ERROR; -- cgit From a12fb3afdda89dd5d5eec6c9371512f668645446 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Nov 2006 17:11:29 +0000 Subject: r19899: Fix some C++ warnings and klokwork ID 3147 (This used to be commit c5e041661ec6dd63188ad0a09a228192b6dfd2b3) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 0c9d1f33a1..2a862c02d6 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -47,7 +47,7 @@ static int ldb_list_find(const void *needle, const void *base, size_t nmemb, size_t size, comparison_fn_t comp_fn) { - const char *base_p = base; + const char *base_p = (const char *)base; size_t min_i, max_i, test_i; if (nmemb == 0) { @@ -897,7 +897,8 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn, static int ltdb_index_add0(struct ldb_module *module, const char *dn, struct ldb_message_element *elements, int num_el) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; int ret; unsigned int i, j; @@ -933,7 +934,8 @@ static int ltdb_index_add0(struct ldb_module *module, const char *dn, */ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; char *dn; int ret; @@ -1025,7 +1027,8 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, */ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; int ret; char *dn; unsigned int i, j; @@ -1082,7 +1085,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_module *module = (struct ldb_module *)state; struct ldb_message *msg; char *dn = NULL; int ret; @@ -1123,7 +1126,10 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * if (msg->dn == NULL) { dn = (char *)key.dptr + 3; } else { - dn = ldb_dn_linearize(msg->dn, msg->dn); + if (!(dn = ldb_dn_linearize(msg->dn, msg->dn))) { + talloc_free(msg); + return -1; + } } ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); @@ -1138,7 +1144,8 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * */ int ltdb_reindex(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; int ret; if (ltdb_cache_reload(module) != 0) { -- cgit From 2685e167fa12d696bf3882e888629f95b81e7683 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Nov 2006 17:14:39 +0000 Subject: r19900: Fix klokwork ID 3148, 3149 (This used to be commit 1f3e20ef3985a0a16e8945907611654ef5e884c4) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 2a862c02d6..d7a8e5e9b5 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -642,6 +642,10 @@ static int ltdb_index_filter(const struct dn_list *dn_list, struct ldb_reply *ares = NULL; unsigned int i; + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + for (i = 0; i < dn_list->count; i++) { struct ldb_dn *dn; int ret; @@ -722,6 +726,10 @@ int ltdb_search_indexed(struct ldb_handle *handle) struct dn_list *dn_list; int ret; + if ((ac == NULL) || (ltdb == NULL)) { + return -1; + } + if (ltdb->cache->indexlist->num_elements == 0 && ac->scope != LDB_SCOPE_BASE) { /* no index list? must do full search */ -- cgit From 847644bdac520a3cca7f30ffa50c0de3eeedf6d9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Nov 2006 08:41:41 +0000 Subject: r19917: Fix warnings (This used to be commit cf4309b9048a8417104cac660421a3dcd2e96ffe) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 29 +++++++++++++++++++---------- source3/lib/ldb/ldb_tdb/ldb_pack.c | 8 ++++---- source3/lib/ldb/ldb_tdb/ldb_search.c | 9 ++++++--- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 8 +++++--- 5 files changed, 35 insertions(+), 21 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index 467f1ac34d..632e22762f 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -60,7 +60,8 @@ static const struct { */ static void ltdb_attributes_unload(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg; int i; @@ -107,7 +108,8 @@ static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) */ static int ltdb_attributes_load(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg = ltdb->cache->attributes; struct ldb_dn *dn; int i; @@ -175,7 +177,8 @@ failed: */ static int ltdb_subclasses_load(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg = ltdb->cache->subclasses; struct ldb_dn *dn; int i, j; @@ -210,7 +213,8 @@ failed: */ static void ltdb_subclasses_unload(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg; int i; @@ -234,7 +238,8 @@ static void ltdb_subclasses_unload(struct ldb_module *module) */ static int ltdb_baseinfo_init(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; @@ -287,7 +292,8 @@ failed: */ static void ltdb_cache_free(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; ltdb->sequence_number = 0; talloc_free(ltdb->cache); @@ -310,11 +316,12 @@ int ltdb_cache_reload(struct ldb_module *module) */ int ltdb_cache_load(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_dn *baseinfo_dn = NULL; struct ldb_dn *indexlist_dn = NULL; uint64_t seq; - struct ldb_message *baseinfo; + struct ldb_message *baseinfo = NULL; /* a very fast check to avoid extra database reads */ if (ltdb->cache != NULL && @@ -416,7 +423,8 @@ failed: */ int ltdb_increase_sequence_number(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; struct ldb_message *msg; struct ldb_message_element el[2]; struct ldb_val val; @@ -493,7 +501,8 @@ int ltdb_increase_sequence_number(struct ldb_module *module) */ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; const struct ldb_message_element *attr_el; int i, j, ret=0; diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index c6edf663ae..50dc20524f 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -114,7 +114,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); + data->dptr = talloc_array(ldb, char, size); if (!data->dptr) { talloc_free(dn); errno = ENOMEM; @@ -122,7 +122,7 @@ int ltdb_pack_data(struct ldb_module *module, } data->dsize = size; - p = data->dptr; + p = (uint8_t *)data->dptr; put_uint32(p, 0, LTDB_PACKING_FORMAT); put_uint32(p, 4, real_elements); p += 8; @@ -173,7 +173,7 @@ int ltdb_unpack_data(struct ldb_module *module, message->elements = NULL; - p = data->dptr; + p = (uint8_t *)data->dptr; if (data->dsize < 8) { errno = EIO; goto failed; @@ -268,7 +268,7 @@ int ltdb_unpack_data(struct ldb_module *module, } message->elements[i].values[j].length = len; - message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + message->elements[i].values[j].data = (uint8_t *)talloc_size(message->elements[i].values, len+1); if (message->elements[i].values[j].data == NULL) { errno = ENOMEM; goto failed; diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c index 884eccd362..7a6fe263fd 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_search.c +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -211,7 +211,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, */ int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; int ret; TDB_DATA tdb_key, tdb_data; @@ -253,7 +254,8 @@ int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct l */ static int ltdb_lock_read(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; return tdb_lockall_read(ltdb->tdb); } @@ -262,7 +264,8 @@ static int ltdb_lock_read(struct ldb_module *module) */ static int ltdb_unlock_read(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = + (struct ltdb_private *)module->private_data; return tdb_unlockall_read(ltdb->tdb); } diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 3f9db39097..232195dfcd 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -150,7 +150,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) goto failed; } - key.dptr = (uint8_t *)key_str; + key.dptr = (char *)key_str; key.dsize = strlen(key_str) + 1; return key; diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index c9eac013fc..4f3acad9ea 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -59,8 +59,8 @@ static int ltdb_wrap_destructor(struct ltdb_wrap *w) } #if defined(_SAMBA_BUILD_) && (_SAMBA_BUILD_ <= 3) -static void ltdb_log_fn(struct tdb_context *tdb, int level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void ltdb_log_fn(struct tdb_context *tdb, int level, const char *fmt, ...) +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { /* until we merge the tdb debug changes into samba3, we don't know how serious the error is, and we can't go via the ldb loggin code */ @@ -147,7 +147,9 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, return NULL; } - w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, log_ctx_p, NULL); + w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, + (const struct tdb_logging_context *)log_ctx_p, + NULL); if (w->tdb == NULL) { talloc_free(w); return NULL; -- cgit From 1c2ed583026631b94fc61a63e609eca2ad099bc1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 29 Nov 2006 06:09:24 +0000 Subject: r19942: Fix Coverity id 333, a dereference before a NULL check. Metze, you wanted to port talloc_get_type_abort() to 4. Should I just use it in 3-ldb? Volker (This used to be commit ba0df1c915c49afad629df789375440225968633) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index d7a8e5e9b5..2c88d7e19d 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -721,12 +721,15 @@ static int ltdb_index_filter(const struct dn_list *dn_list, */ int ltdb_search_indexed(struct ldb_handle *handle) { - struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); - struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); + struct ltdb_context *ac; + struct ltdb_private *ltdb; struct dn_list *dn_list; int ret; - if ((ac == NULL) || (ltdb == NULL)) { + if (!(ac = talloc_get_type(handle->private_data, + struct ltdb_context)) || + !(ltdb = talloc_get_type(ac->module->private_data, + struct ltdb_private))) { return -1; } -- cgit From 8a20dd0ff1b3ba293f311ddfe247953df1728b27 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 6 Dec 2006 11:01:27 +0000 Subject: r20049: Reformatting (This used to be commit 75555ae1c8039b7bbca796dd16609de08230265a) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 106 +++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 39 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 2c88d7e19d..c9a5dc9b05 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -41,7 +41,8 @@ find an element in a list, using the given comparison function and assuming that the list is already sorted using comp_fn - return -1 if not found, or the index of the first occurance of needle if found + return -1 if not found, or the index of the first occurance of needle if + found */ static int ldb_list_find(const void *needle, const void *base, size_t nmemb, size_t size, @@ -128,7 +129,8 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, if (ldb_should_b64_encode(&v)) { char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); if (!vstr) return NULL; - dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); + dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, + vstr); talloc_free(vstr); if (v.data != value->data) { talloc_free(v.data); @@ -138,8 +140,8 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, goto done; } - dn = talloc_asprintf(ldb, "%s:%s:%.*s", - LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); + dn = talloc_asprintf(ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, + (int)v.length, (char *)v.data); if (v.data != value->data) { talloc_free(v.data); @@ -164,7 +166,8 @@ static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr, const struct ldb_message_element *el = &msg->elements[i]; for (j=0;jnum_values;j++) { - if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) { + if (ldb_attr_cmp((char *)el->values[j].data, + attr) == 0) { if (v_idx) { *v_idx = j; } @@ -201,7 +204,8 @@ static int ltdb_index_dn_simple(struct ldb_module *module, /* if the attribute isn't in the list of indexed attributes then this node needs a full search */ - if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) { + if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, + LTDB_IDXATTR) == -1) { return -1; } @@ -237,8 +241,8 @@ static int ltdb_index_dn_simple(struct ldb_module *module, } for (j=0;jnum_values;j++) { - list->dn[list->count] = - talloc_strdup(list->dn, (char *)el->values[j].data); + list->dn[list->count] = talloc_strdup( + list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { talloc_free(msg); return -1; @@ -250,14 +254,16 @@ static int ltdb_index_dn_simple(struct ldb_module *module, talloc_free(msg); if (list->count > 1) { - qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); + qsort(list->dn, list->count, sizeof(char *), + (comparison_fn_t) list_cmp); } return 1; } -static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); +static int list_union(struct ldb_context *, struct dn_list *, + const struct dn_list *); /* return a list of dn's that might match a simple indexed search on @@ -329,7 +335,8 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, struct dn_list *list) { if (ldb_attr_cmp(tree->u.equality.attr, LTDB_OBJECTCLASS) == 0) { - return ltdb_index_dn_objectclass(module, tree, index_list, list); + return ltdb_index_dn_objectclass(module, tree, index_list, + list); } if (ldb_attr_dn(tree->u.equality.attr) == 0) { list->dn = talloc_array(list, char *, 1); @@ -337,7 +344,8 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, ldb_oom(module->ldb); return -1; } - list->dn[0] = talloc_strdup(list, (char *)tree->u.equality.value.data); + list->dn[0] = talloc_strdup( + list, (char *)tree->u.equality.value.data); if (list->dn[0] == NULL) { ldb_oom(module->ldb); return -1; @@ -380,7 +388,8 @@ static int list_intersect(struct ldb_context *ldb, for (i=0;icount;i++) { if (ldb_list_find(list->dn[i], list2->dn, list2->count, sizeof(char *), (comparison_fn_t)strcmp) != -1) { - list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); + list3->dn[list3->count] = talloc_move( + list3->dn, &list->dn[i]); list3->count++; } else { talloc_free(list->dn[i]); @@ -422,7 +431,8 @@ static int list_union(struct ldb_context *ldb, for (i=0;icount;i++) { if (ldb_list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); + list->dn[list->count] = talloc_strdup( + list->dn, list2->dn[i]); if (!list->dn[list->count]) { return -1; } @@ -431,7 +441,8 @@ static int list_union(struct ldb_context *ldb, } if (list->count != count) { - qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp); + qsort(list->dn, list->count, sizeof(char *), + (comparison_fn_t)list_cmp); } return 0; @@ -468,7 +479,8 @@ static int ltdb_index_dn_or(struct ldb_module *module, return -1; } - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); + v = ltdb_index_dn(module, tree->u.list.elements[i], + index_list, list2); if (v == 0) { /* 0 || X == X */ @@ -552,7 +564,8 @@ static int ltdb_index_dn_and(struct ldb_module *module, return -1; } - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); + v = ltdb_index_dn(module, tree->u.list.elements[i], + index_list, list2); if (v == 0) { /* 0 && X == 0 */ @@ -638,7 +651,8 @@ static int ltdb_index_dn(struct ldb_module *module, static int ltdb_index_filter(const struct dn_list *dn_list, struct ldb_handle *handle) { - struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); + struct ltdb_context *ac = talloc_get_type(handle->private_data, + struct ltdb_context); struct ldb_reply *ares = NULL; unsigned int i; @@ -686,7 +700,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list, return LDB_ERR_OPERATIONS_ERROR; } - if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, ac->base, ac->scope)) { + if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, + ac->base, ac->scope)) { talloc_free(ares); continue; } @@ -703,7 +718,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list, ares->type = LDB_REPLY_ENTRY; handle->state = LDB_ASYNC_PENDING; - handle->status = ac->callback(ac->module->ldb, ac->context, ares); + handle->status = ac->callback(ac->module->ldb, ac->context, + ares); if (handle->status != LDB_SUCCESS) { handle->state = LDB_ASYNC_DONE; @@ -759,7 +775,8 @@ int ltdb_search_indexed(struct ldb_handle *handle) dn_list->count = 1; ret = 1; } else { - ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); + ret = ltdb_index_dn(ac->module, ac->tree, + ltdb->cache->indexlist, dn_list); } if (ret == 1) { @@ -787,23 +804,26 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, /* add another entry */ el2 = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); + struct ldb_message_element, msg->num_elements+1); if (!el2) { return -1; } msg->elements = el2; - msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, 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 = talloc(msg->elements, struct ldb_val); + msg->elements[msg->num_elements].values = talloc(msg->elements, + struct ldb_val); if (!msg->elements[msg->num_elements].values) { return -1; } msg->elements[msg->num_elements].values[0].length = strlen(dn); - msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn); + msg->elements[msg->num_elements].values[0].data = + discard_const_p(uint8_t, dn); msg->elements[msg->num_elements].num_values = 1; msg->num_elements++; @@ -826,7 +846,8 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, /* for multi-valued attributes we can end up with repeats */ for (i=0;ielements[idx].num_values;i++) { - if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) { + if (strcmp(dn, + (char *)msg->elements[idx].values[i].data) == 0) { return 0; } } @@ -839,8 +860,10 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } msg->elements[idx].values = v2; - msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn); - msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn); + msg->elements[idx].values[msg->elements[idx].num_values].length = + strlen(dn); + msg->elements[idx].values[msg->elements[idx].num_values].data = + discard_const_p(uint8_t, dn); msg->elements[idx].num_values++; return 0; @@ -923,8 +946,8 @@ static int ltdb_index_add0(struct ldb_module *module, const char *dn, } for (i = 0; i < num_el; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, - NULL, LTDB_IDXATTR); + ret = ldb_msg_find_idx(ltdb->cache->indexlist, + elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; } @@ -997,8 +1020,8 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, } if (ret == 0) { - /* it wasn't indexed. Did we have an earlier error? If we did then - its gone now */ + /* it wasn't indexed. Did we have an earlier error? If we did + then its gone now */ talloc_free(dn_key); return 0; } @@ -1060,13 +1083,15 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) } for (i = 0; i < msg->num_elements; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, - NULL, LTDB_IDXATTR); + ret = ldb_msg_find_idx(ltdb->cache->indexlist, + msg->elements[i].name, NULL, + LTDB_IDXATTR); if (ret == -1) { continue; } for (j = 0; j < msg->elements[i].num_values; j++) { - ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); + ret = ltdb_index_del_value(module, dn, + &msg->elements[i], j); if (ret == -1) { talloc_free(dn); return -1; @@ -1082,7 +1107,8 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) /* traversal function that deletes all @INDEX records */ -static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *state) { const char *dn = "DN=" LTDB_INDEX ":"; if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) { @@ -1094,7 +1120,8 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, vo /* traversal function that adds @INDEX records during a re index */ -static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *state) { struct ldb_module *module = (struct ldb_module *)state; struct ldb_message *msg; @@ -1123,8 +1150,9 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * key2 = ltdb_key(module, msg->dn); if (key2.dptr == NULL) { /* probably a corrupt record ... darn */ - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n", - ldb_dn_linearize(msg, msg->dn)); + ldb_debug(module->ldb, LDB_DEBUG_ERROR, + "Invalid DN in re_index: %s\n", + ldb_dn_linearize(msg, msg->dn)); talloc_free(msg); return 0; } -- cgit From c0d74d11bc205b4fef80f8faa81df2dee5613368 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 6 Dec 2006 11:45:33 +0000 Subject: r20050: Remove a bogus NULL check, LTDB_OBJECTCLASS is a static string (This used to be commit f64866a43fbc21666e919cafdf3002a8e43c60af) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index c9a5dc9b05..e84dac3f90 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -296,9 +296,6 @@ static int ltdb_index_dn_objectclass(struct ldb_module *module, struct dn_list *list2; tree2.operation = LDB_OP_EQUALITY; tree2.u.equality.attr = LTDB_OBJECTCLASS; - if (!tree2.u.equality.attr) { - return -1; - } tree2.u.equality.value.data = (uint8_t *)talloc_strdup(list, subclasses[i]); if (tree2.u.equality.value.data == NULL) { -- cgit From 4a1efb1abe1882173d25dbd6c4ebdbf53521b42c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 6 Dec 2006 14:40:47 +0000 Subject: r20054: Revert my changes, Simo promised to work on it :-) (This used to be commit 4b5cf0c9cffe9903c86ac7e8b41c303fdbde5bac) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 109 ++++++++++++++---------------------- 1 file changed, 42 insertions(+), 67 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index e84dac3f90..2c88d7e19d 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -41,8 +41,7 @@ find an element in a list, using the given comparison function and assuming that the list is already sorted using comp_fn - return -1 if not found, or the index of the first occurance of needle if - found + return -1 if not found, or the index of the first occurance of needle if found */ static int ldb_list_find(const void *needle, const void *base, size_t nmemb, size_t size, @@ -129,8 +128,7 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, if (ldb_should_b64_encode(&v)) { char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); if (!vstr) return NULL; - dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, - vstr); + dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); talloc_free(vstr); if (v.data != value->data) { talloc_free(v.data); @@ -140,8 +138,8 @@ static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, goto done; } - dn = talloc_asprintf(ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, - (int)v.length, (char *)v.data); + dn = talloc_asprintf(ldb, "%s:%s:%.*s", + LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); if (v.data != value->data) { talloc_free(v.data); @@ -166,8 +164,7 @@ static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr, const struct ldb_message_element *el = &msg->elements[i]; for (j=0;jnum_values;j++) { - if (ldb_attr_cmp((char *)el->values[j].data, - attr) == 0) { + if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) { if (v_idx) { *v_idx = j; } @@ -204,8 +201,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, /* if the attribute isn't in the list of indexed attributes then this node needs a full search */ - if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, - LTDB_IDXATTR) == -1) { + if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) { return -1; } @@ -241,8 +237,8 @@ static int ltdb_index_dn_simple(struct ldb_module *module, } for (j=0;jnum_values;j++) { - list->dn[list->count] = talloc_strdup( - list->dn, (char *)el->values[j].data); + list->dn[list->count] = + talloc_strdup(list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { talloc_free(msg); return -1; @@ -254,16 +250,14 @@ static int ltdb_index_dn_simple(struct ldb_module *module, talloc_free(msg); if (list->count > 1) { - qsort(list->dn, list->count, sizeof(char *), - (comparison_fn_t) list_cmp); + qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); } return 1; } -static int list_union(struct ldb_context *, struct dn_list *, - const struct dn_list *); +static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); /* return a list of dn's that might match a simple indexed search on @@ -296,6 +290,9 @@ static int ltdb_index_dn_objectclass(struct ldb_module *module, struct dn_list *list2; tree2.operation = LDB_OP_EQUALITY; tree2.u.equality.attr = LTDB_OBJECTCLASS; + if (!tree2.u.equality.attr) { + return -1; + } tree2.u.equality.value.data = (uint8_t *)talloc_strdup(list, subclasses[i]); if (tree2.u.equality.value.data == NULL) { @@ -332,8 +329,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, struct dn_list *list) { if (ldb_attr_cmp(tree->u.equality.attr, LTDB_OBJECTCLASS) == 0) { - return ltdb_index_dn_objectclass(module, tree, index_list, - list); + return ltdb_index_dn_objectclass(module, tree, index_list, list); } if (ldb_attr_dn(tree->u.equality.attr) == 0) { list->dn = talloc_array(list, char *, 1); @@ -341,8 +337,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, ldb_oom(module->ldb); return -1; } - list->dn[0] = talloc_strdup( - list, (char *)tree->u.equality.value.data); + list->dn[0] = talloc_strdup(list, (char *)tree->u.equality.value.data); if (list->dn[0] == NULL) { ldb_oom(module->ldb); return -1; @@ -385,8 +380,7 @@ static int list_intersect(struct ldb_context *ldb, for (i=0;icount;i++) { if (ldb_list_find(list->dn[i], list2->dn, list2->count, sizeof(char *), (comparison_fn_t)strcmp) != -1) { - list3->dn[list3->count] = talloc_move( - list3->dn, &list->dn[i]); + list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); list3->count++; } else { talloc_free(list->dn[i]); @@ -428,8 +422,7 @@ static int list_union(struct ldb_context *ldb, for (i=0;icount;i++) { if (ldb_list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = talloc_strdup( - list->dn, list2->dn[i]); + list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); if (!list->dn[list->count]) { return -1; } @@ -438,8 +431,7 @@ static int list_union(struct ldb_context *ldb, } if (list->count != count) { - qsort(list->dn, list->count, sizeof(char *), - (comparison_fn_t)list_cmp); + qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp); } return 0; @@ -476,8 +468,7 @@ static int ltdb_index_dn_or(struct ldb_module *module, return -1; } - v = ltdb_index_dn(module, tree->u.list.elements[i], - index_list, list2); + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 || X == X */ @@ -561,8 +552,7 @@ static int ltdb_index_dn_and(struct ldb_module *module, return -1; } - v = ltdb_index_dn(module, tree->u.list.elements[i], - index_list, list2); + v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); if (v == 0) { /* 0 && X == 0 */ @@ -648,8 +638,7 @@ static int ltdb_index_dn(struct ldb_module *module, static int ltdb_index_filter(const struct dn_list *dn_list, struct ldb_handle *handle) { - struct ltdb_context *ac = talloc_get_type(handle->private_data, - struct ltdb_context); + struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); struct ldb_reply *ares = NULL; unsigned int i; @@ -697,8 +686,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, return LDB_ERR_OPERATIONS_ERROR; } - if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, - ac->base, ac->scope)) { + if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, ac->base, ac->scope)) { talloc_free(ares); continue; } @@ -715,8 +703,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, ares->type = LDB_REPLY_ENTRY; handle->state = LDB_ASYNC_PENDING; - handle->status = ac->callback(ac->module->ldb, ac->context, - ares); + handle->status = ac->callback(ac->module->ldb, ac->context, ares); if (handle->status != LDB_SUCCESS) { handle->state = LDB_ASYNC_DONE; @@ -772,8 +759,7 @@ int ltdb_search_indexed(struct ldb_handle *handle) dn_list->count = 1; ret = 1; } else { - ret = ltdb_index_dn(ac->module, ac->tree, - ltdb->cache->indexlist, dn_list); + ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); } if (ret == 1) { @@ -801,26 +787,23 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, /* add another entry */ el2 = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); + struct ldb_message_element, msg->num_elements+1); if (!el2) { return -1; } msg->elements = el2; - msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, - 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 = talloc(msg->elements, - struct ldb_val); + msg->elements[msg->num_elements].values = talloc(msg->elements, struct ldb_val); if (!msg->elements[msg->num_elements].values) { return -1; } msg->elements[msg->num_elements].values[0].length = strlen(dn); - msg->elements[msg->num_elements].values[0].data = - discard_const_p(uint8_t, dn); + msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn); msg->elements[msg->num_elements].num_values = 1; msg->num_elements++; @@ -843,8 +826,7 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, /* for multi-valued attributes we can end up with repeats */ for (i=0;ielements[idx].num_values;i++) { - if (strcmp(dn, - (char *)msg->elements[idx].values[i].data) == 0) { + if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) { return 0; } } @@ -857,10 +839,8 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } msg->elements[idx].values = v2; - msg->elements[idx].values[msg->elements[idx].num_values].length = - strlen(dn); - msg->elements[idx].values[msg->elements[idx].num_values].data = - discard_const_p(uint8_t, dn); + msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn); + msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn); msg->elements[idx].num_values++; return 0; @@ -943,8 +923,8 @@ static int ltdb_index_add0(struct ldb_module *module, const char *dn, } for (i = 0; i < num_el; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, - elements[i].name, NULL, LTDB_IDXATTR); + ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, + NULL, LTDB_IDXATTR); if (ret == -1) { continue; } @@ -1017,8 +997,8 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, } if (ret == 0) { - /* it wasn't indexed. Did we have an earlier error? If we did - then its gone now */ + /* it wasn't indexed. Did we have an earlier error? If we did then + its gone now */ talloc_free(dn_key); return 0; } @@ -1080,15 +1060,13 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) } for (i = 0; i < msg->num_elements; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, - msg->elements[i].name, NULL, - LTDB_IDXATTR); + ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, + NULL, LTDB_IDXATTR); if (ret == -1) { continue; } for (j = 0; j < msg->elements[i].num_values; j++) { - ret = ltdb_index_del_value(module, dn, - &msg->elements[i], j); + ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); if (ret == -1) { talloc_free(dn); return -1; @@ -1104,8 +1082,7 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) /* traversal function that deletes all @INDEX records */ -static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *state) +static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { const char *dn = "DN=" LTDB_INDEX ":"; if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) { @@ -1117,8 +1094,7 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, /* traversal function that adds @INDEX records during a re index */ -static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *state) +static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { struct ldb_module *module = (struct ldb_module *)state; struct ldb_message *msg; @@ -1147,9 +1123,8 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, key2 = ltdb_key(module, msg->dn); if (key2.dptr == NULL) { /* probably a corrupt record ... darn */ - ldb_debug(module->ldb, LDB_DEBUG_ERROR, - "Invalid DN in re_index: %s\n", - ldb_dn_linearize(msg, msg->dn)); + ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n", + ldb_dn_linearize(msg, msg->dn)); talloc_free(msg); return 0; } -- cgit From e59e787b4868acffad49b6264e319d585643d5ab Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 20 Dec 2006 01:10:04 +0000 Subject: r20269: merge -r20264:20267 from SAMBA_3_0_24 more no previous prototype warnings (This used to be commit 41be182f78762372ae13759ede5d2bd40a71d7f5) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 2 ++ source3/lib/ldb/ldb_tdb/ldb_tdb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index 632e22762f..c90885bfab 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -42,6 +42,8 @@ #define LTDB_FLAG_HIDDEN (1<<2) #define LTDB_FLAG_OBJECTCLASS (1<<3) +int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name); + /* valid attribute flags */ static const struct { const char *name; diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 232195dfcd..34daba69bf 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -47,6 +47,7 @@ #include "ldb/ldb_tdb/ldb_tdb.h" +int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg); /* map a tdb error code to a ldb error code -- cgit From 63f43ad5e46b73675a3e3aea9abae2d647c05715 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Feb 2007 12:42:28 +0000 Subject: r21312: merge from SAMBA_4_0: fix memory hierachy, and access to already freed memory metze (This used to be commit 05a23dd75655a80667627e00e0a441b54ec92b22) --- source3/lib/ldb/ldb_tdb/ldb_index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 2c88d7e19d..672bc1f625 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -337,7 +337,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, ldb_oom(module->ldb); return -1; } - list->dn[0] = talloc_strdup(list, (char *)tree->u.equality.value.data); + list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data); if (list->dn[0] == NULL) { ldb_oom(module->ldb); return -1; -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index 50dc20524f..45fcf354a5 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -114,7 +114,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = talloc_array(ldb, char, size); + data->dptr = talloc_array(ldb, uint8_t, size); if (!data->dptr) { talloc_free(dn); errno = ENOMEM; diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 34daba69bf..fead100f72 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -151,7 +151,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) goto failed; } - key.dptr = (char *)key_str; + key.dptr = (uint8_t *)key_str; key.dsize = strlen(key_str) + 1; return key; -- cgit From 9bf4687932853873bae1df460762f3d96c5d332f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Jun 2007 14:25:52 +0000 Subject: r23337: fix a crash bug...I wonder why only HP-UX 11.00 ans 11.11 noticed it via a SIGBUS... I missed to remove the samba3 specifc code path to tdb_open_ex() when I synced lib/tdb/ with samba4. The explicit cast in on tdb_open_ex() dropped the compiler warning :-( metze (This used to be commit 815d2101715d6646fc15ac9f2853cf727cf7fcd8) --- source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index 4f3acad9ea..03c9ae85b2 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -58,22 +58,6 @@ static int ltdb_wrap_destructor(struct ltdb_wrap *w) return 0; } -#if defined(_SAMBA_BUILD_) && (_SAMBA_BUILD_ <= 3) -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - /* until we merge the tdb debug changes into samba3, we don't know - how serious the error is, and we can't go via the ldb loggin code */ - va_list ap; - const char *name = tdb_name(tdb); - char *message; - va_start(ap, fmt); - message = talloc_vasprintf(NULL, fmt, ap); - va_end(ap); - DEBUG(3, ("ltdb: tdb(%s): %s", name, message)); - talloc_free(message); -} -#else static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { @@ -106,7 +90,6 @@ static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, con ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); talloc_free(message); } -#endif /* wrapped connection to a tdb database. The caller should _not_ free @@ -122,14 +105,10 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, { struct ltdb_wrap *w; struct stat st; -#if defined(_SAMBA_BUILD_) && (_SAMBA_BUILD_ <= 3) - tdb_log_func log_ctx_p = ltdb_log_fn; -#else struct tdb_logging_context log_ctx; - const struct tdb_logging_context *log_ctx_p = &log_ctx; + log_ctx.log_fn = ltdb_log_fn; log_ctx.log_private = ldb; -#endif if (stat(path, &st) == 0) { for (w=tdb_list;w;w=w->next) { @@ -147,9 +126,7 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, return NULL; } - w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, - (const struct tdb_logging_context *)log_ctx_p, - NULL); + w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, &log_ctx, NULL); if (w->tdb == NULL) { talloc_free(w); return NULL; -- cgit From 422722aad2e50465627a2f7b249c251652297a7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Jun 2007 13:02:14 +0000 Subject: r23367: check the "use mmap" option for ldb too (This used to be commit 15345bbc73b28d07c069fde33d3d4c1f21f107d3) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index fead100f72..8b53982fdb 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1029,6 +1029,11 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, tdb_flags |= TDB_NOSYNC; } + /* and nommap option */ + if (flags & LDB_FLG_NOMMAP) { + tdb_flags |= TDB_NOMMAP; + } + if (flags & LDB_FLG_RDONLY) { open_flags = O_RDONLY; } else { -- cgit From 2c09988e46d4e917b1c53c9bda3f81a48bba4952 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 01:44:42 +0000 Subject: r23790: LGPLv3+ conversion for our LGPLv2+ library code (This used to be commit 1b78cace504f60c0f525765fbf59d9cc6506cd4d) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_index.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_pack.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_search.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index c90885bfab..cc85479f88 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 672bc1f625..379f5a5994 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index 45fcf354a5..df01dfb438 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c index 7a6fe263fd..d4965ed660 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_search.c +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index 8b53982fdb..dd3aba7662 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -13,7 +13,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index 03c9ae85b2..46de53d54e 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- cgit From 9fa1c63578733077c0aaaeeb2fc97c3b191089cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:42:26 +0000 Subject: r23798: updated old Temple Place FSF addresses to new URL (This used to be commit c676a971142d7176fd5dbf21405fca14515a0a76) --- source3/lib/ldb/ldb_tdb/ldb_cache.c | 3 +-- source3/lib/ldb/ldb_tdb/ldb_index.c | 3 +-- source3/lib/ldb/ldb_tdb/ldb_pack.c | 3 +-- source3/lib/ldb/ldb_tdb/ldb_search.c | 3 +-- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 3 +-- source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_cache.c b/source3/lib/ldb/ldb_tdb/ldb_cache.c index cc85479f88..16e8c55aec 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source3/lib/ldb/ldb_tdb/ldb_cache.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* diff --git a/source3/lib/ldb/ldb_tdb/ldb_index.c b/source3/lib/ldb/ldb_tdb/ldb_index.c index 379f5a5994..5545661f7a 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_index.c +++ b/source3/lib/ldb/ldb_tdb/ldb_index.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index df01dfb438..3f3d1ccca7 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* diff --git a/source3/lib/ldb/ldb_tdb/ldb_search.c b/source3/lib/ldb/ldb_tdb/ldb_search.c index d4965ed660..9ef8eb9295 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_search.c +++ b/source3/lib/ldb/ldb_tdb/ldb_search.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index dd3aba7662..cdcfe5a046 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -21,8 +21,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c index 46de53d54e..2fff74d59a 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ #include "includes.h" -- cgit From 4f4f1dfbb6b66c13de32bdc78fc13c030f10d71d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Mar 2008 11:52:34 +0100 Subject: Fix Coverity ID 473 Simo, S4 also has this bug, you might want to merge the fix. (This used to be commit b82cf75c825298444781697072d83a163c43df4b) --- source3/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb') diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.c b/source3/lib/ldb/ldb_tdb/ldb_tdb.c index cdcfe5a046..27cc0c69c6 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1058,7 +1058,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, ltdb->sequence_number = 0; *module = talloc(ldb, struct ldb_module); - if (!module) { + if ((*module) == NULL) { ldb_oom(ldb); talloc_free(ltdb); return -1; -- cgit