diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-09-09 19:12:47 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-09-09 19:12:47 -0400 |
| commit | 6015107ae3c3eff5fb99fe5452c2475b23c70fd6 (patch) | |
| tree | bfe977d91565e4d9367a44da1439bd38bf239f09 /src | |
| parent | f86f6c16e88047cb1684e3479bf629f748960759 (diff) | |
- fixup some heap corruption
- clean up the reference updating logic
Diffstat (limited to 'src')
| -rw-r--r-- | src/back-shr.c | 173 | ||||
| -rw-r--r-- | src/format.c | 77 |
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, + ¬e_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, + ¬e_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, |
