summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-10-22 11:13:28 +1100
committerAndrew Tridgell <tridge@samba.org>2009-10-22 12:47:54 +1100
commit936c8f311ac435a7d6cf2643c3dc4a9cbc9a79da (patch)
tree5c80965609f0842a2d5ee2e4fe7c4c8fa2d75578
parent74ae8b90ae71446ccafab3a324087f2edf928b13 (diff)
downloadsamba-936c8f311ac435a7d6cf2643c3dc4a9cbc9a79da.tar.gz
samba-936c8f311ac435a7d6cf2643c3dc4a9cbc9a79da.tar.bz2
samba-936c8f311ac435a7d6cf2643c3dc4a9cbc9a79da.zip
s4-ldb: do more validation of idxptr lists
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 709a2e1626..c02e74b61d 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -95,6 +95,31 @@ static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn)
return ltdb_dn_list_find_val(list, &v);
}
+static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent)
+{
+ struct dn_list *list;
+ if (rec.dsize != sizeof(void *)) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Bad data size for idxptr %u", (unsigned)rec.dsize);
+ return NULL;
+ }
+
+ list = talloc_get_type(*(struct dn_list **)rec.dptr, struct dn_list);
+ if (list == NULL) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Bad type '%s' for idxptr",
+ talloc_get_name(*(struct dn_list **)rec.dptr));
+ return NULL;
+ }
+ if (check_parent && list->dn && talloc_parent(list->dn) != list) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Bad parent '%s' for idxptr",
+ talloc_get_name(talloc_parent(list->dn)));
+ return NULL;
+ }
+ return list;
+}
+
/*
return the @IDX list in an index entry for a dn as a
struct dn_list
@@ -128,13 +153,11 @@ static int ltdb_dn_list_load(struct ldb_module *module,
}
/* we've found an in-memory index entry */
- if (rec.dsize != sizeof(void *)) {
+ list2 = ltdb_index_idxptr(module, rec, true);
+ if (list2 == NULL) {
free(rec.dptr);
- ldb_asprintf_errstring(ldb_module_get_ctx(module),
- "Bad internal index size %u", (unsigned)rec.dsize);
return LDB_ERR_OPERATIONS_ERROR;
}
- list2 = *(struct dn_list **)rec.dptr;
free(rec.dptr);
*list = *list2;
@@ -234,13 +257,11 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
rec = tdb_fetch(ltdb->idxptr->itdb, key);
if (rec.dptr != NULL) {
- if (rec.dsize != sizeof(void *)) {
+ list2 = ltdb_index_idxptr(module, rec, false);
+ if (list2 == NULL) {
free(rec.dptr);
- ldb_asprintf_errstring(ldb_module_get_ctx(module),
- "Bad internal index size %u", (unsigned)rec.dsize);
return LDB_ERR_OPERATIONS_ERROR;
}
- list2 = *(struct dn_list **)rec.dptr;
free(rec.dptr);
list2->dn = talloc_steal(list2, list->dn);
list2->count = list->count;
@@ -274,13 +295,11 @@ static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_
struct ldb_val v;
struct dn_list *list;
- if (data.dsize != sizeof(void *)) {
- ldb_asprintf_errstring(ldb, "Bad internal index size %u", (unsigned)data.dsize);
+ list = ltdb_index_idxptr(module, data, true);
+ if (list == NULL) {
ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
return -1;
}
-
- list = *(struct dn_list **)data.dptr;
v.data = key.dptr;
v.length = key.dsize;