From 3e4c4cff2177af33efdb15f03a1bbcb639505cee Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Aug 2005 15:02:01 +0000 Subject: r9391: Convert all the code to use struct ldb_dn to ohandle ldap like distinguished names Provide more functions to handle DNs in this form (This used to be commit 692e35b7797e39533dd2a1c4b63d9da30f1eb5ba) --- source4/lib/ldb/ldb_tdb/ldb_cache.c | 50 ++++++++++--- source4/lib/ldb/ldb_tdb/ldb_index.c | 133 ++++++++++++++++++++++++----------- source4/lib/ldb/ldb_tdb/ldb_pack.c | 21 ++++-- source4/lib/ldb/ldb_tdb/ldb_search.c | 37 ++++++---- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 113 +++++++++++++++++++---------- source4/lib/ldb/ldb_tdb/ldb_tdb.h | 12 ++-- 6 files changed, 253 insertions(+), 113 deletions(-) (limited to 'source4/lib/ldb/ldb_tdb') diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index be76f7085b..5e40b8fd3f 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -115,11 +115,17 @@ 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; - if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, msg) == -1) { + 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++) { @@ -176,11 +182,17 @@ 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; - if (ltdb_search_dn1(module, LTDB_SUBCLASSES, msg) == -1) { + 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]; @@ -245,7 +257,7 @@ static int ltdb_baseinfo_init(struct ldb_module *module) msg->num_elements = 1; msg->elements = ⪙ - msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); if (!msg->dn) { goto failed; } @@ -303,6 +315,8 @@ int ltdb_cache_reload(struct ldb_module *module) 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) { @@ -321,8 +335,11 @@ 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; - - if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) { + + 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; } @@ -331,7 +348,7 @@ int ltdb_cache_load(struct ldb_module *module) if (ltdb_baseinfo_init(module) != 0) { goto failed; } - if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) { + if (ltdb_search_dn1(module, baseinfo_dn, ltdb->cache->baseinfo) != 1) { goto failed; } } @@ -362,7 +379,10 @@ int ltdb_cache_load(struct ldb_module *module) goto failed; } - if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) { + 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; } @@ -374,9 +394,13 @@ int ltdb_cache_load(struct ldb_module *module) } done: + talloc_free(baseinfo_dn); + talloc_free(indexlist_dn); return 0; failed: + talloc_free(baseinfo_dn); + talloc_free(indexlist_dn); return -1; } @@ -407,8 +431,18 @@ int ltdb_increase_sequence_number(struct ldb_module *module) msg->num_elements = 1; msg->elements = ⪙ - msg->dn = talloc_strdup(msg, LTDB_BASEINFO); + msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); + if (msg->dn == NULL) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); + if (el.name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return -1; + } el.values = &val; el.num_values = 1; el.flags = LDB_FLAG_MOD_REPLACE; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 2fb6c34227..f78d840206 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -97,10 +97,11 @@ struct dn_list { return the dn key to be used for an index caller frees */ -static char *ldb_dn_key(struct ldb_context *ldb, +static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, const char *attr, const struct ldb_val *value) { - char *ret = NULL; + struct ldb_dn *ret; + char *dn; struct ldb_val v; const struct ldb_attrib_handler *h; char *attr_folded; @@ -121,16 +122,17 @@ static char *ldb_dn_key(struct ldb_context *ldb, if (ldb_should_b64_encode(&v)) { char *vstr = ldb_base64_encode(ldb, v.data, v.length); if (!vstr) return NULL; - ret = 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); } talloc_free(attr_folded); - return ret; + if (dn == NULL) return NULL; + goto done; } - ret = talloc_asprintf(ldb, "%s:%s:%.*s", + dn = talloc_asprintf(ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); if (v.data != value->data) { @@ -138,6 +140,9 @@ static char *ldb_dn_key(struct ldb_context *ldb, } talloc_free(attr_folded); +done: + ret = ldb_dn_explode(ldb, dn); + talloc_free(dn); return ret; } @@ -180,7 +185,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, struct dn_list *list) { struct ldb_context *ldb = module->ldb; - char *dn = NULL; + struct ldb_dn *dn; int ret; unsigned int i, j; struct ldb_message *msg; @@ -605,7 +610,7 @@ static int ltdb_index_dn(struct ldb_module *module, extracting just the given attributes */ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tree, - const char *base, + const struct ldb_dn *base, enum ldb_scope scope, const struct dn_list *dn_list, const char * const attrs[], struct ldb_message ***res) @@ -613,8 +618,9 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr unsigned int i; int count = 0; - for (i=0;icount;i++) { + for (i = 0; i < dn_list->count; i++) { struct ldb_message *msg; + struct ldb_dn *dn; int ret; msg = talloc(module, struct ldb_message); @@ -622,7 +628,14 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr return -1; } - ret = ltdb_search_dn1(module, dn_list->dn[i], msg); + dn = ldb_dn_explode(msg, dn_list->dn[i]); + if (dn == NULL) { + talloc_free(msg); + return -1; + } + + ret = ltdb_search_dn1(module, dn, msg); + talloc_free(dn); if (ret == 0) { /* the record has disappeared? yes, this can happen */ talloc_free(msg); @@ -654,7 +667,7 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr case the caller should call ltdb_search_full() */ int ltdb_search_indexed(struct ldb_module *module, - const char *base, + const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res) @@ -766,33 +779,32 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, { struct ldb_context *ldb = module->ldb; struct ldb_message *msg; - char *dn_key; + struct ldb_dn *dn_key; int ret; unsigned int i; - dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); - if (!dn_key) { + msg = talloc(module, struct ldb_message); + if (msg == NULL) { + errno = ENOMEM; return -1; } - msg = talloc(dn_key, struct ldb_message); - if (msg == NULL) { + 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(dn_key); + talloc_free(msg); return -1; } if (ret == 0) { - msg->dn = talloc_strdup(msg, dn_key); - if (!msg->dn) { - talloc_free(dn_key); - errno = ENOMEM; - return -1; - } + msg->dn = dn_key; msg->num_elements = 0; msg->elements = NULL; } @@ -813,22 +825,19 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn, ret = ltdb_store(module, msg, TDB_REPLACE); } - talloc_free(dn_key); + talloc_free(msg); return ret; } -/* - 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) +static int ltdb_index_add0(struct ldb_module *module, char *dn, + struct ldb_message_element *elements, int num_el) { struct ltdb_private *ltdb = module->private_data; int ret; unsigned int i, j; - if (msg->dn[0] == '@') { + if (dn[0] == '@') { return 0; } @@ -837,15 +846,16 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) return 0; } - for (i=0;inum_elements;i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, + 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;jelements[i].num_values;j++) { - ret = ltdb_index_add1(module, msg->dn, &msg->elements[i], j); + for (j = 0; j < elements[i].num_values; j++) { + ret = ltdb_index_add1(module, dn, &elements[i], j); if (ret == -1) { + talloc_free(dn); return -1; } } @@ -854,6 +864,28 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) 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 @@ -863,7 +895,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, { struct ldb_context *ldb = module->ldb; struct ldb_message *msg; - char *dn_key; + struct ldb_dn *dn_key; int ret, i; unsigned int j; @@ -897,7 +929,9 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); if (i == -1) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: dn %s not found in %s\n", dn, dn_key); + 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; @@ -930,32 +964,40 @@ 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 (msg->dn[0] == '@') { + 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;inum_elements;i++) { + 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;jelements[i].num_values;j++) { - ret = ltdb_index_del_value(module, msg->dn, &msg->elements[i], j); + 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; } @@ -979,6 +1021,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * { struct ldb_module *module = state; struct ldb_message *msg; + char *dn = NULL; int ret; TDB_DATA key2; @@ -1003,7 +1046,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", 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; } if (strcmp(key2.dptr, key.dptr) != 0) { @@ -1012,11 +1057,13 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * } talloc_free(key2.dptr); - if (!msg->dn) { - msg->dn = key.dptr+3; + if (msg->dn == NULL) { + dn = key.dptr + 3; + } else { + dn = ldb_dn_linearize(msg->dn, msg->dn); } - ret = ltdb_index_add(module, msg); + ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); talloc_free(msg); diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 4433e16cb2..332dbf03df 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -74,9 +74,16 @@ int ltdb_pack_data(struct ldb_module *module, struct ldb_context *ldb = module->ldb; unsigned int i, j, real_elements=0; size_t size; + char *dn; char *p; size_t len; + dn = ldb_dn_linearize(ldb, message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + for (i=0;inum_elements;i++) { if (message->elements[i].num_values != 0) { real_elements++; @@ -86,7 +93,7 @@ int ltdb_pack_data(struct ldb_module *module, /* work out how big it needs to be */ size = 8; - size += 1 + strlen(message->dn); + size += 1 + strlen(dn); for (i=0;inum_elements;i++) { if (message->elements[i].num_values == 0) { @@ -101,6 +108,7 @@ int ltdb_pack_data(struct ldb_module *module, /* allocate it */ data->dptr = talloc_array(ldb, char, size); if (!data->dptr) { + talloc_free(dn); errno = ENOMEM; return -1; } @@ -113,8 +121,8 @@ int ltdb_pack_data(struct ldb_module *module, /* the dn needs to be packed so we can be case preserving while hashing on a case folded dn */ - len = strlen(message->dn); - memcpy(p, message->dn, len+1); + len = strlen(dn); + memcpy(p, dn, len+1); p += len + 1; for (i=0;inum_elements;i++) { @@ -135,6 +143,7 @@ int ltdb_pack_data(struct ldb_module *module, } } + talloc_free(dn); return 0; } @@ -179,7 +188,11 @@ int ltdb_unpack_data(struct ldb_module *module, errno = EIO; goto failed; } - message->dn = p; + message->dn = ldb_dn_explode(message, p); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } remaining -= len + 1; p += len + 1; break; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 922d24b6eb..160affd4e7 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -94,7 +94,7 @@ static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *r for (i=0;inum_elements;i++) { const struct ldb_attrib_handler *h; h = ldb_attrib_handler(ldb, msg->elements[i].name); - if ((msg->dn[0] != '@') && (h->flags & LDB_ATTR_FLAG_HIDDEN)) { + if (ldb_dn_is_special(msg->dn) && (h->flags & LDB_ATTR_FLAG_HIDDEN)) { continue; } if (msg_add_element(ldb, ret, &msg->elements[i]) != 0) { @@ -122,7 +122,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, return NULL; } - ret->dn = talloc_strdup(ret, msg->dn); + ret->dn = ldb_dn_copy(ret, msg->dn); if (!ret->dn) { talloc_free(ret); return NULL; @@ -163,8 +163,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, } el2.num_values = 1; el2.values = &val; - val.data = ret->dn; - val.length = strlen(ret->dn); + val.data = ldb_dn_linearize(ret, ret->dn); + val.length = strlen(val.data); if (msg_add_element(ldb, ret, &el2) != 0) { talloc_free(ret); @@ -194,7 +194,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, return 1 on success, 0 on record-not-found and -1 on error */ -int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_message *msg) +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; @@ -231,7 +231,7 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag } if (!msg->dn) { - msg->dn = talloc_strdup(tdb_data2.dptr, dn); + msg->dn = ldb_dn_copy(tdb_data2.dptr, dn); } if (!msg->dn) { talloc_free(tdb_data2.dptr); @@ -245,7 +245,7 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag /* search the database for a single simple dn */ -static int ltdb_search_dn(struct ldb_module *module, const char *dn, +static int ltdb_search_dn(struct ldb_module *module, const struct ldb_dn *dn, const char * const attrs[], struct ldb_message ***res) { struct ldb_context *ldb = module->ldb; @@ -347,7 +347,7 @@ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg, struct ltdb_search_info { struct ldb_module *module; struct ldb_parse_tree *tree; - const char *base; + const struct ldb_dn *base; enum ldb_scope scope; const char * const *attrs; struct ldb_message **msgs; @@ -384,7 +384,11 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi } if (!msg->dn) { - msg->dn = key.dptr + 3; + msg->dn = ldb_dn_explode(msg, key.dptr + 3); + if (msg->dn == NULL) { + talloc_free(msg); + return -1; + } } /* see if it matches the given expression */ @@ -411,7 +415,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi this is the "full search" non-indexed variant */ static int ltdb_search_full(struct ldb_module *module, - const char *base, + const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res) @@ -454,7 +458,7 @@ static int ltdb_search_full(struct ldb_module *module, search the database with a LDAP-like expression. choses a search method */ -int ltdb_search_bytree(struct ldb_module *module, const char *base, +int ltdb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res) { @@ -466,7 +470,14 @@ int ltdb_search_bytree(struct ldb_module *module, const char *base, if (tree->operation == LDB_OP_EQUALITY && (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0 || ldb_attr_cmp(tree->u.equality.attr, "distinguishedName") == 0)) { - return ltdb_search_dn(module, tree->u.equality.value.data, attrs, res); + struct ldb_dn *dn; + dn = ldb_dn_explode(module->ldb, tree->u.equality.value.data); + if (dn == NULL) { + return -1; + } + ret = ltdb_search_dn(module, dn, attrs, res); + talloc_free(dn); + return ret; } if (ltdb_lock_read(module) != 0) { @@ -497,7 +508,7 @@ int ltdb_search_bytree(struct ldb_module *module, const char *base, search the database with a LDAP-like expression. choses a search method */ -int ltdb_search(struct ldb_module *module, const char *base, +int ltdb_search(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const attrs[], struct ldb_message ***res) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 40cfe97c29..61d0f9b64a 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -50,14 +50,12 @@ 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 char *dn) +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; - struct ldb_dn *edn = NULL; - struct ldb_dn *cedn = NULL; /* most DNs are case insensitive. The exception is index DNs for @@ -70,26 +68,14 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) 2) if the dn starts with @ then leave it alone - the indexing code handles the rest */ - if (*dn == '@') { - dn_folded = talloc_strdup(ldb, dn); - } else { - edn = ldb_dn_explode(ldb, dn); - if (!edn) - goto failed; - - cedn = ldb_dn_casefold(ldb, edn); - if (!cedn) - goto failed; - - dn_folded = ldb_dn_linearize(ldb, cedn); - if (!dn_folded) - goto failed; - talloc_free(edn); - talloc_free(cedn); + 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) { @@ -102,8 +88,6 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn) return key; failed: - talloc_free(edn); - talloc_free(cedn); errno = ENOMEM; key.dptr = NULL; key.dsize = 0; @@ -116,7 +100,8 @@ failed: static int ltdb_lock(struct ldb_module *module, const char *lockname) { struct ltdb_private *ltdb = module->private_data; - char *lock_dn; + struct ldb_dn *lock_dn; + char *ldn; TDB_DATA key; int ret; @@ -124,10 +109,17 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) return -1; } - lock_dn = talloc_asprintf(module->ldb, "%s_%s", LDBLOCK, lockname); + ldn = talloc_asprintf(module->ldb, "%s_%s", LDBLOCK, lockname); + if (ldn == NULL) { + return -1; + } + + lock_dn = ldb_dn_explode(module->ldb, ldn); if (lock_dn == NULL) { + talloc_free(ldn); return -1; } + talloc_free(ldn); key = ltdb_key(module, lock_dn); if (!key.dptr) { @@ -149,17 +141,25 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname) static int ltdb_unlock(struct ldb_module *module, const char *lockname) { struct ltdb_private *ltdb = module->private_data; - char *lock_dn; + struct ldb_dn *lock_dn; + char *ldn; TDB_DATA key; if (lockname == NULL) { return -1; } - lock_dn = talloc_asprintf(module->ldb, "%s_%s", LDBLOCK, lockname); + ldn = talloc_asprintf(module->ldb, "%s_%s", LDBLOCK, lockname); + if (ldn == NULL) { + return -1; + } + + lock_dn = ldb_dn_explode(module->ldb, ldn); if (lock_dn == NULL) { + talloc_free(ldn); return -1; } + talloc_free(ldn); key = ltdb_key(module, lock_dn); if (!key.dptr) { @@ -183,11 +183,21 @@ int ltdb_lock_read(struct ldb_module *module) { struct ltdb_private *ltdb = module->private_data; TDB_DATA key; + struct ldb_dn *lock_dn; int ret; - key = ltdb_key(module, LDBLOCK); + + lock_dn = ldb_dn_explode(module, LDBLOCK); + if (lock_dn == NULL) { + return -1; + } + + key = ltdb_key(module, lock_dn); if (!key.dptr) { + talloc_free(lock_dn); return -1; } + talloc_free(lock_dn); + ret = tdb_chainlock_read(ltdb->tdb, key); talloc_free(key.dptr); return ret; @@ -199,11 +209,21 @@ int ltdb_lock_read(struct ldb_module *module) int ltdb_unlock_read(struct ldb_module *module) { struct ltdb_private *ltdb = module->private_data; + struct ldb_dn *lock_dn; TDB_DATA key; - key = ltdb_key(module, LDBLOCK); + + lock_dn = ldb_dn_explode(module, LDBLOCK); + if (lock_dn == NULL) { + return -1; + } + + key = ltdb_key(module, lock_dn); if (!key.dptr) { + talloc_free(lock_dn); return -1; } + talloc_free(lock_dn); + tdb_chainunlock_read(ltdb->tdb, key); talloc_free(key.dptr); return 0; @@ -217,8 +237,9 @@ int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *m { struct ltdb_private *ltdb = module->private_data; int i, j; - - if (strcmp(msg->dn, LTDB_ATTRIBUTES) != 0) { + + if (! ldb_dn_is_special(msg->dn) || + ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { return 0; } @@ -241,17 +262,19 @@ int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *m we've made a modification to a dn - possibly reindex and update sequence number */ -static int ltdb_modified(struct ldb_module *module, const char *dn) +static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn) { int ret = 0; - if (strcmp(dn, LTDB_INDEXLIST) == 0 || - strcmp(dn, LTDB_ATTRIBUTES) == 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 && - strcmp(dn, LTDB_BASEINFO) != 0) { + !(ldb_dn_is_special(dn) && + ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { ret = ltdb_increase_sequence_number(module); } @@ -335,7 +358,7 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg) delete a record from the database, not updating indexes (used for deleting index records) */ -int ltdb_delete_noindex(struct ldb_module *module, const char *dn) +int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn) { struct ltdb_private *ltdb = module->private_data; TDB_DATA tdb_key; @@ -355,7 +378,7 @@ int ltdb_delete_noindex(struct ldb_module *module, const char *dn) /* delete a record from the database */ -static int ltdb_delete(struct ldb_module *module, const char *dn) +static int ltdb_delete(struct ldb_module *module, const struct ldb_dn *dn) { struct ltdb_private *ltdb = module->private_data; int ret; @@ -477,12 +500,18 @@ 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, msg->dn, &msg->elements[i], j); + ltdb_index_del_value(module, dn, &msg->elements[i], j); } talloc_free(msg->elements[i].values); if (msg->num_elements > (i+1)) { @@ -499,6 +528,7 @@ static int msg_delete_attribute(struct ldb_module *module, } } + talloc_free(dn); return 0; } @@ -593,6 +623,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms 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) { @@ -650,6 +681,10 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms break; case LDB_FLAG_MOD_DELETE: + + dn = ldb_dn_linearize(msg2, msg->dn); + if (dn == NULL) goto failed; + /* we could be being asked to delete all values or just some values */ if (msg->elements[i].num_values == 0) { @@ -668,7 +703,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms ltdb->last_err_string = "No such attribute"; goto failed; } - if (ltdb_index_del_value(module, msg->dn, &msg->elements[i], j) != 0) { + if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) { goto failed; } } @@ -730,7 +765,7 @@ static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg) /* rename a record */ -static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn) +static int ltdb_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn) { struct ltdb_private *ltdb = module->private_data; int ret; @@ -761,7 +796,7 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char goto failed; } - msg->dn = talloc_strdup(msg, newdn); + msg->dn = ldb_dn_copy(msg, newdn); if (!msg->dn) { goto failed; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 9ee3bfb70f..f08601832c 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -57,7 +57,7 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value); struct ldb_parse_tree; int ltdb_search_indexed(struct ldb_module *module, - const char *base, + const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res); @@ -81,23 +81,23 @@ 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); -int ltdb_search_dn1(struct ldb_module *module, const char *dn, 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, struct ldb_message *msg, const char * const attrs[], int *count, struct ldb_message ***res); -int ltdb_search(struct ldb_module *module, const char *base, +int ltdb_search(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const attrs[], struct ldb_message ***res); -int ltdb_search_bytree(struct ldb_module *module, const char *base, +int ltdb_search_bytree(struct ldb_module *module, const struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const attrs[], struct ldb_message ***res); /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ -struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn); +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 char *dn); +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_lock_read(struct ldb_module *module); int ltdb_unlock_read(struct ldb_module *module); -- cgit