summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_tdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_tdb.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c113
1 files changed, 74 insertions, 39 deletions
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;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->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;
}