summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-09-09 19:12:47 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-09-09 19:12:47 -0400
commit6015107ae3c3eff5fb99fe5452c2475b23c70fd6 (patch)
treebfe977d91565e4d9367a44da1439bd38bf239f09 /src
parentf86f6c16e88047cb1684e3479bf629f748960759 (diff)
- fixup some heap corruption
- clean up the reference updating logic
Diffstat (limited to 'src')
-rw-r--r--src/back-shr.c173
-rw-r--r--src/format.c77
2 files changed, 150 insertions, 100 deletions
diff --git a/src/back-shr.c b/src/back-shr.c
index b254d6e..fac2da8 100644
--- a/src/back-shr.c
+++ b/src/back-shr.c
@@ -683,13 +683,6 @@ backend_shr_entry_is_a_set(struct plugin_state *state,
backend_entry_get_set_config_entry_filter());
}
-/* Update any entries in the map for which the passed-in entry will affect the
- * values which are derived. */
-struct backend_shr_update_references_cbdata {
- Slapi_PBlock *pb;
- Slapi_Entry *e;
-};
-
/* Build a filter which includes the basic_filter, if given, and ANDs that
* with an OR of the elements of attrs exactly matching the entry's DN. */
static char *
@@ -697,7 +690,7 @@ backend_build_filter(struct plugin_state *state, Slapi_DN *entry_dn,
const char *basic_filter, char **attrs)
{
char *filter, *tndn;
- int filter_size, i;
+ int filter_size, i, n_attrs;
if (basic_filter == NULL) {
basic_filter = "";
}
@@ -714,6 +707,7 @@ backend_build_filter(struct plugin_state *state, Slapi_DN *entry_dn,
strlen(attrs[i]) +
strlen(tndn));
}
+ n_attrs = i;
filter = malloc(filter_size);
if (filter == NULL) {
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -723,32 +717,63 @@ backend_build_filter(struct plugin_state *state, Slapi_DN *entry_dn,
free(tndn);
return NULL;
}
- if (strlen(basic_filter) > 0) {
- sprintf(filter, "(&%s(|", basic_filter);
+ if (n_attrs > 1) {
+ if (strlen(basic_filter) > 0) {
+ sprintf(filter, "(&%s(|", basic_filter);
+ } else {
+ sprintf(filter, "(|");
+ }
} else {
- sprintf(filter, "(|");
+ if (strlen(basic_filter) > 0) {
+ sprintf(filter, "(&%s", basic_filter);
+ } else {
+ strcpy(filter, "");
+ }
}
for (i = 0; (attrs != NULL) && (attrs[i] != NULL); i++) {
sprintf(filter + strlen(filter),
"(%s=%s)", attrs[i], tndn);
}
free(tndn);
- if (strlen(basic_filter) > 0) {
- strcat(filter, "))");
+ if (n_attrs > 1) {
+ if (strlen(basic_filter) > 0) {
+ strcat(filter, "))");
+ } else {
+ strcat(filter, ")");
+ }
} else {
- strcat(filter, ")");
+ if (strlen(basic_filter) > 0) {
+ strcat(filter, ")");
+ } else {
+ strcat(filter, "");
+ }
}
return filter;
}
+/* Add the name of this entry to the DN list in the cbdata. */
+struct backend_shr_note_entry_sdn_cbdata {
+ struct plugin_state *state;
+ Slapi_DN ***sdn_list;
+};
+
static int
-backend_shr_note_entry_sdn_cb(Slapi_Entry *e, void *cbdata)
+backend_shr_note_entry_sdn_cb(Slapi_Entry *e, void *cbdata_ptr)
{
- Slapi_DN ***sdn_list = cbdata;
- format_add_sdn_list(sdn_list, slapi_entry_get_dn(e));
+ struct backend_shr_note_entry_sdn_cbdata *cbdata = cbdata_ptr;
+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id,
+ "matched entry \"%s\"\n", slapi_entry_get_dn(e));
+ format_add_sdn_list(cbdata->sdn_list, slapi_entry_get_dn(e));
return 0;
}
+/* Update any entries in the map for which the passed-in entry will affect the
+ * values which are derived. */
+struct backend_shr_update_references_cbdata {
+ Slapi_PBlock *pb;
+ Slapi_Entry *e;
+};
+
static bool_t
backend_shr_update_references_cb(const char *group, const char *set,
bool_t flag,
@@ -757,13 +782,16 @@ backend_shr_update_references_cb(const char *group, const char *set,
struct plugin_state *state;
struct backend_shr_set_data *set_data;
struct backend_shr_update_references_cbdata *cbdata;
+ struct backend_shr_note_entry_sdn_cbdata note_cbdata;
Slapi_DN *referred_to_sdn, **these_entries, **prev_entries;
- Slapi_DN **ref_bases, **these_bases;
+ Slapi_DN **these_bases, **prev_bases;
Slapi_ValueSet *values;
Slapi_Value *value;
- char **ref_attrs, *actual_attr, *filter, **set_bases, *attrs[2];
+ char **ref_attrs, *actual_attr, *filter, **set_bases;
+ char *these_attrs[2], *prev_attrs[2];
struct format_inref_attr **inref_attrs;
struct format_ref_attr_list **ref_attr_list, *ref_attr;
+ struct format_ref_attr_list_link *this_attr_link, *prev_attr_link;
const char *ndn, *dn, *map_filter;
int i, j, k, l, disposition, buffer_flags, n_ref_attrs;
@@ -876,33 +904,43 @@ backend_shr_update_references_cb(const char *group, const char *set,
ref_attr = ref_attr_list[i];
these_entries = NULL;
prev_entries = NULL;
+ /* Start with this entry. */
format_add_sdn_list(&these_entries,
slapi_entry_get_dn(cbdata->e));
+ /* The last link in the chain just contains data (and we know
+ * that at the last link we have to find *this* entry), so
+ * start at the next-to-last link and work backwards from
+ * there. */
for (j = ref_attr->n_links - 2;
(j >= 0) && (these_entries != NULL);
j--) {
- /* If it's the first attribute, we can use the map's
- * filter to narrow the result set, too. */
- if (j == 0) {
- /* Search the map's locations using its filter
- * to narrow things down. */
- map_filter = set_data->entry_filter;
- ref_bases = format_make_sdn_list(set_data->bases);
+ /* We can populate the "previous links" set using the
+ * information in the previous link in the chain. */
+ if (j > 0) {
+ prev_attr_link = &ref_attr->links[j - 1];
+ prev_attrs[0] = prev_attr_link->attribute;
+ prev_attrs[1] = NULL;
+ prev_bases = prev_attr_link->base_sdn_list;
} else {
- /* Search the recorded parent locations. */
- map_filter = NULL;
- ref_bases = ref_attr->links[j - 1].base_sdn_list;
+ prev_attr_link = NULL;
+ prev_attrs[0] = NULL;
+ prev_attrs[1] = NULL;
+ prev_bases = NULL;
}
- these_bases = ref_attr->links[j].base_sdn_list;
- attrs[0] = ref_attr->links[j].attribute;
- attrs[1] = NULL;
+ /* We may have entries at this point in the chain
+ * which point to other entries at this point in the
+ * chain. */
+ this_attr_link = &ref_attr->links[j];
+ these_attrs[0] = this_attr_link->attribute;
+ these_attrs[1] = NULL;
+ these_bases = this_attr_link->base_sdn_list;
/* Search for entries which would be predecessors in
* the path to this entry. */
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"searching for references through "
"\"%s\" (link=%d)\n",
- attrs[0], j);
+ these_attrs[0], j);
for (k = 0; these_entries[k] != 0; k++) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
@@ -910,25 +948,26 @@ backend_shr_update_references_cb(const char *group, const char *set,
"\"%s\" (link=%d)\n",
slapi_sdn_get_ndn(these_entries[k]),
j);
- /* Build the search filter. */
+ /* Search for entries at this point in the
+ * chain which point to this entry in the
+ * chain (which we started with the entry
+ * which has just been modified). */
filter = backend_build_filter(state,
these_entries[k],
- map_filter,
- attrs);
- /* Walk the set of places to search for the
- * predecessors and look for predecessors. */
+ NULL,
+ these_attrs);
for (l = 0;
- (ref_bases != NULL) &&
- (ref_bases[l] != NULL);
+ (these_bases != NULL) &&
+ (these_bases[l] != NULL);
l++) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "searching from \"%s\""
- " for \"%s\"\n",
- slapi_sdn_get_ndn(ref_bases[l]),
+ "searching under "
+ "\"%s\" for \"%s\"\n",
+ slapi_sdn_get_ndn(these_bases[l]),
filter);
slapi_search_internal_set_pb(cbdata->pb,
- slapi_sdn_get_ndn(ref_bases[l]),
+ slapi_sdn_get_ndn(these_bases[l]),
LDAP_SCOPE_SUBTREE,
filter,
NULL,
@@ -937,25 +976,35 @@ backend_shr_update_references_cb(const char *group, const char *set,
NULL,
state->plugin_identity,
0);
+ note_cbdata.state = state;
+ note_cbdata.sdn_list = &these_entries;
slapi_search_internal_callback_pb(cbdata->pb,
- &prev_entries,
+ &note_cbdata,
NULL,
backend_shr_note_entry_sdn_cb,
NULL);
}
-#if 1
+ free(filter);
+ /* Search for entries in the previous link in
+ * the chain which point to this entry in the
+ * chain (which we started with the entry
+ * which has just been modified). */
+ filter = backend_build_filter(state,
+ these_entries[k],
+ NULL,
+ prev_attrs);
for (l = 0;
- (these_bases != NULL) &&
- (these_bases[l] != NULL);
+ (prev_bases != NULL) &&
+ (prev_bases[l] != NULL);
l++) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"searching from \"%s\""
" for \"%s\"\n",
- slapi_sdn_get_ndn(these_bases[l]),
+ slapi_sdn_get_ndn(prev_bases[l]),
filter);
slapi_search_internal_set_pb(cbdata->pb,
- slapi_sdn_get_ndn(these_bases[l]),
+ slapi_sdn_get_ndn(prev_bases[l]),
LDAP_SCOPE_SUBTREE,
filter,
NULL,
@@ -964,21 +1013,21 @@ backend_shr_update_references_cb(const char *group, const char *set,
NULL,
state->plugin_identity,
0);
+ note_cbdata.state = state;
+ note_cbdata.sdn_list = &prev_entries;
slapi_search_internal_callback_pb(cbdata->pb,
- &these_entries,
+ &note_cbdata,
NULL,
backend_shr_note_entry_sdn_cb,
NULL);
}
-#endif
+ free(filter);
}
/* Back up to process the list of predecessors. */
- format_free_sdn_list(these_entries);
- these_entries = prev_entries;
- prev_entries = NULL;
- /* Clean up the temporary SDN list, if we used one. */
- if (j == 0) {
- format_free_sdn_list(ref_bases);
+ if (j > 0) {
+ format_free_sdn_list(these_entries);
+ these_entries = prev_entries;
+ prev_entries = NULL;
}
}
/* Walk the last list of predecessors and update any related
@@ -987,9 +1036,17 @@ backend_shr_update_references_cb(const char *group, const char *set,
(these_entries != NULL) && (these_entries[j] != NULL);
j++) {
ndn = slapi_sdn_get_ndn(these_entries[j]);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "possible dependent entry: \"%s\"\n",
+ ndn);
if (!map_data_check_entry(state, group, set, ndn)) {
continue;
}
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "dependent entry: \"%s\"\n",
+ ndn);
backend_shr_set_config_entry_set_one_dn(state,
ndn,
set_data->self);
diff --git a/src/format.c b/src/format.c
index 3be6906..7a23d58 100644
--- a/src/format.c
+++ b/src/format.c
@@ -174,9 +174,10 @@ format_add_sdn_list(struct slapi_dn ***list, const char *dn)
}
ret[i++] = sdn;
ret[i] = NULL;
+ format_free_sdn_list(*list);
+ *list = ret;
}
- *list = ret;
- return ret;
+ return *list;
}
/* Maintain a reference attribute list, which is group of lists of attribute
@@ -217,12 +218,13 @@ format_dup_ref_attr_list(struct format_ref_attr_list **list)
if (ret != NULL) {
memset(ret, 0, (i + 1) * sizeof(struct format_ref_attr_list*));
for (i = 0; (list != NULL) && (list[i] != NULL); i++) {
- ret[i] = malloc(sizeof(list[i]));
+ ret[i] = malloc(sizeof(*(list[i])));
if (ret[i] == NULL) {
format_free_ref_attr_list(ret);
return NULL;
}
- ret[i]->links = malloc(sizeof(*ret[i]->links) *
+ memset(ret[i], 0, sizeof(*(ret[i])));
+ ret[i]->links = malloc(sizeof(*(ret[i]->links)) *
list[i]->n_links);
if (ret[i]->links == NULL) {
format_free_ref_attr_list(ret);
@@ -289,55 +291,30 @@ format_add_ref_attr_list(struct format_ref_attr_list ***list,
}
ret = malloc((i + 2) * sizeof(struct format_ref_attr_list*));
if (ret != NULL) {
- memset(ret, 0, (i + 2) * sizeof(struct format_ref_attr_list*));
- for (i = 0;
- (list != NULL) && (*list != NULL) && ((*list)[i] != NULL);
- i++) {
- ret[i] = malloc(sizeof((*list)[i]));
- if (ret[i] == NULL) {
- format_free_ref_attr_list(ret);
- return *list;
- }
- ret[i]->links = malloc(sizeof(*ret[i]->links) *
- (*list)[i]->n_links);
- if (ret[i]->links == NULL) {
- format_free_ref_attr_list(ret);
- return *list;
- }
- for (j = 0; j < (*list)[i]->n_links; j++) {
- ret[i]->links[j].attribute =
- strdup((*list)[i]->links[j].attribute);
- if (ret[i]->links[j].attribute == NULL) {
- format_free_ref_attr_list(ret);
- return *list;
- }
- sdn_list = (*list)[i]->links[j].base_sdn_list;
- ret[i]->links[j].base_sdn_list =
- format_dup_sdn_list(sdn_list);
- ret[i]->n_links++;
- }
- ret[i]->group = strdup((*list)[i]->group);
- ret[i]->set = strdup((*list)[i]->set);
- }
- ret[i] = malloc(sizeof(*ret));
+ memcpy(ret, *list, i * sizeof(struct format_ref_attr_list*));
+ free(*list);
+ *list = NULL;
+ ret[i] = malloc(sizeof(*(ret[i])));
if (ret[i] == NULL) {
format_free_ref_attr_list(ret);
- return *list;
+ return NULL;
}
+ memset(ret[i], 0, sizeof(*(ret[i])));
for (j = 0; names[j] != NULL; j++) {
continue;
}
ret[i]->links = malloc(sizeof(*(ret[i]->links)) * j);
if (ret[i]->links == NULL) {
format_free_ref_attr_list(ret);
- return *list;
+ return NULL;
}
+ memset(ret[i]->links, 0, sizeof(*(ret[i]->links)) * j);
ret[i]->n_links = j;
for (j = 0; j < ret[i]->n_links; j++) {
ret[i]->links[j].attribute = strdup(names[j]);
if (ret[i]->links[j].attribute == NULL) {
format_free_ref_attr_list(ret);
- return *list;
+ return NULL;
}
ret[i]->links[j].base_sdn_list = NULL;
}
@@ -345,9 +322,8 @@ format_add_ref_attr_list(struct format_ref_attr_list ***list,
ret[i]->set = strdup(set);
i++;
ret[i] = NULL;
+ *list = ret;
}
- format_free_ref_attr_list(*list);
- *list = ret;
return ret;
}
@@ -1075,8 +1051,13 @@ format_derefx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
/* Walk the set of entries for this iteration. */
for (j = 0; these[j] != NULL; j++) {
/* For heuristic use later, note the parent of the
- * entry which we've just found. */
- dn = slapi_sdn_get_dn(these[j]);
+ * entry from which we're reading this attribute. */
+ dn = slapi_sdn_get_ndn(these[j]);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "derefx: noting parent "
+ "\"%s\" for \"%s\"\n",
+ slapi_dn_parent(dn), attrs[0]);
format_add_sdn_list(&list->links[i].base_sdn_list,
slapi_dn_parent(dn));
/* Pull up the named entry. */
@@ -1090,6 +1071,12 @@ format_derefx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
"\"%s\"\n",
slapi_sdn_get_dn(these[j]));
continue;
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "derefx: reading entry "
+ "\"%s\" (%d)\n",
+ slapi_sdn_get_dn(these[j]), i);
}
/* Pull up the value set. */
if (slapi_vattr_values_get(entry, attrs[0], &values,
@@ -1131,6 +1118,12 @@ format_derefx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
continue;
}
format_add_bv_list(&choices, bval);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "derefx: found value "
+ "\"%.*s\" in \"%s\"\n",
+ bval->bv_len,
+ bval->bv_val, dn);
}
}
slapi_vattr_values_free(&values, &actual_attr,