In the original patch (listed previously), when the search recurses it
will inevitably reallocate the visited list to a new array in memory.
When this happens the original patch didn't update it's reference to the
array.
This patch adds an extra level of indirection on the visited list in
order to fix this bug.
Signed-off-by: Adrian Cochrane <adrianc@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
const struct dsdb_dn *dn_to_match,
const char *dn_oid,
struct dsdb_dn *to_visit,
const struct dsdb_dn *dn_to_match,
const char *dn_oid,
struct dsdb_dn *to_visit,
- struct dsdb_dn **visited,
+ struct dsdb_dn ***visited,
unsigned int *visited_count,
bool *matched)
{
unsigned int *visited_count,
bool *matched)
{
* memory context.
*/
if (visited == NULL) {
* memory context.
*/
if (visited == NULL) {
- visited = talloc_array(mem_ctx, struct dsdb_dn *, 1);
- if (visited == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ } else if (*visited == NULL) {
+ *visited = talloc_array(mem_ctx, struct dsdb_dn *, 1);
+ if (*visited == NULL) {
talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
+ (*visited)[0] = to_visit;
(*visited_count) = 1;
} else {
(*visited_count) = 1;
} else {
- visited = talloc_realloc(mem_ctx, visited, struct dsdb_dn *,
+ *visited = talloc_realloc(mem_ctx, *visited, struct dsdb_dn *,
+ if (*visited == NULL) {
talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
- visited[(*visited_count)] = to_visit;
+ (*visited)[(*visited_count)] = to_visit;
* steal to_visit into visited array context, as it has to live until
* the array is freed.
*/
* steal to_visit into visited array context, as it has to live until
* the array is freed.
*/
- talloc_steal(visited, to_visit);
+ talloc_steal(*visited, to_visit);
/*
* Iterate over the values of the attribute of the entry being
/*
* Iterate over the values of the attribute of the entry being
* the current entry DN.
*/
for (j=0; j < (*visited_count) - 1; j++) {
* the current entry DN.
*/
for (j=0; j < (*visited_count) - 1; j++) {
- struct dsdb_dn *visited_dn = visited[j];
+ struct dsdb_dn *visited_dn = (*visited)[j];
if (ldb_dn_compare(visited_dn->dn,
next_to_visit->dn) == 0) {
skip = true;
if (ldb_dn_compare(visited_dn->dn,
next_to_visit->dn) == 0) {
skip = true;
struct dsdb_dn *dn_to_match;
const char *dn_oid;
unsigned int count;
struct dsdb_dn *dn_to_match;
const char *dn_oid;
unsigned int count;
+ struct dsdb_dn **visited;
schema = dsdb_get_schema(ldb, mem_ctx);
if (schema == NULL) {
schema = dsdb_get_schema(ldb, mem_ctx);
if (schema == NULL) {
return ldb_eval_transitive_filter_helper(mem_ctx, ldb, attr,
dn_to_match, dn_oid,
current_object_dn,
return ldb_eval_transitive_filter_helper(mem_ctx, ldb, attr,
dn_to_match, dn_oid,
current_object_dn,
- NULL, &count, matched);
+ &visited, &count, matched);