summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-10-02 22:39:19 +1000
committerAndrew Tridgell <tridge@samba.org>2009-10-02 22:39:19 +1000
commit52b10ff3c5b4291c2f99922016417b2c4ae215e8 (patch)
treebbc08d6e1617038ef27e34cd8a0c00dc3ad24e41
parentdfafd58348278276e51f84fe0d9e04ad41c3ac3d (diff)
downloadsamba-52b10ff3c5b4291c2f99922016417b2c4ae215e8.tar.gz
samba-52b10ff3c5b4291c2f99922016417b2c4ae215e8.tar.bz2
samba-52b10ff3c5b4291c2f99922016417b2c4ae215e8.zip
Revert "s4-ldb: merged with master"
This reverts commit 14c9070322d089dd96b389e8087c4f4bf1a6c7cc.
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c84
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c778
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c43
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c187
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h54
5 files changed, 523 insertions, 623 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index f853023509..2c399686ea 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -190,6 +190,8 @@ static int ltdb_baseinfo_init(struct ldb_module *module)
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
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
@@ -200,21 +202,31 @@ static int ltdb_baseinfo_init(struct ldb_module *module)
ltdb->sequence_number = atof(initial_sequence_number);
- msg = ldb_msg_new(ltdb);
+ msg = talloc(ltdb, struct ldb_message);
+ if (msg == NULL) {
+ goto failed;
+ }
+
+ msg->num_elements = 1;
+ msg->elements = &el;
msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
if (!msg->dn) {
goto failed;
}
-
- if (ldb_msg_add_string(msg, LTDB_SEQUENCE_NUMBER, initial_sequence_number) != 0) {
+ el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
+ if (!el.name) {
goto failed;
}
-
- if (ldb_msg_add_string(msg, LTDB_INDEX_VERSION, "1") != 0) {
+ 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;
}
-
- ret = ltdb_store(module, msg, msg, TDB_INSERT);
+ val.length = 1;
+
+ ret = ltdb_store(module, msg, TDB_INSERT);
talloc_free(msg);
@@ -313,16 +325,6 @@ int ltdb_cache_load(struct ldb_module *module)
}
ltdb->sequence_number = seq;
- /* Determine what index format we are in (updated on reindex) */
- ltdb->index_version = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_INDEX_VERSION, 0);
-
- if (ltdb->index_version > 1) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid index version %d on database. This ldb supports only index version 0 and 1",
- ltdb->index_version);
- goto failed;
- }
-
/* Read an interpret database options */
options = talloc(ltdb->cache, struct ldb_message);
if (options == NULL) goto failed;
@@ -446,15 +448,13 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
s = ldb_timestring(msg, t);
if (s == NULL) {
- talloc_free(msg);
- errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
}
val_time.data = (uint8_t *)s;
val_time.length = strlen(s);
- ret = ltdb_modify_internal(module, msg, msg);
+ ret = ltdb_modify_internal(module, msg);
talloc_free(msg);
@@ -469,50 +469,6 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
return ret;
}
-/*
- increase the index version number to indicate a database change
-*/
-int ltdb_set_casefold_index(struct ldb_module *module)
-{
- struct ldb_context *ldb;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- struct ldb_message *msg;
- struct ldb_message_element *el;
-
- int ret;
-
- ldb = ldb_module_get_ctx(module);
-
- msg = ldb_msg_new(ltdb);
- if (msg == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- msg->dn = ldb_dn_new(msg, ldb, LTDB_BASEINFO);
- if (msg->dn == NULL) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ldb_msg_add_string(msg, LTDB_INDEX_VERSION, "1") != 0) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- el = ldb_msg_find_element(msg, LTDB_INDEX_VERSION);
- if (!el) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- el->flags = LDB_FLAG_MOD_REPLACE;
-
- ret = ltdb_modify_internal(module, msg, msg);
-
- talloc_free(msg);
-
- return ret;
-}
-
int ltdb_check_at_attributes_values(const struct ldb_val *value)
{
int i;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 0b96e07a7d..7b8d2c249b 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -33,7 +33,6 @@
#include "ldb_tdb.h"
#include "dlinklist.h"
-#include "ldb_handlers.h"
/*
the idxptr code is a bit unusual. The way it works is to replace
@@ -54,12 +53,13 @@
@INDEX records many times during indexing.
*/
struct ldb_index_pointer {
- struct ldb_message_element el;
+ struct ldb_index_pointer *next, *prev;
+ struct ldb_val value;
};
struct ltdb_idxptr {
int num_dns;
- struct TDB_DATA *dn_list;
+ const char **dn_list;
bool repack;
};
@@ -71,53 +71,57 @@ static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message *
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
ltdb->idxptr->dn_list = talloc_realloc(ltdb->idxptr, ltdb->idxptr->dn_list,
- struct TDB_DATA, ltdb->idxptr->num_dns+1);
+ const char *, ltdb->idxptr->num_dns+1);
if (ltdb->idxptr->dn_list == NULL) {
ltdb->idxptr->num_dns = 0;
return LDB_ERR_OPERATIONS_ERROR;
}
ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] =
- ltdb_key(ltdb->idxptr->dn_list, msg->dn);
- if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns].dptr == NULL) {
+ talloc_strdup(ltdb->idxptr->dn_list, ldb_dn_get_linearized(msg->dn));
+ if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
ltdb->idxptr->num_dns++;
return LDB_SUCCESS;
}
-/* return an idxptr record */
-static struct ldb_index_pointer *ltdb_return_idxptr(struct ldb_module *module, struct ldb_message_element *el)
+/* free an idxptr record */
+static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el)
{
struct ldb_val val;
struct ldb_index_pointer *ptr;
if (el->num_values != 1) {
- return NULL;
+ return LDB_ERR_OPERATIONS_ERROR;
}
val = el->values[0];
if (val.length != sizeof(void *)) {
- return NULL;
+ return LDB_ERR_OPERATIONS_ERROR;
}
ptr = *(struct ldb_index_pointer **)val.data;
if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
- return NULL;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ while (ptr) {
+ struct ldb_index_pointer *tmp = ptr;
+ DLIST_REMOVE(ptr, ptr);
+ talloc_free(tmp);
}
- return ptr;
+ return LDB_SUCCESS;
}
+
/* convert from the IDXPTR format to a ldb_message_element format */
-static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message *msg, struct ldb_index_pointer **ptr_out)
+static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message_element *el)
{
struct ldb_val val;
- struct ldb_index_pointer *ptr;
-
- struct ldb_message_element *el = ldb_msg_find_element(msg, LTDB_IDXPTR);
- if (!el) {
- return LDB_SUCCESS;
- }
+ struct ldb_index_pointer *ptr, *tmp;
+ int i;
+ struct ldb_val *val2;
if (el->num_values != 1) {
return LDB_ERR_OPERATIONS_ERROR;
@@ -133,28 +137,65 @@ static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_messag
return LDB_ERR_OPERATIONS_ERROR;
}
- *el = ptr->el;
+ /* count the length of the list */
+ for (i=0, tmp = ptr; tmp; tmp=tmp->next) {
+ i++;
+ }
- if (ptr_out) {
- *ptr_out = ptr;
+ /* allocate the new values array */
+ val2 = talloc_realloc(NULL, el->values, struct ldb_val, i);
+ if (val2 == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ el->values = val2;
+ el->num_values = i;
+
+ /* populate the values array */
+ for (i=0, tmp = ptr; tmp; tmp=tmp->next, i++) {
+ el->values[i].length = tmp->value.length;
+ /* we need to over-allocate here as there are still some places
+ in ldb that rely on null termination. */
+ el->values[i].data = talloc_size(el->values, tmp->value.length+1);
+ if (el->values[i].data == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ memcpy(el->values[i].data, tmp->value.data, tmp->value.length);
+ el->values[i].data[tmp->value.length] = 0;
}
+ /* update the name */
+ el->name = LTDB_IDX;
+
return LDB_SUCCESS;
}
/* convert to the IDXPTR format from a ldb_message_element format */
-static int ltdb_update_idxptr(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_index_pointer *ptr,
- struct ldb_message_element *el)
+static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_element *el)
{
+ struct ldb_index_pointer *ptr, *tmp;
+ int i;
struct ldb_val *val2;
- ptr->el = *el;
- talloc_steal(ptr, el->values);
- talloc_steal(ptr, el->name);
+ void *data = ldb_module_get_private(module);
+ struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+
+ ptr = NULL;
+
+ for (i=0;i<el->num_values;i++) {
+ tmp = talloc(ltdb->idxptr, struct ldb_index_pointer);
+ if (tmp == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ tmp->value = el->values[i];
+ tmp->value.data = talloc_memdup(tmp, tmp->value.data, tmp->value.length);
+ if (tmp->value.data == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ DLIST_ADD(ptr, tmp);
+ }
/* allocate the new values array */
- val2 = talloc_array(mem_ctx, struct ldb_val, 1);
+ val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1);
if (val2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -170,21 +211,6 @@ static int ltdb_update_idxptr(struct ldb_module *module, TALLOC_CTX *mem_ctx,
return LDB_SUCCESS;
}
-/* convert to the IDXPTR format from a ldb_message_element format */
-static int ltdb_convert_to_idxptr(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_message_element *el)
-{
- struct ldb_index_pointer *ptr;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
-
- ptr = talloc(ltdb->idxptr, struct ldb_index_pointer);
-
- ltdb_update_idxptr(module, mem_ctx, ptr, el);
-
- return LDB_SUCCESS;
-}
-
/* enable the idxptr mode when transactions start */
int ltdb_index_transaction_start(struct ldb_module *module)
@@ -199,72 +225,57 @@ int ltdb_index_transaction_start(struct ldb_module *module)
a wrapper around ltdb_search_dn1() which translates pointer based index records
and maps them into normal ldb message structures
*/
-static int ltdb_search_dn1_index_key(struct ldb_module *module,
- struct TDB_DATA dn_key, struct ldb_message *msg,
- struct ldb_index_pointer **ptr_out)
+static int ltdb_search_dn1_index(struct ldb_module *module,
+ struct ldb_dn *dn, struct ldb_message *msg)
{
- int ret;
- ret = ltdb_search_dn1_key(module, dn_key, msg);
+ int ret, i;
+ ret = ltdb_search_dn1(module, dn, msg);
if (ret != LDB_SUCCESS) {
return ret;
}
/* if this isn't a @INDEX record then don't munge it */
if (strncmp(ldb_dn_get_linearized(msg->dn), LTDB_INDEX ":", strlen(LTDB_INDEX) + 1) != 0) {
- return LDB_ERR_INVALID_DN_SYNTAX;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_convert_from_idxptr(module, msg, ptr_out);
- if (ret != LDB_SUCCESS) {
- return ret;
+ for (i=0;i<msg->num_elements;i++) {
+ struct ldb_message_element *el = &msg->elements[i];
+ if (strcmp(el->name, LTDB_IDXPTR) == 0) {
+ ret = ltdb_convert_from_idxptr(module, el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
}
return ret;
}
-/*
- a wrapper around ltdb_search_dn1() which translates pointer based index records
- and maps them into normal ldb message structures
- */
-static int ltdb_search_dn1_index(struct ldb_module *module,
- struct ldb_dn *dn, struct ldb_message *msg,
- struct ldb_index_pointer **ptr_out)
-{
- int ret;
- TDB_DATA tdb_key = ltdb_key(msg, dn);
- if (!tdb_key.dptr) {
- /* Why could we not get a casefolded form on this DN? */
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- ret = ltdb_search_dn1_index_key(module, tdb_key, msg, ptr_out);
- talloc_free(tdb_key.dptr);
- return ret;
-}
/*
fixup the idxptr for one DN
*/
-static int ltdb_idxptr_fix_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct TDB_DATA dn_key)
+static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn)
{
struct ldb_context *ldb;
- struct ldb_message *msg = ldb_msg_new(mem_ctx);
- struct ldb_index_pointer *ptr = NULL;
+ struct ldb_dn *dn;
+ struct ldb_message *msg = ldb_msg_new(module);
int ret;
ldb = ldb_module_get_ctx(module);
- if (ltdb_search_dn1_index_key(module, dn_key, msg, &ptr) == LDB_SUCCESS) {
- ret = ltdb_store(module, msg, msg, TDB_REPLACE);
- talloc_free(ptr);
+ dn = ldb_dn_new(msg, ldb, strdn);
+ if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) {
+ ret = ltdb_store(module, msg, TDB_REPLACE);
}
talloc_free(msg);
return ret;
}
/* cleanup the idxptr mode when transaction commits */
-int ltdb_index_transaction_prepare_commit(struct ldb_module *module)
+int ltdb_index_transaction_commit(struct ldb_module *module)
{
int i;
void *data = ldb_module_get_private(module);
@@ -273,8 +284,7 @@ int ltdb_index_transaction_prepare_commit(struct ldb_module *module)
/* fix all the DNs that we have modified */
if (ltdb->idxptr) {
for (i=0;i<ltdb->idxptr->num_dns;i++) {
- ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list,
- ltdb->idxptr->dn_list[i]);
+ ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list[i]);
}
if (ltdb->idxptr->repack) {
@@ -284,7 +294,6 @@ int ltdb_index_transaction_prepare_commit(struct ldb_module *module)
talloc_free(ltdb->idxptr);
ltdb->idxptr = NULL;
-
return LDB_SUCCESS;
}
@@ -305,55 +314,47 @@ int ltdb_index_transaction_cancel(struct ldb_module *module)
WARNING: This modifies the msg which is passed in
*/
-static int ltdb_store_idxptr(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg,
- struct ldb_message_element *idx_el, int flgs)
+int ltdb_store_idxptr(struct ldb_module *module, const struct ldb_message *msg, int flgs)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int ret;
if (ltdb->idxptr) {
- struct ldb_message *msg2;
- struct ldb_message_element *idxptr_el = NULL;
+ int i;
+ struct ldb_message *msg2 = ldb_msg_new(module);
- /* reuse any old pointer */
- msg2 = ldb_msg_new(mem_ctx);
+ /* free any old pointer */
ret = ltdb_search_dn1(module, msg->dn, msg2);
if (ret == 0) {
- idxptr_el = ldb_msg_find_element(msg2, LTDB_IDXPTR);
- }
-
- /* If we have an idxptr record already, then reuse it */
- if (idxptr_el) {
- struct ldb_index_pointer *ptr = ltdb_return_idxptr(module, idxptr_el);
- talloc_free(msg2);
- if (!ptr) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ret = ltdb_update_idxptr(module, msg->elements, ptr, idx_el);
- if (ret != LDB_SUCCESS) {
- talloc_free(msg2);
- return ret;
- }
- } else {
- talloc_free(msg2);
- ret = ltdb_convert_to_idxptr(module, msg->elements, idx_el);
- if (ret != LDB_SUCCESS) {
- return ret;
+ for (i=0;i<msg2->num_elements;i++) {
+ struct ldb_message_element *el = &msg2->elements[i];
+ if (strcmp(el->name, LTDB_IDXPTR) == 0) {
+ ret = ltdb_free_idxptr(module, el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
}
- /* Otherwise, we must add it to the list of
- * things to fix up at the end of the
- * transaction */
- ret = ltdb_idxptr_add(module, msg);
- if (ret != LDB_SUCCESS) {
- return ret;
+ }
+ talloc_free(msg2);
+
+ for (i=0;i<msg->num_elements;i++) {
+ struct ldb_message_element *el = &msg->elements[i];
+ if (strcmp(el->name, LTDB_IDX) == 0) {
+ ret = ltdb_convert_to_idxptr(module, el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
}
}
- /* Make sure we still do the ltdb_store */
+
+ if (ltdb_idxptr_add(module, msg) != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
- ret = ltdb_store(module, mem_ctx, msg, flgs);
+ ret = ltdb_store(module, msg, flgs);
return ret;
}
@@ -411,7 +412,7 @@ static int ldb_list_find(const void *needle,
struct dn_list {
unsigned int count;
- struct ldb_val *dn;
+ char **dn;
};
/*
@@ -419,7 +420,6 @@ struct dn_list {
caller frees
*/
static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
- TALLOC_CTX *mem_ctx,
const char *attr, const struct ldb_val *value,
const struct ldb_schema_attribute **ap)
{
@@ -428,12 +428,8 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
const struct ldb_schema_attribute *a;
char *attr_folded;
int r;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- return NULL;
- }
- attr_folded = ldb_attr_casefold(tmp_ctx, attr);
+ attr_folded = ldb_attr_casefold(ldb, attr);
if (!attr_folded) {
return NULL;
}
@@ -442,7 +438,7 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
if (ap) {
*ap = a;
}
- r = a->syntax->canonicalise_fn(ldb, tmp_ctx, value, &v);
+ r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
if (r != LDB_SUCCESS) {
const char *errstr = ldb_errstring(ldb);
/* canonicalisation can be refused. For example,
@@ -450,19 +446,23 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
if the value contains a wildcard */
ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s",
attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:""));
- talloc_free(tmp_ctx);
+ talloc_free(attr_folded);
return NULL;
}
if (ldb_should_b64_encode(ldb, &v)) {
char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
if (!vstr) return NULL;
- ret = ldb_dn_new_fmt(tmp_ctx, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
+ ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
+ talloc_free(vstr);
} else {
- ret = ldb_dn_new_fmt(tmp_ctx, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data);
+ ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data);
}
- talloc_steal(mem_ctx, ret);
- talloc_free(tmp_ctx);
+ if (v.data != value->data) {
+ talloc_free(v.data);
+ }
+ talloc_free(attr_folded);
+
return ret;
}
@@ -470,7 +470,7 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
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,
- const char *key)
+ unsigned int *v_idx, const char *key)
{
unsigned int i, j;
for (i=0;i<msg->num_elements;i++) {
@@ -485,8 +485,10 @@ static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr,
for (j=0;j<el->num_values;j++) {
if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) {
- /* We found the index we were looking for */
- return 0;
+ if (v_idx) {
+ *v_idx = j;
+ }
+ return i;
}
}
}
@@ -494,122 +496,88 @@ static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr,
return -1;
}
-static int tdb_data_cmp(const struct TDB_DATA *s1, const struct TDB_DATA *s2)
-{
- struct ldb_val l1, l2;
- l1.data = s1->dptr;
- l1.length = s1->dsize;
- l2.data = s2->dptr;
- l2.length = s2->dsize;
- return ldb_comparison_binary(NULL, NULL, &l1, &l2);
-}
-
/* used in sorting dn lists */
-static int ldb_val_list_cmp(const struct ldb_val *l1, const struct ldb_val *l2)
+static int list_cmp(const char **s1, const char **s2)
{
- return ldb_comparison_binary(NULL, NULL, l1, l2);
+ return strcmp(*s1, *s2);
}
/*
return a list of dn's that might match a simple indexed search or
*/
-static int ltdb_index_load(struct ldb_module *module,
- const char *attr, const struct ldb_val *value,
- struct dn_list *list)
+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;
- struct ldb_dn *dn_key;
+ struct ldb_dn *dn;
int ret;
- unsigned int j;
+ unsigned int i, j;
struct ldb_message *msg;
- void *data = ldb_module_get_private(module);
- struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
- struct ldb_message_element *el;
ldb = ldb_module_get_ctx(module);
list->count = 0;
list->dn = NULL;
- msg = talloc(list, struct ldb_message);
- if (msg == 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 LDB_ERR_OPERATIONS_ERROR;
}
/* the attribute is indexed. Pull the list of DNs that match the
search criterion */
- dn_key = ltdb_index_key(ldb, msg, attr, value, NULL);
- if (!dn_key) {
- talloc_free(msg);
+ dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
+ if (!dn) return LDB_ERR_OPERATIONS_ERROR;
+
+ msg = talloc(list, struct ldb_message);
+ if (msg == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_index(module, dn_key, msg, NULL);
- talloc_free(dn_key);
+ ret = ltdb_search_dn1_index(module, dn, msg);
+ talloc_free(dn);
if (ret != LDB_SUCCESS) {
- talloc_free(msg);
return ret;
}
- el = ldb_msg_find_element(msg, LTDB_IDX);
+ for (i=0;i<msg->num_elements;i++) {
+ struct ldb_message_element *el;
- if (!el) {
- return LDB_SUCCESS;
- }
+ if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
+ continue;
+ }
- if (ltdb->index_version > 0) {
- list->dn = el->values;
- list->count = el->num_values;
- }
-
- list->dn = talloc_array(list, struct ldb_val, el->num_values);
- if (!list->dn) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Normalise the index loaded off the disk into the new format */
- for (j=0;j<el->num_values;j++) {
- struct ldb_dn *dn = ldb_dn_from_ldb_val(list->dn, ldb, &el->values[j]);
- if (!dn) {
+ el = &msg->elements[i];
+
+ list->dn = talloc_array(list, char *, el->num_values);
+ if (!list->dn) {
talloc_free(msg);
- return LDB_ERR_INVALID_DN_SYNTAX;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- list->dn[j] = ldb_dn_alloc_casefold_as_ldb_val(list->dn, dn);
- talloc_free(dn);
- if (!list->dn[j].data) {
- talloc_free(msg);
- return LDB_ERR_INVALID_DN_SYNTAX;
+
+ for (j=0;j<el->num_values;j++) {
+ list->dn[list->count] =
+ talloc_strdup(list->dn, (char *)el->values[j].data);
+ if (!list->dn[list->count]) {
+ talloc_free(msg);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ list->count++;
}
}
- /* In the old index version, we must sort the index when
- * reading from disk. In index version 1, the list on disk is
- * pre-sorted */
+ talloc_free(msg);
+
if (list->count > 1) {
- qsort(list->dn, list->count, sizeof(struct ldb_val), (comparison_fn_t) ldb_val_list_cmp);
+ qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp);
}
return LDB_SUCCESS;
}
-/*
- 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)
-{
- /* 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, LTDB_IDXATTR) == -1) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return ltdb_index_load(module, tree->u.equality.attr, &tree->u.equality.value, list);
-}
-
static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
@@ -625,21 +593,15 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
ldb = ldb_module_get_ctx(module);
if (ldb_attr_dn(tree->u.equality.attr) == 0) {
- struct ldb_dn *target_as_dn;
- list->dn = talloc_array(list, struct ldb_val, 1);
+ list->dn = talloc_array(list, char *, 1);
if (list->dn == NULL) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- target_as_dn = ldb_dn_from_ldb_val(list->dn, ldb, &tree->u.equality.value);
- if (target_as_dn == NULL) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- list->dn[0] = ldb_dn_alloc_casefold_as_ldb_val(list->dn, target_as_dn);
- talloc_free(target_as_dn);
-
- if (list->dn[0].data == NULL) {
- return LDB_ERR_INVALID_DN_SYNTAX;
+ list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data);
+ if (list->dn[0] == NULL) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
list->count = 1;
return LDB_SUCCESS;
@@ -653,7 +615,8 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
list = list & list2
relies on the lists being sorted
*/
-static int list_intersect(struct dn_list *list, const struct dn_list *list2)
+static int list_intersect(struct ldb_context *ldb,
+ struct dn_list *list, const struct dn_list *list2)
{
struct dn_list *list3;
unsigned int i;
@@ -663,12 +626,12 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
return LDB_ERR_NO_SUCH_OBJECT;
}
- list3 = talloc(list, struct dn_list);
+ list3 = talloc(ldb, struct dn_list);
if (list3 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- list3->dn = talloc_array(list3, struct ldb_val, list->count);
+ list3->dn = talloc_array(list3, char *, list->count);
if (!list3->dn) {
talloc_free(list3);
return LDB_ERR_OPERATIONS_ERROR;
@@ -676,13 +639,16 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
list3->count = 0;
for (i=0;i<list->count;i++) {
- if (ldb_list_find(&list->dn[i], list2->dn, list2->count,
- sizeof(struct ldb_val), (comparison_fn_t)ldb_val_list_cmp) != -1) {
- list3->dn[list3->count] = list->dn[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);
@@ -700,7 +666,7 @@ static int list_union(struct ldb_context *ldb,
struct dn_list *list, const struct dn_list *list2)
{
unsigned int i;
- struct ldb_val *d;
+ char **d;
unsigned int count = list->count;
if (list->count == 0 && list2->count == 0) {
@@ -708,22 +674,25 @@ static int list_union(struct ldb_context *ldb,
return LDB_ERR_NO_SUCH_OBJECT;
}
- d = talloc_realloc(list, list->dn, struct ldb_val, list->count + list2->count);
+ d = talloc_realloc(list, list->dn, char *, list->count + list2->count);
if (!d) {
return LDB_ERR_OPERATIONS_ERROR;
}
list->dn = d;
for (i=0;i<list2->count;i++) {
- if (ldb_list_find(&list2->dn[i], list->dn, count,
- sizeof(struct ldb_val), (comparison_fn_t)ldb_val_list_cmp) == -1) {
- list->dn[list->count] = list2->dn[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 LDB_ERR_OPERATIONS_ERROR;
+ }
list->count++;
}
}
if (list->count != count) {
- qsort(list->dn, list->count, sizeof(struct ldb_val), (comparison_fn_t) ldb_val_list_cmp);
+ qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp);
}
return LDB_ERR_NO_SUCH_OBJECT;
@@ -757,7 +726,7 @@ static int ltdb_index_dn_or(struct ldb_module *module,
struct dn_list *list2;
int v;
- list2 = talloc(list, struct dn_list);
+ list2 = talloc(module, struct dn_list);
if (list2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -791,6 +760,7 @@ static int ltdb_index_dn_or(struct ldb_module *module,
}
ret = LDB_SUCCESS;
}
+ talloc_free(list2);
}
if (list->count == 0) {
@@ -868,7 +838,7 @@ static int ltdb_index_dn_and(struct ldb_module *module,
}
if (is_unique != only_unique) continue;
- list2 = talloc(list, struct dn_list);
+ list2 = talloc(module, struct dn_list);
if (list2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -893,12 +863,14 @@ static int ltdb_index_dn_and(struct ldb_module *module,
list->dn = talloc_move(list, &list2->dn);
list->count = list2->count;
} else {
- if (list_intersect(list, list2) == -1) {
+ if (list_intersect(ldb, list, list2) == -1) {
talloc_free(list2);
return LDB_ERR_OPERATIONS_ERROR;
}
}
+ talloc_free(list2);
+
if (list->count == 0) {
talloc_free(list->dn);
return LDB_ERR_NO_SUCH_OBJECT;
@@ -920,31 +892,79 @@ static int ltdb_index_dn_one(struct ldb_module *module,
struct ldb_dn *parent_dn,
struct dn_list *list)
{
+ struct ldb_context *ldb;
struct dn_list *list2;
+ struct ldb_message *msg;
+ struct ldb_dn *key;
struct ldb_val val;
+ unsigned int i, j;
int ret;
- list2 = talloc_zero(list, struct dn_list);
+ ldb = ldb_module_get_ctx(module);
+
+ list2 = talloc_zero(module, struct dn_list);
if (list2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
/* the attribute is indexed. Pull the list of DNs that match the
search criterion */
- val = ldb_dn_get_casefold_as_ldb_val(parent_dn);
- if (!val.data) {
+ val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
+ val.length = strlen((char *)val.data);
+ key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
+ if (!key) {
talloc_free(list2);
- return LDB_ERR_INVALID_DN_SYNTAX;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_index_load(module, LTDB_IDXONE, &val, list2);
- if (ret != LDB_SUCCESS) {
+ msg = talloc(list2, struct ldb_message);
+ if (msg == NULL) {
talloc_free(list2);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ltdb_search_dn1_index(module, key, msg);
+ talloc_free(key);
+ if (ret != LDB_SUCCESS) {
return ret;
}
+ for (i = 0; i < msg->num_elements; i++) {
+ struct ldb_message_element *el;
+
+ if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
+ continue;
+ }
+
+ el = &msg->elements[i];
+
+ list2->dn = talloc_array(list2, char *, el->num_values);
+ if (!list2->dn) {
+ talloc_free(list2);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ for (j = 0; j < el->num_values; j++) {
+ list2->dn[list2->count] = talloc_strdup(list2->dn, (char *)el->values[j].data);
+ if (!list2->dn[list2->count]) {
+ talloc_free(list2);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ list2->count++;
+ }
+ }
+
+ if (list2->count == 0) {
+ talloc_free(list2);
+ return LDB_ERR_NO_SUCH_OBJECT;
+ }
+
+ if (list2->count > 1) {
+ qsort(list2->dn, list2->count, sizeof(char *), (comparison_fn_t) list_cmp);
+ }
+
if (list->count > 0) {
- if (list_intersect(list, list2) == -1) {
+ if (list_intersect(ldb, list, list2) == -1) {
talloc_free(list2);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -959,6 +979,8 @@ static int ltdb_index_dn_one(struct ldb_module *module,
list->count = list2->count;
}
+ talloc_free(list2);
+
return LDB_SUCCESS;
}
@@ -1019,22 +1041,22 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
ldb = ldb_module_get_ctx(ac->module);
for (i = 0; i < dn_list->count; i++) {
+ struct ldb_dn *dn;
int ret;
- struct TDB_DATA key;
msg = ldb_msg_new(ac);
if (!msg) {
- ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- key = ltdb_key_from_casefold_dn(msg, dn_list->dn[i]);
- if (!key.dptr) {
+ dn = ldb_dn_new(msg, ldb, dn_list->dn[i]);
+ if (dn == NULL) {
+ talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_key(ac->module, key, msg);
- talloc_free(key.dptr);
+ ret = ltdb_search_dn1(ac->module, dn, msg);
+ talloc_free(dn);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
/* the record has disappeared? yes, this can happen */
talloc_free(msg);
@@ -1089,13 +1111,13 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
ldb = ldb_module_get_ctx(ac->module);
idxattr = idxone = 0;
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, LTDB_IDXATTR);
+ ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXATTR);
if (ret == 0 ) {
idxattr = 1;
}
/* We do one level indexing only if requested */
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, LTDB_IDXONE);
+ ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
if (ret == 0 ) {
idxone = 1;
}
@@ -1115,14 +1137,15 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
if (ac->scope == LDB_SCOPE_BASE) {
/* with BASE searches only one DN can match */
- dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
+ dn_list->dn = talloc_array(dn_list, char *, 1);
if (dn_list->dn == NULL) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- dn_list->dn[0] = ldb_dn_alloc_casefold_as_ldb_val(dn_list->dn, ac->base);
- if (dn_list->dn[0].data == NULL) {
- return LDB_ERR_INVALID_DN_SYNTAX;
+ dn_list->dn[0] = ldb_dn_alloc_linearized(dn_list, ac->base);
+ if (dn_list->dn[0] == NULL) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
dn_list->count = 1;
ret = LDB_SUCCESS;
@@ -1153,18 +1176,33 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
*/
static int ltdb_index_add1_new(struct ldb_context *ldb,
struct ldb_message *msg,
- struct ldb_val *casefold_dn,
- struct ldb_message_element **el)
+ const char *dn)
{
- int ret = ldb_msg_add_value(msg, LTDB_IDX, casefold_dn, el);
- if (ret == LDB_SUCCESS) {
- talloc_steal((*el)->values, casefold_dn->data);
+ struct ldb_message_element *el;
+
+ /* add another entry */
+ el = talloc_realloc(msg, msg->elements,
+ struct ldb_message_element, msg->num_elements+1);
+ if (!el) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- if (ret != LDB_SUCCESS) {
- ldb_oom(ldb);
- return ret;
+
+ msg->elements = el;
+ msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX);
+ if (!msg->elements[msg->num_elements].name) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- return ret;
+ 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 LDB_ERR_OPERATIONS_ERROR;
+ }
+ 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 LDB_SUCCESS;
}
@@ -1174,16 +1212,16 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
*/
static int ltdb_index_add1_add(struct ldb_context *ldb,
struct ldb_message *msg,
- struct ldb_message_element *el,
- struct ldb_val *casefold_dn,
+ int idx,
+ const char *dn,
const struct ldb_schema_attribute *a)
{
struct ldb_val *v2;
unsigned int i;
/* for multi-valued attributes we can end up with repeats */
- for (i=0;i<el->num_values;i++) {
- if (ldb_comparison_binary(NULL, NULL, casefold_dn, &el->values[i]) == 0) {
+ for (i=0;i<msg->elements[idx].num_values;i++) {
+ if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) {
return LDB_SUCCESS;
}
}
@@ -1192,22 +1230,17 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
return LDB_ERR_ENTRY_ALREADY_EXISTS;
}
- v2 = talloc_realloc(msg->elements, el->values,
+ v2 = talloc_realloc(msg->elements, msg->elements[idx].values,
struct ldb_val,
- el->num_values+1);
+ msg->elements[idx].num_values+1);
if (!v2) {
- ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- el->values = v2;
+ msg->elements[idx].values = v2;
- el->values[el->num_values] = *casefold_dn;
- el->num_values++;
- talloc_steal(el->values, casefold_dn->data);
-
- /* In Index version 1, we must have a sorted index list on
- * disk. Harmless for reading with the old index version. */
- qsort(el->values, el->num_values, sizeof(struct ldb_val), (comparison_fn_t) ldb_val_list_cmp);
+ 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 LDB_SUCCESS;
}
@@ -1215,34 +1248,32 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
/*
add an index entry for one message element
*/
-static int ltdb_index_add1(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn,
+static int ltdb_index_add1(struct ldb_module *module, const char *dn,
struct ldb_message_element *el, int v_idx)
{
struct ldb_context *ldb;
struct ldb_message *msg;
struct ldb_dn *dn_key;
int ret;
+ unsigned int i;
const struct ldb_schema_attribute *a;
- struct ldb_val casefold_dn;
ldb = ldb_module_get_ctx(module);
- msg = talloc(mem_ctx, struct ldb_message);
+ msg = talloc(module, struct ldb_message);
if (msg == NULL) {
- ldb_oom(ldb);
+ errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
}
- dn_key = ltdb_index_key(ldb, msg, el->name, &el->values[v_idx], &a);
+ dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
if (!dn_key) {
talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
talloc_steal(msg, dn_key);
- ret = ltdb_search_dn1_index(module, dn_key, msg, NULL);
-
+ ret = ltdb_search_dn1_index(module, dn_key, msg);
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
talloc_free(msg);
return ret;
@@ -1253,30 +1284,21 @@ static int ltdb_index_add1(struct ldb_module *module, TALLOC_CTX *mem_ctx,
msg->num_elements = 0;
msg->elements = NULL;
}
-
- el = ldb_msg_find_element(msg, LTDB_IDX);
- casefold_dn = ldb_dn_get_casefold_as_ldb_val(dn);
- if (!casefold_dn.data) {
- talloc_free(msg);
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- casefold_dn.data = talloc_memdup(msg, casefold_dn.data, casefold_dn.length);
- if (!casefold_dn.data) {
- talloc_free(msg);
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ for (i=0;i<msg->num_elements;i++) {
+ if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) {
+ break;
+ }
}
- if (!el) {
- ret = ltdb_index_add1_new(ldb, msg, &casefold_dn, &el);
+ if (i == msg->num_elements) {
+ ret = ltdb_index_add1_new(ldb, msg, dn);
} else {
- ret = ltdb_index_add1_add(ldb, msg, el, &casefold_dn, a);
+ ret = ltdb_index_add1_add(ldb, msg, i, dn, a);
}
if (ret == LDB_SUCCESS) {
- ret = ltdb_store_idxptr(module, msg, msg, el, TDB_REPLACE);
+ ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
}
talloc_free(msg);
@@ -1284,8 +1306,7 @@ static int ltdb_index_add1(struct ldb_module *module, TALLOC_CTX *mem_ctx,
return ret;
}
-static int ltdb_index_add0(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn,
+static int ltdb_index_add0(struct ldb_module *module, const char *dn,
struct ldb_message_element *elements, int num_el)
{
void *data = ldb_module_get_private(module);
@@ -1293,6 +1314,10 @@ static int ltdb_index_add0(struct ldb_module *module, TALLOC_CTX *mem_ctx,
int ret;
unsigned int i, j;
+ if (dn[0] == '@') {
+ return LDB_SUCCESS;
+ }
+
if (ltdb->cache->indexlist->num_elements == 0) {
/* no indexed fields */
return LDB_SUCCESS;
@@ -1300,12 +1325,12 @@ static int ltdb_index_add0(struct ldb_module *module, TALLOC_CTX *mem_ctx,
for (i = 0; i < num_el; i++) {
ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name,
- LTDB_IDXATTR);
+ NULL, LTDB_IDXATTR);
if (ret == -1) {
continue;
}
for (j = 0; j < elements[i].num_values; j++) {
- ret = ltdb_index_add1(module, mem_ctx, dn, &elements[i], j);
+ ret = ltdb_index_add1(module, dn, &elements[i], j);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -1318,17 +1343,17 @@ static int ltdb_index_add0(struct ldb_module *module, TALLOC_CTX *mem_ctx,
/*
add the index entries for a new record
*/
-int ltdb_index_add(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg)
+int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg)
{
+ const char *dn;
int ret;
- if (ldb_dn_is_special(msg->dn)) {
- return LDB_SUCCESS;
+ dn = ldb_dn_get_linearized(msg->dn);
+ if (dn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_index_add0(module, mem_ctx,
- msg->dn, msg->elements, msg->num_elements);
+ ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
return ret;
}
@@ -1337,93 +1362,76 @@ int ltdb_index_add(struct ldb_module *module, TALLOC_CTX *mem_ctx,
/*
delete an index entry for one message element
*/
-int ltdb_index_del_value(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn,
+int ltdb_index_del_value(struct ldb_module *module, const char *dn,
struct ldb_message_element *el, int v_idx)
{
struct ldb_context *ldb;
struct ldb_message *msg;
struct ldb_dn *dn_key;
- struct ldb_val dn_as_ldb_val, *found_val;
- int ret;
+ int ret, i;
+ unsigned int j;
ldb = ldb_module_get_ctx(module);
- if (ldb_dn_is_special(dn)) {
+ if (dn[0] == '@') {
return LDB_SUCCESS;
}
- msg = talloc(mem_ctx, struct ldb_message);
- if (msg == NULL) {
- ldb_oom(ldb);
+ dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
+ if (!dn_key) {
return LDB_ERR_OPERATIONS_ERROR;
}
- dn_key = ltdb_index_key(ldb, msg, el->name, &el->values[v_idx], NULL);
- if (!dn_key) {
- talloc_free(msg);
+ msg = talloc(dn_key, struct ldb_message);
+ if (msg == NULL) {
+ talloc_free(dn_key);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_index(module, dn_key, msg, NULL);
-
+ ret = ltdb_search_dn1_index(module, dn_key, msg);
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(msg);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(dn_key);
+ return ret;
}
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- talloc_free(msg);
/* it wasn't indexed. Did we have an earlier error? If we did then
its gone now */
+ talloc_free(dn_key);
return LDB_SUCCESS;
}
- el = ldb_msg_find_element(msg, LTDB_IDX);
- if (!el) {
- talloc_free(msg);
- /* there was set of index values on this index. Did we have an earlier error? If we did then
- its gone now */
- return LDB_SUCCESS;
- }
-
-
- dn_as_ldb_val = ldb_dn_get_casefold_as_ldb_val(dn);
- if (!dn_as_ldb_val.data) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- found_val = ldb_msg_find_val(el, &dn_as_ldb_val);
-
- if (!found_val) {
+ i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX);
+ if (i == -1) {
struct ldb_ldif ldif;
char *ldif_string;
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msg;
- ldif_string = ldb_ldif_write_string(ldb, msg, &ldif);
+ ldif_string = ldb_ldif_write_string(ldb, NULL, &ldif);
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "ERROR: dn %s not found in %s", ldb_dn_get_linearized(dn),
+ "ERROR: dn %s not found in %s", dn,
ldif_string);
+ talloc_free(ldif_string);
/* it ain't there. hmmm */
- talloc_free(msg);
+ talloc_free(dn_key);
return LDB_SUCCESS;
}
- talloc_free(found_val->data);
+ 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 (el->num_values == 1) {
- ret = ltdb_delete_noindex(module, msg, dn_key);
+ if (msg->elements[i].num_values == 0) {
+ ret = ltdb_delete_noindex(module, dn_key);
} else {
- int n = (found_val - el->values);
- if (n != el->num_values-1) {
- memmove(found_val, found_val+1, ((el->num_values-1) - n)*sizeof(*found_val));
- }
- el->num_values--;
-
- ret = ltdb_store_idxptr(module, msg, msg, el, TDB_REPLACE);
+ ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
}
- talloc_free(msg);
+ talloc_free(dn_key);
return ret;
}
@@ -1432,11 +1440,12 @@ int ltdb_index_del_value(struct ldb_module *module, TALLOC_CTX *mem_ctx,
delete the index entries for a record
return -1 on failure
*/
-int ltdb_index_del(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct ldb_message *msg)
+int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int ret;
+ const char *dn;
unsigned int i, j;
/* find the list of indexed fields */
@@ -1449,14 +1458,19 @@ int ltdb_index_del(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct
return LDB_SUCCESS;
}
+ dn = ldb_dn_get_linearized(msg->dn);
+ if (dn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
for (i = 0; i < msg->num_elements; i++) {
ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
- LTDB_IDXATTR);
+ NULL, LTDB_IDXATTR);
if (ret == -1) {
continue;
}
for (j = 0; j < msg->elements[i].num_values; j++) {
- ret = ltdb_index_del_value(module, mem_ctx, msg->dn, &msg->elements[i], j);
+ ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -1469,14 +1483,14 @@ int ltdb_index_del(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct
/*
handle special index for one level searches
*/
-int ltdb_index_one(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg, int add)
+int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
struct ldb_message_element el;
struct ldb_val val;
struct ldb_dn *pdn;
+ const char *dn;
int ret;
if (ldb_dn_is_special(msg->dn)) {
@@ -1484,30 +1498,37 @@ int ltdb_index_one(struct ldb_module *module, TALLOC_CTX *mem_ctx,
}
/* We index for ONE Level only if requested */
- ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, LTDB_IDXONE);
+ ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE);
if (ret != 0) {
return LDB_SUCCESS;
}
- pdn = ldb_dn_get_parent(mem_ctx, msg->dn);
+ pdn = ldb_dn_get_parent(module, msg->dn);
if (pdn == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- val = ldb_dn_get_casefold_as_ldb_val(pdn);
+ dn = ldb_dn_get_linearized(msg->dn);
+ if (dn == NULL) {
+ talloc_free(pdn);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn));
if (val.data == NULL) {
talloc_free(pdn);
- return LDB_ERR_INVALID_DN_SYNTAX;
+ return LDB_ERR_OPERATIONS_ERROR;
}
+ val.length = strlen((char *)val.data);
el.name = LTDB_IDXONE;
el.values = &val;
el.num_values = 1;
if (add) {
- ret = ltdb_index_add1(module, pdn, msg->dn, &el, 0);
+ ret = ltdb_index_add1(module, dn, &el, 0);
} else { /* delete */
- ret = ltdb_index_del_value(module, pdn, msg->dn, &el, 0);
+ ret = ltdb_index_del_value(module, dn, &el, 0);
}
talloc_free(pdn);
@@ -1536,6 +1557,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
struct ldb_context *ldb;
struct ldb_module *module = (struct ldb_module *)state;
struct ldb_message *msg;
+ const char *dn = NULL;
int ret;
TDB_DATA key2;
@@ -1561,7 +1583,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
/* check if the DN key has changed, perhaps due to the
case insensitivity of an element changing */
- key2 = ltdb_key(msg, msg->dn);
+ key2 = ltdb_key(module, msg->dn);
if (key2.dptr == NULL) {
/* probably a corrupt record ... darn */
ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
@@ -1569,15 +1591,21 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
talloc_free(msg);
return 0;
}
-
- if (tdb_data_cmp(&key2, &key) != 0) {
+ if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) {
tdb_delete(tdb, key);
tdb_store(tdb, key2, data, 0);
}
+ talloc_free(key2.dptr);
- ret = ltdb_index_one(module, msg, msg, 1);
+ if (msg->dn == NULL) {
+ dn = (char *)key.dptr + 3;
+ } else {
+ dn = ldb_dn_get_linearized(msg->dn);
+ }
+
+ ret = ltdb_index_one(module, msg, 1);
if (ret == LDB_SUCCESS) {
- ret = ltdb_index_add0(module, msg, msg->dn, msg->elements, msg->num_elements);
+ ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
} else {
ldb_debug(ldb, LDB_DEBUG_ERROR,
"Adding special ONE LEVEL index failed (%s)!",
@@ -1625,5 +1653,5 @@ int ltdb_reindex(struct ldb_module *module)
ltdb->idxptr->repack = true;
}
- return ltdb_set_casefold_index(module);
+ return LDB_SUCCESS;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index a128d9cc0c..a089a2f826 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -232,23 +232,29 @@ static int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn)
}
/*
- search the database for a single tdb key, returning all attributes
+ search the database for a single simple dn, returning all attributes
in a single message
return LDB_ERR_NO_SUCH_OBJECT on record-not-found
and LDB_SUCCESS on success
*/
-int ltdb_search_dn1_key(struct ldb_module *module,
- TDB_DATA tdb_key, struct ldb_message *msg)
+int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
int ret;
- TDB_DATA tdb_data;
+ 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 LDB_ERR_OPERATIONS_ERROR;
+ }
+
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
+ talloc_free(tdb_key.dptr);
if (!tdb_data.dptr) {
return LDB_ERR_NO_SUCH_OBJECT;
}
@@ -266,36 +272,13 @@ int ltdb_search_dn1_key(struct ldb_module *module,
}
if (!msg->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
+ msg->dn = ldb_dn_copy(msg, dn);
}
-
- return LDB_SUCCESS;
-}
-
-/*
- search the database for a single simple dn, returning all attributes
- in a single message
-
- return LDB_ERR_NO_SUCH_OBJECT on record-not-found
- and LDB_SUCCESS on success
-*/
-
-int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg)
-{
- int ret;
- TDB_DATA tdb_key;
-
- memset(msg, 0, sizeof(*msg));
-
- /* form the key */
- tdb_key = ltdb_key(msg, dn);
- if (!tdb_key.dptr) {
+ if (!msg->dn) {
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1_key(module, tdb_key, msg);
- talloc_free(tdb_key.dptr);
- return ret;
+ return LDB_SUCCESS;
}
/*
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 2348c0dcce..55acb6132d 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -103,53 +103,6 @@ int ltdb_unlock_read(struct ldb_module *module)
return 0;
}
-struct ldb_val ldb_dn_get_casefold_as_ldb_val(struct ldb_dn *dn) {
- struct ldb_val val;
- const char *casefold_dn = ldb_dn_get_casefold(dn);
- val.data = (uint8_t *)((uintptr_t)casefold_dn);
- val.length = strlen(casefold_dn);
- return val;
-}
-
-struct ldb_val ldb_dn_alloc_casefold_as_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
- struct ldb_val val;
- const char *casefold_dn = ldb_dn_alloc_casefold(mem_ctx, dn);
- val.data = (uint8_t *)((uintptr_t)casefold_dn);
- val.length = strlen(casefold_dn);
- return val;
-}
-
-/*
- form a TDB_DATA for a record key
- caller frees
-
- This version takes the casefolded string form of the DN as an ldb_val
-*/
-struct TDB_DATA ltdb_key_from_casefold_dn(TALLOC_CTX *mem_ctx,
- struct ldb_val dn_folded)
-{
- TDB_DATA key;
-
- key.dsize = dn_folded.length + 4;
- key.dptr = talloc_size(mem_ctx, key.dsize);
- if (!key.dptr) {
- goto failed;
- }
-
- memcpy(key.dptr, "DN=", 3);
- memcpy(&key.dptr[3], dn_folded.data, key.dsize - 4);
-
- key.dptr[key.dsize - 1] = '\0';
-
- return key;
-
-failed:
- errno = ENOMEM;
- key.dptr = NULL;
- key.dsize = 0;
- return key;
-}
-
/*
form a TDB_DATA for a record key
@@ -158,10 +111,12 @@ failed:
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(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
TDB_DATA key;
- struct ldb_val dn_folded;
+ char *key_str = NULL;
+ const char *dn_folded = NULL;
/*
most DNs are case insensitive. The exception is index DNs for
@@ -175,15 +130,31 @@ struct TDB_DATA ltdb_key(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
the indexing code handles the rest
*/
- dn_folded = ldb_dn_get_casefold_as_ldb_val(dn);
- if (!dn_folded.data) {
- errno = EINVAL;
- key.dptr = NULL;
- key.dsize = 0;
- return key;
+ dn_folded = ldb_dn_get_casefold(dn);
+ if (!dn_folded) {
+ goto failed;
+ }
+
+ key_str = talloc_strdup(ldb, "DN=");
+ if (!key_str) {
+ goto failed;
+ }
+
+ key_str = talloc_strdup_append_buffer(key_str, dn_folded);
+ if (!key_str) {
+ goto failed;
}
- return ltdb_key_from_casefold_dn(mem_ctx, dn_folded);
+ 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;
}
/*
@@ -242,15 +213,14 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
/*
store a record into the db
*/
-int ltdb_store(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg, int flgs)
+int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
TDB_DATA tdb_key, tdb_data;
int ret;
- tdb_key = ltdb_key(mem_ctx, msg->dn);
+ tdb_key = ltdb_key(module, msg->dn);
if (!tdb_key.dptr) {
return LDB_ERR_OTHER;
}
@@ -267,7 +237,7 @@ int ltdb_store(struct ldb_module *module, TALLOC_CTX *mem_ctx,
goto done;
}
- ret = ltdb_index_add(module, mem_ctx, msg);
+ ret = ltdb_index_add(module, msg);
if (ret != LDB_SUCCESS) {
tdb_delete(ltdb->tdb, tdb_key);
}
@@ -281,7 +251,6 @@ done:
static int ltdb_add_internal(struct ldb_module *module,
- TALLOC_CTX *mem_ctx,
const struct ldb_message *msg)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
@@ -314,7 +283,7 @@ static int ltdb_add_internal(struct ldb_module *module,
}
}
- ret = ltdb_store(module, mem_ctx, msg, TDB_INSERT);
+ ret = ltdb_store(module, msg, TDB_INSERT);
if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
ldb_asprintf_errstring(ldb,
@@ -324,7 +293,7 @@ static int ltdb_add_internal(struct ldb_module *module,
}
if (ret == LDB_SUCCESS) {
- ret = ltdb_index_one(module, mem_ctx, msg, 1);
+ ret = ltdb_index_one(module, msg, 1);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -349,7 +318,7 @@ static int ltdb_add(struct ltdb_context *ctx)
ldb_request_set_state(req, LDB_ASYNC_PENDING);
- tret = ltdb_add_internal(module, req, req->op.add.message);
+ tret = ltdb_add_internal(module, req->op.add.message);
if (tret != LDB_SUCCESS) {
return tret;
}
@@ -361,14 +330,14 @@ static int ltdb_add(struct ltdb_context *ctx)
delete a record from the database, not updating indexes (used for deleting
index records)
*/
-int ltdb_delete_noindex(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
{
void *data = ldb_module_get_private(module);
struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
TDB_DATA tdb_key;
int ret;
- tdb_key = ltdb_key(mem_ctx, dn);
+ tdb_key = ltdb_key(module, dn);
if (!tdb_key.dptr) {
return LDB_ERR_OTHER;
}
@@ -383,12 +352,12 @@ int ltdb_delete_noindex(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct l
return ret;
}
-static int ltdb_delete_internal(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
{
struct ldb_message *msg;
int ret;
- msg = talloc(mem_ctx, struct ldb_message);
+ msg = talloc(module, struct ldb_message);
if (msg == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -401,19 +370,19 @@ static int ltdb_delete_internal(struct ldb_module *module, TALLOC_CTX *mem_ctx,
goto done;
}
- ret = ltdb_delete_noindex(module, msg, dn);
+ ret = ltdb_delete_noindex(module, dn);
if (ret != LDB_SUCCESS) {
goto done;
}
/* remove one level attribute */
- ret = ltdb_index_one(module, msg, msg, 0);
+ ret = ltdb_index_one(module, msg, 0);
if (ret != LDB_SUCCESS) {
goto done;
}
/* remove any indexed attributes */
- ret = ltdb_index_del(module, msg, msg);
+ ret = ltdb_index_del(module, msg);
if (ret != LDB_SUCCESS) {
goto done;
}
@@ -443,7 +412,7 @@ static int ltdb_delete(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
- tret = ltdb_delete_internal(module, req, req->op.del.dn);
+ tret = ltdb_delete_internal(module, req->op.del.dn);
if (tret != LDB_SUCCESS) {
return tret;
}
@@ -520,14 +489,21 @@ static int msg_add_element(struct ldb_context *ldb,
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)
{
+ const char *dn;
unsigned int i, j;
+ dn = ldb_dn_get_linearized(msg->dn);
+ if (dn == NULL) {
+ return -1;
+ }
+
for (i=0;i<msg->num_elements;i++) {
if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
for (j=0;j<msg->elements[i].num_values;j++) {
- ltdb_index_del_value(module, msg, msg->dn,
+ ltdb_index_del_value(module, dn,
&msg->elements[i], j);
}
talloc_free(msg->elements[i].values);
@@ -574,7 +550,7 @@ static int msg_delete_element(struct ldb_module *module,
a = ldb_schema_attribute_by_name(ldb, el->name);
for (i=0;i<el->num_values;i++) {
- if (a->syntax->comparison_fn(ldb, msg,
+ if (a->syntax->comparison_fn(ldb, ldb,
&el->values[i], val) == 0) {
if (i<el->num_values-1) {
memmove(&el->values[i], &el->values[i+1],
@@ -583,7 +559,7 @@ static int msg_delete_element(struct ldb_module *module,
}
el->num_values--;
if (el->num_values == 0) {
- return msg_delete_attribute(module,
+ return msg_delete_attribute(module, ldb,
msg, name);
}
return 0;
@@ -602,7 +578,6 @@ static int msg_delete_element(struct ldb_module *module,
then we'll need to look at this again
*/
int ltdb_modify_internal(struct ldb_module *module,
- TALLOC_CTX *mem_ctx,
const struct ldb_message *msg)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
@@ -612,32 +587,28 @@ int ltdb_modify_internal(struct ldb_module *module,
struct ldb_message *msg2;
unsigned i, j;
int ret, idx;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- tdb_key = ltdb_key(tmp_ctx, msg->dn);
+
+ tdb_key = ltdb_key(module, msg->dn);
if (!tdb_key.dptr) {
- talloc_free(tmp_ctx);
return LDB_ERR_OTHER;
}
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
- talloc_free(tdb_key.dptr);
-
if (!tdb_data.dptr) {
+ talloc_free(tdb_key.dptr);
return ltdb_err_map(tdb_error(ltdb->tdb));
}
- msg2 = talloc(tmp_ctx, struct ldb_message);
+ msg2 = talloc(tdb_key.dptr, struct ldb_message);
if (msg2 == NULL) {
- ldb_oom(ldb);
- ret = LDB_ERR_OPERATIONS_ERROR;
- goto failed;
+ 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) {
@@ -648,6 +619,7 @@ int ltdb_modify_internal(struct ldb_module *module,
struct ldb_message_element *el = &msg->elements[i];
struct ldb_message_element *el2;
struct ldb_val *vals;
+ const char *dn;
const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
@@ -708,8 +680,7 @@ int ltdb_modify_internal(struct ldb_module *module,
el2->num_values + el->num_values);
if (vals == NULL) {
- ldb_oom(ldb);
- ret = LDB_ERR_OPERATIONS_ERROR;
+ ret = LDB_ERR_OTHER;
goto failed;
}
@@ -733,7 +704,7 @@ int ltdb_modify_internal(struct ldb_module *module,
}
/* replace all elements of this attribute name with the elements
listed. The attribute not existing is not an error */
- msg_delete_attribute(module, msg2, el->name);
+ msg_delete_attribute(module, ldb, msg2, el->name);
for (j=0;j<el->num_values;j++) {
if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
@@ -753,12 +724,17 @@ int ltdb_modify_internal(struct ldb_module *module,
case LDB_FLAG_MOD_DELETE:
+ dn = ldb_dn_get_linearized(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, msg2,
+ if (msg_delete_attribute(module, ldb, msg2,
msg->elements[i].name) != 0) {
- const char *dn = ldb_dn_get_linearized(msg->dn);
ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
goto failed;
@@ -770,15 +746,11 @@ int ltdb_modify_internal(struct ldb_module *module,
msg2,
msg->elements[i].name,
&msg->elements[i].values[j]) != 0) {
- const char *dn = ldb_dn_get_linearized(msg->dn);
- ldb_asprintf_errstring(ldb, "No matching attribute value (%*.*s) when deleting attribute: %s on %s",
- (int)msg->elements[i].values[j].length, (int)msg->elements[i].values[j].length,
- (const char *)msg->elements[i].values[j].data,
- msg->elements[i].name, dn);
+ ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
goto failed;
}
- ret = ltdb_index_del_value(module, tmp_ctx, msg->dn, &msg->elements[i], j);
+ ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
if (ret != LDB_SUCCESS) {
goto failed;
}
@@ -796,7 +768,7 @@ int ltdb_modify_internal(struct ldb_module *module,
/* we've made all the mods
* save the modified record back into the database */
- ret = ltdb_store(module, mem_ctx, msg2, TDB_MODIFY);
+ ret = ltdb_store(module, msg2, TDB_MODIFY);
if (ret != LDB_SUCCESS) {
goto failed;
}
@@ -806,11 +778,12 @@ int ltdb_modify_internal(struct ldb_module *module,
goto failed;
}
+ talloc_free(tdb_key.dptr);
free(tdb_data.dptr);
return ret;
failed:
- talloc_free(tmp_ctx);
+ talloc_free(tdb_key.dptr);
free(tdb_data.dptr);
return ret;
}
@@ -835,7 +808,7 @@ static int ltdb_modify(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
- tret = ltdb_modify_internal(module, req, req->op.mod.message);
+ tret = ltdb_modify_internal(module, req->op.mod.message);
if (tret != LDB_SUCCESS) {
return tret;
}
@@ -868,14 +841,12 @@ static int ltdb_rename(struct ltdb_context *ctx)
to fetch the old record */
tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
if (tret != LDB_SUCCESS) {
- talloc_free(msg);
/* not finding the old record is an error */
return tret;
}
msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
if (!msg->dn) {
- talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -883,14 +854,12 @@ static int ltdb_rename(struct ltdb_context *ctx)
* unique indexes. We rely on the transaction to make this
* atomic
*/
- tret = ltdb_delete_internal(module, msg, req->op.rename.olddn);
+ tret = ltdb_delete_internal(module, req->op.rename.olddn);
if (tret != LDB_SUCCESS) {
- talloc_free(msg);
return tret;
}
- tret = ltdb_add_internal(module, msg, msg);
- talloc_free(msg);
+ tret = ltdb_add_internal(module, msg);
if (tret != LDB_SUCCESS) {
return tret;
}
@@ -923,7 +892,7 @@ static int ltdb_prepare_commit(struct ldb_module *module)
return LDB_SUCCESS;
}
- if (ltdb_index_transaction_prepare_commit(module) != 0) {
+ if (ltdb_index_transaction_commit(module) != 0) {
tdb_transaction_cancel(ltdb->tdb);
ltdb->in_transaction--;
return ltdb_err_map(tdb_error(ltdb->tdb));
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 43f2909008..c8c1dad5de 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -29,8 +29,6 @@ struct ltdb_private {
bool check_base;
struct ltdb_idxptr *idxptr;
bool prepared_commit;
-
- int index_version;
};
/*
@@ -67,14 +65,6 @@ struct ltdb_context {
#define LTDB_OPTIONS "@OPTIONS"
#define LTDB_ATTRIBUTES "@ATTRIBUTES"
-#define LTDB_INDEX_VERSION "@INDEX_VERSION"
-
-/* ltdb index versions:
- 0 - Initial version, DN values as index values, not casefolded
- 1 - DN values as index values, casefolded and sorted (binary compare)
- */
-
-
/* special attribute types */
#define LTDB_SEQUENCE_NUMBER "sequenceNumber"
#define LTDB_CHECK_BASE "checkBaseOnSearch"
@@ -86,7 +76,6 @@ struct ltdb_context {
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_set_casefold_index(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 */
@@ -94,15 +83,12 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value);
struct ldb_parse_tree;
int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *);
-int ltdb_index_add(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg);
-int ltdb_index_del(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg);
-int ltdb_index_one(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg, int add);
+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_index_one(struct ldb_module *module, const struct ldb_message *msg, int add);
int ltdb_reindex(struct ldb_module *module);
int ltdb_index_transaction_start(struct ldb_module *module);
-int ltdb_index_transaction_prepare_commit(struct ldb_module *module);
+int ltdb_index_transaction_commit(struct ldb_module *module);
int ltdb_index_transaction_cancel(struct ldb_module *module);
/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */
@@ -121,14 +107,6 @@ int ltdb_unpack_data(struct ldb_module *module,
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);
-/*
- search the database for a single tdb key, returning all attributes
- in a single message
-
- return LDB_ERR_NO_SUCH_OBJECT on record-not-found
- and LDB_SUCCESS on success
-*/
-int ltdb_search_dn1_key(struct ldb_module *module, TDB_DATA tdb_key, struct ldb_message *msg);
int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg);
int ltdb_add_attr_results(struct ldb_module *module,
TALLOC_CTX *mem_ctx,
@@ -142,26 +120,12 @@ int ltdb_search(struct ltdb_context *ctx);
/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */
int ltdb_lock_read(struct ldb_module *module);
int ltdb_unlock_read(struct ldb_module *module);
-struct TDB_DATA ltdb_key(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
-/*
- form a TDB_DATA for a record key
- caller frees
+struct TDB_DATA ltdb_key(struct ldb_module *module, 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, struct ldb_dn *dn);
+int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg);
- This version takes the casefolded string form of the DN as an ldb_val
-*/
-struct TDB_DATA ltdb_key_from_casefold_dn(TALLOC_CTX *mem_ctx,
- struct ldb_val dn_folded);
-struct ldb_val ldb_dn_get_casefold_as_ldb_val(struct ldb_dn *dn);
-struct ldb_val ldb_dn_alloc_casefold_as_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
-int ltdb_store(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg, int flgs);
-int ltdb_delete_noindex(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn);
-int ltdb_modify_internal(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg);
-
-int ltdb_index_del_value(struct ldb_module *module, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn,
+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,